Special-audit.vue 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. <template>
  2. <el-dialog v-model="state.dialogVisible" draggable title="特提审批" width="50%" append-to-body destroy-on-close @close="close">
  3. <div class="collapse-container" v-loading="state.loading">
  4. <el-form label-width="110px" ref="ruleFormRef" :model="state.ruleForm">
  5. <el-row :gutter="35">
  6. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  7. <el-form-item label="工单编码" class="mb5"> {{ state.detail?.order?.no }} </el-form-item>
  8. </el-col>
  9. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  10. <el-form-item label="工单标题" class="mb5"> {{ state.detail?.order?.title }} </el-form-item>
  11. </el-col>
  12. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  13. <el-form-item label="申请人" class="mb5"> {{ state.detail?.creatorName }} </el-form-item>
  14. </el-col>
  15. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  16. <el-form-item label="申请部门" class="mb5"> {{ state.detail?.creatorOrgName }} </el-form-item>
  17. </el-col>
  18. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  19. <el-form-item label="申请时间" class="mb5"> {{ formatDate(state.detail?.creationTime, 'YYYY-mm-dd HH:MM:SS') }} </el-form-item>
  20. </el-col>
  21. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  22. <el-form-item label="特提原因" class="mb5">
  23. {{ state.detail?.cause }}
  24. </el-form-item>
  25. </el-col>
  26. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  27. <el-form-item label="申请特提节点" class="mb5">
  28. {{ state.detail?.stepName }}
  29. </el-form-item>
  30. </el-col>
  31. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  32. <el-form-item label="审批通过后节点" class="mb5">
  33. {{ state.detail?.nextStepName }}
  34. </el-form-item>
  35. </el-col>
  36. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  37. <el-form-item label="特提理由" class="formatted-text mb5">
  38. {{ state.detail?.reason }}
  39. </el-form-item>
  40. </el-col>
  41. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  42. <el-form-item label="附件" class="mb5">
  43. <annex-list name="特提附件" readonly classify="特提申请" v-model="state.detail.files" />
  44. </el-form-item>
  45. </el-col>
  46. <el-divider />
  47. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="12">
  48. <el-form-item label="审批结果" prop="isPass" :rules="[{ required: true, message: '请选择审批结果', trigger: 'change' }]">
  49. <el-radio-group v-model="state.ruleForm.isPass">
  50. <el-radio :value="true">同意</el-radio>
  51. <el-radio :value="false">不同意</el-radio>
  52. </el-radio-group>
  53. </el-form-item>
  54. </el-col>
  55. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  56. <el-form-item label="审批意见" prop="opinion" :rules="[{ required: true, message: '请填写特提审批意见', trigger: 'blur' }]">
  57. <el-input v-model="state.ruleForm.opinion" type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" placeholder="请填写特提审批意见" />
  58. </el-form-item>
  59. </el-col>
  60. </el-row>
  61. </el-form>
  62. </div>
  63. <template #footer>
  64. <span class="dialog-footer">
  65. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  66. <el-button type="primary" @click="onAudit(ruleFormRef)" :loading="state.loading">确 定</el-button>
  67. </span>
  68. </template>
  69. </el-dialog>
  70. </template>
  71. <script setup lang="ts">
  72. import { defineAsyncComponent, reactive, ref } from 'vue';
  73. import { ElMessage, FormInstance } from 'element-plus';
  74. import { formatDate } from '@/utils/formatTime';
  75. import { specialApplyBase, specialApprove, specialDetail } from '@/api/business/special';
  76. import { transformFile } from '@/utils/tools';
  77. // 引入组件
  78. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue'));
  79. // 定义子组件向父组件传值/事件
  80. const emit = defineEmits(['updateList']);
  81. // 定义变量内容
  82. const state = reactive<any>({
  83. dialogVisible: false, // 是否显示弹窗
  84. loading: false, // 是否显示加载
  85. ruleForm: {
  86. nextStepCode: null, // 特提节点
  87. nextHandlers: [], // 处理对象
  88. timeLimitUnit: 2, // 期满时间单位
  89. orgId: null, // 部门id
  90. orgName: null, // 部门名称
  91. alterTime: false, // 是否修改期满时间
  92. opinion: '', // 审批意见
  93. isPass: true, // 是否通过
  94. },
  95. detail: {}, // 详情信息
  96. workflowId: null, // 工作流id
  97. });
  98. const ruleFormRef = ref<RefType>();
  99. const steps = ref<EmptyArrayType>([]); // 特提节点
  100. const stepsItems = ref<EmptyArrayType>([]); // 处理对象
  101. const specialTimeType = ref<EmptyArrayType>([]); // 期满时间单位
  102. // 打开弹窗
  103. const openDialog = async (val: any) => {
  104. state.loading = true;
  105. state.dialogVisible = true;
  106. state.workflowId = val.workflowId;
  107. try {
  108. const [baseRes, detailRes] = await Promise.all([specialApplyBase(val.workflowId), specialDetail(val.id)]);
  109. steps.value = baseRes.result?.step?.steps ?? [];
  110. specialTimeType.value = baseRes.result.specialTimeType ?? [];
  111. state.detail = detailRes.result;
  112. state.detail.files = transformFile(detailRes.result.files);
  113. state.ruleForm.nextStepCode = detailRes.result.nextStepCode;
  114. state.ruleForm.nextStepName = detailRes.result.nextStepName;
  115. selectTrace(detailRes.result.nextStepCode);
  116. state.ruleForm.nextHandlers = detailRes.result.nextHandlers;
  117. state.ruleForm.alterTime = detailRes.result.alterTime;
  118. state.ruleForm.timeLimit = detailRes.result.timeLimit;
  119. state.ruleForm.timeLimitUnit = detailRes.result.timeLimitUnit;
  120. state.loading = false;
  121. } catch (e) {
  122. console.log(e);
  123. state.loading = false;
  124. }
  125. };
  126. // 关闭弹窗
  127. const closeDialog = () => {
  128. state.dialogVisible = false;
  129. };
  130. const close = () => {
  131. ruleFormRef.value?.clearValidate();
  132. ruleFormRef.value?.resetFields();
  133. steps.value = [];
  134. stepsItems.value = [];
  135. };
  136. // 选择节点确定处理对象
  137. const selectTrace = (val: any) => {
  138. const step = steps.value.find((item) => item.key === val);
  139. state.ruleForm.nextStepName = step?.value;
  140. ruleFormRef.value?.resetFields('nextHandlers');
  141. stepsItems.value = step?.items ?? [];
  142. stepsItems.value = stepsItems.value.map((item: any) => {
  143. return {
  144. value: {
  145. ...item,
  146. },
  147. label: item.value,
  148. };
  149. });
  150. state.ruleForm.flowDirection = step?.flowDirection;
  151. };
  152. // 审批
  153. const onAudit = (formEl: FormInstance | undefined) => {
  154. if (!formEl) return;
  155. formEl.validate((valid: boolean) => {
  156. if (!valid) return;
  157. state.loading = true;
  158. let request: {};
  159. if (state.ruleForm.isPass) {
  160. request = {
  161. id: state.detail.id,
  162. orderId: state.detail.orderId,
  163. opinion: state.ruleForm.opinion,
  164. workflowId: state.workflowId,
  165. state: 1, // 审核结果 0 待审核 1 审核通过 2 审核不通过
  166. };
  167. } else {
  168. request = {
  169. id: state.detail.id,
  170. orderId: state.detail.orderId,
  171. opinion: state.ruleForm.opinion,
  172. workflowId: state.workflowId,
  173. state: 2, // 审核结果 0 待审核 1 审核通过 2 审核不通过
  174. };
  175. }
  176. specialApprove(request)
  177. .then(() => {
  178. state.loading = false;
  179. closeDialog();
  180. emit('updateList');
  181. ElMessage.success('操作成功');
  182. })
  183. .catch(() => {
  184. state.loading = false;
  185. });
  186. });
  187. };
  188. defineExpose({
  189. openDialog,
  190. closeDialog,
  191. });
  192. </script>