Kaynağa Gözat

feat: 演练记录

wyf 9 ay önce
ebeveyn
işleme
f284b1ea55

+ 40 - 0
src/api/emergency-drill/emergency-drill.ts

@@ -67,6 +67,36 @@ export const submitEmergencyDrillExecute = (params: ExecuteDrillPlanRuleForm) =>
   });
 };
 
+export const saveEmergencyDrillRecord = (params) => {
+  return http.request({
+    url: '/emergencyDrill/saveEmergencyDrillRecord',
+    method: 'POST',
+    data: {
+      drillPlanId: params.drillPlanId,
+      // participants: params.participants,
+      drillDescription: params.drillDescription,
+      drillImage: params.drillImage,
+      drillEffectAssess: params.drillEffectAssess,
+      saveOrSubmit: 0,
+    },
+  });
+};
+
+export const submitEmergencyDrillRecord = (params) => {
+  return http.request({
+    url: '/emergencyDrill/saveEmergencyDrillRecord',
+    method: 'POST',
+    data: {
+      drillPlanId: params.drillPlanId,
+      // participants: params.participants,
+      drillDescription: params.drillDescription,
+      drillImage: params.drillImage,
+      drillEffectAssess: params.drillEffectAssess,
+      saveOrSubmit: 1,
+    },
+  });
+};
+
 export const deleteEmergencyDrillPlan = (id) => {
   return http.request({
     url: `/emergencyDrill/deleteEmergencyDrillPlan?drillPlanId=${id}`,
@@ -123,3 +153,13 @@ export const signDrillScript = (data: { drillPlanId: number; planToParticipateCo
     data,
   });
 };
+
+/**
+ * 查询审批模板
+ */
+export const queryDrillApproval = (id: number) => {
+  return http.request<any>({
+    url: `/emergencyDrill/queryApprovalProcess?drillPlanId=${id}`,
+    method: 'get',
+  });
+};

+ 8 - 2
src/views/emergency/emergency-drill/PageDrillPlanItem.vue

@@ -96,8 +96,14 @@
     formLoading.value = false;
   };
 
-  const recordSave = async () => {};
-  const recordSubmit = async () => {};
+  const recordSave = async () => {
+    formLoading.value = true;
+    await dynamicComponentRef.value.saveDrillRecord();
+    formLoading.value = false;
+  };
+  const recordSubmit = async () => {
+    await dynamicComponentRef.value.submitDrillRecord();
+  };
 </script>
 
 <style scoped lang="scss">

+ 0 - 0
src/views/emergency/emergency-drill/components/DrillApprovalDialog.vue


+ 6 - 6
src/views/emergency/emergency-drill/components/DrillPlanExecuteForm.vue

@@ -68,7 +68,7 @@
   import UploadFiles from '@/views/disaster/components/UploadFiles.vue';
 
   const props = defineProps<{
-    insCode: string;
+    insName: string;
     drillData: DrillPlanItemDetail;
   }>();
 
@@ -88,7 +88,7 @@
             drillScript: props.drillData.drillScript,
           }
         : DRILL_EXECUTE_FORM_DATA,
-      props.drillData.drillScope === props.insCode ? INS_DRILL_EXECUTE_FORM_RULES : DEP_DRILL_EXECUTE_FORM_RULES,
+      props.drillData.drillScope === props.insName ? INS_DRILL_EXECUTE_FORM_RULES : DEP_DRILL_EXECUTE_FORM_RULES,
     );
 
   const cascaderProp = { multiple: true, expandTrigger: 'hover', emitPath: false, value: 'id', label: 'deptName' };
@@ -119,13 +119,13 @@
     loadDeptTreeData();
   });
 
-  const handleValidate = async () => {
+  const formValidate = async () => {
     if (!basicFormRef.value) return;
     const validateResult = await basicFormRef.value.validateForm();
     return validateResult;
   };
 
-  const handleClearValidate = () => {
+  const formClearValidate = () => {
     if (!basicFormRef.value) return;
     basicFormRef.value.clearValidate();
   };
@@ -135,8 +135,8 @@
   }
 
   defineExpose({
-    handleValidate,
-    handleClearValidate,
+    formValidate,
+    formClearValidate,
     getFormData,
   });
 

+ 7 - 2
src/views/emergency/emergency-drill/components/DrillPlanExecuteItem.vue

@@ -15,7 +15,7 @@
       <DrillPlanExecuteForm
         v-if="drillData"
         ref="drillPlanExecuteFormRef"
-        :ins-code="drillScopeDice[0].itemCode"
+        :ins-name="drillScopeDice[0].itemValue"
         :drill-data="drillData"
         style="margin-top: 20px"
       />
@@ -100,7 +100,7 @@
     if (!drillPlanExecuteFormRef.value) return;
     // drillPlanExecuteFormRef.value.handleClearValidate();
     if (mode === 'submit') {
-      const res = await drillPlanExecuteFormRef.value.handleValidate();
+      const res = await drillPlanExecuteFormRef.value.formValidate();
       if (!res) return;
     }
 
@@ -127,6 +127,9 @@
       try {
         await saveEmergencyDrillExecute(executeParams);
         ElMessage.success('保存成功');
+        drillPlanExecuteFormRef.value.formClearValidate();
+        drillData.value = undefined;
+        getDrillData();
       } catch (e) {
         console.log(e);
       }
@@ -134,6 +137,8 @@
       try {
         await submitEmergencyDrillExecute(executeParams);
         ElMessage.success('提交成功');
+        drillPlanExecuteFormRef.value.formClearValidate();
+        getDrillData();
       } catch (e) {
         console.log(e);
       }

+ 86 - 0
src/views/emergency/emergency-drill/components/DrillPlanRecordForm.vue

@@ -0,0 +1,86 @@
+<template>
+  <div>
+    <BasicForm ref="basicFormRef" :formData="ruleFormData" :formRules="formRules" :formConfig="ruleFormConfig">
+      <template #drillImage>
+        <UploadImages
+          v-if="!uploadImgDisabled"
+          :maxCount="9"
+          ref="uploadImagesRef"
+          @uploadChange="handleUploadChange"
+        />
+        <ShowImages v-else :image-list="ruleFormData.drillImage" />
+      </template>
+    </BasicForm>
+  </div>
+</template>
+
+<script setup lang="ts">
+  import BasicForm from '@/components/BasicForm.vue';
+  import UploadImages from '@/views/disaster/disaster-control/src/components/UploadImages.vue';
+  import ShowImages from './ShowImages.vue';
+  import { useFormConfigHook } from '@/hooks/useFormConfigHook';
+  import { DRILL_RECORD_FORM_CONFIG, DRILL_RECORD_FORM_RULES, DRILL_RECORD_FORM_DATA } from '../configs/plan/form';
+  import { DrillPlanRecord, DrillRecordRuleForm } from '../types';
+  import { ref } from 'vue';
+
+  const props = defineProps<{
+    drillRecord?: DrillPlanRecord;
+  }>();
+
+  const { ruleFormConfig, ruleFormData, formRules, cloneRuleFormData, beforeRouteLeave } =
+    useFormConfigHook<DrillRecordRuleForm>(
+      DRILL_RECORD_FORM_CONFIG,
+      props.drillRecord
+        ? {
+            participants: props.drillRecord.participants,
+            drillDescription: props.drillRecord.drillDescription,
+            drillImage: props.drillRecord.drillImage,
+            drillEffectAssess: props.drillRecord.drillEffectAssess,
+          }
+        : DRILL_RECORD_FORM_DATA,
+      DRILL_RECORD_FORM_RULES,
+    );
+
+  const handleUploadChange = (files: File[]) => {};
+
+  const basicFormRef = ref<typeof BasicForm>();
+
+  const FormValidate = async () => {
+    if (!basicFormRef.value) return;
+    const validateResult = await basicFormRef.value.validateForm();
+    return validateResult;
+  };
+
+  const FormClearValidate = () => {
+    if (!basicFormRef.value) return;
+    basicFormRef.value.clearValidate();
+  };
+
+  function getFormData() {
+    return ruleFormData;
+  }
+
+  const uploadImgDisabled = ref(false);
+  function disableFormInput() {
+    uploadImgDisabled.value = true;
+    ruleFormConfig.value.forEach((x) => {
+      if (x.componentProps) x.componentProps.disabled = true;
+    });
+  }
+  function enableFormInput() {
+    uploadImgDisabled.value = false;
+    ruleFormConfig.value.forEach((x) => {
+      if (x.componentProps) x.componentProps.disabled = false;
+    });
+  }
+
+  defineExpose({
+    FormValidate,
+    FormClearValidate,
+    getFormData,
+    disableFormInput,
+    enableFormInput,
+  });
+</script>
+
+<style scoped></style>

+ 46 - 2
src/views/emergency/emergency-drill/components/DrillPlanRecordItem.vue

@@ -1,7 +1,51 @@
 <template>
-  <div> 记录 </div>
+  <div>
+    <DrillPlanRecordForm ref="drillPlanRecordFormRef" :drill-record="recordData" />
+  </div>
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import DrillPlanRecordForm from './DrillPlanRecordForm.vue';
+  import { onMounted, ref } from 'vue';
+  import { useRoute } from 'vue-router';
+  import { DrillPlanRecord } from '../types';
+  import { queryEmergencyDrillRecord } from '@/api/emergency-drill/emergency-drill';
+
+  const route = useRoute();
+  const id = route.query.id;
+  const recordData = ref<DrillPlanRecord>();
+
+  async function getData() {
+    try {
+      recordData.value = await queryEmergencyDrillRecord(id);
+
+      // 演练记录数据处理
+    } catch (e) {
+      console.log(e);
+    }
+  }
+
+  onMounted(() => {
+    getData();
+  });
+
+  const drillPlanRecordFormRef = ref();
+
+  async function saveDrillRecord() {
+    if (!drillPlanRecordFormRef) return;
+    const formData = drillPlanRecordFormRef.value.getFormData();
+  }
+
+  async function submitDrillRecord() {
+    if (!drillPlanRecordFormRef) return;
+    const res = await drillPlanRecordFormRef.value.formValidate();
+    if (!res) return;
+  }
+
+  defineExpose({
+    saveDrillRecord,
+    submitDrillRecord,
+  });
+</script>
 
 <style scoped></style>

+ 45 - 0
src/views/emergency/emergency-drill/components/ShowImages.vue

@@ -0,0 +1,45 @@
+<template>
+  <div class="show-box-container">
+    <div v-for="(image, index) in imageList" :key="index" class="image-preview">
+      <el-image
+        :src="image.url"
+        :zoom-rate="1.2"
+        :max-scale="7"
+        :min-scale="0.2"
+        :preview-src-list="imageList.map((item) => item.url)"
+        show-progress
+        :initial-index="index"
+        fit="contain"
+      />
+    </div>
+  </div>
+</template>
+
+<script setup lang="ts">
+  // import type { ImageItem } from '@/types/disaster-control';
+  import { computed } from 'vue';
+
+  const props = defineProps<{
+    imageList?: string;
+  }>();
+
+  const imageList = computed(() => {
+    if (!props.imageList) return [];
+    return JSON.parse(props.imageList);
+  });
+</script>
+
+<style scoped>
+  .show-box-container {
+    display: flex;
+    flex-wrap: wrap;
+    gap: 5px;
+    width: 100%;
+  }
+
+  .image-preview {
+    width: 100px;
+    height: 100px;
+    border-radius: 4px;
+  }
+</style>

+ 57 - 0
src/views/emergency/emergency-drill/configs/plan/form.ts

@@ -163,3 +163,60 @@ export const DRILL_EXECUTE_FORM_DATA = {
   drillDeptIdList: undefined,
   drillScript: undefined,
 };
+
+export const DRILL_RECORD_FORM_CONFIG: FormConfig[] = [
+  {
+    prop: 'participants',
+    label: '参与人员:',
+    component: 'el-input',
+    componentProps: {
+      type: 'textarea',
+      maxLength: 1000,
+      autosize: { minRows: 3 },
+      showWordLimit: true,
+      placeholder: '请描述演练人员,不超过1000字',
+    },
+  },
+  {
+    prop: 'drillDescription',
+    label: '演练描述:',
+    component: 'el-input',
+    componentProps: {
+      type: 'textarea',
+      maxLength: 2000,
+      showWordLimit: true,
+      autosize: { minRows: 8 },
+      placeholder: '请描述演练过程,不超过2000字',
+    },
+  },
+  {
+    prop: 'drillImage',
+    label: '演练照片:',
+    slot: 'drillImage',
+  },
+  {
+    prop: 'drillEffectAssess',
+    label: '演练效果评估:',
+    component: 'el-input',
+    componentProps: {
+      type: 'textarea',
+      maxLength: 2000,
+      showWordLimit: true,
+      autosize: { minRows: 5 },
+      placeholder: '请描述演练效果评估,不超过2000字',
+    },
+  },
+];
+
+export const DRILL_RECORD_FORM_RULES = {
+  participants: [{ required: true, message: '请填写参与人员', trigger: 'blur' }],
+  drillDescription: [{ required: true, message: '请填写演练描述', trigger: 'blur' }],
+  drillEffectAssess: [{ required: true, message: '请填写演练效果评估', trigger: 'blur' }],
+};
+
+export const DRILL_RECORD_FORM_DATA = {
+  participants: '',
+  drillDescription: '',
+  drillImage: '',
+  drillEffectAssess: '',
+};

+ 29 - 12
src/views/emergency/emergency-drill/types.ts

@@ -135,6 +135,21 @@ export interface DrillPlanItemDetail {
   }[];
 }
 
+export interface ExecuteDrillPlanRuleForm {
+  drillPlanId?: number;
+  /*演练时间 */
+  drillTime?: string;
+  /*演练地点 */
+  drillLocation?: string;
+  /*演练负责人id */
+  personInChargeId?: number;
+  personInChargeName?: string;
+  /*演练部门id列表 */
+  drillDeptIdList?: number[];
+  /*演练脚本 */
+  drillScript?: any;
+}
+
 export interface DrillPlanRecord {
   /*自增主键 */
   id?: number;
@@ -178,17 +193,19 @@ export interface DrillPlanRecord {
   approvalTemplateId?: number;
 }
 
-export interface ExecuteDrillPlanRuleForm {
+export interface DrillRecordRuleForm {
   drillPlanId?: number;
-  /*演练时间 */
-  drillTime?: string;
-  /*演练地点 */
-  drillLocation?: string;
-  /*演练负责人id */
-  personInChargeId?: number;
-  personInChargeName?: string;
-  /*演练部门id列表 */
-  drillDeptIdList?: number[];
-  /*演练脚本 */
-  drillScript?: any;
+  /*参与人员 */
+  participants?: string;
+  /*演练描述 */
+  drillDescription?: string;
+  /*演练照片 */
+  drillImage?: string;
+  /*演练效果评估 */
+  drillEffectAssess?: string;
+  /*演练记录审批内容 */
 }
+
+// export interface DrillApprovalItem {
+
+// }