<template> <div v-if="data && data.length" class="workflow-step-wrapper"> <div class="workflow-step" v-for="step, k in data" :key="k" > <div class="step-head"> <div class="step-icon"> <svg :class="`step-icon ${isCurrentStep(step, k) ? 'waiting-icon' : 'finish-icon'}`" aria-hidden="true"> <!-- 未到达 --> <use v-if="step.state == 1" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_weidaoda"></use> <!-- 通过 --> <use v-else-if="step.result == 1" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_shenpitongguo"></use> <!-- 取回 --> <use v-else-if="step.result == 4" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_quhui"></use> <!-- 提交 --> <use v-else-if="step.result == -1" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_shenpitijiao"></use> <!-- 驳回 --> <use v-else-if="isRejectStep(step)" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_shenpibohui"></use> <!-- 末端节点 --> <use v-else-if="step.result == -2" xlink:href="#icon-a-24_BILLEXPAND_C_RBC_moduanjiedian"></use> </svg> </div> <div :class="`step-line ${step.state === 2 ? 'finish-line' : 'waiting-line'}`" v-if="k != data.length - 1"></div> </div> <div class="step-main"> <div class="step-main-body"> <div :class="`${isCurrentStep(step, k) ? 'text-black' : isRejectStep(step) ? 'text-error' : 'text-grey'}`"> <div v-if="step.result == -2"> <span class="result">审批结束</span> </div> <div v-else-if="step.state == 2"> <span v-if="step.actualOwner" class="participants">{{step.actualOwner}} </span> <span class="result"> {{ step.result == -1 ? '提交' : step.result == 1 ? '通过' : step.result == 4 ? '取回' : '驳回' }} </span> </div> <div v-else> <span v-if="isCurrentStep(step, k)" class="participants">等待</span> <span class="participants">{{step.participants.join('、')}}</span> <span class="result"> 审批</span> </div> </div> <div v-if="isCurrentStep(step, k) || step.state == 2">{{formatStepTime(step)}}</div> <div class="comment" v-if="step.comments"> <div class="label">审批意见:</div> <div class="text">{{step.comments}}</div> </div> <div v-if="step.title" :class="isRejectStep(step) ? 'text-error' : 'text-main'">环节名称: {{step.title}}</div> </div> </div> </div> </div> </template> <script> export default { props: { data: { default: () => [], } }, data() { return { } }, methods: { isCurrentStep(step, k) { if (k != 0) return false return step.result != -2 }, isRejectStep(step) { return step.result === 3 }, formatDate(datetime) { const t = new Date(datetime) return t.format('yyyy-MM-dd HH:mm:ss') }, /** * 根据节点状态返回完成时间或时间差 * @param {object} step * @param {string} step.createTime - 创建时间 * @param {string | null} step.completeTime - 结束时间 * @param {number} step.result - 状态 * @returns {string} */ formatStepTime(step) { const currentTimestamp = Date.now() if (step.state === 1) { let ans = '' const createTimestamp = (new Date(step.createTime)).getTime() let seconds = (currentTimestamp - createTimestamp) / 1000 const formatList = [ { rate: 60 * 60 * 24, label: '天', }, { rate: 60 * 60, label: '小时', }, { rate: 60, label: '分钟', }, ] // for (const o of formatList) { // const num = Math.floor(seconds / o.rate) // if (num > 0 || o.alwaysShow) { // ans += `${num}${o.label}` // seconds -= num * o.rate // } // } for (let i = 0; i < formatList.length; ++i) { const o = formatList[i] const num = Math.floor(seconds / o.rate) if (num > 0 || (!ans && i == formatList.length - 1)) { ans += `${num}${o.label}` seconds -= num * o.rate } } ans = '已等待' + ans return ans } else { return this.formatDate(step.completeTime) } }, } } </script> <style lang="less" scoped> @icon-width: 24px; @main-color: #0DA2E6; .workflow-step-wrapper { width: 100%; .workflow-step { width: 100%; position: relative; .step-head { width: @icon-width; position: absolute; height: 100%; .step-icon { width: 100%; fill: currentColor; height: @icon-width; } .waiting-icon { color: @main-color; } .finish-icon { color: #888; } .step-line { margin-left: @icon-width / 2; width: 1px; height: calc(100% - @icon-width); } .finish-line { background-color: #C8C8C8; } .waiting-line { background-color: @main-color; } } .step-main { width: 100%; min-height: calc(@icon-width + 10px); padding-left: @icon-width; font-size: 12px; color: #888888; line-height: 17px; font-family: PingFangSC-Regular, PingFang SC; font-weight: 400; .step-main-body { padding-bottom: 30px; padding-left: 5px; > div { margin-bottom: 5px; } .text-gray { color: #888888; } .text-black { color: #222222; } .text-main { color: @main-color; } .text-error { color: #ED664B; } .participants { height: 20px; font-size: 14px; line-height: 20px; } .result { height: 20px; font-size: 14px; line-height: 20px; } .comment { display: flex; .text { white-space: pre-line; } } } } } } </style>