Ver código fonte

应急预案完成

chauncey 9 meses atrás
pai
commit
491d1edf0c

+ 35 - 8
src/api/emergency-plan/index.ts

@@ -6,6 +6,8 @@ import type {
   ApprovalProcessParam,
   PlanApprovalListQuery,
   PlanApprovalListResponse,
+  ApprovalParam,
+  ApprovalProcessResponse,
 } from '@/types/emergency-plan';
 import type { QueryPageRequest, QueryPageResponse } from '@/types/basic-query';
 
@@ -35,7 +37,7 @@ export const createEmergencyPlan = (data: AddEmergencyPlanParam) => {
  * 删除应急预案
  */
 export const deleteEmergencyPlan = (emergencyPlanId: number) => {
-  return http.request({
+  return http.request<ApprovalProcessResponse[]>({
     url: `/emergencyPlan/deleteEmergencyPlan?emergencyPlanId=${emergencyPlanId}`,
     method: 'delete',
   });
@@ -66,7 +68,7 @@ export const editEmergencyPlan = (data: AddEmergencyPlanParam & { id: number })
 /**
  * 提交审批流程
  */
-export const submitApproval = (data: ApprovalProcessParam) => {
+export const submitApprovalProcess = (data: ApprovalProcessParam) => {
   return http.request({
     url: '/emergencyPlan/saveApprovalProcess',
     method: 'post',
@@ -78,9 +80,34 @@ export const submitApproval = (data: ApprovalProcessParam) => {
  * 查询预案审批列表
  */
 export const getEmergencyApprovalList = (data: QueryPageRequest<PlanApprovalListQuery>) => {
-    return http.request<QueryPageResponse<PlanApprovalListResponse>>({
-      url: '/emergencyPlan/queryEmergencyPlanApprovalPage',
-      method: 'post',
-      data,
-    });
-};
+  return http.request<QueryPageResponse<PlanApprovalListResponse>>({
+    url: '/emergencyPlan/queryEmergencyPlanApprovalPage',
+    method: 'post',
+    data,
+  });
+};
+
+/**
+ * 提交审批
+ */
+export const submitApproval = (data: ApprovalParam) => {
+  return http.request({
+    url: '/emergencyPlan/saveApproval',
+    method: 'post',
+    data,
+  });
+};
+
+/**
+ * 查询审批流程
+ */
+export const queryApprovalProcess = (approvalTemplateId: number, sourceId: number) => {
+  return http.request({
+    url: '/approvalManagement/queryApprovalProcess',
+    method: 'post',
+    data: {
+      approvalTemplateId,
+      sourceId,
+    },
+  });
+};

+ 28 - 2
src/types/emergency-plan/index.ts

@@ -21,6 +21,7 @@ interface BasicListResponse {
 
 export interface PlanEmergencyListResponse extends BasicListResponse {
   status: number;
+  approvalTemplateId: number;
 }
 
 export interface PlanApprovalListResponse extends BasicListResponse {
@@ -32,10 +33,10 @@ export interface PlanApprovalListResponse extends BasicListResponse {
   approvalOrder: number;
 }
 
-export interface AddEmergencyPlanForm extends Omit<PlanEmergencyListResponse, 'id' | 'status'> {
-  approvalTemplateId: string;
+export interface AddEmergencyPlanForm extends Omit<PlanEmergencyListResponse, 'id' | 'status' | 'approvalTemplateId'> {
   uploadFile: FileItem[];
   appendix: string;
+  approvalTemplateId: number | null;
 }
 
 export interface EditEmergencyPlaneForm extends AddEmergencyPlanForm {
@@ -54,3 +55,28 @@ export interface ApprovalProcessParam {
     approverIdList: number[];
   }[];
 }
+
+export interface ApprovalParam {
+  planId: number;
+  approvalOrder: number;
+  approvalStatus: number;
+  returnReason: string;
+}
+
+interface BasicProcessType {
+  approvalOrder: number;
+  nodeDescription: string;
+}
+export interface ProcessInfoListType {
+  approverName: string;
+  approvalType: number;
+  approvalStatus: number;
+  approvalTime: string;
+  approvalContent: string;
+}
+
+export interface ApprovalProcessResponse extends BasicProcessType {
+  processInfoList: ProcessInfoListType[];
+}
+
+export interface ApprovalProcessList extends BasicProcessType, ProcessInfoListType {}

+ 57 - 4
src/views/emergency/emergency-plan/PageApproval.vue

@@ -35,7 +35,12 @@
           </template>
           <template #action="scope">
             <div class="action-container--div">
-              <ActionButton text="审批" @click="handleApproval(scope.row.id, scope.row.approvalOrder)" />
+              <ActionButton
+                v-if="scope.row.status === APPROVAL_STATUS.PENDING"
+                text="审批"
+                @click="handleApproval(scope.row.id, scope.row.approvalOrder)"
+              />
+              <span v-else>--</span>
             </div>
           </template>
         </BasicTable>
@@ -43,13 +48,35 @@
     </div>
     <PreviewOnline ref="previewOnlineRef" />
   </div>
-  <BasicDialog ref="basicDialogRef" title="审批">
+  <BasicDialog ref="basicDialogRef" title="审批" @refresh="closeDialog">
+    <template #form>
+      <el-form ref="formRef" :model="formData" style="width: 100%">
+        <el-form-item label="审批:" prop="approvalStatus" :rules="[{ required: true, message: '请选择审批状态' }]">
+          <el-radio-group v-model="formData.approvalStatus">
+            <el-radio :value="APPROVAL_STATUS.APPROVED">通过</el-radio>
+            <el-radio :value="APPROVAL_STATUS.REJECTED">退回</el-radio>
+          </el-radio-group>
+        </el-form-item>
+        <el-form-item
+          v-if="formData.approvalStatus === APPROVAL_STATUS.REJECTED"
+          label="退回原因:"
+          prop="rejectReason"
+          :rules="[{ required: true, message: '请输入退回原因' }]"
+        >
+          <el-input v-model="formData.rejectReason" placeholder="请输入退回原因" />
+        </el-form-item>
+      </el-form>
+    </template>
+    <template #footer>
+      <el-button type="primary" @click="handleApprovalSubmit">提交</el-button>
+      <el-button @click="basicDialogRef?.closeDialog">返回</el-button>
+    </template>
   </BasicDialog>
 </template>
 
 <script setup lang="ts">
   import { ref, reactive, onMounted } from 'vue';
-  import { ElMessage } from 'element-plus';
+  import { ElMessage, type ElForm } from 'element-plus';
   import BasicSearch from '@/components/BasicSearch.vue';
   import BasicTable from '@/components/BasicTable.vue';
   import BasicDialog from '@/components/BasicDialog.vue';
@@ -60,12 +87,13 @@
   import { useEmergencyPlanHook } from './src/hook';
   import type { QueryPageRequest } from '@/types/basic-query';
   import type { PlanApprovalListQuery, PlanApprovalListResponse } from '@/types/emergency-plan';
-  import { getEmergencyApprovalList } from '@/api/emergency-plan';
+  import { getEmergencyApprovalList, submitApproval } from '@/api/emergency-plan';
   import {
     EMERGENCY_PLAN_APPROVAL_SEARCH_CONFIG,
     EMERGENCY_PLAN_APPROVAL_TABLE_OPTIONS,
     EMERGENCY_PLAN_APPROVAL_TABLE_COLUMNS,
   } from './src/config';
+  import { APPROVAL_STATUS } from './src/constant';
   import { FILE_TYPE_ICON } from '@/views/disaster/constant';
 
   const { tableConfig, pagination } = useTableConfig(
@@ -83,8 +111,13 @@
   const searchData = reactive({
     approvalStatus: null,
   });
+  const formData = reactive({
+    approvalStatus: APPROVAL_STATUS.APPROVED,
+    rejectReason: '',
+  });
   const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
   const basicDialogRef = ref<InstanceType<typeof BasicDialog>>();
+  const formRef = ref<InstanceType<typeof ElForm>>();
   const handleSearch = () => {
     planApprovalListQuery.queryParam = {};
     if (searchData.approvalStatus) {
@@ -120,6 +153,26 @@
     currentOrder.value = approvalOrder;
     basicDialogRef.value?.openDialog();
   };
+  const closeDialog = () => {
+    formRef.value?.resetFields();
+    basicDialogRef.value?.closeDialog();
+  };
+  const handleApprovalSubmit = () => {
+    formRef.value?.validate(async (valid) => {
+      if (valid) {
+        if (!currentId.value || !currentOrder.value) return;
+        await submitApproval({
+          planId: currentId.value,
+          approvalOrder: currentOrder.value,
+          approvalStatus: formData.approvalStatus,
+          returnReason: formData.rejectReason,
+        });
+        ElMessage.success('审批成功');
+        basicDialogRef.value?.closeDialog();
+        getTableData();
+      }
+    });
+  };
   onMounted(() => {
     getPlanTypeDict();
     getEmergencyEventDict();

+ 72 - 6
src/views/emergency/emergency-plan/PageManagement.vue

@@ -54,14 +54,27 @@
             <span>{{ getEmergencyEvent(scope.row.eventType) }}</span>
           </template>
           <template #status="scope">
-            <span>{{ getEmergencyPlanStatusLabel(scope.row.status) }}</span>
+            <span
+              :class="
+                scope.row.status === EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS ||
+                scope.row.status === EMERGENCY_PLAN_STATUS.RETURNED
+                  ? 'highlight-text'
+                  : ''
+              "
+              @click="handleViewApprovalProcess(scope.row)"
+              >{{ getEmergencyPlanStatusLabel(scope.row.status) }}</span
+            >
           </template>
           <template #action="scope">
             <div class="action-container--div">
               <ActionButton text="查看" @click="handleView(scope.row.id)" />
-              <ActionButton v-if="planManagementPremissions" text="编辑" @click="handleEdit(scope.row.id)" />
               <ActionButton
-                v-if="planManagementPremissions"
+                v-if="planManagementPremissions && scope.row.status !== EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS"
+                text="编辑"
+                @click="handleEdit(scope.row.id)"
+              />
+              <ActionButton
+                v-if="planManagementPremissions && scope.row.status !== EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS"
                 text="删除"
                 :popconfirm="{ title: '确认删除' }"
                 @confirm="handleDelete(scope.row.id)"
@@ -72,6 +85,18 @@
       </div>
     </div>
   </div>
+  <BasicDialog ref="basicDialogRef" title="审批流程" width="1000">
+    <template #form>
+      <BasicTable :tableData="approvalProcessData" :tableConfig="approvalProcessConfig">
+        <template #approvalType="scope">
+          <span>{{ APPROVAL_TYPE_MAP[scope.row.approvalType] }}</span>
+        </template>
+        <template #approvalStatus="scope">
+          <span>{{ APPROVAL_STATUS_MAP[scope.row.approvalStatus] }}</span>
+        </template>
+      </BasicTable>
+    </template>
+  </BasicDialog>
 </template>
 
 <script setup lang="ts">
@@ -81,22 +106,31 @@
   import { ElMessage } from 'element-plus';
   import BasicSearch from '@/components/BasicSearch.vue';
   import BasicTable from '@/components/BasicTable.vue';
+  import BasicDialog from '@/components/BasicDialog.vue';
   import ActionButton from '@/components/ActionButton.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
   import { useEmergencyHook } from '../src/hoos';
   import { useEmergencyPlanHook } from './src/hook';
   import { useUserInfoHook } from '@/hooks/useUserInfoHook';
   import type { QueryPageRequest } from '@/types/basic-query';
-  import type { PlanEmergencyListQuery, PlanEmergencyListResponse } from '@/types/emergency-plan';
-  import { getEmergencyPlanList, deleteEmergencyPlan } from '@/api/emergency-plan';
+  import type {
+    PlanEmergencyListQuery,
+    PlanEmergencyListResponse,
+    ApprovalProcessList,
+    ApprovalProcessResponse,
+    ProcessInfoListType,
+  } from '@/types/emergency-plan';
+  import { getEmergencyPlanList, deleteEmergencyPlan, queryApprovalProcess } from '@/api/emergency-plan';
   import {
     EMERGENCY_PLAN_MANAGEMENT_SEARCH_CONFIG,
     EMERGENCY_PLAN_MANAGEMENT_TABLE_OPTIONS,
     EMERGENCY_PLAN_MANAGEMENT_TABLE_COLUMNS,
     TABLE_MAX_HEIGHT_DEFAULT,
     TABLE_MAX_HEIGHT_PERMISSION,
+    APPROVAL_PROCESS_TABLE_COLUMNS,
   } from './src/config';
   import { EMERGENCY_PERMISSIONS } from '@/views/emergency/src/constant';
+  import { EMERGENCY_PLAN_STATUS, APPROVAL_TYPE_MAP,APPROVAL_STATUS_MAP } from './src/constant';
 
   const router = useRouter();
   const planManagementPremissions = ref<boolean>(false);
@@ -104,6 +138,7 @@
     EMERGENCY_PLAN_MANAGEMENT_TABLE_COLUMNS,
     EMERGENCY_PLAN_MANAGEMENT_TABLE_OPTIONS,
   );
+  const { tableConfig: approvalProcessConfig } = useTableConfig(APPROVAL_PROCESS_TABLE_COLUMNS, {}, false);
   const { emergencyEventDice, getEmergencyEventDict, getEmergencyEvent } = useEmergencyHook();
   const { planTypeDice, getPlanTypeDict, getPlanType, getEmergencyPlanStatusLabel } = useEmergencyPlanHook();
   const { permissions } = useUserInfoHook();
@@ -175,7 +210,7 @@
       name: defaultName,
       query: {
         id,
-        type: 'view'
+        type: 'view',
       },
     });
   };
@@ -184,6 +219,33 @@
     ElMessage.success('删除成功');
     await getTableData();
   };
+  const basicDialogRef = ref<InstanceType<typeof BasicDialog>>();
+  const approvalProcessData = ref<ApprovalProcessList[]>([]);
+  const handleViewApprovalProcess = async (row: PlanEmergencyListResponse) => {
+    if (row.status !== EMERGENCY_PLAN_STATUS.APPROVAL_IN_PROGRESS && row.status !== EMERGENCY_PLAN_STATUS.RETURNED)
+      return;
+
+    const res = await queryApprovalProcess(row.approvalTemplateId, row.id);
+
+    // 处理审批流程数据
+    approvalProcessData.value = [];
+    res.forEach((item: ApprovalProcessResponse) => {
+      if (item.processInfoList && item.processInfoList.length > 0) {
+        item.processInfoList.forEach((process: ProcessInfoListType) => {
+          approvalProcessData.value.push({
+            approvalOrder: item.approvalOrder,
+            nodeDescription: item.nodeDescription,
+            approvalType: process.approvalType,
+            approverName: process.approverName,
+            approvalContent: process.approvalContent,
+            approvalStatus: process.approvalStatus,
+            approvalTime: process.approvalTime,
+          });
+        });
+      }
+    });
+    basicDialogRef.value?.openDialog();
+  };
 
   onMounted(() => {
     getPlanTypeDict();
@@ -200,4 +262,8 @@
   @use '@/styles/page-details-layout.scss' as *;
   @use '@/styles/page-main-layout.scss' as *;
   @use '@/styles/basic-table-action.scss' as *;
+  .highlight-text {
+    cursor: pointer;
+    color: $primary-color;
+  }
 </style>

+ 2 - 2
src/views/emergency/emergency-plan/PageManagementDetail.vue

@@ -77,7 +77,7 @@
   import type { AddEmergencyPlanForm } from '@/types/emergency-plan';
   import type { ApprovalNodeInstanceType } from '@/views/system/approval/types';
   import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
-  import { createEmergencyPlan, editEmergencyPlan,submitApproval } from '@/api/emergency-plan';
+  import { createEmergencyPlan, editEmergencyPlan,submitApprovalProcess } from '@/api/emergency-plan';
   import { getApprovalNodeInstanceList } from '@/api/approval/approval';
   import { APPROVAL_TYPE_MAP, APPROVER_TYPE } from './src/constant';
 
@@ -212,7 +212,7 @@
             };
           }),
         };
-        await submitApproval(approvalData);
+        await submitApprovalProcess(approvalData);
         ElMessage.success('提交成功');
         basicDialogRef.value.closeDialog();
         router.back();

+ 4 - 3
src/views/emergency/emergency-plan/src/components/EditManagementDetail.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="emergency-plan-container">
-    <BasicForm ref="formRef" :formData="ruleFormData" :formConfig="ruleFormConfig">
+    <BasicForm ref="formRef" :formData="ruleFormData" :formConfig="ruleFormConfig" :formRules="formRules">
       <template #appendix>
         <UploadFiles
           label="上传附件"
@@ -23,15 +23,16 @@
   import type { EditEmergencyPlaneForm } from '@/types/emergency-plan';
   import type { FileItem } from '@/views/disaster/types';
   import { queryEmergencyPlan } from '@/api/emergency-plan';
-  import { PLAN_MANAGEMENT_FORM_CONFIG_EDIT, PLAN_MANAGEMENT_FORM_DATA_EDIT } from '../config';
+  import { PLAN_MANAGEMENT_FORM_CONFIG_EDIT, PLAN_MANAGEMENT_FORM_DATA_EDIT,PLAN_MANAGEMENT_FORM_RULES_EDIT } from '../config';
 
   const formRef = ref();
   const props = defineProps<{
     id: number;
   }>();
-  const { ruleFormConfig, ruleFormData } = useFormConfigHook<EditEmergencyPlaneForm>(
+  const { ruleFormConfig, ruleFormData, formRules } = useFormConfigHook<EditEmergencyPlaneForm>(
     PLAN_MANAGEMENT_FORM_CONFIG_EDIT,
     PLAN_MANAGEMENT_FORM_DATA_EDIT,
+    PLAN_MANAGEMENT_FORM_RULES_EDIT
   );
 
   const { getEmergencyEventDict, getEmergencyEvent, getApprovalList, approvalList } = useEmergencyHook();

+ 10 - 1
src/views/emergency/emergency-plan/src/config/form.ts

@@ -98,7 +98,7 @@ const BASE_FORM_DATA = {
   eventType: '',
   deptId: null,
   deptName: '',
-  approvalTemplateId: '',
+  approvalTemplateId: null,
   appendix: '',
   uploadFile: [],
 };
@@ -112,6 +112,10 @@ export const PLAN_MANAGEMENT_FORM_DATA_EDIT = {
   approvalTemplateName: '',
 };
 
+const BASIC_FORM_RULES = {
+  appendix: [{ required: true, message: '请上传预案文件',trigger: 'blur' }],
+};
+
 // 盘点任务表单规则
 export const PLAN_MANAGEMENT_FORM_RULES = {
   planName: [{ required: true, message: '请输入预案名称', trigger: 'blur' }],
@@ -119,4 +123,9 @@ export const PLAN_MANAGEMENT_FORM_RULES = {
   eventType: [{ required: true, message: '请选择事件类型', trigger: 'change' }],
   deptId: [{ required: true, message: '请选择制定部门', trigger: 'blur' }],
   approvalTemplateId: [{ required: true, message: '请选择审批流程', trigger: 'change' }],
+  ...BASIC_FORM_RULES,
+};
+
+export const PLAN_MANAGEMENT_FORM_RULES_EDIT = {
+  ...BASIC_FORM_RULES,
 };

+ 4 - 0
src/views/emergency/emergency-plan/src/config/index.ts

@@ -6,6 +6,7 @@ import {
   TABLE_MAX_HEIGHT_PERMISSION,
   EMERGENCY_PLAN_APPROVAL_TABLE_OPTIONS,
   EMERGENCY_PLAN_APPROVAL_TABLE_COLUMNS,
+  APPROVAL_PROCESS_TABLE_COLUMNS
 } from './table';
 import {
   PLAN_MANAGEMENT_FORM_CONFIG,
@@ -13,6 +14,7 @@ import {
   PLAN_MANAGEMENT_FORM_RULES,
   PLAN_MANAGEMENT_FORM_CONFIG_EDIT,
   PLAN_MANAGEMENT_FORM_DATA_EDIT,
+  PLAN_MANAGEMENT_FORM_RULES_EDIT,
 } from './form';
 export {
   EMERGENCY_PLAN_MANAGEMENT_SEARCH_CONFIG,
@@ -28,4 +30,6 @@ export {
   EMERGENCY_PLAN_APPROVAL_SEARCH_CONFIG,
   EMERGENCY_PLAN_APPROVAL_TABLE_OPTIONS,
   EMERGENCY_PLAN_APPROVAL_TABLE_COLUMNS,
+  PLAN_MANAGEMENT_FORM_RULES_EDIT,
+  APPROVAL_PROCESS_TABLE_COLUMNS,
 };

+ 32 - 0
src/views/emergency/emergency-plan/src/config/table.ts

@@ -102,3 +102,35 @@ export const EMERGENCY_PLAN_APPROVAL_TABLE_COLUMNS: TableColumnProps[] = [
   },
   BASIC_TABLE_COLUMNS.ACTION,
 ];
+
+export const APPROVAL_PROCESS_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    label: '流程步骤',
+    prop: 'approvalOrder',
+  },
+  {
+    label: '节点描述',
+    prop: 'nodeDescription',
+  },
+  {
+    label: '审批人',
+    prop: 'approverName',
+  },
+  {
+    label: '审批方式',
+    slot: 'approvalType',
+  },
+  {
+    label: '状态',
+    slot: 'approvalStatus',
+  },
+  {
+    label: '审批时间',
+    prop: 'approvalTime',
+    width: '200px',
+  },
+  {
+    label: '审批内容',
+    prop: 'approvalContent',
+  },
+];