From 76ebf70b38016446c18af3d9b1d153ed7901d146 Mon Sep 17 00:00:00 2001 From: gaoluyang <2820782392@qq.com> Date: 星期五, 11 七月 2025 17:19:33 +0800 Subject: [PATCH] 1.协同审批流程联调 --- src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue | 238 ++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 files changed, 200 insertions(+), 38 deletions(-) diff --git a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue index 7e9488a..9d5c19c 100644 --- a/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue +++ b/src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue @@ -1,41 +1,118 @@ <template> <div> <el-dialog - v-model="dialogFormVisible" - :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'" - width="700px" - @close="closeDia" + v-model="dialogFormVisible" + :title="operationType === 'add' ? '鏂板瀹℃壒娴佺▼' : '缂栬緫瀹℃壒娴佺▼'" + width="700px" + @close="closeDia" > + <el-form :model="form" label-width="140px" label-position="top" ref="formRef"> + <el-row> + <el-col :span="24"> + <el-form-item label="娴佺▼缂栧彿锛�" prop="approveId"> + <el-input v-model="form.approveId" placeholder="鑷姩缂栧彿" clearable disabled/> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="24"> + <el-form-item label="鐢宠閮ㄩ棬锛�" prop="approveDeptId"> + <el-select + disabled + v-model="form.approveDeptId" + placeholder="閫夋嫨閮ㄩ棬" + > + <el-option + v-for="user in productOptions" + :key="user.deptId" + :label="user.deptName" + :value="user.deptId" + /> + </el-select> + </el-form-item> + </el-col> + </el-row> + <el-row> + <el-col :span="24"> + <el-form-item label="瀹℃壒浜嬬敱锛�" prop="approveReason"> + <el-input v-model="form.approveReason" placeholder="璇疯緭鍏�" clearable type="textarea" disabled/> + </el-form-item> + </el-col> + </el-row> + <!-- 瀹℃壒浜洪�夋嫨锛堝姩鎬佽妭鐐癸級 --> + <el-row :gutter="30"> + <el-col :span="12"> + <el-form-item label="鐢宠浜猴細" prop="approveUser"> + <el-select + v-model="form.approveUser" + placeholder="閫夋嫨浜哄憳" + disabled + > + <el-option + v-for="user in userList" + :key="user.userId" + :label="user.nickName" + :value="user.userId" + /> + </el-select> + </el-form-item> + </el-col> + <el-col :span="12"> + <el-form-item label="鐢宠鏃ユ湡锛�" prop="approveTime"> + <el-date-picker + v-model="form.approveTime" + type="date" + placeholder="璇烽�夋嫨鏃ユ湡" + value-format="YYYY-MM-DD" + format="YYYY-MM-DD" + clearable + style="width: 100%" + disabled + /> + </el-form-item> + </el-col> + </el-row> + </el-form> <el-form :model="{ activities }" ref="formRef" label-position="top"> - <el-timeline style="max-width: 600px"> - <el-timeline-item - v-for="(activity, index) in activities" - :key="index" - :type="activity.current ? 'primary' : ''" - :hollow="activity.current" - :timestamp="activity.approveNodeTime" + <el-steps :active="getActiveStep()" finish-status="success" process-status="process" align-center direction="vertical"> + <el-step + v-for="(activity, index) in activities" + :key="index" + finish-status="success" + :title="getNodeTitle(index, activities.length)" + :description="activity.approveNodeUser" + :icon="getNodeIcon(activity, index)" > - <el-card> - <span style="font-size: 18px;font-weight: 700">鑺傜偣{{activity.approveNodeOrder}}</span> - <div style="margin: 10px 0"> - <span style="font-size: 16px;font-weight: 600">瀹℃壒浜猴細{{activity.approveNodeUser}}</span> + <template #icon> + <el-icon v-if="activity.approveNodeStatus === 2" color="red" :size="22"><WarningFilled /></el-icon> + <el-icon v-else-if="activity.isShen" color="#1890ff" :size="22"><Edit /></el-icon> + <el-icon v-else-if="activity.approveNodeStatus === 1" color="#67C23A" :size="26"><Check /></el-icon> + <el-icon v-else color="#C0C4CC" :size="22"><MoreFilled /></el-icon> + </template> + <template #title> + <span style="color: #000000">{{ getNodeTitle(index, activities.length) }}</span> + </template> + <template #description> + <div class="node-user"> + <div class="avatar-wrapper"> + <img :src="userStore.avatar" class="user-avatar" alt=""/> + </div> + <span style="color: #000000">{{ activity.approveNodeUser }}-{{activity.isApproval}}</span> </div> - <div> - <span style="margin-bottom: 8px;display: inline-block;font-size: 16px;font-weight: 600">瀹℃壒鎰忚锛�</span> + <div v-if="!activity.isShen" class="node-reason"> + <span>瀹℃壒鎰忚锛�</span>{{ activity.approveNodeReason }} + </div> + <div v-else-if="activity.isShen"> <el-form-item - v-if="activity.approveNodeRemark == 1" :prop="'activities.' + index + '.approveNodeReason'" :rules="[{ required: true, message: '瀹℃壒鎰忚涓嶈兘涓虹┖', trigger: 'blur' }]" > <el-input v-model="activity.approveNodeReason" clearable type="textarea" :disabled="operationType === 'view'"></el-input> </el-form-item> - <el-form-item v-else> - <el-input v-model="activity.approveNodeReason" clearable type="textarea" disabled></el-input> - </el-form-item> </div> - </el-card> - </el-timeline-item> - </el-timeline> + </template> + </el-step> + </el-steps> </el-form> <template #footer v-if="operationType === 'approval'"> <div class="dialog-footer"> @@ -49,8 +126,15 @@ </template> <script setup> -import {getCurrentInstance, ref} from "vue"; -import {approveProcessDetails, updateApproveNode} from "../../../../api/collaborativeApproval/approvalProcess.js"; +import {getCurrentInstance, reactive, ref, toRefs} from "vue"; +import { + approveProcessDetails, + getDept, + updateApproveNode +} from "@/api/collaborativeApproval/approvalProcess.js"; +import useUserStore from "@/store/modules/user.js"; +import {userListNoPageByTenantId} from "@/api/system/user.js"; +import { WarningFilled, Edit, Check, MoreFilled } from '@element-plus/icons-vue' const emit = defineEmits(['close']) const { proxy } = getCurrentInstance() @@ -58,24 +142,80 @@ const operationType = ref('') const activities = ref([]) const formRef = ref(null); +const userStore = useUserStore() +const productOptions = ref([]); +const userList = ref([]) +const data = reactive({ + form: { + approveTime: "", + approveId: "", + approveUser: "", + approveDeptId: "", + approveReason: "", + checkResult: "", + }, +}); +const { form } = toRefs(data); +// 鑺傜偣鏍囬 +const getNodeTitle = (index, len) => { + if (index === 0) return '鍙戣捣'; + if (index === len - 1) return '缁撴潫'; + return '瀹℃壒'; +}; + +// 鑾峰彇褰撳墠婵�娲绘楠� +const getActiveStep = () => { + // 濡傛灉鎵�鏈� isShen 閮戒负 false锛岃繑鍥炴渶鍚庝竴涓楠わ紙鍏ㄩ儴瀹屾垚锛� + const hasActive = activities.value.some(a => a.isShen === true); + if (!hasActive) return activities.value.length; + // 褰撳墠鑺傜偣绱㈠紩 + return activities.value.findIndex(a => a.isShen == true); +}; +// 姝ラicon +const getNodeIcon = (activity, index) => { + if (activity.approveNodeStatus === 2) return 'el-icon-warning'; // 涓嶉�氳繃 + if (activity.isShen) return 'Edit'; + return ''; +}; // 鎵撳紑寮规 const openDialog = (type, row) => { operationType.value = type; dialogFormVisible.value = true; - approveProcessDetails(row.approveId).then((res) => { - console.log(res) - activities.value = res.data - }) + userListNoPageByTenantId().then((res) => { + userList.value = res.data; + }); + form.value = {...row} + getProductOptions() + approveProcessDetails(row.approveId).then((res) => { + activities.value = res.data + // 澧炲姞isApproval瀛楁 + activities.value.forEach(item => { + if (item.approveNodeStatus === 2) { + item.isApproval = '宸查┏鍥�'; + } else if (item.approveNodeStatus === 1) { + item.isApproval = '宸插悓鎰�'; + } else { + item.isApproval = '鏈鎵�'; + } + }) + }) } +const getProductOptions = () => { + getDept().then((res) => { + productOptions.value = res.data; + }); +}; // 鎻愪氦瀹℃壒 const submitForm = (status) => { - const filteredActivities = activities.value.filter(activity => activity.approveNodeRemark == 1); - filteredActivities[0].approveNodeStatus = status - updateApproveNode(filteredActivities[0]).then(() => { - proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); - closeDia(); - }) + const filteredActivities = activities.value.filter(activity => activity.isShen); + filteredActivities[0].approveNodeStatus = status + // 鍒ゆ柇鏄惁涓烘渶鍚庝竴姝� + const isLast = activities.value.findIndex(a => a.isShen) === activities.value.length-1; + updateApproveNode({ ...filteredActivities[0], isLast }).then(() => { + proxy.$modal.msgSuccess("鎻愪氦鎴愬姛"); + closeDia(); + }) } // 鍏抽棴寮规 const closeDia = () => { @@ -89,7 +229,29 @@ </script> <style scoped> -.el-timeline { - padding-left: 10px; + +.node-user { + margin: 10px 0; + font-size: 16px; + font-weight: 600; + display: flex; + align-items: center; + gap: 8px; +} +.node-status { + color: #1890ff; + margin-left: 8px; + font-size: 14px; +} +.node-reason { + font-size: 15px; + color: #333; + margin: 10px 0; +} +.user-avatar { + cursor: pointer; + width: 30px; + height: 30px; + border-radius: 50px; } </style> \ No newline at end of file -- Gitblit v1.9.3