bonus-ui/src/views/index.vue

477 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<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>