357 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
		
		
			
		
	
	
			357 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
|  | <template> | |||
|  |   <div class="p-4 bg-gray-50"> | |||
|  |     <div class="max-w-4xl mx-auto"> | |||
|  |       <!-- 顶部按钮区域 --> | |||
|  |       <el-card class="mb-4 rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md"> | |||
|  |         <approvalButton | |||
|  |           @submitForm="submitForm" | |||
|  |           @approvalVerifyOpen="approvalVerifyOpen" | |||
|  |           @handleApprovalRecord="handleApprovalRecord" | |||
|  |           :buttonLoading="buttonLoading" | |||
|  |           :id="form.id" | |||
|  |           :status="form.completeAuditStatus" | |||
|  |           :pageType="routeParams.type" | |||
|  |         /> | |||
|  |       </el-card> | |||
|  |       <!-- 表单区域 --> | |||
|  |       <el-card class="rounded-lg shadow-sm bg-white border border-gray-100 transition-all hover:shadow-md overflow-hidden"> | |||
|  |         <div class="p-4 bg-gradient-to-r from-blue-50 to-indigo-50 border-b border-gray-100"> | |||
|  |           <h3 class="text-lg font-semibold text-gray-800">设计完工产值</h3> | |||
|  |         </div> | |||
|  |         <div class="p-6"> | |||
|  |           <el-form | |||
|  |             ref="leaveFormRef" | |||
|  |             v-loading="loading" | |||
|  |             :disabled="routeParams.type === 'view' || form.completeAuditStatus == 'waiting'" | |||
|  |             :model="form" | |||
|  |             :rules="rules" | |||
|  |             label-width="120px" | |||
|  |             class="space-y-4" | |||
|  |           > | |||
|  |             <div class="grid grid-cols-1 gap-4"> | |||
|  |               <el-row :gutter="20" justify="center"> | |||
|  |                 <el-col :span="13" :offset="0"> | |||
|  |                   <el-form-item label="计划月份" prop="planMonth"> | |||
|  |                     <el-input v-model="form.planMonth" clearable disabled></el-input> | |||
|  |                   </el-form-item> | |||
|  |                 </el-col> | |||
|  | 
 | |||
|  |                 <el-col :span="13" :offset="0"> | |||
|  |                   <el-form-item label="完成产值" prop="completeValue"> | |||
|  |                     <el-input v-model="form.completeValue" disabled></el-input> | |||
|  |                   </el-form-item> | |||
|  |                 </el-col> | |||
|  |               </el-row> | |||
|  |             </div> | |||
|  |           </el-form> | |||
|  |         </div> | |||
|  |       </el-card> | |||
|  |       <!-- 提交组件 --> | |||
|  |       <submitVerify ref="submitVerifyRef" :task-variables="taskVariables" @submit-callback="submitCallback" /> | |||
|  |       <approvalRecord ref="approvalRecordRef"></approvalRecord> | |||
|  |       <!-- 流程选择对话框 --> | |||
|  |       <el-dialog | |||
|  |         draggable | |||
|  |         v-model="dialogVisible.visible" | |||
|  |         :title="dialogVisible.title" | |||
|  |         :before-close="handleClose" | |||
|  |         width="500" | |||
|  |         class="rounded-lg shadow-lg" | |||
|  |       > | |||
|  |         <div class="p-4"> | |||
|  |           <p class="text-gray-600 mb-4">请选择要启动的流程:</p> | |||
|  |           <el-select v-model="flowCode" placeholder="请选择流程" style="width: 100%"> | |||
|  |             <el-option v-for="item in flowCodeOptions" :key="item.value" :label="item.label" :value="item.value" /> | |||
|  |           </el-select> | |||
|  |         </div> | |||
|  |         <template #footer> | |||
|  |           <div class="dialog-footer p-4 border-t border-gray-100 flex justify-end space-x-3"> | |||
|  |             <el-button @click="handleClose" class="px-4 py-2 border border-gray-300 rounded-md text-gray-700 hover:bg-gray-50 transition-colors" | |||
|  |               >取消</el-button | |||
|  |             > | |||
|  |             <el-button type="primary" @click="submitFlow()" class="px-4 py-2 bg-primary text-white rounded-md hover:bg-primary/90 transition-colors" | |||
|  |               >确认</el-button | |||
|  |             > | |||
|  |           </div> | |||
|  |         </template> | |||
|  |       </el-dialog> | |||
|  |     </div> | |||
|  |   </div> | |||
|  | </template> | |||
|  | 
 | |||
|  | <script setup name="Leave" lang="ts"> | |||
|  | import { LeaveForm, LeaveQuery, LeaveVO } from '@/api/workflow/leave/types'; | |||
|  | import { startWorkFlow } from '@/api/workflow/task'; | |||
|  | import SubmitVerify from '@/components/Process/submitVerify.vue'; | |||
|  | import ApprovalRecord from '@/components/Process/approvalRecord.vue'; | |||
|  | import ApprovalButton from '@/components/Process/approvalButton.vue'; | |||
|  | import { StartProcessBo } from '@/api/workflow/workflowCommon/types'; | |||
|  | const { proxy } = getCurrentInstance() as ComponentInternalInstance; | |||
|  | import { useUserStoreHook } from '@/store/modules/user'; | |||
|  | const { design_change_reason_type } = toRefs<any>(proxy?.useDict('design_change_reason_type')); | |||
|  | import { getKnowledgeDocument } from '@/api/design/technicalStandard'; | |||
|  | import { getConstructionValue } from '@/api/out/constructionValue'; | |||
|  | import { workScheduleListDetail } from '@/api/progress/plan'; | |||
|  | import { getMonthPlan } from '@/api/out/monthPlan'; | |||
|  | // 获取用户 store
 | |||
|  | const userStore = useUserStoreHook(); | |||
|  | // 从 store 中获取项目列表和当前选中的项目
 | |||
|  | const currentProject = computed(() => userStore.selectedProject); | |||
|  | const buttonLoading = ref(false); | |||
|  | const loading = ref(true); | |||
|  | //路由参数
 | |||
|  | const routeParams = ref<Record<string, any>>({}); | |||
|  | const flowCode = ref<string>(''); | |||
|  | const status = ref<string>(''); | |||
|  | const dialogVisible = reactive<DialogOption>({ | |||
|  |   visible: false, | |||
|  |   title: '流程定义' | |||
|  | }); | |||
|  | //提交组件
 | |||
|  | const submitVerifyRef = ref<InstanceType<typeof SubmitVerify>>(); | |||
|  | //审批记录组件
 | |||
|  | const approvalRecordRef = ref<InstanceType<typeof ApprovalRecord>>(); | |||
|  | //按钮组件
 | |||
|  | const flowCodeOptions = [ | |||
|  |   { | |||
|  |     value: currentProject.value?.id + '_designCompleteValue', | |||
|  |     label: '设计完工产值审批' | |||
|  |   } | |||
|  | ]; | |||
|  | 
 | |||
|  | const leaveFormRef = ref<ElFormInstance>(); | |||
|  | const dialog = reactive({ | |||
|  |   visible: false, | |||
|  |   title: '', | |||
|  |   isEdit: false | |||
|  | }); | |||
|  | const submitFormData = ref<StartProcessBo>({ | |||
|  |   businessId: '', | |||
|  |   flowCode: '', | |||
|  |   variables: {} | |||
|  | }); | |||
|  | const taskVariables = ref<Record<string, any>>({}); | |||
|  | 
 | |||
|  | const initFormData = { | |||
|  |   id: undefined, | |||
|  |   projectId: currentProject.value?.id, | |||
|  |   planValue: undefined, | |||
|  |   completeValue: undefined, | |||
|  |   differenceValue: undefined, | |||
|  |   planMonth: undefined, | |||
|  |   valueType: '1', | |||
|  |   planAuditStatus: undefined, | |||
|  |   completeAuditStatus: undefined | |||
|  | }; | |||
|  | const data = reactive({ | |||
|  |   form: { ...initFormData }, | |||
|  |   rules: {} | |||
|  | }); | |||
|  | 
 | |||
|  | const handleClose = () => { | |||
|  |   dialogVisible.visible = false; | |||
|  |   flowCode.value = ''; | |||
|  |   buttonLoading.value = false; | |||
|  | }; | |||
|  | const { form, rules } = toRefs(data); | |||
|  | 
 | |||
|  | /** 表单重置 */ | |||
|  | const reset = () => { | |||
|  |   form.value = { ...initFormData }; | |||
|  |   leaveFormRef.value?.resetFields(); | |||
|  | }; | |||
|  | 
 | |||
|  | /** 获取详情 */ | |||
|  | const getInfo = () => { | |||
|  |   loading.value = true; | |||
|  |   buttonLoading.value = false; | |||
|  |   nextTick(async () => { | |||
|  |     const res = await getMonthPlan(routeParams.value.id); | |||
|  |     Object.assign(form.value, res.data); | |||
|  |     loading.value = false; | |||
|  |     buttonLoading.value = false; | |||
|  |   }); | |||
|  | }; | |||
|  | 
 | |||
|  | /** 提交按钮 */ | |||
|  | const submitForm = (status1: string) => { | |||
|  |   status.value = status1; | |||
|  |   submit(status.value, form.value); | |||
|  | }; | |||
|  | 
 | |||
|  | const submitFlow = async () => { | |||
|  |   handleStartWorkFlow(form.value); | |||
|  |   dialogVisible.visible = false; | |||
|  | }; | |||
|  | //提交申请
 | |||
|  | const handleStartWorkFlow = async (data: LeaveForm) => { | |||
|  |   try { | |||
|  |     submitFormData.value.flowCode = flowCode.value; | |||
|  |     submitFormData.value.businessId = data.id; | |||
|  |     //流程变量
 | |||
|  |     taskVariables.value = { | |||
|  |       // leave4/5 使用的流程变量
 | |||
|  |       userList: ['1', '3', '4'] | |||
|  |     }; | |||
|  |     submitFormData.value.variables = taskVariables.value; | |||
|  |     const resp = await startWorkFlow(submitFormData.value); | |||
|  |     if (submitVerifyRef.value) { | |||
|  |       buttonLoading.value = false; | |||
|  |       submitVerifyRef.value.openDialog(resp.data.taskId); | |||
|  |     } | |||
|  |   } finally { | |||
|  |     buttonLoading.value = false; | |||
|  |   } | |||
|  | }; | |||
|  | //审批记录
 | |||
|  | const handleApprovalRecord = () => { | |||
|  |   approvalRecordRef.value.init(form.value.id); | |||
|  | }; | |||
|  | //提交回调
 | |||
|  | const submitCallback = async () => { | |||
|  |   await proxy.$tab.closePage(proxy.$route); | |||
|  |   proxy.$router.go(-1); | |||
|  | }; | |||
|  | //审批
 | |||
|  | const approvalVerifyOpen = async () => { | |||
|  |   submitVerifyRef.value.openDialog(routeParams.value.taskId); | |||
|  | }; | |||
|  | // 图纸上传成功之后 开始提交
 | |||
|  | const submit = async (status, data) => { | |||
|  |   form.value = data; | |||
|  |   if (status === 'draft') { | |||
|  |     buttonLoading.value = false; | |||
|  |     proxy?.$modal.msgSuccess('暂存成功'); | |||
|  |     proxy.$tab.closePage(proxy.$route); | |||
|  |     proxy.$router.go(-1); | |||
|  |   } else { | |||
|  |     if ((form.value.completeAuditStatus === 'draft' && (flowCode.value === '' || flowCode.value === null)) || routeParams.value.type === 'add') { | |||
|  |       flowCode.value = flowCodeOptions[0].value; | |||
|  |       dialogVisible.visible = true; | |||
|  |       return; | |||
|  |     } | |||
|  |     //说明启动过先随意穿个参数
 | |||
|  |     if (flowCode.value === '' || flowCode.value === null) { | |||
|  |       flowCode.value = 'xx'; | |||
|  |     } | |||
|  |     await handleStartWorkFlow(data); | |||
|  |   } | |||
|  | }; | |||
|  | 
 | |||
|  | onMounted(() => { | |||
|  |   nextTick(async () => { | |||
|  |     routeParams.value = proxy.$route.query; | |||
|  |     console.log('🚀 ~ proxy.$route.query:', proxy.$route.query); | |||
|  |     reset(); | |||
|  |     loading.value = false; | |||
|  |     if (routeParams.value.type === 'update' || routeParams.value.type === 'view' || routeParams.value.type === 'approval') { | |||
|  |       getInfo(); | |||
|  |     } | |||
|  |   }); | |||
|  | }); | |||
|  | </script> | |||
|  | <style scoped lang="scss"> | |||
|  | /* 全局样式 */ | |||
|  | :root { | |||
|  |   --primary: #409eff; | |||
|  |   --primary-light: #66b1ff; | |||
|  |   --primary-dark: #3a8ee6; | |||
|  |   --success: #67c23a; | |||
|  |   --warning: #e6a23c; | |||
|  |   --danger: #f56c6c; | |||
|  |   --info: #909399; | |||
|  | } | |||
|  | 
 | |||
|  | /* 表单样式优化 */ | |||
|  | .el-form-item { | |||
|  |   .el-form-item__label { | |||
|  |     color: #606266; | |||
|  |     font-weight: 500; | |||
|  |   } | |||
|  | 
 | |||
|  |   .el-input__inner, | |||
|  |   .el-select .el-input__inner { | |||
|  |     border-radius: 4px; | |||
|  |     transition: | |||
|  |       border-color 0.2s, | |||
|  |       box-shadow 0.2s; | |||
|  | 
 | |||
|  |     &:focus { | |||
|  |       border-color: var(--primary-light); | |||
|  |       box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1); | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .el-textarea__inner { | |||
|  |     border-radius: 4px; | |||
|  |     transition: | |||
|  |       border-color 0.2s, | |||
|  |       box-shadow 0.2s; | |||
|  | 
 | |||
|  |     &:focus { | |||
|  |       border-color: var(--primary-light); | |||
|  |       box-shadow: 0 0 0 2px rgba(64, 158, 255, 0.1); | |||
|  |     } | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | /* 按钮样式优化 */ | |||
|  | .el-button { | |||
|  |   border-radius: 4px; | |||
|  |   transition: all 0.2s; | |||
|  | 
 | |||
|  |   &.is-primary { | |||
|  |     background-color: var(--primary); | |||
|  |     border-color: var(--primary); | |||
|  | 
 | |||
|  |     &:hover { | |||
|  |       background-color: var(--primary-light); | |||
|  |       border-color: var(--primary-light); | |||
|  |     } | |||
|  | 
 | |||
|  |     &:active { | |||
|  |       background-color: var(--primary-dark); | |||
|  |       border-color: var(--primary-dark); | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   &.is-text { | |||
|  |     color: var(--primary); | |||
|  | 
 | |||
|  |     &:hover { | |||
|  |       color: var(--primary-light); | |||
|  |       background-color: rgba(64, 158, 255, 0.05); | |||
|  |     } | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | /* 卡片样式优化 */ | |||
|  | .el-card { | |||
|  |   transition: all 0.3s ease; | |||
|  | 
 | |||
|  |   &:hover { | |||
|  |     /* transform: translateY(-2px); */ | |||
|  |   } | |||
|  | } | |||
|  | 
 | |||
|  | /* 对话框样式优化 */ | |||
|  | .el-dialog { | |||
|  |   .el-dialog__header { | |||
|  |     background-color: #f5f7fa; | |||
|  |     border-bottom: 1px solid #ebeef5; | |||
|  |     padding: 15px 20px; | |||
|  |   } | |||
|  | 
 | |||
|  |   .el-dialog__title { | |||
|  |     font-size: 16px; | |||
|  |     font-weight: 600; | |||
|  |     color: #303133; | |||
|  |   } | |||
|  | 
 | |||
|  |   .el-dialog__footer { | |||
|  |     padding: 15px 20px; | |||
|  |     border-top: 1px solid #ebeef5; | |||
|  |   } | |||
|  | } | |||
|  | </style> |