d1ca0cffa90d4c68534e97fd5816f6f4697aff336d50b92bfd4ede163a078eda.json 72 KB

1
  1. {"ast":null,"code":"import \"core-js/modules/es.array.concat.js\";\nimport \"core-js/modules/es.array.fill.js\";\nimport \"core-js/modules/es.array.find.js\";\nimport \"core-js/modules/es.array.push.js\";\nimport \"core-js/modules/es.function.name.js\";\nimport \"core-js/modules/es.iterator.constructor.js\";\nimport \"core-js/modules/es.iterator.find.js\";\nimport \"core-js/modules/es.object.to-string.js\";\nimport \"core-js/modules/es.string.starts-with.js\";\nimport Hammer from 'hammerjs';\nexport default {\n name: 'EmployeeProcess',\n data: function data() {\n return {\n processType: 'employee',\n currentType: 'employee-process',\n scale: 1,\n panEnabled: false,\n lastPosX: 0,\n lastPosY: 0,\n processOptions: [{\n value: 'employee',\n label: '员工入职流程'\n }, {\n value: 'sales',\n label: '销售订单流程'\n }, {\n value: 'shipping',\n label: '发货业务流程'\n }],\n processNodes: {\n employee: [{\n id: 'start',\n type: 'start',\n label: '开始',\n x: 400,\n y: 50,\n url: '/process/start'\n }, {\n id: 'interview',\n type: 'condition',\n label: '面试',\n x: 400,\n y: 150,\n url: '/interview'\n }, {\n id: 'pass',\n type: 'process',\n label: '发录用通知书',\n x: 600,\n y: 150,\n url: '/offer'\n }, {\n id: 'prepare',\n type: 'process',\n label: '准备入职材料',\n x: 600,\n y: 250,\n url: '/prepare'\n }, {\n id: 'verify',\n type: 'condition',\n label: '材料核实',\n x: 600,\n y: 350,\n url: '/verify'\n }, {\n id: 'onboard',\n type: 'process',\n label: '办理入职',\n x: 600,\n y: 450,\n url: '/onboard'\n }, {\n id: 'reject',\n type: 'process',\n label: '发送拒绝通知',\n x: 200,\n y: 250,\n url: '/reject'\n }, {\n id: 'archive',\n type: 'process',\n label: '归档简历',\n x: 200,\n y: 350,\n url: '/archive'\n }, {\n id: 'end',\n type: 'end',\n label: '结束',\n x: 400,\n y: 550,\n url: '/process/end'\n }],\n sales: [{\n id: 'start',\n type: 'start',\n label: '开始',\n x: 400,\n y: 50,\n url: '/sales/start'\n }, {\n id: 'inquiry',\n type: 'process',\n label: '客户询价',\n x: 400,\n y: 150,\n url: '/sales/inquiry'\n }, {\n id: 'need-analysis',\n type: 'process',\n label: '需求分析',\n x: 400,\n y: 250,\n url: '/sales/analysis'\n }, {\n id: 'solution',\n type: 'process',\n label: '方案制定',\n x: 400,\n y: 350,\n url: '/sales/solution'\n }, {\n id: 'quotation',\n type: 'process',\n label: '报价单生成',\n x: 400,\n y: 450,\n url: '/sales/quotation'\n }, {\n id: 'negotiation',\n type: 'process',\n label: '商务谈判',\n x: 400,\n y: 550,\n url: '/sales/negotiation'\n }, {\n id: 'decision',\n type: 'condition',\n label: '客户决策',\n x: 400,\n y: 650,\n url: '/sales/decision'\n }, {\n id: 'contract',\n type: 'process',\n label: '签订合同',\n x: 600,\n y: 650,\n url: '/sales/contract'\n }, {\n id: 'reject-reason',\n type: 'process',\n label: '原因分析',\n x: 200,\n y: 650,\n url: '/sales/reject'\n }, {\n id: 'followup',\n type: 'process',\n label: '持续跟进',\n x: 200,\n y: 750,\n url: '/sales/followup'\n }, {\n id: 'production',\n type: 'process',\n label: '生产准备',\n x: 600,\n y: 750,\n url: '/sales/production'\n }, {\n id: 'end-success',\n type: 'end',\n label: '流程完成',\n x: 400,\n y: 850,\n url: '/sales/completed'\n }],\n shipping: [{\n id: 'start',\n type: 'start',\n label: '开始',\n x: 400,\n y: 50,\n url: '/shipping/start'\n }, {\n id: 'order-receive',\n type: 'process',\n label: '接收订单',\n x: 400,\n y: 150,\n url: '/shipping/receive'\n }, {\n id: 'order-review',\n type: 'condition',\n label: '订单审核',\n x: 400,\n y: 250,\n url: '/shipping/review'\n }, {\n id: 'order-problem',\n type: 'process',\n label: '问题处理',\n x: 200,\n y: 250,\n url: '/shipping/problem'\n }, {\n id: 'batch-assign',\n type: 'process',\n label: '批次分配',\n x: 400,\n y: 350,\n url: '/shipping/batch'\n }, {\n id: 'inventory-check',\n type: 'condition',\n label: '库存检查',\n x: 400,\n y: 450,\n url: '/shipping/inventory'\n }, {\n id: 'replenishment',\n type: 'process',\n label: '补货流程',\n x: 600,\n y: 450,\n url: '/shipping/replenishment'\n }, {\n id: 'pick-pack',\n type: 'process',\n label: '拣货包装',\n x: 400,\n y: 550,\n url: '/shipping/pick'\n }, {\n id: 'quality-check',\n type: 'condition',\n label: '质量检查',\n x: 400,\n y: 650,\n url: '/shipping/quality'\n }, {\n id: 'rework',\n type: 'process',\n label: '返工处理',\n x: 200,\n y: 650,\n url: '/shipping/rework'\n }, {\n id: 'shipping-arrange',\n type: 'process',\n label: '物流安排',\n x: 400,\n y: 750,\n url: '/shipping/arrange'\n }, {\n id: 'invoice',\n type: 'process',\n label: '开具发票',\n x: 600,\n y: 750,\n url: '/shipping/invoice'\n }, {\n id: 'end',\n type: 'end',\n label: '发货完成',\n x: 400,\n y: 850,\n url: '/shipping/complete'\n }]\n },\n nodes: [],\n isMobile: false\n };\n },\n methods: {\n // 绘制流程线\n drawFlowLines: function drawFlowLines() {\n var withTransform = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;\n var canvas = this.$refs.flowCanvas;\n if (!canvas) {\n // 员工流程使用SVG绘制,所以Canvas可能不存在\n if (this.currentType !== 'employee-process') {\n console.warn('Canvas element not found but not in employee process mode');\n }\n return;\n }\n var ctx = canvas.getContext('2d');\n if (!withTransform) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n\n // 根据当前流程类型绘制不同的线条\n switch (this.currentType) {\n case 'employee-process':\n // 员工流程使用SVG绘制,不需要Canvas绘制\n break;\n case 'sales-process':\n this.drawSalesFlow(ctx);\n break;\n case 'shipping-process':\n this.drawShippingFlow(ctx);\n break;\n }\n },\n // 绘制员工入职流程线\n drawEmployeeFlow: function drawEmployeeFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#409EFF';\n\n // 从开始到面试\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n\n // 从面试到通过/不通过的分支\n ctx.beginPath();\n ctx.moveTo(430, 150);\n ctx.lineTo(570, 150);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(370, 150);\n ctx.lineTo(230, 250);\n ctx.stroke();\n\n // 通过分支:录用通知书 -> 准备入职材料 -> 材料核实 -> 办理入职\n ctx.beginPath();\n ctx.moveTo(600, 180);\n ctx.lineTo(600, 250);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(600, 280);\n ctx.lineTo(600, 350);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(600, 380);\n ctx.lineTo(600, 450);\n ctx.stroke();\n\n // 不通过分支:拒绝通知 -> 归档简历\n ctx.beginPath();\n ctx.moveTo(200, 280);\n ctx.lineTo(200, 350);\n ctx.stroke();\n\n // 办理入职 -> 结束\n ctx.beginPath();\n ctx.moveTo(600, 480);\n ctx.lineTo(600, 530);\n ctx.lineTo(400, 530);\n ctx.lineTo(400, 550);\n ctx.stroke();\n\n // 归档简历 -> 结束\n ctx.beginPath();\n ctx.moveTo(200, 380);\n ctx.lineTo(200, 530);\n ctx.lineTo(400, 530);\n ctx.stroke();\n\n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#409EFF';\n ctx.textAlign = 'center';\n ctx.fillText('通过', 500, 130);\n ctx.fillText('不通过', 300, 200);\n\n // 绘制材料核实的判断结果箭头\n ctx.beginPath();\n ctx.moveTo(570, 350);\n ctx.lineTo(530, 350);\n ctx.stroke();\n ctx.fillText('材料无误', 550, 330);\n },\n // 绘制销售订单流程线\n drawSalesFlow: function drawSalesFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#67C23A';\n\n // 主流程线条 - 垂直连线\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 180);\n ctx.lineTo(400, 250);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 280);\n ctx.lineTo(400, 350);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 380);\n ctx.lineTo(400, 450);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 480);\n ctx.lineTo(400, 550);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 580);\n ctx.lineTo(400, 650);\n ctx.stroke();\n\n // 决策分支\n ctx.beginPath();\n ctx.moveTo(400, 690);\n ctx.lineTo(400, 710);\n ctx.lineTo(600, 710);\n ctx.lineTo(600, 650);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 690);\n ctx.lineTo(400, 710);\n ctx.lineTo(200, 710);\n ctx.lineTo(200, 650);\n ctx.stroke();\n\n // 签订合同 -> 生产准备\n ctx.beginPath();\n ctx.moveTo(600, 680);\n ctx.lineTo(600, 750);\n ctx.stroke();\n\n // 原因分析 -> 持续跟进\n ctx.beginPath();\n ctx.moveTo(200, 680);\n ctx.lineTo(200, 750);\n ctx.stroke();\n\n // 生产准备 -> 结束\n ctx.beginPath();\n ctx.moveTo(600, 780);\n ctx.lineTo(600, 830);\n ctx.lineTo(400, 830);\n ctx.lineTo(400, 850);\n ctx.stroke();\n\n // 持续跟进 -> 结束\n ctx.beginPath();\n ctx.moveTo(200, 780);\n ctx.lineTo(200, 830);\n ctx.lineTo(400, 830);\n ctx.stroke();\n\n // 添加销售流程特效\n // 波纹效果圆圈\n ctx.beginPath();\n ctx.arc(400, 550, 15, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.2)';\n ctx.fill();\n ctx.beginPath();\n ctx.arc(400, 550, 10, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.4)';\n ctx.fill();\n ctx.beginPath();\n ctx.arc(400, 550, 5, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.6)';\n ctx.fill();\n\n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#67C23A';\n ctx.textAlign = 'center';\n ctx.fillText('通过', 500, 700);\n ctx.fillText('未通过', 300, 700);\n ctx.fillText('准备生产', 670, 750);\n ctx.fillText('流程终止', 150, 750);\n },\n // 绘制物流发货流程线\n drawShippingFlow: function drawShippingFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#E6A23C';\n ctx.shadowColor = 'rgba(230, 162, 60, 0.5)';\n ctx.shadowBlur = 10;\n\n // 主流程线条\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 180);\n ctx.lineTo(400, 250);\n ctx.stroke();\n\n // 订单审核分支\n ctx.beginPath();\n ctx.moveTo(400, 280);\n ctx.lineTo(400, 350);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(370, 250);\n ctx.lineTo(230, 250);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(200, 280);\n ctx.lineTo(200, 300);\n ctx.lineTo(350, 350);\n ctx.stroke();\n\n // 库存检查分支\n ctx.beginPath();\n ctx.moveTo(400, 380);\n ctx.lineTo(400, 450);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(430, 450);\n ctx.lineTo(570, 450);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(600, 480);\n ctx.lineTo(600, 500);\n ctx.lineTo(400, 500);\n ctx.lineTo(400, 550);\n ctx.stroke();\n\n // 质量检查分支\n ctx.beginPath();\n ctx.moveTo(400, 580);\n ctx.lineTo(400, 650);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(370, 650);\n ctx.lineTo(230, 650);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(400, 680);\n ctx.lineTo(400, 750);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(200, 680);\n ctx.lineTo(200, 700);\n ctx.lineTo(350, 750);\n ctx.stroke();\n\n // 发票和物流并行\n ctx.beginPath();\n ctx.moveTo(430, 750);\n ctx.lineTo(570, 750);\n ctx.stroke();\n\n // 收尾\n ctx.beginPath();\n ctx.moveTo(400, 780);\n ctx.lineTo(400, 850);\n ctx.stroke();\n ctx.beginPath();\n ctx.moveTo(600, 780);\n ctx.lineTo(600, 820);\n ctx.lineTo(400, 820);\n ctx.stroke();\n\n // 清除阴影效果,以免影响其他绘制\n ctx.shadowBlur = 0;\n\n // 添加发光点\n ctx.beginPath();\n ctx.arc(400, 150, 8, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n ctx.beginPath();\n ctx.arc(400, 450, 8, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n ctx.beginPath();\n ctx.arc(400, 750, 8, 0, Math.PI * 2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n\n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#E6A23C';\n ctx.textAlign = 'center';\n ctx.fillText('订单有问题', 280, 230);\n ctx.fillText('处理完成', 280, 330);\n ctx.fillText('库存不足', 510, 430);\n ctx.fillText('需要返工', 280, 630);\n ctx.fillText('完成修正', 280, 730);\n },\n handleNodeClick: function handleNodeClick(nodeId) {\n var _this = this;\n var node = this.processNodes[this.processType].find(function (n) {\n return n.id === nodeId;\n });\n if (node && node.url) {\n if (node.url.startsWith('http')) {\n window.open(node.url, '_blank');\n } else {\n this.$router.push(node.url)[\"catch\"](function (err) {\n if (err.name !== 'NavigationDuplicated') {\n _this.$message({\n type: 'info',\n message: \"\\u6B63\\u5728\\u8DF3\\u8F6C\\u5230\".concat(node.label, \"\\u9875\\u9762...\")\n });\n }\n });\n }\n }\n },\n checkDevice: function checkDevice() {\n this.isMobile = window.innerWidth < 768;\n if (this.isMobile) {\n this.scale = 0.6; // 移动端默认缩小到60%\n } else {\n this.scale = 1;\n }\n this.applyScale();\n },\n applyScale: function applyScale() {\n var el = this.$refs.processFlow;\n el.style.transform = \"translate(\".concat(this.lastPosX, \"px, \").concat(this.lastPosY, \"px) scale(\").concat(this.scale, \")\");\n\n // Canvas不能使用CSS缩放,需要重绘\n var canvas = this.$refs.flowCanvas;\n if (canvas && this.currentType !== 'employee-process') {\n var ctx = canvas.getContext('2d');\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.save();\n ctx.translate(this.lastPosX, this.lastPosY);\n ctx.scale(this.scale, this.scale);\n this.drawFlowLines(true); // 传递true表示已应用变换\n ctx.restore();\n }\n },\n handleResize: function handleResize() {\n this.checkDevice();\n },\n zoomIn: function zoomIn() {\n this.scale += 0.1;\n this.applyScale();\n },\n zoomOut: function zoomOut() {\n if (this.scale > 0.3) {\n this.scale -= 0.1;\n this.applyScale();\n }\n },\n resetZoom: function resetZoom() {\n this.scale = 1;\n this.$refs.processFlow.style.transform = 'translate(0px, 0px) scale(1)';\n this.lastPosX = 0;\n this.lastPosY = 0;\n },\n changeProcessType: function changeProcessType(type) {\n var _this2 = this;\n this.processType = type;\n switch (type) {\n case 'employee':\n this.currentType = 'employee-process';\n break;\n case 'sales':\n this.currentType = 'sales-process';\n break;\n case 'shipping':\n this.currentType = 'shipping-process';\n break;\n default:\n this.currentType = 'employee-process';\n }\n\n // 确保DOM更新后再应用缩放\n this.$nextTick(function () {\n _this2.resetZoom();\n _this2.applyScale();\n // 只有在非员工流程时才需要重绘Canvas流程线\n if (_this2.currentType !== 'employee-process') {\n _this2.drawFlowLines();\n }\n });\n },\n initHammer: function initHammer() {\n var _this3 = this;\n var el = this.$refs.processFlow;\n var hammertime = new Hammer(el);\n hammertime.get('pinch').set({\n enable: true\n });\n hammertime.get('pan').set({\n direction: Hammer.DIRECTION_ALL\n });\n hammertime.on('pinch', function (e) {\n var newScale = Math.max(0.3, Math.min(3, _this3.scale * e.scale));\n if (Math.abs(newScale - _this3.scale) > 0.01) {\n _this3.scale = newScale;\n _this3.applyScale();\n }\n });\n hammertime.on('pan', function (e) {\n if (_this3.panEnabled) {\n var deltaX = e.deltaX;\n var deltaY = e.deltaY;\n el.style.transform = \"translate(\".concat(_this3.lastPosX + deltaX, \"px, \").concat(_this3.lastPosY + deltaY, \"px) scale(\").concat(_this3.scale, \")\");\n if (e.isFinal) {\n _this3.lastPosX += deltaX;\n _this3.lastPosY += deltaY;\n }\n }\n });\n\n // 双击事件处理\n hammertime.on('doubletap', function () {\n _this3.resetZoom();\n });\n\n // 启用/禁用平移\n el.addEventListener('mousedown', function () {\n _this3.panEnabled = true;\n });\n document.addEventListener('mouseup', function () {\n _this3.panEnabled = false;\n });\n\n // 移动端触摸事件\n el.addEventListener('touchstart', function () {\n _this3.panEnabled = true;\n });\n document.addEventListener('touchend', function () {\n _this3.panEnabled = false;\n });\n }\n },\n mounted: function mounted() {\n var _this4 = this;\n // 确保初始化流程类型正确\n this.processType = 'employee';\n this.currentType = 'employee-process';\n this.$nextTick(function () {\n _this4.initHammer();\n // 只有在非员工流程时才绘制Canvas流程线\n if (_this4.currentType !== 'employee-process') {\n _this4.drawFlowLines();\n }\n });\n this.checkDevice();\n window.addEventListener('resize', this.handleResize);\n },\n beforeDestroy: function beforeDestroy() {\n window.removeEventListener('resize', this.handleResize);\n },\n computed: {\n displayNodes: function displayNodes() {\n return this.processNodes[this.processType];\n }\n }\n};","map":{"version":3,"names":["Hammer","name","data","processType","currentType","scale","panEnabled","lastPosX","lastPosY","processOptions","value","label","processNodes","employee","id","type","x","y","url","sales","shipping","nodes","isMobile","methods","drawFlowLines","withTransform","arguments","length","undefined","canvas","$refs","flowCanvas","console","warn","ctx","getContext","clearRect","width","height","drawSalesFlow","drawShippingFlow","drawEmployeeFlow","lineWidth","strokeStyle","beginPath","moveTo","lineTo","stroke","font","fillStyle","textAlign","fillText","arc","Math","PI","fill","shadowColor","shadowBlur","handleNodeClick","nodeId","_this","node","find","n","startsWith","window","open","$router","push","err","$message","message","concat","checkDevice","innerWidth","applyScale","el","processFlow","style","transform","save","translate","restore","handleResize","zoomIn","zoomOut","resetZoom","changeProcessType","_this2","$nextTick","initHammer","_this3","hammertime","get","set","enable","direction","DIRECTION_ALL","on","e","newScale","max","min","abs","deltaX","deltaY","isFinal","addEventListener","document","mounted","_this4","beforeDestroy","removeEventListener","computed","displayNodes"],"sources":["src/views/EmployeeProcess.vue"],"sourcesContent":["<template>\n <div class=\"process-container\">\n <el-card class=\"process-intro\">\n <div slot=\"header\" class=\"clearfix\">\n <span>业务流程图</span>\n <el-select v-model=\"processType\" placeholder=\"请选择流程类型\" size=\"mini\" style=\"float: right; width: 140px\" @change=\"changeProcessType\">\n <el-option\n v-for=\"item in processOptions\"\n :key=\"item.value\"\n :label=\"item.label\"\n :value=\"item.value\">\n </el-option>\n </el-select>\n </div>\n <div class=\"intro-header\">\n <h2 v-if=\"processType === 'employee'\">员工入职业务流程</h2>\n <h2 v-else-if=\"processType === 'sales'\">销售订单业务流程</h2>\n <h2 v-else-if=\"processType === 'shipping'\">物流发货业务流程</h2>\n <el-tag size=\"medium\" type=\"success\">正常运行</el-tag>\n </div>\n <div class=\"intro-content\">\n <div class=\"intro-description\">\n <p v-if=\"processType === 'employee'\">本流程规范了新员工从招聘到入职的完整过程,确保人才招聘和入职流程的规范化和标准化。</p>\n <p v-else-if=\"processType === 'sales'\">本流程详细描述了从客户询价到签订合同的销售订单全过程,提高销售转化率和客户满意度。</p>\n <p v-else-if=\"processType === 'shipping'\">本流程明确了从订单接收到物流发货的完整链条,保证货物及时准确送达客户手中。</p>\n </div>\n <div class=\"intro-stats\">\n <div class=\"stat-item\">\n <div class=\"stat-value\" v-if=\"processType === 'employee'\">7</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'sales'\">12</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'shipping'\">13</div>\n <div class=\"stat-label\">总步骤</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" v-if=\"processType === 'employee'\">4</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'sales'\">8</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'shipping'\">10</div>\n <div class=\"stat-label\">已完成</div>\n </div>\n <div class=\"stat-item\">\n <div class=\"stat-value\" v-if=\"processType === 'employee'\">15天</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'sales'\">7天</div>\n <div class=\"stat-value\" v-else-if=\"processType === 'shipping'\">3天</div>\n <div class=\"stat-label\">平均耗时</div>\n </div>\n </div>\n </div>\n </el-card>\n\n <div class=\"process-flow\" :class=\"currentType\" ref=\"processFlow\">\n <!-- 调试信息 -->\n <div class=\"debug-info\" style=\"position: absolute; top: 10px; right: 10px; background: rgba(0,0,0,0.7); color: white; padding: 5px; z-index: 100; font-size: 12px;\">\n 当前流程类型: {{ currentType }}\n </div>\n \n <!-- 使用Canvas代替SVG绘制流程线 -->\n <canvas ref=\"flowCanvas\" width=\"800\" height=\"800\" style=\"position: absolute; top: 0; left: 0; z-index: 5;\" v-if=\"currentType !== 'employee-process'\"></canvas>\n \n <!-- 员工流程使用SVG绘制 -->\n <svg class=\"flow-connectors\" width=\"900\" height=\"900\" v-if=\"currentType === 'employee-process'\">\n <!-- 定义箭头标记 -->\n <defs>\n <!-- 主流程蓝色箭头 -->\n <marker id=\"arrow-main\" viewBox=\"0 0 10 10\" refX=\"10\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#409EFF\"/>\n </marker>\n \n <!-- 分支流程橙色箭头 -->\n <marker id=\"arrow-branch\" viewBox=\"0 0 10 10\" refX=\"10\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#E6A23C\"/>\n </marker>\n \n <!-- 条件判断绿色箭头 -->\n <marker id=\"arrow-condition\" viewBox=\"0 0 10 10\" refX=\"10\" refY=\"5\"\n markerWidth=\"8\" markerHeight=\"8\" orient=\"auto\">\n <path d=\"M 0 0 L 10 5 L 0 10 z\" fill=\"#67C23A\"/>\n </marker>\n </defs>\n \n <!-- 主流程线 -->\n <!-- 从开始到面试 -->\n <path d=\"M 400,80 L 400,115\" class=\"process-line main\" \n marker-end=\"url(#arrow-main)\"/>\n \n <!-- 从面试到通过/不通过的分支 -->\n <path d=\"M 430,150 L 560,150\" class=\"process-line main\"\n marker-end=\"url(#arrow-main)\"/>\n \n <path d=\"M 370,150 L 230,220\" class=\"process-line branch\"\n marker-end=\"url(#arrow-branch)\"/>\n \n <!-- 通过分支:录用通知书 -> 准备入职材料 -> 材料核实 -> 办理入职 -->\n <path d=\"M 600,180 L 600,215\" class=\"process-line main\"\n marker-end=\"url(#arrow-main)\"/>\n \n <path d=\"M 600,280 L 600,315\" class=\"process-line main\"\n marker-end=\"url(#arrow-main)\"/>\n \n <path d=\"M 600,380 L 600,415\" class=\"process-line main\"\n marker-end=\"url(#arrow-main)\"/>\n \n <!-- 不通过分支:拒绝通知 -> 归档简历 -->\n <path d=\"M 200,280 L 200,315\" class=\"process-line branch\"\n marker-end=\"url(#arrow-branch)\"/>\n \n <!-- 条件判断 -->\n <path d=\"M 570,350 L 530,350\" class=\"process-line condition\"\n marker-end=\"url(#arrow-condition)\"/>\n \n <!-- 办理入职 -> 结束 -->\n <path d=\"M 600,480 L 600,530 L 400,530 L 400,515\" class=\"process-line main\"\n marker-end=\"url(#arrow-main)\"/>\n \n <!-- 归档简历 -> 结束 -->\n <path d=\"M 200,380 L 200,530 L 365,530\" class=\"process-line branch\"\n marker-end=\"url(#arrow-branch)\"/>\n \n <!-- 文本标签 -->\n <text x=\"500\" y=\"130\" class=\"flow-text main\">通过</text>\n <text x=\"290\" y=\"180\" class=\"flow-text branch\">不通过</text>\n <text x=\"550\" y=\"330\" class=\"flow-text condition\">材料无误</text>\n \n <!-- 给流程图添加一些视觉效果 -->\n <!-- 流程节点强调圆圈 -->\n <circle cx=\"400\" cy=\"50\" r=\"10\" class=\"node-emphasis start\" />\n <circle cx=\"400\" cy=\"150\" r=\"8\" class=\"node-emphasis condition\" />\n <circle cx=\"600\" cy=\"350\" r=\"8\" class=\"node-emphasis condition\" />\n <circle cx=\"400\" cy=\"550\" r=\"10\" class=\"node-emphasis end\" />\n </svg>\n\n <!-- 节点 -->\n <div \n v-for=\"(node, index) in displayNodes\"\n :key=\"index\"\n :id=\"node.id\" \n :class=\"['flow-node', node.type]\" \n :style=\"{\n left: `${node.x - 60}px`,\n top: `${node.y - 30}px`,\n width: node.width ? `${node.width}px` : '120px',\n height: node.height ? `${node.height}px` : '60px'\n }\"\n @click=\"handleNodeClick(node.id)\"\n >\n <span class=\"node-label\">{{ node.label }}</span>\n </div>\n </div>\n \n <!-- 缩放控制按钮 -->\n <div class=\"zoom-controls\">\n <div class=\"zoom-btn\" @click=\"zoomIn\"><i class=\"el-icon-plus\"></i></div>\n <div class=\"zoom-btn\" @click=\"zoomOut\"><i class=\"el-icon-minus\"></i></div>\n <div class=\"zoom-btn\" @click=\"resetZoom\"><i class=\"el-icon-refresh\"></i></div>\n </div>\n </div>\n</template>\n\n<script>\nimport Hammer from 'hammerjs';\n\nexport default {\n name: 'EmployeeProcess',\n data() {\n return {\n processType: 'employee',\n currentType: 'employee-process',\n scale: 1,\n panEnabled: false,\n lastPosX: 0,\n lastPosY: 0,\n processOptions: [\n { value: 'employee', label: '员工入职流程' },\n { value: 'sales', label: '销售订单流程' },\n { value: 'shipping', label: '发货业务流程' }\n ],\n processNodes: {\n employee: [\n { \n id: 'start', \n type: 'start', \n label: '开始', \n x: 400, \n y: 50,\n url: '/process/start'\n },\n { \n id: 'interview', \n type: 'condition', \n label: '面试', \n x: 400, \n y: 150,\n url: '/interview'\n },\n { \n id: 'pass', \n type: 'process', \n label: '发录用通知书', \n x: 600, \n y: 150,\n url: '/offer'\n },\n { \n id: 'prepare', \n type: 'process', \n label: '准备入职材料', \n x: 600, \n y: 250,\n url: '/prepare'\n },\n { \n id: 'verify', \n type: 'condition', \n label: '材料核实', \n x: 600, \n y: 350,\n url: '/verify'\n },\n { \n id: 'onboard', \n type: 'process', \n label: '办理入职', \n x: 600, \n y: 450,\n url: '/onboard'\n },\n { \n id: 'reject', \n type: 'process', \n label: '发送拒绝通知', \n x: 200, \n y: 250,\n url: '/reject'\n },\n { \n id: 'archive', \n type: 'process', \n label: '归档简历', \n x: 200, \n y: 350,\n url: '/archive'\n },\n { \n id: 'end', \n type: 'end', \n label: '结束', \n x: 400, \n y: 550,\n url: '/process/end'\n }\n ],\n sales: [\n { \n id: 'start', \n type: 'start', \n label: '开始', \n x: 400, \n y: 50,\n url: '/sales/start'\n },\n { \n id: 'inquiry', \n type: 'process', \n label: '客户询价', \n x: 400, \n y: 150,\n url: '/sales/inquiry'\n },\n { \n id: 'need-analysis', \n type: 'process', \n label: '需求分析', \n x: 400, \n y: 250,\n url: '/sales/analysis'\n },\n { \n id: 'solution', \n type: 'process', \n label: '方案制定', \n x: 400, \n y: 350,\n url: '/sales/solution'\n },\n { \n id: 'quotation', \n type: 'process', \n label: '报价单生成', \n x: 400, \n y: 450,\n url: '/sales/quotation'\n },\n { \n id: 'negotiation', \n type: 'process', \n label: '商务谈判', \n x: 400, \n y: 550,\n url: '/sales/negotiation'\n },\n { \n id: 'decision', \n type: 'condition', \n label: '客户决策', \n x: 400, \n y: 650,\n url: '/sales/decision'\n },\n { \n id: 'contract', \n type: 'process', \n label: '签订合同', \n x: 600, \n y: 650,\n url: '/sales/contract'\n },\n { \n id: 'reject-reason', \n type: 'process', \n label: '原因分析', \n x: 200, \n y: 650,\n url: '/sales/reject'\n },\n { \n id: 'followup', \n type: 'process', \n label: '持续跟进', \n x: 200, \n y: 750,\n url: '/sales/followup'\n },\n { \n id: 'production', \n type: 'process', \n label: '生产准备', \n x: 600, \n y: 750,\n url: '/sales/production'\n },\n { \n id: 'end-success', \n type: 'end', \n label: '流程完成', \n x: 400, \n y: 850,\n url: '/sales/completed'\n }\n ],\n shipping: [\n { \n id: 'start', \n type: 'start', \n label: '开始', \n x: 400, \n y: 50,\n url: '/shipping/start'\n },\n { \n id: 'order-receive', \n type: 'process', \n label: '接收订单', \n x: 400, \n y: 150,\n url: '/shipping/receive'\n },\n { \n id: 'order-review', \n type: 'condition', \n label: '订单审核', \n x: 400, \n y: 250,\n url: '/shipping/review'\n },\n { \n id: 'order-problem', \n type: 'process', \n label: '问题处理', \n x: 200, \n y: 250,\n url: '/shipping/problem'\n },\n { \n id: 'batch-assign', \n type: 'process', \n label: '批次分配', \n x: 400, \n y: 350,\n url: '/shipping/batch'\n },\n { \n id: 'inventory-check', \n type: 'condition', \n label: '库存检查', \n x: 400, \n y: 450,\n url: '/shipping/inventory'\n },\n { \n id: 'replenishment', \n type: 'process', \n label: '补货流程', \n x: 600, \n y: 450,\n url: '/shipping/replenishment'\n },\n { \n id: 'pick-pack', \n type: 'process', \n label: '拣货包装', \n x: 400, \n y: 550,\n url: '/shipping/pick'\n },\n { \n id: 'quality-check', \n type: 'condition', \n label: '质量检查', \n x: 400, \n y: 650,\n url: '/shipping/quality'\n },\n { \n id: 'rework', \n type: 'process', \n label: '返工处理', \n x: 200, \n y: 650,\n url: '/shipping/rework'\n },\n { \n id: 'shipping-arrange', \n type: 'process', \n label: '物流安排', \n x: 400, \n y: 750,\n url: '/shipping/arrange'\n },\n { \n id: 'invoice', \n type: 'process', \n label: '开具发票', \n x: 600, \n y: 750,\n url: '/shipping/invoice'\n },\n { \n id: 'end', \n type: 'end', \n label: '发货完成', \n x: 400, \n y: 850,\n url: '/shipping/complete'\n }\n ]\n },\n nodes: [],\n isMobile: false\n }\n },\n methods: {\n // 绘制流程线\n drawFlowLines(withTransform = false) {\n const canvas = this.$refs.flowCanvas;\n if (!canvas) {\n // 员工流程使用SVG绘制,所以Canvas可能不存在\n if (this.currentType !== 'employee-process') {\n console.warn('Canvas element not found but not in employee process mode');\n }\n return;\n }\n \n const ctx = canvas.getContext('2d');\n if (!withTransform) {\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n }\n \n // 根据当前流程类型绘制不同的线条\n switch(this.currentType) {\n case 'employee-process':\n // 员工流程使用SVG绘制,不需要Canvas绘制\n break;\n case 'sales-process':\n this.drawSalesFlow(ctx);\n break;\n case 'shipping-process':\n this.drawShippingFlow(ctx);\n break;\n }\n },\n \n // 绘制员工入职流程线\n drawEmployeeFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#409EFF';\n \n // 从开始到面试\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n \n // 从面试到通过/不通过的分支\n ctx.beginPath();\n ctx.moveTo(430, 150);\n ctx.lineTo(570, 150);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(370, 150);\n ctx.lineTo(230, 250);\n ctx.stroke();\n \n // 通过分支:录用通知书 -> 准备入职材料 -> 材料核实 -> 办理入职\n ctx.beginPath();\n ctx.moveTo(600, 180);\n ctx.lineTo(600, 250);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(600, 280);\n ctx.lineTo(600, 350);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(600, 380);\n ctx.lineTo(600, 450);\n ctx.stroke();\n \n // 不通过分支:拒绝通知 -> 归档简历\n ctx.beginPath();\n ctx.moveTo(200, 280);\n ctx.lineTo(200, 350);\n ctx.stroke();\n \n // 办理入职 -> 结束\n ctx.beginPath();\n ctx.moveTo(600, 480);\n ctx.lineTo(600, 530);\n ctx.lineTo(400, 530);\n ctx.lineTo(400, 550);\n ctx.stroke();\n \n // 归档简历 -> 结束\n ctx.beginPath();\n ctx.moveTo(200, 380);\n ctx.lineTo(200, 530);\n ctx.lineTo(400, 530);\n ctx.stroke();\n \n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#409EFF';\n ctx.textAlign = 'center';\n \n ctx.fillText('通过', 500, 130);\n ctx.fillText('不通过', 300, 200);\n \n // 绘制材料核实的判断结果箭头\n ctx.beginPath();\n ctx.moveTo(570, 350);\n ctx.lineTo(530, 350);\n ctx.stroke();\n \n ctx.fillText('材料无误', 550, 330);\n },\n \n // 绘制销售订单流程线\n drawSalesFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#67C23A';\n \n // 主流程线条 - 垂直连线\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 180);\n ctx.lineTo(400, 250);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 280);\n ctx.lineTo(400, 350);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 380);\n ctx.lineTo(400, 450);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 480);\n ctx.lineTo(400, 550);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 580);\n ctx.lineTo(400, 650);\n ctx.stroke();\n \n // 决策分支\n ctx.beginPath();\n ctx.moveTo(400, 690);\n ctx.lineTo(400, 710);\n ctx.lineTo(600, 710);\n ctx.lineTo(600, 650);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 690);\n ctx.lineTo(400, 710);\n ctx.lineTo(200, 710);\n ctx.lineTo(200, 650);\n ctx.stroke();\n \n // 签订合同 -> 生产准备\n ctx.beginPath();\n ctx.moveTo(600, 680);\n ctx.lineTo(600, 750);\n ctx.stroke();\n \n // 原因分析 -> 持续跟进\n ctx.beginPath();\n ctx.moveTo(200, 680);\n ctx.lineTo(200, 750);\n ctx.stroke();\n \n // 生产准备 -> 结束\n ctx.beginPath();\n ctx.moveTo(600, 780);\n ctx.lineTo(600, 830);\n ctx.lineTo(400, 830);\n ctx.lineTo(400, 850);\n ctx.stroke();\n \n // 持续跟进 -> 结束\n ctx.beginPath();\n ctx.moveTo(200, 780);\n ctx.lineTo(200, 830);\n ctx.lineTo(400, 830);\n ctx.stroke();\n \n // 添加销售流程特效\n // 波纹效果圆圈\n ctx.beginPath();\n ctx.arc(400, 550, 15, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.2)';\n ctx.fill();\n \n ctx.beginPath();\n ctx.arc(400, 550, 10, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.4)';\n ctx.fill();\n \n ctx.beginPath();\n ctx.arc(400, 550, 5, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(103, 194, 58, 0.6)';\n ctx.fill();\n \n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#67C23A';\n ctx.textAlign = 'center';\n \n ctx.fillText('通过', 500, 700);\n ctx.fillText('未通过', 300, 700);\n ctx.fillText('准备生产', 670, 750);\n ctx.fillText('流程终止', 150, 750);\n },\n \n // 绘制物流发货流程线\n drawShippingFlow(ctx) {\n ctx.lineWidth = 3;\n ctx.strokeStyle = '#E6A23C';\n ctx.shadowColor = 'rgba(230, 162, 60, 0.5)';\n ctx.shadowBlur = 10;\n \n // 主流程线条\n ctx.beginPath();\n ctx.moveTo(400, 80);\n ctx.lineTo(400, 150);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 180);\n ctx.lineTo(400, 250);\n ctx.stroke();\n \n // 订单审核分支\n ctx.beginPath();\n ctx.moveTo(400, 280);\n ctx.lineTo(400, 350);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(370, 250);\n ctx.lineTo(230, 250);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(200, 280);\n ctx.lineTo(200, 300);\n ctx.lineTo(350, 350);\n ctx.stroke();\n \n // 库存检查分支\n ctx.beginPath();\n ctx.moveTo(400, 380);\n ctx.lineTo(400, 450);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(430, 450);\n ctx.lineTo(570, 450);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(600, 480);\n ctx.lineTo(600, 500);\n ctx.lineTo(400, 500);\n ctx.lineTo(400, 550);\n ctx.stroke();\n \n // 质量检查分支\n ctx.beginPath();\n ctx.moveTo(400, 580);\n ctx.lineTo(400, 650);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(370, 650);\n ctx.lineTo(230, 650);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(400, 680);\n ctx.lineTo(400, 750);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(200, 680);\n ctx.lineTo(200, 700);\n ctx.lineTo(350, 750);\n ctx.stroke();\n \n // 发票和物流并行\n ctx.beginPath();\n ctx.moveTo(430, 750);\n ctx.lineTo(570, 750);\n ctx.stroke();\n \n // 收尾\n ctx.beginPath();\n ctx.moveTo(400, 780);\n ctx.lineTo(400, 850);\n ctx.stroke();\n \n ctx.beginPath();\n ctx.moveTo(600, 780);\n ctx.lineTo(600, 820);\n ctx.lineTo(400, 820);\n ctx.stroke();\n \n // 清除阴影效果,以免影响其他绘制\n ctx.shadowBlur = 0;\n \n // 添加发光点\n ctx.beginPath();\n ctx.arc(400, 150, 8, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n \n ctx.beginPath();\n ctx.arc(400, 450, 8, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n \n ctx.beginPath();\n ctx.arc(400, 750, 8, 0, Math.PI*2);\n ctx.fillStyle = 'rgba(230, 162, 60, 0.6)';\n ctx.fill();\n \n // 添加文本\n ctx.font = '14px Arial';\n ctx.fillStyle = '#E6A23C';\n ctx.textAlign = 'center';\n \n ctx.fillText('订单有问题', 280, 230);\n ctx.fillText('处理完成', 280, 330);\n ctx.fillText('库存不足', 510, 430);\n ctx.fillText('需要返工', 280, 630);\n ctx.fillText('完成修正', 280, 730);\n },\n handleNodeClick(nodeId) {\n const node = this.processNodes[this.processType].find(n => n.id === nodeId)\n if (node && node.url) {\n if (node.url.startsWith('http')) {\n window.open(node.url, '_blank')\n } else {\n this.$router.push(node.url).catch(err => {\n if (err.name !== 'NavigationDuplicated') {\n this.$message({\n type: 'info',\n message: `正在跳转到${node.label}页面...`\n })\n }\n })\n }\n }\n },\n checkDevice() {\n this.isMobile = window.innerWidth < 768\n if (this.isMobile) {\n this.scale = 0.6 // 移动端默认缩小到60%\n } else {\n this.scale = 1\n }\n this.applyScale()\n },\n applyScale() {\n const el = this.$refs.processFlow;\n el.style.transform = `translate(${this.lastPosX}px, ${this.lastPosY}px) scale(${this.scale})`;\n \n // Canvas不能使用CSS缩放,需要重绘\n const canvas = this.$refs.flowCanvas;\n if (canvas && this.currentType !== 'employee-process') {\n const ctx = canvas.getContext('2d');\n ctx.clearRect(0, 0, canvas.width, canvas.height);\n ctx.save();\n ctx.translate(this.lastPosX, this.lastPosY);\n ctx.scale(this.scale, this.scale);\n this.drawFlowLines(true); // 传递true表示已应用变换\n ctx.restore();\n }\n },\n handleResize() {\n this.checkDevice()\n },\n zoomIn() {\n this.scale += 0.1;\n this.applyScale();\n },\n zoomOut() {\n if (this.scale > 0.3) {\n this.scale -= 0.1;\n this.applyScale();\n }\n },\n resetZoom() {\n this.scale = 1;\n this.$refs.processFlow.style.transform = 'translate(0px, 0px) scale(1)';\n this.lastPosX = 0;\n this.lastPosY = 0;\n },\n changeProcessType(type) {\n this.processType = type;\n \n switch(type) {\n case 'employee':\n this.currentType = 'employee-process';\n break;\n case 'sales':\n this.currentType = 'sales-process';\n break;\n case 'shipping':\n this.currentType = 'shipping-process';\n break;\n default:\n this.currentType = 'employee-process';\n }\n \n // 确保DOM更新后再应用缩放\n this.$nextTick(() => {\n this.resetZoom();\n this.applyScale();\n // 只有在非员工流程时才需要重绘Canvas流程线\n if (this.currentType !== 'employee-process') {\n this.drawFlowLines();\n }\n });\n },\n initHammer() {\n const el = this.$refs.processFlow;\n const hammertime = new Hammer(el);\n \n hammertime.get('pinch').set({ enable: true });\n hammertime.get('pan').set({ direction: Hammer.DIRECTION_ALL });\n \n hammertime.on('pinch', (e) => {\n const newScale = Math.max(0.3, Math.min(3, this.scale * e.scale));\n if (Math.abs(newScale - this.scale) > 0.01) {\n this.scale = newScale;\n this.applyScale();\n }\n });\n \n hammertime.on('pan', (e) => {\n if (this.panEnabled) {\n const deltaX = e.deltaX;\n const deltaY = e.deltaY;\n \n el.style.transform = `translate(${this.lastPosX + deltaX}px, ${this.lastPosY + deltaY}px) scale(${this.scale})`;\n \n if (e.isFinal) {\n this.lastPosX += deltaX;\n this.lastPosY += deltaY;\n }\n }\n });\n \n // 双击事件处理\n hammertime.on('doubletap', () => {\n this.resetZoom();\n });\n \n // 启用/禁用平移\n el.addEventListener('mousedown', () => {\n this.panEnabled = true;\n });\n \n document.addEventListener('mouseup', () => {\n this.panEnabled = false;\n });\n \n // 移动端触摸事件\n el.addEventListener('touchstart', () => {\n this.panEnabled = true;\n });\n \n document.addEventListener('touchend', () => {\n this.panEnabled = false;\n });\n }\n },\n mounted() {\n // 确保初始化流程类型正确\n this.processType = 'employee';\n this.currentType = 'employee-process';\n \n this.$nextTick(() => {\n this.initHammer();\n // 只有在非员工流程时才绘制Canvas流程线\n if (this.currentType !== 'employee-process') {\n this.drawFlowLines();\n }\n });\n \n this.checkDevice()\n window.addEventListener('resize', this.handleResize)\n },\n beforeDestroy() {\n window.removeEventListener('resize', this.handleResize)\n },\n computed: {\n displayNodes() {\n return this.processNodes[this.processType];\n }\n }\n}\n</script>\n\n<style lang=\"scss\" scoped>\n.process-container {\n padding: 20px;\n background: #f8f9fa;\n min-height: 100vh;\n}\n\n.process-intro {\n margin-bottom: 30px;\n border-radius: 12px;\n box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);\n border: none;\n}\n\n.intro-header {\n display: flex;\n justify-content: space-between;\n align-items: center;\n margin-bottom: 20px;\n padding-bottom: 15px;\n border-bottom: 1px solid #ebeef5;\n}\n\n.intro-header h2 {\n margin: 0;\n font-size: 22px;\n color: #2c3e50;\n font-weight: 600;\n}\n\n.intro-content {\n display: flex;\n justify-content: space-between;\n align-items: flex-start;\n}\n\n.intro-description {\n flex: 1;\n padding-right: 40px;\n}\n\n.intro-description p {\n margin: 0;\n color: #5c6b77;\n line-height: 1.8;\n font-size: 15px;\n}\n\n.intro-stats {\n display: flex;\n gap: 40px;\n padding: 20px;\n background: #f8fafc;\n border-radius: 8px;\n}\n\n.stat-item {\n text-align: center;\n padding: 0 20px;\n position: relative;\n}\n\n.stat-item:not(:last-child)::after {\n content: '';\n position: absolute;\n right: -20px;\n top: 50%;\n transform: translateY(-50%);\n height: 70%;\n width: 1px;\n background: #e0e6ed;\n}\n\n.stat-value {\n font-size: 28px;\n font-weight: 600;\n color: #409EFF;\n margin-bottom: 8px;\n line-height: 1;\n}\n\n.stat-label {\n font-size: 14px;\n color: #8492a6;\n}\n\n.process-flow {\n margin: 40px 0;\n padding: 60px;\n position: relative;\n height: 900px;\n min-width: 900px;\n overflow: visible;\n transform-origin: top left;\n}\n\n.flow-connectors {\n width: 100%;\n height: 100%;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 5;\n pointer-events: none;\n}\n\n/* 确保不同流程线正确显示 */\nsvg.flow-connectors {\n overflow: visible;\n position: absolute;\n top: 0;\n left: 0;\n z-index: 5;\n pointer-events: none;\n}\n\n/* 流程线样式 */\n.process-line {\n stroke: #409EFF;\n stroke-width: 3px;\n fill: none;\n /* 增加间距,确保箭头完全可见 */\n stroke-linecap: square;\n}\n\n.process-line.main {\n stroke-width: 3.5px;\n}\n\n.process-line.branch {\n stroke: #E6A23C;\n stroke-dasharray: 5, 3;\n}\n\n.process-line.condition {\n stroke: #67C23A;\n stroke-width: 2.5px;\n}\n\n/* 文本标签样式 */\n.flow-text {\n font-size: 14px;\n font-weight: 500;\n text-anchor: middle;\n /* 确保文本不被线条遮挡 */\n dominant-baseline: middle;\n \n &.main {\n fill: #409EFF;\n }\n \n &.branch {\n fill: #E6A23C;\n }\n \n &.condition {\n fill: #67C23A;\n }\n}\n\n/* SVG节点强调效果 */\n.node-emphasis {\n fill: rgba(64, 158, 255, 0.1);\n stroke: #409EFF;\n stroke-width: 1px;\n \n &.start {\n fill: rgba(64, 158, 255, 0.2);\n animation: pulse 2s infinite;\n }\n \n &.condition {\n fill: rgba(230, 162, 60, 0.1);\n stroke: #E6A23C;\n }\n \n &.end {\n fill: rgba(64, 158, 255, 0.2);\n animation: pulse 2s infinite;\n }\n}\n\n@keyframes pulse {\n 0% {\n r: 10px;\n opacity: 0.6;\n }\n 50% {\n r: 15px;\n opacity: 0.3;\n }\n 100% {\n r: 10px;\n opacity: 0.6;\n }\n}\n\n/* 流程图节点样式 */\n.flow-node {\n position: absolute;\n min-width: 120px;\n padding: 15px 25px;\n text-align: center;\n background: #fff;\n border: 2px solid #409EFF;\n border-radius: 8px;\n cursor: pointer;\n transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);\n z-index: 10; /* 确保节点在线条上方 */\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.04);\n}\n\n.flow-node:hover {\n box-shadow: 0 8px 16px rgba(64, 158, 255, 0.2);\n transform: translateY(-4px);\n}\n\n.flow-node.start,\n.flow-node.end {\n background: linear-gradient(135deg, #409EFF, #3a8ee6);\n color: #fff;\n border-radius: 25px;\n min-width: 100px;\n border: none;\n font-weight: 500;\n box-shadow: 0 4px 15px rgba(64, 158, 255, 0.3);\n}\n\n.flow-node.condition {\n border-color: #E6A23C;\n background: #fff;\n color: #E6A23C;\n transform: rotate(45deg);\n width: 90px;\n height: 90px;\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n box-shadow: 0 4px 15px rgba(230, 162, 60, 0.2);\n}\n\n.flow-node.condition:hover {\n box-shadow: 0 8px 20px rgba(230, 162, 60, 0.3);\n transform: rotate(45deg) translateY(-4px);\n}\n\n.flow-node.condition .node-label {\n transform: rotate(-45deg);\n white-space: nowrap;\n font-weight: 500;\n font-size: 14px;\n}\n\n.flow-node.process {\n border-color: #409EFF;\n color: #2c3e50;\n background: linear-gradient(to bottom, #fff, #f8fafc);\n}\n\n.node-label {\n font-size: 14px;\n font-weight: 500;\n}\n\n/* 响应式样式 */\n@media screen and (max-width: 768px) {\n .process-flow {\n padding: 20px;\n margin: 10px 0 40px 0;\n overflow: auto;\n -webkit-overflow-scrolling: touch; /* 改善iOS滚动体验 */\n height: auto;\n min-height: 600px;\n transform-origin: top left;\n width: calc(100vw - 20px);\n max-width: 100%;\n }\n\n .process-container {\n padding: 10px;\n overflow: hidden;\n position: relative;\n }\n \n .zoom-controls {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n display: flex;\n flex-direction: column;\n background: rgba(255, 255, 255, 0.9);\n border-radius: 8px;\n box-shadow: 0 2px 12px rgba(0, 0, 0, 0.15);\n padding: 8px;\n }\n \n .zoom-btn {\n width: 40px;\n height: 40px;\n margin: 4px;\n background: white;\n border: 1px solid #dcdfe6;\n border-radius: 4px;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 20px;\n cursor: pointer;\n color: #606266;\n }\n \n .zoom-btn:active {\n background: #f2f6fc;\n }\n\n .intro-content {\n flex-direction: column;\n }\n\n .intro-description {\n padding-right: 0;\n margin-bottom: 20px;\n }\n\n .intro-stats {\n flex-wrap: wrap;\n gap: 20px;\n padding: 15px;\n }\n\n .stat-item {\n padding: 0 15px;\n }\n\n .stat-item:not(:last-child)::after {\n display: none;\n }\n\n .stat-value {\n font-size: 24px;\n }\n}\n\n/* 不同流程类型的样式 */\n.employee-process {\n /* 调整流程图Z轴次序,确保箭头显示 */\n svg.flow-connectors {\n z-index: 8;\n }\n \n .flow-node {\n z-index: 10;\n border-color: #409EFF;\n \n /* 增加条件节点的外边距,为箭头腾出空间 */\n &.condition {\n border-color: #E6A23C;\n margin: 5px;\n }\n \n &.start, &.end {\n background: linear-gradient(135deg, #409EFF, #3a8ee6);\n }\n \n &.process {\n border-color: #409EFF;\n }\n }\n \n .process-line {\n stroke: #409EFF;\n stroke-width: 3px;\n \n &.main {\n stroke-width: 3.5px;\n }\n \n &.branch {\n stroke: #E6A23C;\n stroke-dasharray: 5, 3;\n }\n \n &.condition {\n stroke: #67C23A;\n stroke-width: 2.5px;\n }\n }\n \n .flow-text {\n &.main {\n fill: #409EFF;\n }\n \n &.branch {\n fill: #E6A23C;\n }\n \n &.condition {\n fill: #67C23A;\n }\n }\n}\n\n.sales-process {\n .flow-node {\n border-color: #67C23A;\n box-shadow: 0 2px 12px 0 rgba(103, 194, 58, 0.1);\n \n &.condition {\n border-color: #67C23A;\n background-color: #f0f9eb;\n }\n \n &.start, &.end {\n background-color: #f0f9eb;\n }\n \n // 销售流程节点的脉动效果\n animation: pulse-green 2s infinite;\n }\n \n @keyframes pulse-green {\n 0% {\n box-shadow: 0 0 0 0 rgba(103, 194, 58, 0.4);\n }\n 70% {\n box-shadow: 0 0 0 10px rgba(103, 194, 58, 0);\n }\n 100% {\n box-shadow: 0 0 0 0 rgba(103, 194, 58, 0);\n }\n }\n \n .process-line {\n stroke: #67C23A;\n stroke-width: 2.5px;\n stroke-dasharray: none;\n }\n \n .process-line.branch {\n stroke-dasharray: 5, 3;\n }\n \n .arrow-marker path {\n fill: #67C23A;\n }\n \n .effect-circle {\n fill: #67C23A;\n opacity: 0.3;\n }\n \n text {\n fill: #67C23A;\n font-weight: bold;\n }\n}\n\n.shipping-process {\n .process-node {\n border-color: #E6A23C;\n box-shadow: 0 2px 12px 0 rgba(230, 162, 60, 0.1);\n \n &.condition {\n border-color: #E6A23C;\n background-color: #fdf6ec;\n }\n \n &.start, &.end {\n background-color: #fdf6ec;\n }\n \n transition: transform 0.3s ease;\n &:hover {\n transform: scale(1.05);\n }\n }\n \n .process-line {\n stroke: #E6A23C;\n stroke-width: 2px;\n filter: drop-shadow(0 2px 5px rgba(230, 162, 60, 0.3));\n }\n \n .process-line.main {\n stroke-width: 3px;\n }\n \n .process-line.return {\n stroke: #F56C6C;\n stroke-width: 2px;\n }\n \n .arrow-marker path {\n fill: #E6A23C;\n }\n \n .glow-effect {\n fill: #E6A23C;\n opacity: 0.4;\n filter: blur(4px);\n animation: glow 3s infinite alternate;\n }\n \n @keyframes glow {\n 0% { opacity: 0.2; r: 8px; }\n 100% { opacity: 0.6; r: 15px; }\n }\n \n text {\n fill: #E6A23C;\n font-weight: 500;\n }\n}\n\n// 移动端样式优化\n@media screen and (max-width: 768px) {\n .zoom-controls {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 100;\n display: flex;\n flex-direction: column;\n }\n\n .zoom-btn {\n width: 40px;\n height: 40px;\n background: rgba(255, 255, 255, 0.9);\n border: 1px solid #dcdfe6;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 18px;\n margin-bottom: 10px;\n cursor: pointer;\n box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);\n }\n \n // 更新流程图容器,支持适应不同屏幕\n .process-flow {\n overflow: auto;\n -webkit-overflow-scrolling: touch;\n padding: 20px;\n min-height: 70vh;\n transform-origin: top left;\n }\n}\n</style> "],"mappings":"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","ignoreList":[]},"metadata":{},"sourceType":"module","externalDependencies":[]}