477 lines
12 KiB
Vue
477 lines
12 KiB
Vue
<template>
|
||
<div class="flowchart-container">
|
||
<h2 class="flowchart-title">装备管理系统流程图</h2>
|
||
|
||
<!-- 流程图主体 -->
|
||
<div class="flowchart-wrapper">
|
||
<!-- 所有连接线 (放在节点下层) -->
|
||
<div class="connections">
|
||
<!-- 装备录入 → 录入审核 -->
|
||
<line
|
||
:x1="140" :y1="140" :x2="140" :y2="200"
|
||
:class="{ active: activeNode === 'equipmentEntry' }"
|
||
/>
|
||
|
||
<!-- 录入审核 → 装备台账 -->
|
||
<line
|
||
:x1="200" :y1="230" :x2="230" :y2="230"
|
||
:class="{ active: activeNode === 'entryAudit' }"
|
||
/>
|
||
|
||
<!-- 装备台账 → 装备上架 -->
|
||
<line
|
||
:x1="300" :y1="260" :x2="300" :y2="320"
|
||
:class="{ active: activeNode === 'equipmentLedger' && activeLine === 'ledgerToShelf' }"
|
||
/>
|
||
|
||
<!-- 装备台账 → 自用出库 -->
|
||
<line
|
||
:x1="370" :y1="230" :x2="380" :y2="230"
|
||
:class="{ active: activeNode === 'equipmentLedger' && activeLine === 'ledgerToSelfOut' }"
|
||
/>
|
||
|
||
<!-- 自用出库 → 装备退库 -->
|
||
<line
|
||
:x1="440" :y1="380" :x2="440" :y2="440"
|
||
:class="{ active: activeNode === 'selfUseOut' }"
|
||
/>
|
||
|
||
<!-- 装备退库 → 装备维修 -->
|
||
<line
|
||
:x1="440" :y1="500" :x2="440" :y2="540"
|
||
:class="{ active: activeNode === 'equipmentReturn' }"
|
||
/>
|
||
|
||
<!-- 装备维修 → 装备退役 -->
|
||
<path
|
||
d="M440 600 H440 Q440 400 440 140"
|
||
:class="{ active: activeNode === 'equipmentRepair' && activeLine === 'repairToRetire' }"
|
||
/>
|
||
|
||
<!-- 装备上架 → 共享大厅 -->
|
||
<line
|
||
:x1="290" :y1="350" :x2="530" :y2="350"
|
||
:class="{ active: activeNode === 'equipmentShelf' && activeLine === 'shelfToRental' }"
|
||
/>
|
||
|
||
<!-- 装备上架 → 装备下架 -->
|
||
<path
|
||
d="M230 350 H200 V440 H140"
|
||
:class="{ active: activeNode === 'equipmentShelf' && activeLine === 'shelfToOffShelf' }"
|
||
/>
|
||
|
||
<!-- 共享大厅 → 共享出库 -->
|
||
<line
|
||
:x1="600" :y1="380" :x2="600" :y2="440"
|
||
:class="{ active: activeNode === 'rentalHall' }"
|
||
/>
|
||
|
||
<!-- 共享出库 → 共享退库 -->
|
||
<line
|
||
:x1="590" :y1="470" :x2="590" :y2="540"
|
||
:class="{ active: activeNode === 'shareOut' }"
|
||
/>
|
||
|
||
<!-- 共享退库 → 装备维修 -->
|
||
<line
|
||
:x1="590" :y1="570" :x2="440" :y2="570"
|
||
:class="{ active: activeNode === 'shareReturn' }"
|
||
/>
|
||
|
||
<!-- 装备维修 → 装备台账 -->
|
||
<path
|
||
d="M410 570 H370 V260 H300"
|
||
:class="{ active: activeNode === 'equipmentRepair' && activeLine === 'repairToLedger' }"
|
||
/>
|
||
|
||
<!-- 装备下架 → 装备退役 -->
|
||
<path
|
||
d="M140 470 V380 H180 Q250 200 380 110"
|
||
:class="{ active: activeNode === 'equipmentOffShelf' }"
|
||
/>
|
||
</div>
|
||
|
||
<!-- 所有节点 -->
|
||
<div class="nodes">
|
||
<!-- 装备录入 -->
|
||
<div
|
||
class="node entry-node"
|
||
:style="{ left: '80px', top: '80px' }"
|
||
@click="handleNodeClick('equipmentEntry')"
|
||
>
|
||
装备录入
|
||
</div>
|
||
|
||
<!-- 装备退役 -->
|
||
<div
|
||
class="node retire-node"
|
||
:style="{ left: '380px', top: '80px' }"
|
||
@click="handleNodeClick('equipmentRetire')"
|
||
>
|
||
装备退役
|
||
</div>
|
||
|
||
<!-- 录入审核 -->
|
||
<div
|
||
class="node audit-node"
|
||
:style="{ left: '80px', top: '200px' }"
|
||
@click="handleNodeClick('entryAudit')"
|
||
>
|
||
录入审核
|
||
</div>
|
||
|
||
<!-- 装备台账 -->
|
||
<div
|
||
class="node ledger-node"
|
||
:style="{ left: '230px', top: '200px' }"
|
||
@click="handleNodeClick('equipmentLedger')"
|
||
>
|
||
装备台账
|
||
</div>
|
||
|
||
<!-- 装备上架 -->
|
||
<div
|
||
class="node shelf-node"
|
||
:style="{ left: '230px', top: '320px' }"
|
||
@click="handleNodeClick('equipmentShelf')"
|
||
>
|
||
装备上架
|
||
</div>
|
||
|
||
<!-- 自用出库 -->
|
||
<div
|
||
class="node self-out-node"
|
||
:style="{ left: '380px', top: '320px' }"
|
||
@click="handleNodeClick('selfUseOut')"
|
||
>
|
||
自用出库
|
||
</div>
|
||
|
||
<!-- 装备退库 -->
|
||
<div
|
||
class="node return-node"
|
||
:style="{ left: '380px', top: '440px' }"
|
||
@click="handleNodeClick('equipmentReturn')"
|
||
>
|
||
装备退库
|
||
</div>
|
||
|
||
<!-- 装备维修 -->
|
||
<div
|
||
class="node repair-node"
|
||
:style="{ left: '380px', top: '540px' }"
|
||
@click="handleNodeClick('equipmentRepair')"
|
||
>
|
||
装备维修
|
||
</div>
|
||
|
||
<!-- 共享大厅 -->
|
||
<div
|
||
class="node rental-node"
|
||
:style="{ left: '530px', top: '320px' }"
|
||
@click="handleNodeClick('rentalHall')"
|
||
>
|
||
共享大厅
|
||
</div>
|
||
|
||
<!-- 共享出库 -->
|
||
<div
|
||
class="node share-out-node"
|
||
:style="{ left: '530px', top: '440px' }"
|
||
@click="handleNodeClick('shareOut')"
|
||
>
|
||
共享出库
|
||
</div>
|
||
|
||
<!-- 共享退库 -->
|
||
<div
|
||
class="node share-return-node"
|
||
:style="{ left: '530px', top: '540px' }"
|
||
@click="handleNodeClick('shareReturn')"
|
||
>
|
||
共享退库
|
||
</div>
|
||
|
||
<!-- 装备下架 -->
|
||
<div
|
||
class="node off-shelf-node"
|
||
:style="{ left: '80px', top: '440px' }"
|
||
@click="handleNodeClick('equipmentOffShelf')"
|
||
>
|
||
装备下架
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 节点信息面板 -->
|
||
<div class="info-panel" v-if="activeNode">
|
||
<h3>{{ nodeInfo.name }}</h3>
|
||
<p><strong>节点类型:</strong>{{ nodeInfo.type }}</p>
|
||
<p><strong>描述:</strong>{{ nodeInfo.description }}</p>
|
||
<p><strong>后续节点:</strong>{{ nodeInfo.nextNodes }}</p>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
name: 'EquipmentFlowChart',
|
||
data() {
|
||
return {
|
||
activeNode: null,
|
||
activeLine: null,
|
||
nodeData: {
|
||
equipmentEntry: {
|
||
name: '装备录入',
|
||
type: '初始节点',
|
||
description: '新增装备信息到系统中,记录装备基本属性',
|
||
nextNodes: '录入审核'
|
||
},
|
||
entryAudit: {
|
||
name: '录入审核',
|
||
type: '审核节点',
|
||
description: '对新录入的装备信息进行真实性和完整性审核',
|
||
nextNodes: '装备台账'
|
||
},
|
||
equipmentLedger: {
|
||
name: '装备台账',
|
||
type: '核心数据节点',
|
||
description: '存储和管理所有装备的基础信息及状态变动记录',
|
||
nextNodes: '装备上架、自用出库'
|
||
},
|
||
equipmentShelf: {
|
||
name: '装备上架',
|
||
type: '操作节点',
|
||
description: '将装备从库存状态转换为可共享状态,上架到共享平台',
|
||
nextNodes: '共享大厅、装备下架'
|
||
},
|
||
selfUseOut: {
|
||
name: '自用出库',
|
||
type: '操作节点',
|
||
description: '内部部门领用装备时办理的出库手续',
|
||
nextNodes: '装备退库'
|
||
},
|
||
equipmentReturn: {
|
||
name: '装备退库',
|
||
type: '操作节点',
|
||
description: '内部使用完毕后将装备归还入库的手续办理',
|
||
nextNodes: '装备维修'
|
||
},
|
||
equipmentRepair: {
|
||
name: '装备维修',
|
||
type: '处理节点',
|
||
description: '对有故障或达到维护周期的装备进行维修处理',
|
||
nextNodes: '装备退役、装备台账'
|
||
},
|
||
rentalHall: {
|
||
name: '共享大厅',
|
||
type: '展示节点',
|
||
description: '展示可共享装备信息,提供共享申请入口',
|
||
nextNodes: '共享出库'
|
||
},
|
||
shareOut: {
|
||
name: '共享出库',
|
||
type: '操作节点',
|
||
description: '外部单位共享装备时办理的出库手续',
|
||
nextNodes: '共享退库'
|
||
},
|
||
shareReturn: {
|
||
name: '共享退库',
|
||
type: '操作节点',
|
||
description: '外部单位共享装备归还时办理的入库手续',
|
||
nextNodes: '装备维修'
|
||
},
|
||
equipmentOffShelf: {
|
||
name: '装备下架',
|
||
type: '操作节点',
|
||
description: '将装备从共享平台下架,转为库存或待处理状态',
|
||
nextNodes: '装备退役'
|
||
},
|
||
equipmentRetire: {
|
||
name: '装备退役',
|
||
type: '终结节点',
|
||
description: '将达到使用年限或无法维修的装备标记为退役状态',
|
||
nextNodes: '无'
|
||
}
|
||
}
|
||
};
|
||
},
|
||
computed: {
|
||
nodeInfo() {
|
||
return this.nodeData[this.activeNode] || {};
|
||
}
|
||
},
|
||
methods: {
|
||
handleNodeClick(nodeId) {
|
||
// 重置状态
|
||
this.activeNode = nodeId;
|
||
this.activeLine = null;
|
||
|
||
// 对于有多个出线的节点,默认高亮第一条线
|
||
if (nodeId === 'equipmentLedger') {
|
||
this.activeLine = 'ledgerToShelf';
|
||
} else if (nodeId === 'equipmentShelf') {
|
||
this.activeLine = 'shelfToRental';
|
||
} else if (nodeId === 'equipmentRepair') {
|
||
this.activeLine = 'repairToRetire';
|
||
}
|
||
}
|
||
}
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
.flowchart-container {
|
||
position: relative;
|
||
padding: 20px;
|
||
background-color: #f8f9fa;
|
||
min-height: 100vh;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.flowchart-title {
|
||
text-align: center;
|
||
color: #333;
|
||
margin-bottom: 30px;
|
||
font-size: 24px;
|
||
}
|
||
|
||
.flowchart-wrapper {
|
||
position: relative;
|
||
width: 900px;
|
||
height: 700px;
|
||
margin: 0 auto;
|
||
background-color: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 连接线样式 */
|
||
.connections {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
pointer-events: none;
|
||
}
|
||
|
||
line, path {
|
||
stroke: #999;
|
||
stroke-width: 2px;
|
||
fill: none;
|
||
transition: all 0.3s ease;
|
||
}
|
||
|
||
line.active, path.active {
|
||
stroke: #ff4500;
|
||
stroke-width: 2.5px;
|
||
}
|
||
|
||
path {
|
||
stroke-dasharray: none;
|
||
}
|
||
|
||
/* 节点样式 */
|
||
.nodes {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
width: 100%;
|
||
height: 100%;
|
||
}
|
||
|
||
.node {
|
||
position: absolute;
|
||
width: 120px;
|
||
height: 60px;
|
||
border-radius: 6px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 14px;
|
||
font-weight: 500;
|
||
cursor: pointer;
|
||
transition: all 0.2s ease;
|
||
box-shadow: 0 2px 5px rgba(0, 0, 0, 0.1);
|
||
}
|
||
|
||
.node:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
||
}
|
||
|
||
/* 节点类型样式 */
|
||
.entry-node {
|
||
background-color: #e6f7ff;
|
||
border: 2px solid #409EFF;
|
||
color: #333;
|
||
}
|
||
|
||
.retire-node {
|
||
background-color: #ffe3e0;
|
||
border: 2px solid #f5222d;
|
||
color: #333;
|
||
}
|
||
|
||
.audit-node, .repair-node, .shelf-node, .off-shelf-node {
|
||
background-color: #f0fff3;
|
||
border: 2px solid #52c41a;
|
||
color: #333;
|
||
}
|
||
|
||
.ledger-node {
|
||
background-color: #fff1e8;
|
||
border: 2px solid #fa8c16;
|
||
color: #333;
|
||
width: 140px;
|
||
}
|
||
|
||
.self-out-node, .return-node, .share-out-node, .share-return-node {
|
||
background-color: #f0e6ff;
|
||
border: 2px solid #722ed1;
|
||
color: #333;
|
||
}
|
||
|
||
.rental-node {
|
||
background-color: #ffe6f2;
|
||
border: 2px solid #eb2f96;
|
||
color: #333;
|
||
width: 140px;
|
||
}
|
||
|
||
/* 选中节点样式 */
|
||
.node.active {
|
||
border-color: #ff4500;
|
||
border-width: 2.5px;
|
||
}
|
||
|
||
/* 信息面板 */
|
||
.info-panel {
|
||
position: fixed;
|
||
right: 30px;
|
||
top: 50%;
|
||
transform: translateY(-50%);
|
||
width: 250px;
|
||
background-color: white;
|
||
border-radius: 8px;
|
||
box-shadow: 0 3px 15px rgba(0, 0, 0, 0.15);
|
||
padding: 15px;
|
||
border-left: 4px solid #409EFF;
|
||
}
|
||
|
||
.info-panel h3 {
|
||
margin-top: 0;
|
||
color: #409EFF;
|
||
border-bottom: 1px solid #eee;
|
||
padding-bottom: 10px;
|
||
}
|
||
|
||
.info-panel p {
|
||
margin: 10px 0;
|
||
font-size: 14px;
|
||
color: #666;
|
||
}
|
||
</style>
|