Special-apply-order.vue 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  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">
  4. <el-form label-width="110px" ref="ruleFormRef" :model="state.ruleForm">
  5. <el-row :gutter="35">
  6. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  7. <el-form-item label="特提节点" prop="nextStepCode" :rules="[{ required: true, message: '请选择特提节点', trigger: 'change' }]">
  8. <el-select v-model="state.ruleForm.nextStepCode" placeholder="请选择特提节点" class="w100" @change="selectTrace">
  9. <el-option v-for="item in steps" :value="item.key" :key="item.key" :label="item.value"> </el-option>
  10. </el-select>
  11. </el-form-item>
  12. </el-col>
  13. <template v-if="state.ruleForm.nextStepCode">
  14. <!-- <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12" >
  15. <el-form-item label="办理时限" prop="timeLimit" :rules="[{ required: true, message: '请输入办理时限', trigger: 'blur' }]">
  16. <el-row :gutter="10" class="w100">
  17. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  18. <el-input-number
  19. placeholder="办理时限"
  20. v-model="state.ruleForm.timeLimit"
  21. controls-position="right"
  22. class="w100"
  23. :min="1"
  24. :max="99"
  25. ></el-input-number>
  26. </el-col>
  27. <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  28. <el-form-item
  29. label=""
  30. label-width="0"
  31. prop="timeLimitUnit"
  32. :rules="[{ required: true, message: '请选择办理时限单位', trigger: 'change' }]"
  33. >
  34. <el-select v-model="state.ruleForm.timeLimitUnit" placeholder="办理时限单位">
  35. <el-option v-for="item in specialTimeType" :value="item.key" :key="item.key" :label="item.value" />
  36. </el-select>
  37. </el-form-item>
  38. </el-col>
  39. </el-row>
  40. </el-form-item>
  41. </el-col>-->
  42. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  43. <el-form-item label="办理对象" prop="nextHandlers" :rules="[{ required: true, message: '请选择办理对象', trigger: 'change' }]">
  44. <el-select-v2
  45. v-model="state.ruleForm.nextHandlers"
  46. :options="stepsItems"
  47. placeholder="请选择办理对象"
  48. class="w100"
  49. multiple
  50. clearable
  51. collapse-tags
  52. collapse-tags-tooltip
  53. filterable
  54. value-key="key"
  55. :multiple-limit="1"
  56. />
  57. </el-form-item>
  58. </el-col>
  59. </template>
  60. <el-col :xs="24" :sm="24" :md="12" :lg="12" :xl="12">
  61. <el-form-item label="特提原因" prop="cause" :rules="[{ required: true, message: '请选择特提原因', trigger: 'change' }]">
  62. <el-select v-model="state.ruleForm.cause" placeholder="请选择特提原因" class="w100">
  63. <el-option v-for="item in specialReason" :value="item.dicDataName" :key="item.dicDataName" :label="item.dicDataName" />
  64. </el-select>
  65. </el-form-item>
  66. </el-col>
  67. <!-- <el-col :xs="24" :sm="12" :md="12" :lg="12" :xl="12">
  68. <el-form-item label="" prop="alterTime">
  69. <el-checkbox v-model="state.ruleForm.alterTime" label="无需计算期满时间" />
  70. </el-form-item>
  71. </el-col>-->
  72. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  73. <el-form-item label="特提理由" prop="reason" :rules="[{ required: true, message: '请填写特提理由', trigger: 'blur' }]">
  74. <el-input v-model="state.ruleForm.reason" type="textarea" :autosize="{ minRows: 6, maxRows: 10 }" placeholder="请填写特提理由" />
  75. </el-form-item>
  76. </el-col>
  77. <el-col :xs="24" :sm="24" :md="24" :lg="24" :xl="24">
  78. <el-form-item label="附件" prop="files" :rules="[{ required: false, message: '请选择附件', trigger: 'change' }]">
  79. <annex-list name="特提附件" v-model:format="filesFormat" :businessId="state.orderDetail.id" classify="特提附件" />
  80. </el-form-item>
  81. </el-col>
  82. </el-row>
  83. </el-form>
  84. </div>
  85. <template #footer>
  86. <span class="dialog-footer">
  87. <el-button @click="closeDialog" class="default-button">取 消</el-button>
  88. <el-button type="primary" @click="onSubmit(ruleFormRef)" :loading="state.loading">提交</el-button>
  89. </span>
  90. </template>
  91. </el-dialog>
  92. </template>
  93. <script setup lang="ts" name="SpecialDialog">
  94. import { defineAsyncComponent, reactive, ref } from 'vue';
  95. import { ElMessage, FormInstance } from 'element-plus';
  96. import { specialApplyBase, specialApply } from '@/api/business/special';
  97. import { orderTimeConfig } from '@/api/business/order';
  98. import { storeToRefs } from 'pinia';
  99. import { useUserInfo } from '@/stores/userInfo';
  100. import { useThemeConfig } from '@/stores/themeConfig';
  101. // 引入组件
  102. const AnnexList = defineAsyncComponent(() => import('@/components/AnnexList/index.vue'));
  103. // 定义子组件向父组件传值/事件
  104. const emit = defineEmits(['updateList']);
  105. // 定义变量内容
  106. const state = reactive<any>({
  107. dialogVisible: false, // 是否显示弹窗
  108. loading: false, // 是否显示加载
  109. ruleForm: {
  110. nextStepCode: null, // 特提节点
  111. timeLimitUnit: 2, // 期满时间单位
  112. alterTime: true, // 是否修改期满时间
  113. nextHandlers: [], // 办理对象
  114. },
  115. orderDetail: {}, // 工单详情
  116. workflowId: null, // 工作流id
  117. });
  118. const ruleFormRef = ref<RefType>();
  119. const specialReason = ref<EmptyArrayType>([]); // 特提理由
  120. const steps = ref<EmptyArrayType>([]); // 特提节点
  121. const stepsItems = ref<EmptyArrayType>([]); // 特提部门
  122. const specialTimeType = ref<EmptyArrayType>([]); // 期满时间单位
  123. const baseTypeId = ref<string>(''); // 默认选中的特提节点ID
  124. /**
  125. * @description 打开弹窗
  126. * @param {object} val 工单详情
  127. */
  128. const openDialog = async (val: any) => {
  129. state.orderDetail = val;
  130. state.workflowId = val.workflowId;
  131. state.loading = true;
  132. state.dialogVisible = true;
  133. try {
  134. const [baseRes] = await Promise.all([specialApplyBase(val.workflowId)]);
  135. baseTypeId.value = baseRes.result?.baseTypeId ?? '';
  136. steps.value = baseRes.result?.step?.steps ?? [];
  137. specialReason.value = baseRes.result.specialReason ?? [];
  138. specialTimeType.value = baseRes.result.specialTimeType ?? [];
  139. if (baseRes.result?.baseTypeId) selectTrace(baseRes.result?.baseTypeId, true);
  140. } catch (e) {
  141. console.log(e);
  142. } finally {
  143. state.loading = false;
  144. }
  145. state.dialogVisible = true;
  146. };
  147. // 关闭弹窗
  148. const closeDialog = () => {
  149. state.dialogVisible = false;
  150. };
  151. const close = () => {
  152. ruleFormRef.value?.clearValidate();
  153. ruleFormRef.value?.resetFields();
  154. steps.value = [];
  155. stepsItems.value = [];
  156. };
  157. // 选择节点确定处理对象
  158. const stores = useUserInfo();
  159. const storesThemeConfig = useThemeConfig();
  160. const { userInfos } = storeToRefs(stores);
  161. const selectTrace = (val: any, choose?) => {
  162. const step = steps.value.find((item) => item.key === val);
  163. if (choose) state.ruleForm.nextStepCode = val;
  164. state.ruleForm.nextStepName = step?.value;
  165. ruleFormRef.value?.resetFields('nextHandlers');
  166. stepsItems.value = step?.items ?? [];
  167. stepsItems.value = stepsItems.value.map((item: any) => {
  168. return {
  169. value: {
  170. ...item,
  171. },
  172. label: item.value,
  173. };
  174. });
  175. if (baseTypeId.value === val) {
  176. //如果默认选中节点 判断选择的对象是否有当前用户 如果有 默认选中当前用户
  177. const user = stepsItems.value.find((item: any) => item.value.key === userInfos.value?.id);
  178. if (user) {
  179. state.ruleForm.nextHandlers = [user.value];
  180. }
  181. }
  182. state.ruleForm.flowDirection = step?.flowDirection;
  183. console.log(step.handler);
  184. queryHandleTime();
  185. };
  186. // 查询办理时限
  187. const queryHandleTime = () => {
  188. if (state.ruleForm.alterTime) return;
  189. state.loading = true;
  190. orderTimeConfig({ acceptTypeCode: state.orderDetail.acceptTypeCode, FlowDirection: state.ruleForm.flowDirection })
  191. .then((res) => {
  192. state.ruleForm.timeLimit = res.result.count ?? 0; // 办理时限
  193. state.ruleForm.timeLimitUnit = res.result.timeType ?? ''; // 办理时限单位
  194. })
  195. .finally(() => {
  196. state.loading = false;
  197. });
  198. };
  199. // 提交
  200. const filesFormat = ref<EmptyArrayType>([]); // 附件列表
  201. const onSubmit = (formEl: FormInstance | undefined) => {
  202. if (!formEl) return;
  203. formEl.validate((valid: boolean) => {
  204. if (!valid) return;
  205. state.loading = true;
  206. let request = {
  207. ...state.ruleForm,
  208. workflowId: state.workflowId,
  209. orderId: state.orderDetail.id,
  210. files: filesFormat.value,
  211. stepCode: state.orderDetail.actualHandleStepCode,
  212. stepName: state.orderDetail.actualHandleStepName,
  213. };
  214. specialApply(request)
  215. .then(() => {
  216. state.loading = false;
  217. closeDialog();
  218. emit('updateList');
  219. ElMessage.success('特提申请成功');
  220. })
  221. .catch(() => {
  222. state.loading = false;
  223. });
  224. });
  225. };
  226. defineExpose({
  227. openDialog,
  228. closeDialog,
  229. });
  230. </script>