<template>
|
<view class="emergency-plan-view">
|
<!-- 使用通用页面头部组件 -->
|
<PageHeader title="应急预案详情"
|
@back="goBack" />
|
<!-- 详情内容 -->
|
<view class="detail-content"
|
v-if="currentPlan">
|
<!-- 基本信息 -->
|
<view class="info-section">
|
<!-- <view class="section-title">
|
<text class="title-text">{{ currentPlan.planName }}</text>
|
</view> -->
|
<view class="info-grid">
|
<view class="info-item">
|
<text class="info-label">应急预案编码</text>
|
<text class="info-value">{{ currentPlan.planCode || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">应急预案名称</text>
|
<text class="info-value">{{ currentPlan.planName || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">预案类型</text>
|
<u-tag :type="getPlanTypeTagType(currentPlan.planType)">
|
{{ emergencyPlanTypeLabel(currentPlan.planType) }}
|
</u-tag>
|
</view>
|
<view class="info-item">
|
<text class="info-label">发布生效时间</text>
|
<text class="info-value">{{ currentPlan.publishTime || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">核心责任人</text>
|
<text class="info-value">{{ currentPlan.coreResponsorUserName || '-' }}</text>
|
</view>
|
<view class="info-item">
|
<text class="info-label">备注</text>
|
<text class="info-value">{{ currentPlan.remark || '-' }}</text>
|
</view>
|
</view>
|
</view>
|
<!-- 适用范围 -->
|
<view class="scope-section">
|
<view class="section-header">
|
<text class="section-heading">适用范围</text>
|
</view>
|
<view class="scope-tags">
|
<u-tag v-for="(scope, index) in applyScopeList"
|
:key="index"
|
type="primary"
|
size="small"
|
class="scope-tag">
|
{{ scope }}
|
</u-tag>
|
</view>
|
</view>
|
<!-- 应急处置步骤 -->
|
<view class="steps-section">
|
<view class="section-header">
|
<text class="section-heading">应急处置步骤</text>
|
</view>
|
<view class="steps-list"
|
v-if="execStepsList.length > 0">
|
<view v-for="(step, index) in execStepsList"
|
:key="index"
|
class="step-item">
|
<view class="step-number">{{ index + 1 }}</view>
|
<view class="step-content">
|
<text class="step-title">{{ step.step }}</text>
|
<text class="step-description">{{ step.description }}</text>
|
</view>
|
</view>
|
</view>
|
<view class="no-steps"
|
v-else>
|
<text>暂无应急处置步骤</text>
|
</view>
|
</view>
|
</view>
|
<!-- 空状态 -->
|
<view class="empty-state"
|
v-else>
|
<text>暂无应急预案信息</text>
|
</view>
|
</view>
|
</template>
|
|
<script setup>
|
import { ref, onMounted, computed } from "vue";
|
import { onShow } from "@dcloudio/uni-app";
|
import PageHeader from "@/components/PageHeader.vue";
|
import { useDict } from "@/utils/dict";
|
|
// 替换 toast 方法
|
defineOptions({ name: "emergency-plan-view" });
|
const showToast = message => {
|
uni.showToast({
|
title: message,
|
icon: "none",
|
});
|
};
|
|
// 当前应急预案
|
const currentPlan = ref(null);
|
|
// 应急处置步骤列表
|
const execStepsList = ref([]);
|
|
// 适用范围列表
|
const applyScopeList = ref([]);
|
|
// 应急预案类型选项
|
const { emergency_plan_type } = useDict("emergency_plan_type");
|
const emergencyPlanTypeOptions = computed(
|
() => emergency_plan_type?.value || []
|
);
|
|
// 获取预案类型标签类型
|
const getPlanTypeTagType = planType => {
|
const typeMap = {
|
emergency: "warning",
|
fire: "danger",
|
natural: "info",
|
accident: "error",
|
};
|
return typeMap[planType] || "info";
|
};
|
|
// 获取预案类型标签文本
|
const emergencyPlanTypeLabel = val => {
|
const item = emergencyPlanTypeOptions.value.find(
|
i => String(i.value) === String(val)
|
);
|
return item ? item.label : val;
|
};
|
|
// 初始化数据
|
const initData = () => {
|
const emergencyPlan = uni.getStorageSync("emergencyPlan") || {};
|
if (emergencyPlan.id) {
|
currentPlan.value = emergencyPlan;
|
|
// 处理适用范围
|
if (emergencyPlan.applyScope) {
|
const scopes = emergencyPlan.applyScope.split(",");
|
applyScopeList.value = scopes.map(scope => {
|
const scopeMap = {
|
all: "全体员工",
|
manager: "管理层",
|
hr: "人事部门",
|
finance: "财务部门",
|
tech: "技术部门",
|
};
|
return scopeMap[scope] || scope;
|
});
|
} else {
|
applyScopeList.value = [];
|
}
|
|
// 处理应急处置步骤
|
if (emergencyPlan.execSteps) {
|
try {
|
execStepsList.value = JSON.parse(emergencyPlan.execSteps);
|
} catch (e) {
|
execStepsList.value = [];
|
}
|
} else {
|
execStepsList.value = [];
|
}
|
} else {
|
currentPlan.value = null;
|
applyScopeList.value = [];
|
execStepsList.value = [];
|
showToast("未找到应急预案信息");
|
}
|
};
|
|
// 返回上一页
|
const goBack = () => {
|
uni.navigateBack();
|
};
|
|
onMounted(() => {
|
initData();
|
});
|
|
onShow(() => {
|
initData();
|
});
|
</script>
|
|
<style scoped lang="scss">
|
@import "../../../styles/sales-common.scss";
|
|
.emergency-plan-view {
|
min-height: 100vh;
|
background: #f8f9fa;
|
padding-bottom: 32px;
|
}
|
|
.detail-content {
|
padding: 20px;
|
}
|
|
// 信息 section
|
.info-section {
|
background: #ffffff;
|
border-radius: 12px;
|
padding: 24px;
|
margin-bottom: 24px;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
}
|
|
.section-title {
|
display: flex;
|
align-items: center;
|
justify-content: space-between;
|
margin-bottom: 24px;
|
}
|
|
.title-text {
|
font-size: 18px;
|
font-weight: 600;
|
color: #303133;
|
flex: 1;
|
}
|
|
.type-tag {
|
margin-left: 16px;
|
}
|
|
.info-grid {
|
display: grid;
|
grid-template-columns: 1fr 1fr;
|
gap: 20px;
|
}
|
|
.info-item {
|
display: flex;
|
flex-direction: column;
|
gap: 8px;
|
}
|
|
.info-label {
|
font-size: 14px;
|
color: #909399;
|
}
|
|
.info-value {
|
font-size: 14px;
|
color: #303133;
|
word-break: break-all;
|
}
|
|
// 适用范围 section
|
.scope-section {
|
background: #ffffff;
|
border-radius: 12px;
|
padding: 24px;
|
margin-bottom: 24px;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
}
|
|
.section-header {
|
margin-bottom: 16px;
|
}
|
|
.section-heading {
|
font-size: 16px;
|
font-weight: 600;
|
color: #303133;
|
border-left: 4px solid #2979ff;
|
padding-left: 16px;
|
}
|
|
.scope-tags {
|
display: flex;
|
flex-wrap: wrap;
|
gap: 12px;
|
}
|
|
.scope-tag {
|
margin-bottom: 8px;
|
}
|
|
// 应急处置步骤 section
|
.steps-section {
|
background: #ffffff;
|
border-radius: 12px;
|
padding: 24px;
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
|
}
|
|
.steps-list {
|
margin-top: 16px;
|
}
|
|
.step-item {
|
display: flex;
|
margin-bottom: 24px;
|
position: relative;
|
}
|
|
.step-item::before {
|
content: "";
|
position: absolute;
|
left: 15px;
|
top: 40px;
|
bottom: -24px;
|
width: 2px;
|
background-color: #eaeaea;
|
}
|
|
.step-item:last-child::before {
|
display: none;
|
}
|
|
.step-number {
|
width: 32px;
|
height: 32px;
|
border-radius: 50%;
|
background-color: #2979ff;
|
color: #ffffff;
|
font-size: 14px;
|
font-weight: 600;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
margin-right: 16px;
|
flex-shrink: 0;
|
margin-top: 4px;
|
}
|
|
.step-content {
|
flex: 1;
|
}
|
|
.step-title {
|
font-size: 16px;
|
font-weight: 600;
|
color: #303133;
|
display: block;
|
margin-bottom: 8px;
|
}
|
|
.step-description {
|
font-size: 14px;
|
color: #606266;
|
line-height: 1.5;
|
word-break: break-all;
|
}
|
|
.no-steps {
|
padding: 40px;
|
text-align: center;
|
color: #909399;
|
font-size: 14px;
|
background-color: #f8f9fa;
|
border-radius: 8px;
|
}
|
|
// 空状态
|
.empty-state {
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
height: 60vh;
|
font-size: 16px;
|
color: #909399;
|
}
|
</style>
|