<script lang="ts" setup name="ProcessNode"> import { Aim, Rank, Remove, } from '@element-plus/icons-vue' import chooseLab from './chooseLab.vue' import type { ILabList } from './lab-interface' // 逻辑代码 const props = defineProps({ // 默认数据 modelValue: { type: Object, default: () => { return { measurePersonId: '', // 执行人 measurePerson: '', // 执行人名称 measureSegmentId: '', // 执行部门 measureSegment: '', // 执行部门名称 executiveItem: '', // 检定项目 alreadyCertifications: 0, // 已出具证书总数 requireCertifications: 0, // 应出具证书总数 measureStatus: '', // 检测状态: 待分配,待检测,检测中,检测完, 已退回/取消 measureStatusName: '', // 检测状态: 待分配,待检测,检测中,检测完, 已退回/取消 updateTime: '', // 流程更新时间 } }, }, // 是否为详情展示页面-暂时无用 detail: { type: Boolean, default: false, }, // 步骤 step: { type: Number, default: 1, }, }) const emit = defineEmits(['update:modelValue', 'delete']) // ------------定义props参数---------- const processNodeData = computed({ get() { return props.modelValue }, set(value) { emit('update:modelValue', value) }, }) // 检定环节可编辑-只有待分发状态可编辑 const deptEdit = computed(() => { const editStates = [''] return editStates.includes(processNodeData.value.measureStatus) }) // 检定人可编辑-待分配状态可编辑 const personEdit = computed(() => { const editStates = ['', '1', '2'] return editStates.includes(processNodeData.value.measureStatus) }) // 证书可编辑-待分发、待分配、待检测状态可编辑 const certificationEdit = computed(() => { const editStates = ['', '1', '2', '3'] return editStates.includes(processNodeData.value.measureStatus) }) // 节点可移动 const canMove = computed(() => { const editStates = ['', '1'] return editStates.includes(processNodeData.value.measureStatus) }) // 选择实验室 const chooseLabDialog = ref() const clickChoose = () => { chooseLabDialog.value.initDialog(false) } // 实验室选择完毕 const chooseOver = (lab: ILabList) => { console.log(lab) processNodeData.value.measureSegmentId = lab.deptId processNodeData.value.measureSegment = lab.organizeName } // 选择人员 const choosePersonShow = ref(false) const choosePerson = () => { choosePersonShow.value = true } // 人员选择完毕 const choosePersonOver = (person: { id: string; name: string }) => { processNodeData.value.measurePersonId = person.id processNodeData.value.measurePerson = person.name choosePersonShow.value = false } // 移除该节点 const deleteNode = () => { emit('delete') } </script> <template> <div class="process-node"> <div class="header"> <div class="step"> {{ props.step }} </div> <div class="buttons"> <el-icon v-show="canMove" class="icon-button" title="移除" @click="deleteNode"> <remove /> </el-icon> <el-icon v-show="canMove" class="icon-button handle" title="移动"> <rank /> </el-icon> </div> </div> <div> <div class="line"> <span class="label">检定环节</span> <el-input v-model="processNodeData.measureSegment" class="process-input" readonly size="small" :disabled="!deptEdit"> <template v-if="deptEdit" #append> <el-button :icon="Aim" size="small" link @click="clickChoose" /> </template> </el-input> </div> <div class="line"> <span class="label">检定人员</span> <el-input v-model="processNodeData.measurePerson" readonly class="process-input" size="small" :disabled="!personEdit"> <template v-if="personEdit" #append> <el-button :icon="Aim" size="small" link @click="choosePerson" /> </template> </el-input> </div> <div class="line"> <span class="label">应出具证书</span><el-input-number v-model="processNodeData.requireCertifications" class="process-input" size="small" :disabled="!certificationEdit" /><span class="unit"> 份</span> </div> <div class="line"> <span class="label">当前状态</span><span class="process-input">{{ processNodeData.measureStatusName }}</span> </div> <div class="line"> <span class="label">更新时间</span><span class="process-input">{{ processNodeData.updateTime }}</span> </div> </div> <!-- 选择实验室弹窗 --> <choose-lab ref="chooseLabDialog" @confirm-checkout="chooseOver" /> <!-- 成员弹框 --> <select-staff-dialog v-model:visible="choosePersonShow" :data="[processNodeData.measurePersonId]" :dept-id="processNodeData.measureSegmentId" :multi="false" @change="choosePersonOver" /> </div> </template> <style lang="scss" scoped> .process-node { // display: inline-block; margin-right: 10px; width: 280px; height: 215px; border: 1px solid #e0e0e0; padding: 5px 15px; border-radius: 5px; background-color: #fafafa; margin-bottom: 10px; .header { display: flex; justify-content: space-between; align-items: center; .step { line-height: 28px; font-size: 16px; color: #3d7eff; font-weight: bold; margin-bottom: 5px; } .icon-button { color: #999; margin-left: 5px; font-size: 16px; &:hover { cursor: pointer; } } } .line { width: 100%; display: flex; align-items: center; justify-content: space-between; padding: 4px 0; .label { width: 80px; font-size: 14px; } .process-input { flex: 1; font-size: 14px; } .unit { margin-left: 5px; font-size: 14px; } } } </style>