DrillPlanExecuteItem.vue 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. <template>
  2. <div v-if="drillData">
  3. <div class="drill-activity-container">
  4. <div class="drill-container__title">
  5. <div class="drill-container--line"></div>
  6. <span>演练活动</span>
  7. </div>
  8. <div class="drill-container__content">
  9. <el-row :gutter="20">
  10. <el-col :span="8">
  11. <div class="drill-container__content--item">
  12. <span class="label">演练规模:</span>
  13. <span class="value">{{ getDrillScope(drillData.drillScope) }}</span>
  14. </div>
  15. </el-col>
  16. <el-col :span="8">
  17. <div class="drill-container__content--item">
  18. <span class="label">演练内容:</span>
  19. <span class="value">{{ drillData.drillContent }}</span>
  20. </div>
  21. </el-col>
  22. <el-col :span="8">
  23. <div class="drill-container__content--item">
  24. <span class="label">计划完成时间:</span>
  25. <span class="value">{{ drillData.dueCompleteTime }}</span>
  26. </div>
  27. </el-col>
  28. </el-row>
  29. <el-row :gutter="20">
  30. <el-col :span="8">
  31. <div class="drill-container__content--item">
  32. <div>
  33. <span class="label">责任部门:</span>
  34. <template v-for="(dept, index) in safatyJsonParse(drillData.responsibleDeptNameList)" :key="index">
  35. <span class="value">
  36. {{ dept }}
  37. <span v-if="index !== safatyJsonParse(drillData.responsibleDeptNameList).length - 1">、</span>
  38. </span>
  39. </template>
  40. </div>
  41. </div>
  42. </el-col>
  43. <el-col :span="8">
  44. <div class="drill-container__content--item">
  45. <div>
  46. <span class="label">配合部门:</span>
  47. <template
  48. v-if="drillData.coordinateDeptNameList"
  49. v-for="(dept, index) in safatyJsonParse(drillData.coordinateDeptNameList)"
  50. :key="index"
  51. >
  52. <span class="value">
  53. {{ dept }}
  54. <span v-if="index !== safatyJsonParse(drillData.coordinateDeptNameList).length - 1">、</span>
  55. </span>
  56. </template>
  57. </div>
  58. </div>
  59. </el-col>
  60. <el-col :span="8">
  61. <div class="drill-container__content--item" v-if="drillData.emergencyPlanAppendix">
  62. <span class="label">关联应急预案:</span>
  63. <span class="value font-primary link" @click="handlePreviewFile(drillData.emergencyPlanAppendix)">{{
  64. JSON.parse(drillData.emergencyPlanAppendix)[0].fileName
  65. }}</span>
  66. </div>
  67. </el-col>
  68. </el-row>
  69. <el-row :gutter="20">
  70. <el-col>
  71. <div class="drill-container__content--item">
  72. <span class="label">审批流程:</span>
  73. <span class="value">{{ getApprovalName(drillData.approvalTemplateId) }}</span>
  74. </div>
  75. </el-col>
  76. </el-row>
  77. </div>
  78. </div>
  79. <div class="drill-execute-form" style="margin-top: 20px">
  80. <div class="drill-container__title">
  81. <div class="drill-container--line"></div>
  82. <span>演练实施</span>
  83. </div>
  84. <DrillPlanExecuteForm
  85. v-if="drillData"
  86. ref="drillPlanExecuteFormRef"
  87. :ins-name="drillScopeDice[0].itemCode"
  88. :drill-data="drillData"
  89. style="margin-top: 20px"
  90. />
  91. </div>
  92. </div>
  93. </template>
  94. <script setup lang="ts">
  95. import { ref, onMounted } from 'vue';
  96. import { ElMessage } from 'element-plus';
  97. import { useRoute } from 'vue-router';
  98. import { DrillPlanItemDetail } from '../types';
  99. import DrillPlanExecuteForm from './DrillPlanExecuteForm.vue';
  100. import {
  101. queryEmergencyDrillPlanDetail,
  102. saveEmergencyDrillExecute,
  103. submitEmergencyDrillExecute,
  104. } from '@/api/emergency-drill/emergency-drill';
  105. import { getAllApproval } from '@/api/approval/approval';
  106. import type { FileItem } from '@/views/disaster/types';
  107. import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
  108. import { useEmergencyDrillHook } from '../hook';
  109. import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
  110. import { FILE_TYPE_ICON } from '@/views/disaster/constant';
  111. const route = useRoute();
  112. const id = route.query.id;
  113. const approvalList = ref();
  114. const drillData = ref<DrillPlanItemDetail>();
  115. const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
  116. const { drillScopeDice, getDrillScopeDict, getDrillScope } = useEmergencyDrillHook();
  117. const getApprovalList = async () => {
  118. approvalList.value = await getAllApproval();
  119. };
  120. async function getDrillData() {
  121. try {
  122. drillData.value = await queryEmergencyDrillPlanDetail(id);
  123. } catch (e) {
  124. console.log(e);
  125. }
  126. }
  127. onMounted(async () => {
  128. await getApprovalList();
  129. await getDrillScopeDict();
  130. getDrillData();
  131. });
  132. const getApprovalName = (id: number) => {
  133. return approvalList.value.find((item) => item.id === id)?.templateName;
  134. };
  135. const safatyJsonParse = (str: string) => {
  136. return str.slice(1, -1).split(',');
  137. };
  138. const drillPlanExecuteFormRef = ref();
  139. const formatAttachmentList = async (data: FileItem[]) => {
  140. if (!data || data.length === 0) return null;
  141. const file = data[0];
  142. if (!file.file) return file;
  143. const fileName = file.fileName;
  144. const res = await uploadFileApi({ bizType: UPLOAD_BIZ_TYPE.ATTACHMENT, fileName, file: file.file });
  145. const fileType = file.fileType;
  146. const fileSize = file.fileSize;
  147. const fileId = file.fileId;
  148. const fileUrl = res.url;
  149. return {
  150. fileName,
  151. fileType,
  152. fileSize,
  153. fileUrl,
  154. fileId,
  155. };
  156. };
  157. const handlePreviewFile = (str: string) => {
  158. const obj = JSON.parse(str);
  159. const file = Array.isArray(obj) ? obj[0] : obj;
  160. const url = file.fileUrl;
  161. const type = file.fileType as keyof typeof FILE_TYPE_ICON;
  162. if (!url) return;
  163. previewOnlineRef.value?.open(url, type);
  164. };
  165. async function executeSaveOrSubmit(mode: string) {
  166. if (!drillPlanExecuteFormRef.value) return;
  167. // drillPlanExecuteFormRef.value.handleClearValidate();
  168. if (mode === 'submit') {
  169. const res = await drillPlanExecuteFormRef.value.formValidate();
  170. if (!res) return;
  171. }
  172. const formData = drillPlanExecuteFormRef.value.getFormData();
  173. let attachmentListRes;
  174. if (typeof formData.drillScript === 'string') {
  175. attachmentListRes = formData.drillScript;
  176. } else if (!formData.drillScript || formData.drillScript.length === 0) {
  177. attachmentListRes = '';
  178. } else {
  179. attachmentListRes = JSON.stringify(await formatAttachmentList(formData.drillScript));
  180. }
  181. const executeParams = {
  182. drillPlanId: formData.drillPlanId,
  183. drillTime: formData.drillTime,
  184. drillLocation: formData.drillLocation,
  185. personInChargeId: formData.personInChargeId,
  186. drillDeptIdList: formData.drillDeptIdList,
  187. drillScript: attachmentListRes,
  188. };
  189. if (mode === 'save') {
  190. try {
  191. await saveEmergencyDrillExecute(executeParams);
  192. ElMessage.success('保存成功');
  193. drillPlanExecuteFormRef.value.formClearValidate();
  194. drillData.value = undefined;
  195. getDrillData();
  196. } catch (e) {
  197. console.log(e);
  198. ElMessage.error('保存失败');
  199. }
  200. } else {
  201. try {
  202. await submitEmergencyDrillExecute(executeParams);
  203. ElMessage.success('提交成功');
  204. drillPlanExecuteFormRef.value.formClearValidate();
  205. drillData.value = undefined;
  206. getDrillData();
  207. } catch (e) {
  208. console.log(e);
  209. ElMessage.error('提交失败');
  210. }
  211. }
  212. }
  213. defineExpose({
  214. executeSaveOrSubmit,
  215. });
  216. </script>
  217. <style scoped lang="scss">
  218. @use '../style/common.scss' as *;
  219. </style>