隐患详情重新设计,检查计划重新设计成做题排查式

This commit is contained in:
王利强
2026-06-21 16:30:12 +08:00
parent 1fe87ec438
commit cc94d3e3e9
256 changed files with 12542 additions and 5956 deletions

View File

@@ -0,0 +1,371 @@
/** 隐患详情历史节点类型 */
export const HAZARD_NODE_TYPES = {
SUBMIT: 'submit',
ASSIGN: 'assign',
RECTIFY: 'rectify',
VERIFY: 'verify',
WRITEOFF: 'writeoff'
};
export const HAZARD_STATUS_CLASS_MAP = {
1: 'status-blue',
2: 'status-orange',
3: 'status-red',
4: 'status-yellow',
5: 'status-green'
};
const STATUS_NAME_CLASS_MAP = {
待交办: 'status-blue',
待整改: 'status-orange',
整改中: 'status-orange',
待验收: 'status-red',
待销号: 'status-yellow',
已完成: 'status-green',
已销号: 'status-green'
};
const LEVEL_NAME_MAP = {
2: '一般隐患',
3: '重大隐患'
};
export function getLevelName(level) {
return LEVEL_NAME_MAP[level] || '未知';
}
export function getStatusClass(status, statusName) {
if (statusName && STATUS_NAME_CLASS_MAP[statusName]) {
return STATUS_NAME_CLASS_MAP[statusName];
}
return HAZARD_STATUS_CLASS_MAP[status] || '';
}
const LEVEL_CLASS_MAP = {
2: 'level-normal',
3: 'level-major'
};
const LEVEL_NAME_CLASS_MAP = {
一般: 'level-normal',
一般隐患: 'level-normal',
重大: 'level-major',
重大隐患: 'level-major'
};
export function getStepIconPath(type, active = false) {
const baseMap = {
submit: 'tijiao',
assign: 'jiaoban',
rectify: 'zhenggai',
verify: 'yanshou',
writeoff: 'xiaohao'
};
const base = baseMap[type] || 'tijiao';
if (base === 'zhenggai') {
return active
? '/static/yinhuan_detail/zhenggai_selected.png'
: '/static/yinhuan_detail/zhenggai__unselected.png';
}
return `/static/yinhuan_detail/${base}__${active ? 'selected' : 'unselected'}.png`;
}
export function getLevelClass(level, levelName) {
if (level != null && LEVEL_CLASS_MAP[level]) {
return LEVEL_CLASS_MAP[level];
}
if (levelName && LEVEL_NAME_CLASS_MAP[levelName]) {
return LEVEL_NAME_CLASS_MAP[levelName];
}
return '';
}
/** 将姓名数组或字符串格式化为「a、b、c」 */
export function formatNameList(names, fallback = '-') {
if (Array.isArray(names) && names.length) {
return names.join('、');
}
if (typeof names === 'string' && names.trim()) {
const parts = names.split(/[,,、]/).map((s) => s.trim()).filter(Boolean);
return parts.length ? parts.join('、') : names;
}
return fallback;
}
/** 判断是否为销号记录type=2 或 typeName=销号) */
export function isWriteoffRecord(record) {
if (!record) return false;
return record.type === 2 || record.typeName === '销号';
}
function buildVerifyNode(record) {
return {
type: HAZARD_NODE_TYPES.VERIFY,
nodeName: '验收',
titlePrefix: '验收',
operator: record.verifierName || '-',
time: record.verifyTime || '-',
content: {
resultName: record.resultName || '-',
remark: record.remark || '',
attachments: record.attachments || [],
signPath: record.signPath || '',
verifyDeptName: record.verifyDeptName || '-'
}
};
}
function buildWriteoffNode(record) {
return {
type: HAZARD_NODE_TYPES.WRITEOFF,
nodeName: '销号',
titlePrefix: '销号',
operator: record.verifierName || '-',
time: record.verifyTime || '-',
content: {
resultName: record.resultName || '-',
remark: record.remark || '',
attachments: record.attachments || [],
signPath: record.signPath || '',
writeoffDeptName: record.writeoffDeptName || '-'
}
};
}
/** 合并验收/销号记录,按 verifyId 去重 */
function appendAuditNodes(list, records, seenIds) {
(records || []).forEach((record) => {
if (!record) return;
const key = record.verifyId ?? record.id;
if (key != null) {
if (seenIds.has(key)) return;
seenIds.add(key);
}
list.push(isWriteoffRecord(record) ? buildWriteoffNode(record) : buildVerifyNode(record));
});
}
function resolveWriteoffRecords(flow) {
return flow.writeOffs || flow.writeoffs || [];
}
/** 解析整改责任人(兼容数组、逗号分隔字符串、单人字段) */
export function resolveRectifierNames(rectify) {
if (!rectify) return '-';
if (Array.isArray(rectify.rectifierNames) && rectify.rectifierNames.length) {
return rectify.rectifierNames.join('、');
}
if (Array.isArray(rectify.memberNames) && rectify.memberNames.length) {
return rectify.memberNames.join('、');
}
return formatNameList(rectify.rectifierName, '-');
}
/**
* 将隐患详情转为步骤历史列表(与后台 HazardDetailDrawer 保持一致)
* @param {Object} data 隐患详情
* @returns {Array}
*/
export function generateHazardHistory(data) {
if (!data) return [];
const list = [];
list.push({
type: HAZARD_NODE_TYPES.SUBMIT,
nodeName: '提交',
titlePrefix: '提交',
operator: data.reporterName || '-',
time: data.createdAt || '-',
content: {
title: data.title || '-',
source: data.source || '-',
areaName: data.areaName || '-',
areaColor: data.areaColor || '',
address: data.address || '-',
level: data.level,
levelName: data.levelName || getLevelName(data.level),
tagName: data.tagName || '-',
description: data.description || '-',
attachments: data.attachments || [],
legalBasis: data.legalBasis || data.regulationName || '-',
reporterPhone: data.reporterPhone || '-',
reportDeptName: data.reportDeptName || '-'
}
});
if (data.assignFlows && data.assignFlows.length > 0) {
data.assignFlows.forEach((flow) => {
if (flow.assignId) {
list.push({
type: HAZARD_NODE_TYPES.ASSIGN,
nodeName: '交办',
titlePrefix: '交办',
operator: flow.assignerName || '-',
time: flow.assignTime || '-',
content: {
assigneeName: flow.assigneeName || '-',
deadline: flow.deadline || '-',
assignDeptName: flow.assignDeptName || '-',
assignRemark: flow.assignRemark || '-',
priorityName: flow.priorityName || '-'
}
});
}
if (flow.rectify) {
list.push({
type: HAZARD_NODE_TYPES.RECTIFY,
nodeName: '整改',
titlePrefix: '整改',
operator: flow.rectify.rectifierName || '-',
time: flow.rectify.rectifyTime || '-',
content: {
rectifyPlan: flow.rectify.rectifyPlan || '-',
rectifyResult: flow.rectify.rectifyResult || '-',
rectificationMeasures: flow.rectify.rectificationMeasures || '-',
controlMeasures: flow.rectify.controlMeasures || '-',
deadline: flow.deadline || '-',
rectifierNames: resolveRectifierNames(flow.rectify),
managerNames: formatNameList(flow.rectify.managerNames, '-'),
planCost: flow.rectify.planCost,
actualCost: flow.rectify.actualCost,
attachments: flow.rectify.attachments || [],
signPath: flow.rectify.signPath || '',
rectifyStatusName: flow.rectify.rectifyStatusName || '-'
}
});
}
const seenAuditIds = new Set();
appendAuditNodes(list, flow.verifies || [], seenAuditIds);
appendAuditNodes(list, resolveWriteoffRecords(flow), seenAuditIds);
});
}
return list;
}
const LONG_DESCRIPTION =
'消防通道内堆放大量纸箱及杂物,影响疏散通道畅通,存在火灾安全隐患。' +
'现场检查发现通道宽度不足1.2米,部分区域被临时物料占用,紧急情况下可能影响人员撤离。' +
'建议立即清理并建立日常巡查机制,防止问题反弹。';
/** 开发联调前使用的 mock 详情数据(各节点均含完整假数据) */
export const MOCK_HAZARD_DETAIL = {
id: 'mock-hazard-001',
status: 2,
statusName: '整改中',
reporterName: '张三',
reporterPhone: '13800138000',
reportDeptName: '安全管理部',
createdAt: '2026-06-01 09:30:00',
title: '消防通道堆放杂物',
level: 2,
levelName: '一般隐患',
source: '部门检查',
areaName: '生产车间A区',
areaColor: '#409EFF',
address: '办公楼3层东侧消防通道',
tagName: '消防安全',
description: LONG_DESCRIPTION,
legalBasis: '《中华人民共和国消防法》第二十八条',
regulationName: '《中华人民共和国消防法》第二十八条',
attachments: [
{
fileName: 'hazard-1.jpg',
filePath: 'https://picsum.photos/seed/hazard1/200/200',
fileType: 'image'
},
{
fileName: 'hazard-2.jpg',
filePath: 'https://picsum.photos/seed/hazard2/200/200',
fileType: 'image'
},
{
fileName: 'hazard-3.jpg',
filePath: 'https://picsum.photos/seed/hazard3/200/200',
fileType: 'image'
}
],
assignFlows: [
{
assignId: 'mock-assign-001',
assignerName: '李主管',
assignTime: '2026-06-02 10:00:00',
assigneeName: '王整改',
assignDeptName: '设备保障部',
assignRemark: '该隐患位于主疏散通道,请优先处理,务必在整改期限内完成闭环。',
priorityName: '高',
deadline: '2026-06-10 18:00:00',
rectify: {
rectifyId: 'mock-rectify-001',
rectifierName: '王整改',
rectifyTime: '2026-06-08 15:20:00',
rectifyStatusName: '已完成',
rectifyPlan:
'立即清理消防通道杂物,并设置警示标识,后续每周巡查一次。' +
'对责任区域进行划分,明确禁止堆放物料的范围,同时组织一次消防安全培训。',
rectifyResult: '已完成清理,通道恢复畅通,现场已张贴禁止堆放标识。',
rectificationMeasures: '组织人员清理杂物,划定禁止堆放区域,增加日常巡检频次。',
controlMeasures: '安装监控并纳入日常巡检清单,发现反弹情况立即上报。',
rectifierNames: ['王整改', '赵协助'],
managerNames: ['李主管'],
planCost: 500,
actualCost: 380,
attachments: [
{
fileName: 'rectify-1.jpg',
filePath: 'https://picsum.photos/seed/rectify1/200/200',
fileType: 'image'
},
{
fileName: 'rectify-2.jpg',
filePath: 'https://picsum.photos/seed/rectify2/200/200',
fileType: 'image'
}
],
signPath: 'https://picsum.photos/seed/sign1/300/120'
},
verifies: [
{
verifierName: '陈验收',
verifyTime: '2026-06-09 11:00:00',
verifyDeptName: '安全监察组',
resultName: '通过',
remark: '现场复查通道畅通,整改到位,未发现反弹迹象。',
attachments: [
{
fileName: 'verify-1.jpg',
filePath: 'https://picsum.photos/seed/verify1/200/200',
fileType: 'image'
},
{
fileName: 'verify-2.jpg',
filePath: 'https://picsum.photos/seed/verify2/200/200',
fileType: 'image'
}
],
signPath: 'https://picsum.photos/seed/sign2/300/120'
}
],
writeOffs: [
{
verifierName: '刘销号',
verifyTime: '2026-06-10 16:30:00',
writeoffDeptName: '公司安委会',
resultName: '通过',
remark: '隐患已消除,整改资料齐全,同意销号。',
attachments: [
{
fileName: 'writeoff-1.jpg',
filePath: 'https://picsum.photos/seed/writeoff1/200/200',
fileType: 'image'
}
],
signPath: 'https://picsum.photos/seed/sign3/300/120'
}
]
}
]
};