Parcourir la source

完成静态页面 等待总览联调

chauncey il y a 10 mois
Parent
commit
43f11ff83c

+ 4 - 0
src/components/BasicTable.vue

@@ -111,8 +111,12 @@
   :deep(.el-table__empty-text) {
     @include flex-center;
     flex-direction: column;
+    padding-top: 20px;
     img {
       width: 510px;
     }
   }
+  :deep(.el-table__empty-block) {
+    border-bottom: 1px solid rgba(0, 0, 0, 0.06);
+  }
 </style>

+ 3 - 2
src/styles/custom-component.scss

@@ -5,14 +5,15 @@
 }
 
 .customDialog--pushObject {
-  height: 60vh;
+  max-height: 60vh;
   border-radius: 8px !important;
+  overflow-y: hidden;
   .el-dialog__body {
     display: flex;
     flex-direction: column;
     gap: 10px;
     width: 100%;
-    height: calc(100% - 50px);
+    max-height: calc(60vh - 100px);
     overflow-y: auto;
   }
 }

+ 1 - 0
src/types/disaster-control/index.ts

@@ -186,6 +186,7 @@ export interface LossRecordEditQuery extends Omit<LossRecordCreateQuery, 'report
 }
 
 export interface DisposalRectificationFormData {
+  id?: number;
   fixStatus: string;
   fixMethod: string;
   fixDeadline: string;

+ 5 - 11
src/views/disaster/disaster-control/PageDisposalRectificationItem.vue

@@ -5,7 +5,7 @@
       <span class="disaster-precaution-container__title">整改处理</span>
     </header>
     <main class="disaster-precaution-container__main">
-      <DisasterInfo :LossReportItemFormData="LossReportItemFormData" v-if="LossReportItemFormData?.isLoss" />
+      <DisasterInfo :LossReportItemFormData="lossReportItem" v-if="lossReportItem?.isLoss" />
       <section class="disaster-information">
         <div class="disaster-information__title">
           <div class="disaster-information--line"></div>
@@ -44,7 +44,7 @@
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
   import { useUserInfoHook } from '@/views/disaster/hooks';
   import type { FileItem } from '@/views/disaster/types';
-  import type { disasterReportRecordDetailListResponse, DisposalRectificationFormData } from '@/types/disaster-control';
+  import type { DisposalRectificationFormData } from '@/types/disaster-control';
   import { createDisposalRectification } from '@/api/disaster-control';
   import { uploadFileApi, UPLOAD_BIZ_TYPE } from '@/api/minio';
   import {
@@ -57,8 +57,7 @@
   const uploadImagesRef = ref<InstanceType<typeof UploadImages>>();
   const uploadFilesRef = ref<InstanceType<typeof UploadFiles>>();
 
-  const LossReportItemFormData = ref<disasterReportRecordDetailListResponse>();
-  const { getLossReportItem, getSafetyLevel, getSafetyLevelDict } = useDisasterControlHook();
+  const { getLossReportItem, lossReportItem } = useDisasterControlHook();
   const { realname, id: userId } = useUserInfoHook();
 
   const router = useRouter();
@@ -67,10 +66,6 @@
   const handleTaskId = Number(route.query.handleTaskId);
   const fixTaskId = Number(route.query.fixTaskId);
   const formLoading = ref(false);
-  const getLossReportItemData = async () => {
-    const res = await getLossReportItem(handleTaskId, id.value);
-    LossReportItemFormData.value = res;
-  };
   const { ruleFormConfig, ruleFormData, formRules, cloneRuleFormData, beforeRouteLeave } =
     useFormConfigHook<DisposalRectificationFormData>(
       DISPOSAL_RECTIFICATION_FORM_CONFIG,
@@ -192,8 +187,7 @@
     initRuleFormCreatedBy();
     cloneRuleFormData();
     beforeRouteLeave();
-    getLossReportItemData();
-    getSafetyLevelDict();
+    getLossReportItem(handleTaskId, id.value);
     const sessionRectificationIds = sessionStorage.getItem('rectificationIds') || '[]';
     rectificationIds.value = JSON.parse(sessionRectificationIds);
   });
@@ -204,7 +198,7 @@
     () => route.params.id,
     (newId) => {
       id.value = Number(newId);
-      getLossReportItemData();
+      getLossReportItem(handleTaskId, id.value);
       basicFormRef.value?.clearValidate();
       initRuleFormCreatedBy();
       uploadImagesRef.value?.removeAllImages();

+ 49 - 29
src/views/disaster/disaster-control/PageViewDisposalRectification.vue

@@ -29,8 +29,13 @@
                 <DamagedList :damagedList="damagedList" :activeId="0" />
               </section>
               <section class="disaster-info-container">
-                <DisasterInfo :LossReportItemFormData="LossReportItemFormData" v-if="LossReportItemFormData?.isLoss" />
-                <Rectification :rectificationList="rectificationList" />
+                <DisasterInfo :LossReportItemFormData="lossReportItem" rectification v-if="lossReportItem?.isLoss" />
+                <Rectification
+                  :rectification-list="rectificationList"
+                  :rectification-dept-name="rectificationDeptName"
+                  :rectification-responsible-user-list="rectificationResponsibleUserList"
+                  :rectification-priority="rectificationPriority"
+                />
               </section>
             </div>
           </template>
@@ -41,7 +46,6 @@
 </template>
 
 <script lang="ts" setup>
-  import BackIcon from 'assets/svg/back.svg';
   import { useRoute, useRouter } from 'vue-router';
   import { onMounted, ref } from 'vue';
   import { ElMessage } from 'element-plus';
@@ -50,8 +54,12 @@
   import DamagedList from './src/components/DamagedList.vue';
   import DisasterInfo from './src/components/DisasterInfo.vue';
   import Rectification from './src/components/Rectification.vue';
-  import type { disasterReportRecordDetailListResponse, DisposalRectificationFormData } from '@/types/disaster-control';
+  import { useDisasterControlHook } from './src/hook';
+  import type { PersonGroupItem } from '@/types/person-group/type';
+  import type { DisposalRectificationFormData } from '@/types/disaster-control';
   import { getRectificationList } from '@/api/disaster-control';
+  import { queryUserInfoByIds } from '@/api/system/person-group';
+  import BackIcon from 'assets/svg/back.svg';
 
   const router = useRouter();
   const route = useRoute();
@@ -61,6 +69,8 @@
     lossTaskId: number;
     fixTaskId: number;
   };
+  const { lossReportItem, getLossReportItem } = useDisasterControlHook();
+
   const exportLossDetail = () => {
     ElMessage.warning('暂未开放');
   };
@@ -72,30 +82,6 @@
       activeId.value = itemId;
     }
   };
-  const LossReportItemFormData: disasterReportRecordDetailListResponse = {
-    affectedItems: 'hahah',
-    buildingNo: '16',
-    description: '测试',
-    estimatedLoss: null,
-    fixStatus: 1,
-    fixTaskId: 98,
-    fixerList: '[70]',
-    floorNo: '17',
-    id: 162,
-    images:
-      '["./skyeye-file-upload/sfysecurity/ATTACHMENT/attachment_avatar.jpg","./skyeye-file-upload/sfysecurity/ATTACHMENT/attachment_pig.jpg","./skyeye-file-upload/sfysecurity/ATTACHMENT/attachment_R-C.jpg"]',
-    isAffectWork: 0,
-    isFixPrincipal: true,
-    isLoss: 1,
-    priority: 'urgent',
-    remark: '',
-    responsibleDeptName: '综合计划部',
-    roomNo: '18',
-    safetyLevel: 'mild',
-    updatedAt: '2025-06-13 10:29:06',
-    userGroupList: '[13]',
-    createdBy: '70',
-  };
   const damagedList: string[] = [
     '玻璃破损6处',
     '树木倒伏',
@@ -105,10 +91,40 @@
     '遥控器',
     '室外防水设备箱',
   ];
+  const rectificationDeptName = ref<string>('建设管理部');
+  const rectificationResponsibleUserList = ref<PersonGroupItem[]>([
+    {
+      id: 1,
+      realname: '张三',
+      staffNo: '123456',
+    },
+    {
+      id: 2,
+      realname: '李四',
+      staffNo: '123456',
+    },
+    {
+      id: 3,
+      realname: '王五',
+      staffNo: '123456',
+    },
+  ]);
+  const rectificationPriority = ref<string>('normal');
   const rectificationList = ref<DisposalRectificationFormData[]>([]);
   onMounted(async () => {
     const res = await getRectificationList([lossTaskId]);
     rectificationList.value = res[0].disasterLossFixRecordList;
+    // 直接for循环查
+    for (const item of rectificationList.value) {
+      item.remark = item.remark ? item.remark : '--';
+      if (item.createdBy) {
+        const userInfo = await queryUserInfoByIds([Number(item.createdBy)]);
+        item.createdByName = userInfo[0]?.realname || '--';
+      } else {
+        item.createdByName = '--';
+      }
+    }
+    getLossReportItem(Number(handleTaskId), Number(lossTaskId));
   });
 </script>
 
@@ -130,11 +146,15 @@
   .rectification-table {
     display: flex;
     gap: 10px;
+    width: 100%;
+  }
+  .damaged-list-container {
+    width: 200px;
   }
   .disaster-info-container {
     display: flex;
     flex-direction: column;
     gap: 10px;
-    flex: 1;
+    width: calc(100% - 220px);
   }
 </style>

+ 1 - 1
src/views/disaster/disaster-control/src/components/DamagedList.vue

@@ -18,7 +18,7 @@
 
 <style lang="scss" scoped>
   .damaged-list {
-    width: 200px;
+    width: 100%;
     height: 100%;
     border-radius: 4px;
     background-color: $white-color;

+ 13 - 4
src/views/disaster/disaster-control/src/components/DisasterInfo.vue

@@ -1,5 +1,5 @@
 <template>
-  <div class="disaster-information">
+  <div class="disaster-information" :class="{ 'disaster-information--rectification': rectification }">
     <div class="disaster-information__title">
       <div class="disaster-information--line"></div>
       <span>受灾信息</span>
@@ -56,7 +56,10 @@
           <span class="label">损失描述:</span>
           <span class="value">{{ LossReportItemFormData?.description }}</span>
         </div>
-        <div class="disaster-information__content--item" v-if="JSON.parse(LossReportItemFormData?.images).length">
+        <div
+          class="disaster-information__content--item"
+          v-if="LossReportItemFormData?.images && JSON.parse(LossReportItemFormData?.images).length"
+        >
           <span class="label">受灾图片:</span>
           <div class="image-container">
             <el-image
@@ -83,18 +86,24 @@
 </template>
 
 <script lang="ts" setup>
+  import { ref, onMounted } from 'vue';
   import { useDisasterControlHook } from '../hook';
   import type { disasterReportRecordDetailListResponse } from '@/types/disaster-control';
 
   defineProps<{
     LossReportItemFormData: disasterReportRecordDetailListResponse;
+    rectification?: boolean;
   }>();
-  const { getSafetyLevel } = useDisasterControlHook();
+
+  const { getSafetyLevel, getSafetyLevelDict } = useDisasterControlHook();
+  onMounted(() => {
+    getSafetyLevelDict();
+  });
 </script>
 
 <style lang="scss" scoped>
   @use '../style/view-item.scss' as *;
-  .disaster-information {
+  .disaster-information--rectification {
     background-color: $white-color;
     padding: 10px;
     border-radius: 4px;

+ 131 - 6
src/views/disaster/disaster-control/src/components/Rectification.vue

@@ -5,6 +5,21 @@
       <span>整改信息</span>
     </div>
     <div class="disaster-information__content">
+      <div class="disaster-information__content--title">
+        <p v-show="rectificationDeptName">
+          整改部门:<span>{{ rectificationDeptName }}</span>
+        </p>
+        <p v-show="rectificationResponsibleUserList.length">
+          整改责任人:
+          <span>
+            {{ rectificationResponsibleUserList[0].realname }}({{ rectificationResponsibleUserList[0].staffNo }})
+          </span>
+          <a v-if="rectificationResponsibleUserList.length > 1" @click="groupInfo = true">查看详情</a>
+        </p>
+        <p v-show="rectificationPriority">
+          处置优先级:<span>{{ getPriority(rectificationPriority) }}</span>
+        </p>
+      </div>
       <BasicTable :tableData="rectificationList" :tableConfig="tableConfig">
         <template #fixImages="scope">
           <div class="image-container" v-if="JSON.parse(scope.row.fixImages).length">
@@ -21,31 +36,80 @@
             />
             <span class="image-count"> 共{{ JSON.parse(scope.row.fixImages).length }}张 </span>
           </div>
+          <div class="empty-container" v-else>
+            <span>--</span>
+          </div>
+        </template>
+        <template #fixStatus="scope">
+          <span>{{ getFixStatus(scope.row.fixStatus) }}</span>
         </template>
         <template #fixMaterials="scope">
-          <div class="material-container" v-for="item in JSON.parse(scope.row.fixMaterials)" :key="item.fileId">
-            <div class="material-container--item" v-if="item">
-              <img :src="FILE_TYPE_ICON[item.fileType]" />
-              <span>{{ item.fileName }}</span>
+          <div class="material-container" v-if="JSON.parse(scope.row.fixMaterials).length">
+            <div class="material-container--item" v-for="item in JSON.parse(scope.row.fixMaterials)" :key="item.fileId">
+              <div
+                class="material-container--left"
+                @click="previewOnline(item.fileUrl, item.fileType as keyof typeof FILE_TYPE_ICON)"
+              >
+                <img :src="FILE_TYPE_ICON[item.fileType]" />
+                <span>{{ item.fileName }}</span>
+              </div>
+              <img :src="DownloadIcon" class="download-icon" @click="downloadFile(item.fileUrl, item.fileName)" />
             </div>
           </div>
+          <div class="empty-container" v-else>
+            <span>--</span>
+          </div>
         </template>
       </BasicTable>
     </div>
+    <PreviewOnline ref="previewOnlineRef" />
+    <el-dialog v-model="groupInfo" title="整改责任人详情" align-center class="customDialog--pushObject">
+      <div class="user-info">
+        <el-tag type="primary" v-for="user in rectificationResponsibleUserList" :key="user.id">
+          {{ user.realname }}({{ user.staffNo }})
+        </el-tag>
+      </div>
+    </el-dialog>
   </div>
 </template>
 
 <script lang="ts" setup>
+  import { onMounted, ref } from 'vue';
   import BasicTable from '@/components/BasicTable.vue';
+  import PreviewOnline from '@/views/disaster/components/PreviewOnline.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
+  import { useDisasterControlHook } from '../hook';
+  import { downloadFile } from '@/views/disaster/utils';
   import type { DisposalRectificationFormData } from '@/types/disaster-control';
+  import type { PersonGroupItem } from '@/types/person-group/type';
   import { RECTIFICATION_INFO_TABLE_COLUMNS, RECTIFICATION_INFO_TABLE_OPTIONS } from '../config';
   import { FILE_TYPE_ICON } from '@/views/disaster/constant';
+  import { FIX_STATUS_OPTIONS_DISPOSAL_RECTIFICATION } from '../constant';
+  import DownloadIcon from '../svg/download.svg';
+
   defineProps<{
     rectificationList: DisposalRectificationFormData[];
+    rectificationDeptName: string;
+    rectificationResponsibleUserList: PersonGroupItem[];
+    rectificationPriority: string;
   }>();
+
+  const { getPriority, getPriorityDict } = useDisasterControlHook();
+  const groupInfo = ref(false);
+  const getFixStatus = (status: number) => {
+    return FIX_STATUS_OPTIONS_DISPOSAL_RECTIFICATION.find((item) => item.value === status)?.label;
+  };
+  const previewOnlineRef = ref<InstanceType<typeof PreviewOnline>>();
+  const previewOnline = (url: string | undefined, type: keyof typeof FILE_TYPE_ICON) => {
+    if (url) {
+      previewOnlineRef.value?.open(url, type);
+    }
+  };
   const { tableConfig } = useTableConfig(RECTIFICATION_INFO_TABLE_COLUMNS, RECTIFICATION_INFO_TABLE_OPTIONS, false);
   tableConfig.loading = false;
+  onMounted(() => {
+    getPriorityDict();
+  });
 </script>
 
 <style lang="scss" scoped>
@@ -55,11 +119,29 @@
     padding: 10px;
     border-radius: 4px;
   }
+  .disaster-information__content {
+    display: flex;
+    flex-direction: column;
+    gap: 20px;
+    &--title {
+      display: flex;
+      gap: 100px;
+      span {
+        color: rgba($text-color, 0.65);
+      }
+      a {
+        margin-left: 5px;
+        color: $primary-color;
+        cursor: pointer;
+      }
+    }
+  }
   .image-container {
     position: relative;
   }
   .el-image {
     display: block !important;
+    position: relative;
   }
   .image-count {
     position: absolute;
@@ -69,13 +151,56 @@
     background: rgba($text-color, 0.6);
     color: rgba($white-color, 0.7);
     font-size: 14px;
+    pointer-events: none;
   }
   .material-container {
     display: flex;
     flex-direction: column;
+    gap: 5px;
     width: 100%;
-    img {
-      width: 20px;
+    cursor: pointer;
+    &--item {
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      width: 100%;
+      padding: 2px 5px;
+      &:hover {
+        background-color: #f8f9fa;
+        box-shadow: 0 0 5px 0 rgba($text-color, 0.1);
+      }
+    }
+    &--left {
+      display: flex;
+      gap: 4px;
+      align-items: center;
+      flex: 1;
+      img {
+        width: 12px;
+      }
+      span {
+        width: 110px;
+        text-align: left;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
     }
+    .download-icon {
+      width: 16px;
+    }
+  }
+  .empty-container {
+    width: 100%;
+  }
+  .user-info {
+    display: flex;
+    gap: 10px;
+  }
+  .el-tag {
+    font-weight: 500;
+    font-size: 12px;
+    color: $primary-color;
+    line-height: 20px;
   }
 </style>

+ 1 - 1
src/views/disaster/disaster-control/src/config/form.ts

@@ -271,7 +271,7 @@ export const DISPOSAL_RECTIFICATION_FORM_CONFIG: FormConfig[] = [
     slot: 'fixImages',
   },
   {
-    label: '上传整改材料:',
+    label: '整改材料:',
     prop: 'fixMaterials',
     slot: 'fixMaterials',
   },

+ 10 - 9
src/views/disaster/disaster-control/src/config/table.ts

@@ -151,13 +151,7 @@ export const RECTIFICATION_INFO_TABLE_COLUMNS: TableColumnProps[] = [
     prop: 'fixImages',
     slot: 'fixImages',
     align: 'center',
-    minWidth: '120px',
-  },
-  {
-    label: '整改材料',
-    prop: 'fixMaterials',
-    slot: 'fixMaterials',
-    width: '120px'
+    width: '200px',
   },
   {
     label: '整改时限',
@@ -177,8 +171,7 @@ export const RECTIFICATION_INFO_TABLE_COLUMNS: TableColumnProps[] = [
   },
   {
     label: '整改人',
-    prop: 'createdBy',
-    slot: 'createdBy',
+    prop: 'createdByName',
     minWidth: '120px',
   },
   {
@@ -186,4 +179,12 @@ export const RECTIFICATION_INFO_TABLE_COLUMNS: TableColumnProps[] = [
     prop: 'remark',
     minWidth: '200px',
   },
+  {
+    label: '整改材料',
+    prop: 'fixMaterials',
+    slot: 'fixMaterials',
+    align: 'center',
+    width: '200px',
+    fixed: 'right',
+  },
 ];

+ 5 - 2
src/views/disaster/disaster-control/src/hook.ts

@@ -5,12 +5,14 @@
 import { ref } from 'vue';
 import { queryDictTypeDetail } from '@/api/dict';
 import type { SysDictDataDetail } from '@/api/dict';
-import { DICT_CODE } from '@/constant/dict';
+import type { disasterReportRecordDetailListResponse } from '@/types/disaster-control';
 import { getLossRecordTableData } from '@/api/disaster-control';
+import { DICT_CODE } from '@/constant/dict';
 
 export const useDisasterControlHook = () => {
   const safetyLevelDice = ref<SysDictDataDetail[]>([]);
   const priorityDice = ref<SysDictDataDetail[]>([]);
+  const lossReportItem = ref<disasterReportRecordDetailListResponse>();
   const getSafetyLevelDict = async () => {
     const res = await queryDictTypeDetail(DICT_CODE.SAFETY_LEVEL);
     safetyLevelDice.value = res.sysDictDataList;
@@ -31,7 +33,7 @@ export const useDisasterControlHook = () => {
       handleTaskIds: [handleTaskId],
     });
     const disasterReportRecordDetailList = res[0].disasterReportRecordDetailList;
-    return disasterReportRecordDetailList.find((item) => item.id === id);
+    lossReportItem.value = disasterReportRecordDetailList.find((item) => item.id === id);
   };
   return {
     priorityDice,
@@ -40,6 +42,7 @@ export const useDisasterControlHook = () => {
     getSafetyLevelDict,
     getSafetyLevel,
     getPriority,
+    lossReportItem,
     getLossReportItem,
   };
 };

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 0
src/views/disaster/disaster-control/src/svg/download.svg