<template> <div class="processApproval"> <div class="left-card"> <div class="top"> <div class="commons-title title"> {{ route.query.flowName || props.query.flowName || "流程标题(发起)" }} </div> <div class="line"></div> <!-- 报价单 --> <template v-if="flowForm.flowKey == 'sale_quotation_flow'"> <PriceSheetEHSD ref="makeDom" v-if="flowForm.tenantType === 'EHSD'" :queryData="queryData.data" ></PriceSheetEHSD> </template> <!-- 样品单 --> <template v-else-if="flowForm.flowKey == 'sample_flow'"> <SampleEHSD ref="makeDom" :queryData="queryData.data"></SampleEHSD> </template> <!-- 样品单变更 --> <template v-else-if="flowForm.flowKey == 'sample_update_flow'"> <SampleChangeEHSD ref="makeDom" :queryData="queryData.data" ></SampleChangeEHSD> </template> <!-- 销售合同 --> <template v-else-if="flowForm.flowKey == 'contract_flow'"> <ContractEHSD ref="makeDom" :queryData="queryData.data" @auxiliaryChange="(e) => getAuxiliaryData(e)" ></ContractEHSD> </template> <!-- 销售合同变更 --> <template v-else-if="flowForm.flowKey == 'contract_update_flow'"> <ContractChangeEHSD ref="makeDom" :queryData="queryData.data" @auxiliaryChange="(e) => getAuxiliaryData(e)" ></ContractChangeEHSD> </template> <!-- 申购 --> <SendSubscribe ref="makeDom" @auxiliaryChange="(e) => getAuxiliaryData(e)" v-else-if="flowForm.flowKey == 'subscribe_flow'" :queryData="queryData.data" ></SendSubscribe> <!-- 样品单采购、交接单采购 --> <template v-else-if="flowForm.flowKey == 'ehsd_purchase_flow'"> <PurchaseEHSD ref="makeDom" :queryData="queryData.data" v-if="flowForm.submitType === '10'" @auxiliaryChange="(e) => getAuxiliaryData(e)" ></PurchaseEHSD> <SendPurchase ref="makeDom" :queryData="queryData.data" v-else @auxiliaryChange="(e) => getAuxiliaryData(e)" ></SendPurchase> </template> <PurchaseChangeEHSD ref="makeDom" :queryData="queryData.data" v-else-if="flowForm.flowKey == 'ehsd_purchase_update_flow'" @auxiliaryChange="(e) => getAuxiliaryData(e)" ></PurchaseChangeEHSD> <!-- 采购付款 --> <PurchasePayment ref="makeDom" @auxiliaryChange="(e) => getAuxiliaryData(e)" v-else-if="flowForm.flowKey == 'pay_flow'" :queryData="queryData.data" ></PurchasePayment> <!-- 请款 --> <SendFunds ref="makeDom" v-else-if="flowForm.flowKey == 'account_request_funds_flow'" :queryData="queryData.data" ></SendFunds> </div> <div class="bottom" v-if="isShowSubmitDom"> <div class="commons-title title">处理意见</div> <el-form :model="flowForm" :rules="flowRules" ref="flowFormDom"> <el-form-item prop="remark" label-width="0px" label=""> <el-input type="textarea" placeholder="请输入" v-model="flowForm.remark" > </el-input> </el-form-item> <el-form-item prop="remark" label-width="80px" label="附件上传"> <el-upload v-model:fileList="flowForm.fileList" action="https://winfaster.obs.cn-south-1.myhuaweicloud.com" :data="uploadData" multiple :before-upload="uploadFile" :on-success="handleSuccess" :on-preview="onPreviewFile" > <el-button>选择</el-button> </el-upload> </el-form-item> <el-form-item> <el-button type="primary" v-if="approvalRecordData.buttonInfoList.length == 0" @click="handleSubmit" :loading="btnLoading" >提交</el-button > <el-button type="primary" v-else v-for="i in approvalRecordData.buttonInfoList" :key="i.type" :loading="btnLoading" @click="handleSubmit(i.type)" >{{ i.name }}</el-button > </el-form-item> </el-form> </div> </div> <div class="right-card"> <el-tabs v-model="activeName" class="demo-tabs"> <el-tab-pane label="审批记录" name="first"> <ul class="flow-chart"> <li v-for="item in recordList" :key="item.id" :class=" !route.query.id ? '' : item.status == 2 ? 'flow-orange' : item.status == 3 && !route.query.id ? 'flow-orange' : item.status == 3 && route.query.id ? 'flow-grey' : '' " > <div class="left-icon"> <i class="iconfont icon-iconm_daick"></i> <i class="iconfont icon-icomx_quertj1 right-btm-status"></i> </div> <div class="right-conetnt"> <div class="name">{{ item.nodeName }}</div> <div class="remark"> <div class="label"> <span v-if="item.status != 3">办理人:</span >{{ item.processedUser }}<span class="time">{{ item.processedDate }}</span> </div> {{ item.remark }} <div v-for="j in fileObj[item.flowExampleDetailId]" v-if="fileObj[item.flowExampleDetailId]" > <a @click="proxy.download(j.fileUrl, j.fileName)" style="color: #409eff; line-height: 30px" >{{ j.fileName }}</a > </div> </div> </div> <div class="line"></div> </li> </ul> </el-tab-pane> <el-tab-pane label="决策辅助" name="second" v-if="auxiliaryData.length > 0" > <div style="overflow: auto; height: calc(100vh - 200px)"> <auxiliary :data="auxiliaryData"></auxiliary> </div> </el-tab-pane> </el-tabs> </div> <el-dialog title="下一处理人" width="400" v-model="dialogVisible" v-if="dialogVisible" > <el-form :model="flowForm"> <el-form-item prop="remark" label="处理人"> <el-select v-model="flowForm.handleUserId" placeholder="请选择" filterable style="width: 100%" > <el-option v-for="item in nextHandleUser" :label="item.nickName" :value="item.userId" > </el-option> </el-select> </el-form-item> <el-form-item> <div style="width: 100%; text-align: center"> <el-button type="primary" @click="handleSelectUser">提交</el-button> </div> </el-form-item> </el-form> </el-dialog> </div> </template> <script setup name="ProcessApproval"> import useTagsViewStore from "@/store/modules/tagsView.js"; import { useRouter, useRoute } from "vue-router"; // 消息提示 import { ElMessage, ElMessageBox } from "element-plus"; //决策辅助 import auxiliary from "./auxiliary"; // 报价单-EHSD import PriceSheetEHSD from "@/components/process/EHSD/PriceSheet"; // 销售合同-EHSD import ContractEHSD from "@/components/process/EHSD/Contract"; // 销售合同变更-EHSD import ContractChangeEHSD from "@/components/process/EHSD/ContractChange"; // 样品单-EHSD import SampleEHSD from "@/components/process/EHSD/Sample"; // 样品单变更-EHSD import SampleChangeEHSD from "@/components/process/EHSD/SampleChange"; // 采购交接单-EHSD import PurchaseEHSD from "@/components/process/EHSD/Purchase"; // 采购交接单-EHSD import PurchaseChangeEHSD from "@/components/process/EHSD/PurchaseChange"; //申购发起 import SendSubscribe from "@/components/process/SendSubscribe"; //采购发起 import SendPurchase from "@/components/process/SendPurchase"; //请款发起 import SendFunds from "@/components/process/SendFunds"; // 采购付款 import PurchasePayment from "@/components/process/PurchasePayment"; import { computed, ref, watch } from "vue"; const router = useRouter(); const route = useRoute(); // 传参 const props = defineProps({ query: Object, }); // tab切换逻辑 const activeName = ref("first"); let auxiliaryData = ref([]); const getAuxiliaryData = (data) => { auxiliaryData.value = data; }; const btnLoading = ref(false); // 意见表单 const flowForm = reactive({ flowKey: "", tenantType: "", handleUserId: "", remark: "", data: {}, fileList: [], }); const uploadData = ref({}); const flowRules = reactive({ // remark: [{ required: true, message: "请输入处理意见", trigger: "blur" }], }); //组件实例 const { proxy } = getCurrentInstance(); const makeDom = ref(null); const flowFormDom = ref(null); let dialogVisible = ref(false); const nextHandleUser = ref([]); const handleType = ref(null); const handleSelectUser = () => { if (!flowForm.handleUserId) { return ElMessage({ message: "请选择下一节点处理人!", type: "info", }); } handleSubmit(handleType.value); }; const handleResult = (res) => { if (res.userList == null && res.success) { skipPage(); } else if (res.userList && res.userList.length > 0) { dialogVisible.value = true; nextHandleUser.value = res.userList; } else { return ElMessage({ message: "请联系管理员!", type: "info", }); } }; const uploadFile = async (file) => { const res = await proxy.post("/fileInfo/getSing", { fileName: file.name }); uploadData.value = res.uploadBody; file.id = res.id; file.fileName = res.fileName; file.fileUrl = res.fileUrl; file.uploadState = true; return true; }; const handleSuccess = (any, UploadFile) => { UploadFile.raw.uploadState = false; }; const onPreviewFile = (file) => { window.open(file.raw.fileUrl, "_blank"); }; // 提交逻辑 const handleSubmit = async (_type) => { handleType.value = _type ? _type : undefined; try { // 调用发起组件的提交事件 const flag = await makeDom.value.handleSubmit(); if (flag) { flowFormDom.value.validate((valid) => { btnLoading.value = true; if (valid) { const data = { ...makeDom.value.getFormData() }; if (flowForm.flowKey == "subscribe_flow") { } else if (flowForm.flowKey == "account_request_funds_flow") { } else if (flowForm.flowKey == "sale_quotation_flow") { if (flowForm.tenantType === "EHSD") { data.ehsdJson = JSON.stringify({ deliveryTime: data.deliveryTime, }); data.quotationProductList = data.quotationProductList.map( (item) => { let ehsdJson = JSON.stringify({ packMethod: item.packMethod, tradeMethods: item.tradeMethods, }); return { ...item, ehsdJson: ehsdJson, }; } ); } } else if (flowForm.flowKey == "contract_flow") { data.dataJson = JSON.stringify(proxy.deepClone(data)); if (data.fileList && data.fileList.length > 0) { data.fileList = data.fileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.fileList = []; } if (data.packageFileList && data.packageFileList.length > 0) { data.packageFileList = data.packageFileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.packageFileList = []; } data.ehsdJson = JSON.stringify({ deliveryTime: data.deliveryTime, }); data.contractProductList = data.contractProductList.map((item) => { let ehsdJson = JSON.stringify({ packMethod: item.packMethod, tradeMethods: item.tradeMethods, }); return { ...item, ehsdJson: ehsdJson, }; }); } else if (flowForm.flowKey == "contract_update_flow") { data.dataJson = JSON.stringify(proxy.deepClone(data)); if (data.fileList && data.fileList.length > 0) { data.fileList = data.fileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.fileList = []; } if (data.packageFileList && data.packageFileList.length > 0) { data.packageFileList = data.packageFileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.packageFileList = []; } data.ehsdJson = JSON.stringify({ deliveryTime: data.deliveryTime, }); data.contractProductList = data.contractProductList.map((item) => { let ehsdJson = JSON.stringify({ packMethod: item.packMethod, tradeMethods: item.tradeMethods, }); return { ...item, ehsdJson: ehsdJson, }; }); } else if (flowForm.flowKey == "sample_flow") { data.dataJson = JSON.stringify(proxy.deepClone(data)); if (data.fileList && data.fileList.length > 0) { data.fileList = data.fileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.fileList = []; } if (data.packageFileList && data.packageFileList.length > 0) { data.packageFileList = data.packageFileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.packageFileList = []; } data.ehsdJson = JSON.stringify({ deliveryTime: data.deliveryTime, }); data.sampleProductList = data.sampleProductList.map((item) => { let ehsdJson = JSON.stringify({ packMethod: item.packMethod, tradeMethods: item.tradeMethods, }); return { ...item, ehsdJson: ehsdJson, }; }); } else if (flowForm.flowKey == "sample_update_flow") { data.dataJson = JSON.stringify(proxy.deepClone(data)); if (data.fileList && data.fileList.length > 0) { data.fileList = data.fileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.fileList = []; } if (data.packageFileList && data.packageFileList.length > 0) { data.packageFileList = data.packageFileList.map((item) => { return { id: item.raw.id, fileName: item.raw.fileName, fileUrl: item.raw.fileUrl, }; }); } else { data.packageFileList = []; } data.ehsdJson = JSON.stringify({ deliveryTime: data.deliveryTime, }); data.sampleProductList = data.sampleProductList.map((item) => { let ehsdJson = JSON.stringify({ packMethod: item.packMethod, tradeMethods: item.tradeMethods, }); return { ...item, ehsdJson: ehsdJson, }; }); } flowForm.fileList = flowForm.fileList.map((item) => { return { ...item, ...item.raw, }; }); if (route.query.processType == 10 || route.query.processType == 30) { // if (_type && _type == 1) { // proxy // .post("/flowExample/setStartData", { // exampleId: route.query.id, // startData: data, // }) // .then(); // } proxy .post("/flowProcess/jump", { ...flowForm, data, handleType: _type, version: route.query.version, flowId: route.query.id, }) .then( (res) => { handleResult(res); }, (err) => { btnLoading.value = false; } ); return; } else { proxy .post("/flowProcess/initiate", { ...flowForm, data, }) .then( (res) => { handleResult(res); }, (err) => { btnLoading.value = false; } ); } } }); } } catch (err) { console.log("数据未填完整!", err); } }; // 页面跳转 const skipPage = () => { const useTagsStore = useTagsViewStore(); useTagsStore.delVisitedView(router.currentRoute.value); if (route.query.processType) { router.replace({ path: "/oa/1/backlog", }); } else { ElMessage({ message: "操作成功!", type: "success", }); if (flowForm.flowKey == "subscribe_flow") { router.replace({ path: "/ehsd/procurement/subscribe", }); } else if (flowForm.flowKey == "account_request_funds_flow") { router.replace({ path: "/ehsd/fundManage/funds", }); } else if (flowForm.flowKey == "pay_flow") { router.replace({ path: "/ehsd/purchasePayment/payment", }); } else if (flowForm.flowKey == "sale_quotation_flow") { if (flowForm.tenantType === "EHSD") { router.replace({ path: "/ehsd/saleContract/quotation", }); } } else if ( flowForm.flowKey == "contract_flow" || flowForm.flowKey == "contract_update_flow" ) { router.replace({ path: "/ehsd/saleContract/contract", }); } else if ( flowForm.flowKey == "sample_flow" || flowForm.flowKey == "sample_update_flow" ) { router.replace({ path: "/ehsd/saleContract/sample", }); } else if ( flowForm.flowKey == "ehsd_purchase_flow" || flowForm.flowKey == "ehsd_purchase_update_flow" ) { router.replace({ path: "/ehsd/procurement/purchased", }); } } }; let queryData = reactive({ data: {}, }); // 记录 const recordList = ref([]); const fileIds = ref([]); const fileObj = ref({}); const approvalRecordData = ref({ buttonInfoList: [], }); const getRecords = (_id) => { if (_id) { proxy .post("/flowExample/getApprovalRecord", { id: _id, }) .then((res) => { recordList.value = res.recordList; queryData.data.recordList = res.recordList; approvalRecordData.value = res; fileIds.value = res.recordList.map((item) => { return item.flowExampleDetailId; }); proxy .post("fileInfo/getList", { businessIdList: fileIds.value }) .then((res2) => { console.log(res2); fileObj.value = res2; }); console.log(fileObj.value); }); } else { proxy .post("/flowExample/getFlowNode", { flowKey: flowForm.flowKey, }) .then((res) => { recordList.value = res; }); } }; const isShowSubmitDom = ref(true); onMounted(async () => { // 路由进入 if (route.query && route.query.flowKey) { //processType 10 为修改 20为查看 30回退发起 if (route.query.processType == 20) { isShowSubmitDom.value = false; } if ( route.query.processType == 10 || route.query.processType == 20 || route.query.processType == 30 ) { // await proxy // .post("/flowProcess/getStartData", { flowId: route.query.id }) // .then((res) => { // queryData.data = { ...res }; // }); } else { queryData.data = { ...route.query }; } flowForm.flowKey = route.query.flowKey; flowForm.tenantType = route.query.tenantType; flowForm.submitType = route.query.submitType; getRecords(route.query.id); } }); watch( () => props.query, () => { if (props.query) { if (props.query.processType == 20) { isShowSubmitDom.value = false; } if ( props.query.processType == 10 || props.query.processType == 20 || props.query.processType == 30 ) { // await proxy // .post("/flowProcess/getStartData", { flowId: props.query.id }) // .then((res) => { // queryData.data = { ...res }; // }); queryData.data = { ...props.query }; } else { queryData.data = { ...props.query }; } flowForm.flowKey = props.query.flowKey; flowForm.tenantType = props.query.tenantType; flowForm.submitType = props.query.submitType; getRecords(props.query.id); } }, { deep: true, immediate: true, } ); </script> <style> .el-upload-list { float: left; margin: 0 !important; } .el-upload-list li { width: 200px; margin-left: 10px; } .el-upload--text { float: left; } </style> <style lang="scss" scoped> .processApproval { display: flex; justify-content: space-between; margin-top: 20px; padding: 0 20px; height: calc(100vh - 130px); .left-card { // background: #fff; border-radius: 4px; // padding: 20px; // flex: 1; width: calc(100% - 400px - 20px); margin-right: 20px; display: flex; flex-direction: column; .top { flex: 1; overflow-y: auto; background: #fff; padding: 20px 20px 0px 20px; .line { border-bottom: 1px solid #ddd; margin-bottom: 20px; } } .bottom { margin-top: 10px; height: 220px; background: #fff; padding: 20px 20px 0px 20px; } } .right-card { background: #fff; border-radius: 4px; padding: 0 20px 20px; width: 400px; box-sizing: border-box; .flow-chart { overflow: auto; height: calc(100vh - 200px); padding: 0; margin: 0; li { margin: 0; padding: 0 0 20px; list-style: none; display: flex; justify-content: space-between; position: relative; .right-conetnt { flex: 1; .name { font-size: 12px; color: #39c55a; margin-bottom: 10px; span { color: #999; } } .time { float: right; } .remark { padding: 10px; color: #666666; font-size: 12px; background: #f1f1f1; border-radius: 2px; .label { color: #999; margin-bottom: 10px; } } } .left-icon { width: 40px; height: 40px; text-align: center; line-height: 40px; background: #0084ff; border-radius: 10px; color: #fff; font-size: 20px; position: relative; margin-right: 27px; z-index: 2; .right-btm-status { position: absolute; bottom: 0px; right: -10px; height: 20px; width: 20px; line-height: 16px; border-radius: 10px; background: #39c55a; border: 2px solid #fff; font-size: 12px; box-sizing: border-box; } } } li::before { content: ""; position: absolute; top: 0; left: 20px; width: 2px; height: 100%; background: #ddd; z-index: 1; } li:last-child::before { display: none; } .flow-orange { .right-btm-status { background: #ff9a00 !important; } .name { color: #ff9a00 !important; } .left-icon { background: #ff9a00 !important; } } .flow-grey { .right-btm-status { background: #999 !important; } .name { color: #999 !important; } .left-icon { background: #999 !important; } } .flow-red { .right-btm-status { background: #ff4d4f !important; } .name { color: #ff4d4f !important; } .left-icon { background: #ff4d4f !important; } } } } } </style>