<template>
|
<div class="warning-system">
|
<h2>预警联动机制</h2>
|
|
<!-- 统计卡片 -->
|
<div class="stats">
|
<div class="stat-card red">
|
<span class="number">2</span>
|
<span class="label">红色预警</span>
|
</div>
|
<div class="stat-card orange">
|
<span class="number">1</span>
|
<span class="label">橙色预警</span>
|
</div>
|
<div class="stat-card yellow">
|
<span class="number">1</span>
|
<span class="label">黄色预警</span>
|
</div>
|
<div class="stat-card green">
|
<span class="number">1</span>
|
<span class="label">绿色预警</span>
|
</div>
|
</div>
|
|
<!-- 预警列表 -->
|
<div class="warning-list">
|
<h3>预警列表</h3>
|
<table>
|
<thead>
|
<tr>
|
<th>编号</th>
|
<th>标题</th>
|
<th>类型</th>
|
<th>等级</th>
|
<th>状态</th>
|
<th>责任人</th>
|
<th>操作</th>
|
</tr>
|
</thead>
|
<tbody>
|
<tr v-for="warning in warnings" :key="warning.id">
|
<td>{{ warning.id }}</td>
|
<td>{{ warning.title }}</td>
|
<td>{{ warning.type }}</td>
|
<td>
|
<span :class="['level-tag', warning.level]">
|
{{ warning.levelText }}
|
</span>
|
</td>
|
<td>
|
<span :class="['status-tag', warning.status]">
|
{{ warning.statusText }}
|
</span>
|
</td>
|
<td>{{ warning.responsible }}</td>
|
<td>
|
<button @click="viewDetail(warning)">查看详情</button>
|
</td>
|
</tr>
|
</tbody>
|
</table>
|
</div>
|
|
<!-- 详情对话框 -->
|
<div v-if="showDetail" class="modal">
|
<div class="modal-content">
|
<h3>预警详情</h3>
|
<div v-if="currentWarning">
|
<p><strong>编号:</strong>{{ currentWarning.id }}</p>
|
<p><strong>标题:</strong>{{ currentWarning.title }}</p>
|
<p><strong>类型:</strong>{{ currentWarning.type }}</p>
|
<p><strong>等级:</strong>{{ currentWarning.levelText }}</p>
|
<p><strong>描述:</strong>{{ currentWarning.description }}</p>
|
<p><strong>影响:</strong>{{ currentWarning.impact }}</p>
|
<p><strong>建议:</strong>{{ currentWarning.suggestions }}</p>
|
</div>
|
<button @click="showDetail = false">关闭</button>
|
</div>
|
</div>
|
</div>
|
</template>
|
|
<script>
|
export default {
|
name: 'WarningSystem',
|
data() {
|
return {
|
showDetail: false,
|
currentWarning: null,
|
warnings: [
|
{
|
id: 'W001',
|
title: '项目预算超支预警',
|
type: '财务预警',
|
level: 'red',
|
levelText: '红色预警',
|
status: 'pending',
|
statusText: '待处理',
|
responsible: '张经理',
|
description: 'A项目预算执行率已达95%,预计将超出预算范围。',
|
impact: '影响项目整体财务指标,可能导致项目亏损',
|
suggestions: '暂停非必要支出,优化资源配置,申请预算调整'
|
},
|
{
|
id: 'W002',
|
title: '合同到期预警',
|
type: '合规预警',
|
level: 'orange',
|
levelText: '橙色预警',
|
status: 'processing',
|
statusText: '处理中',
|
responsible: '李主管',
|
description: '与供应商B的合同将于2024年1月25日到期。',
|
impact: '影响供应链稳定性,可能导致服务中断',
|
suggestions: '评估供应商表现,准备续签材料,制定备选方案'
|
},
|
{
|
id: 'W003',
|
title: '设备维护预警',
|
type: '运营预警',
|
level: 'yellow',
|
levelText: '黄色预警',
|
status: 'pending',
|
statusText: '待处理',
|
responsible: '王工程师',
|
description: '生产线设备C已运行8000小时,接近维护周期。',
|
impact: '可能影响生产效率和产品质量',
|
suggestions: '安排维护时间,准备备件,制定维护计划'
|
},
|
{
|
id: 'W004',
|
title: '人员配置预警',
|
type: '运营预警',
|
level: 'green',
|
levelText: '绿色预警',
|
status: 'resolved',
|
statusText: '已解决',
|
responsible: '赵HR',
|
description: '技术部门人员配置充足,项目进度正常。',
|
impact: '无负面影响',
|
suggestions: '继续监控人员配置情况'
|
},
|
{
|
id: 'W005',
|
title: '质量事故预警',
|
type: '运营预警',
|
level: 'red',
|
levelText: '红色预警',
|
status: 'pending',
|
statusText: '待处理',
|
responsible: '陈总监',
|
description: '产品D在客户现场出现质量问题。',
|
impact: '影响客户满意度,可能造成经济损失',
|
suggestions: '立即召回问题产品,分析原因,制定改进措施'
|
}
|
]
|
}
|
},
|
methods: {
|
viewDetail(warning) {
|
this.currentWarning = warning
|
this.showDetail = true
|
}
|
}
|
}
|
</script>
|
|
<style scoped>
|
.warning-system {
|
padding: 20px;
|
max-width: 1200px;
|
margin: 0 auto;
|
}
|
|
h2 {
|
color: #333;
|
margin-bottom: 30px;
|
}
|
|
.stats {
|
display: grid;
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
gap: 20px;
|
margin-bottom: 30px;
|
}
|
|
.stat-card {
|
padding: 20px;
|
border-radius: 8px;
|
color: white;
|
text-align: center;
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
}
|
|
.stat-card.red { background: linear-gradient(135deg, #ff6b6b, #ee5a52); }
|
.stat-card.orange { background: linear-gradient(135deg, #ffa726, #ff9800); }
|
.stat-card.yellow { background: linear-gradient(135deg, #ffd54f, #ffc107); }
|
.stat-card.green { background: linear-gradient(135deg, #66bb6a, #4caf50); }
|
|
.stat-card .number {
|
display: block;
|
font-size: 32px;
|
font-weight: bold;
|
margin-bottom: 8px;
|
}
|
|
.stat-card .label {
|
font-size: 14px;
|
opacity: 0.9;
|
}
|
|
.warning-list h3 {
|
margin-bottom: 20px;
|
color: #333;
|
}
|
|
table {
|
width: 100%;
|
border-collapse: collapse;
|
background: white;
|
border-radius: 8px;
|
overflow: hidden;
|
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
|
}
|
|
th, td {
|
padding: 12px;
|
text-align: left;
|
border-bottom: 1px solid #eee;
|
}
|
|
th {
|
background: #f8f9fa;
|
font-weight: 600;
|
color: #333;
|
}
|
|
.level-tag, .status-tag {
|
padding: 4px 8px;
|
border-radius: 4px;
|
font-size: 12px;
|
color: white;
|
}
|
|
.level-tag.red { background: #f56c6c; }
|
.level-tag.orange { background: #e6a23c; }
|
.level-tag.yellow { background: #e6a23c; }
|
.level-tag.green { background: #67c23a; }
|
|
.status-tag.pending { background: #f56c6c; }
|
.status-tag.processing { background: #e6a23c; }
|
.status-tag.resolved { background: #67c23a; }
|
|
button {
|
padding: 6px 12px;
|
margin: 0 4px;
|
border: none;
|
border-radius: 4px;
|
cursor: pointer;
|
font-size: 12px;
|
background: #409eff;
|
color: white;
|
}
|
|
.modal {
|
position: fixed;
|
top: 0;
|
left: 0;
|
width: 100%;
|
height: 100%;
|
background: rgba(0,0,0,0.5);
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
}
|
|
.modal-content {
|
background: white;
|
padding: 30px;
|
border-radius: 8px;
|
max-width: 600px;
|
width: 90%;
|
max-height: 80vh;
|
overflow-y: auto;
|
}
|
|
.modal-content h3 {
|
margin-bottom: 20px;
|
color: #333;
|
}
|
|
.modal-content p {
|
margin-bottom: 15px;
|
line-height: 1.6;
|
}
|
|
.modal-content strong {
|
color: #333;
|
}
|
|
.modal-content button {
|
background: #409eff;
|
color: white;
|
padding: 10px 20px;
|
font-size: 14px;
|
}
|
</style>
|