Explorar el Código

feat: 报警问题处理,默认数据导出+问题类型变为两级选择

bxy hace 1 año
padre
commit
caab8cca28

+ 11 - 3
src/api/datamanagement/alert.ts

@@ -4,7 +4,7 @@ import { http } from '@/utils/http/axios';
 export const getAIList = () => {
   return http.request({
     url: '/cameraPreview/getAlgoList',
-    method: 'get'
+    method: 'get',
   });
 };
 
@@ -12,7 +12,7 @@ export const getAIList = () => {
 export const getManualList = () => {
   return http.request({
     url: '/issue/getIssueTypeList',
-    method: 'get'
+    method: 'get',
   });
 };
 
@@ -20,6 +20,14 @@ export const getManualList = () => {
 export const getWorkLocationList = () => {
   return http.request({
     url: '/issue/getSiteList',
-    method: 'get'
+    method: 'get',
+  });
+};
+
+// AI问题类型(issueMainType-issueType)
+export const getAIMainList = () => {
+  return http.request({
+    url: '/issue/getIssueSubTypeList',
+    method: 'get',
   });
 };

+ 4 - 1
src/views/datamanager/alertformdata/components/common/DetailDialog.vue

@@ -158,7 +158,10 @@
   }
 
   .media-box {
-    display: flex;
+    display: grid;
+    grid-template-columns: repeat(auto-fill, 200px);
+    column-gap: 10px;
+    row-gap: 10px;
 
     .video-box {
       width: 200px;

+ 52 - 12
src/views/datamanager/alertformdata/components/common/QueryForm.vue

@@ -18,14 +18,23 @@
           </el-select>
         </el-form-item>
         <el-form-item label="类型:" prop="issueType">
-          <el-select
+          <!-- <el-select
             v-model="queryForm.issueType"
             placeholder="全部"
             clearable
             :disabled="typeDisable"
           >
             <el-option v-for="item in options" :label="item.name" :value="item.id" />
-          </el-select>
+          </el-select> -->
+          <el-cascader
+            v-model="issueTypeValue"
+            :options="options"
+            :props="issueMainTypeProp"
+            :show-all-levels="false"
+            clearable
+            :disabled="typeDisable"
+            @change="handleIssueMainTypeChange"
+          />
         </el-form-item>
         <el-form-item label="地点:" prop="workspaceId">
           <el-cascader
@@ -56,7 +65,7 @@
             end-placeholder="结束时间"
             clearable
             unlink-panels
-            value-format="YYYY-MM-DD HH:mm:ss.SSS"
+            value-format="YYYY-MM-DD HH:mm:ss"
             :default-time="defaultTime"
             @change="handleDateChange"
           />
@@ -66,6 +75,7 @@
         <el-form-item>
           <el-button class="search-btn" type="primary" @click="handleSearch">查询</el-button>
           <el-button class="reset-btn" @click="handleReset">重置</el-button>
+          <el-button class="reset-btn" @click="handleExport" v-if="!isShowTab">导出</el-button>
         </el-form-item>
       </div>
     </el-form>
@@ -74,22 +84,23 @@
 
 <script setup lang="ts">
   import type { FormInstance } from 'element-plus';
-  import { reactive, ref } from 'vue';
+  import { computed, reactive, ref } from 'vue';
   import { sourceOptions, issueStateOptions } from './constant.question';
 
   interface Props {
-    // isShowTab: boolean       // true展示数据,false默认数据
+    isShowTab: boolean; // true展示数据,false默认数据
     aiOptions: Array<any>;
     manualOptions: Array<any>;
     locationOptions: Array<any>;
   }
   const props = defineProps<Props>();
-  const emits = defineEmits(['onSearch', 'onReset']);
+  const emits = defineEmits(['onSearch', 'onReset', 'onExport']);
 
   interface QueryModel {
     pageNumber: number;
     pageSize: number;
     source?: number; // 来源
+    issueMainType?: number; // 一级类型
     issueType?: number; // 类型
     workspaceId?: number[]; // 地点=工位id
     issueState?: number[]; // 状态
@@ -103,37 +114,53 @@
     pageSize: 10,
   });
 
-  interface OptionModel {
-    id: number;
-    name: string;
-  }
+  type MainOption = {
+    value: number;
+    label: string;
+    children: {
+      value: number;
+      label: string;
+    }[];
+  };
 
-  const options = ref<OptionModel[]>([]);
+  const options = ref<MainOption[]>([]);
   const typeDisable = ref(true);
-  const location = { multiple: true }; // 级联选择器(打开多选)
   const workLocation = ref([]); // 级联选择器,为二维数组(提取workspaceId)
+  const location = { multiple: true }; // 级联选择器(打开多选)
   const tempState = ref(''); // 状态,字符串转number[]
   const dateRange = ref([]); // 时间段,拆分成startTime/endTime
   const defaultTime = ref<[Date, Date]>([
     new Date(2000, 1, 1, 0, 0, 0),
     new Date(2000, 2, 1, 23, 59, 59),
   ]);
+  const issueTypeValue = ref([]); // 问题类型,级联选择器
+  const issueMainTypeProp = computed(() => {
+    if (props.isShowTab) return { expandTrigger: 'hover' as const, checkStrictly: false };
+    else return { expandTrigger: 'hover' as const, checkStrictly: true };
+  });
+  const workShopIds = ref([]);
 
   const handleSearch = () => {
     emits('onSearch', queryForm);
   };
 
   const handleReset = () => {
+    issueTypeValue.value = [];
     typeDisable.value = true;
     workLocation.value = [];
     tempState.value = '';
     dateRange.value = [];
     Reflect.deleteProperty(queryForm, 'startTime');
     Reflect.deleteProperty(queryForm, 'endTime');
+    Reflect.deleteProperty(queryForm, 'issueMainType');
     formRef.value?.resetFields();
     emits('onReset', queryForm);
   };
 
+  const handleExport = () => {
+    emits('onExport', queryForm, workShopIds.value);
+  };
+
   const handleSelectChange = () => {
     if (Number(queryForm.source) === 1) {
       typeDisable.value = false;
@@ -144,14 +171,27 @@
     } else {
       typeDisable.value = true;
       options.value = [];
+      queryForm.issueMainType = undefined;
       queryForm.issueType = undefined;
     }
   };
 
+  const handleIssueMainTypeChange = () => {
+    if (issueTypeValue.value) {
+      queryForm.issueMainType = issueTypeValue.value[0];
+      queryForm.issueType = issueTypeValue.value[1];
+    } else {
+      Reflect.deleteProperty(queryForm, 'issueMainType');
+      Reflect.deleteProperty(queryForm, 'issueType');
+    }
+  };
+
   const handleCascaderChange = () => {
     const arr = [];
+    workShopIds.value = [];
     workLocation.value.forEach((item) => {
       arr.push(item[1]);
+      workShopIds.value.push(item[0]);
     });
     queryForm.workspaceId = arr;
   };

+ 31 - 18
src/views/datamanager/alertformdata/components/common/constant.question.ts

@@ -4,31 +4,30 @@ export enum Source {
   manual = 2,
 }
 export const sourceNameMap = {
-  [Source.ai]: "AI检测",
-  [Source.manual]: "人工上报",
-}
+  [Source.ai]: 'AI检测',
+  [Source.manual]: '人工上报',
+};
 // 问题来源下拉框选项
 export const sourceOptions = [
   { label: sourceNameMap[Source.ai], value: Source.ai },
-  { label: sourceNameMap[Source.manual], value: Source.manual }
-]
+  { label: sourceNameMap[Source.manual], value: Source.manual },
+];
 // 表格数据-转换value为label
 export const getNameBySource = (source: Source) => {
-  return sourceNameMap[source] || '-'
-}
-
+  return sourceNameMap[source] || '-';
+};
 
 // 问题状态
 export enum IssueState {
   toAuth0 = 0,
   toAuth1 = 1,
-  toAuth2 = 2,    // 待审核
-  hasRevoke = 3,  // 已撤销
-  toDeal4 = 4,    // 待处理
+  toAuth2 = 2, // 待审核
+  hasRevoke = 3, // 已撤销
+  toDeal4 = 4, // 待处理
   toDeal6 = 6,
-  toReview = 5,   // 待复核
+  toReview = 5, // 待复核
   hasDone7 = 7,
-  hasDone8 = 8,   // 已处理
+  hasDone8 = 8, // 已处理
 }
 export const issueStateNameMap = {
   [IssueState.toAuth0]: '待审核',
@@ -40,25 +39,39 @@ export const issueStateNameMap = {
   [IssueState.toReview]: '待复核',
   [IssueState.hasDone7]: '已处理',
   [IssueState.hasDone8]: '已处理',
-}
+};
 // 问题状态下拉框选项(默认数据——待审核(012) 待处理(46) 待复核(5) 已处理(78) 已撤销(3))
 export const issueStateOptions = [
   { label: issueStateNameMap[IssueState.toAuth0], value: '[0, 1, 2]' },
   { label: issueStateNameMap[IssueState.toDeal4], value: '[4, 6]' },
   { label: issueStateNameMap[IssueState.toReview], value: '[5]' },
   { label: issueStateNameMap[IssueState.hasDone7], value: '[7,8]' },
-  { label: issueStateNameMap[IssueState.hasRevoke], value: '[3]' }
-]
+  { label: issueStateNameMap[IssueState.hasRevoke], value: '[3]' },
+];
 
 export const issueStateOptionsAdd = [
   { label: issueStateNameMap[IssueState.toAuth2], value: IssueState.toAuth2 },
   { label: issueStateNameMap[IssueState.toDeal4], value: IssueState.toDeal4 },
   { label: issueStateNameMap[IssueState.toReview], value: IssueState.toReview },
   { label: issueStateNameMap[IssueState.hasDone8], value: IssueState.hasDone8 },
-]
+];
 
 // 表格数据-转换value为label
 export const getNameByState = (issueState: IssueState) => {
-  return issueStateNameMap[issueState] || '-'
+  return issueStateNameMap[issueState] || '-';
+};
+
+// 问题四大类
+export enum QUESTION_TYPE_MAIN {
+  fromHuman = 1, //人的不安全行为
+  fromThing = 2, //物的不安全状态
+  fromEnvir = 3, //环境的不安全因素
+  fromManage = 4, //管理措施的不规范
 }
 
+export const questionMainTypeNameMap = {
+  [QUESTION_TYPE_MAIN.fromHuman]: '人的不安全行为',
+  [QUESTION_TYPE_MAIN.fromThing]: '物的不安全状态',
+  [QUESTION_TYPE_MAIN.fromEnvir]: '环境的不安全因素',
+  [QUESTION_TYPE_MAIN.fromManage]: '管理措施的不规范',
+};

+ 62 - 6
src/views/datamanager/alertformdata/components/default/Default.vue

@@ -2,11 +2,13 @@
   <div class="box">
     <div class="search-form">
       <QueryForm
-        :ai-options="aiOptions"
-        :manual-options="manualOptions"
+        :is-show-tab="false"
+        :ai-options="aiMainOptions"
+        :manual-options="manualMainOptions"
         :location-options="locationOptions"
         @on-search="handleSearch"
         @on-reset="handleReset"
+        @on-export="handleExport"
       />
     </div>
     <div class="table-list">
@@ -77,12 +79,14 @@
 <script setup lang="ts">
   import { ref, onMounted, onBeforeMount } from 'vue';
   import { ElMessage, ElMessageBox } from 'element-plus';
+  import axios, { AxiosRequestConfig } from 'axios';
   import QueryForm from '../common/QueryForm.vue';
   import AlertTable from '../common/AlertTable.vue';
   import DetailDialog from '../common/DetailDialog.vue';
   import Pagination from '../common/Pagination.vue';
-  import { useIssueType } from '../../hooks/useIssueType';
+  // import { useIssueType } from '../../hooks/useIssueType';
   import { useWorkLocation } from '../../hooks/useWorkLocation';
+  import { useIssueMainType } from '../../hooks/useIssueMainType';
   import {
     getDefaultTableData,
     deleteDefaultTableData,
@@ -93,10 +97,19 @@
     updateDefaultPriorityAll,
   } from '@/api/datamanagement/alert-default';
   import { useUserStore } from '@/store/modules/user';
+  import { useGlobSetting } from '@/hooks/setting';
 
   const userStore = useUserStore();
-  const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
+  // const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
   const { locationOptions, getLocationOptions } = useWorkLocation();
+  const { aiMainOptions, manualMainOptions, getAIMainOptions, getManualMainOptions } =
+    useIssueMainType();
+
+  const headers = {
+    Satoken: userStore.getToken,
+    Tenantid: userStore.getTenantId,
+  };
+  const { urlPrefix } = useGlobSetting();
 
   const alertTableRef = ref<typeof AlertTable>();
   const tableData = ref([]);
@@ -133,6 +146,47 @@
     query.value = queryForm;
     getTableData();
   };
+  // 导出
+  const handleExport = async (queryForm, workShop) => {
+    console.log(queryForm);
+    console.log('workshopId', workShop);
+
+    try {
+      const now = new Date();
+      const year = now.getFullYear();
+      const month = String(now.getMonth() + 1).padStart(2, '0');
+      const day = String(now.getDate()).padStart(2, '0');
+      const currentDate = `${year}${month}${day}`;
+
+      const requestBody = {
+        endTime: queryForm.endTime,
+        fileName: '',
+        isExportHidden: true,
+        startTime: queryForm.startTime,
+        workshopIds: workShop,
+      };
+
+      const config: AxiosRequestConfig = {
+        headers,
+        responseType: 'blob',
+      };
+      const response = await axios.post(urlPrefix + '/issue/export', requestBody, config);
+      const blob = new Blob([response.data], {
+        type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+      });
+      // 创建下载链接
+      let downloadLink: HTMLAnchorElement | null = document.createElement('a');
+      const url = window.URL.createObjectURL(blob);
+      downloadLink.href = url;
+      downloadLink.download = `安全违规问题数据统计表${currentDate}.xlsx`;
+      downloadLink.click();
+      // 移除下载链接
+      window.URL.revokeObjectURL(url);
+      downloadLink = null;
+    } catch (error) {
+      console.error('Error downloading file:', error);
+    }
+  };
 
   // 多选
   const handlePop = (selection) => {
@@ -370,9 +424,11 @@
   });
 
   onBeforeMount(() => {
-    getAIOptions();
-    getManualOptions();
+    // getAIOptions();
+    // getManualOptions();
     getLocationOptions();
+    getAIMainOptions();
+    getManualMainOptions();
   });
 </script>
 

+ 305 - 278
src/views/datamanager/alertformdata/components/show/Show.vue

@@ -1,8 +1,14 @@
 <template>
   <div class="box">
     <div class="search-form">
-      <QueryForm :ai-options="aiOptions" :manual-options="manualOptions" :location-options="locationOptions"
-        @on-search="handleSearch" @on-reset="handleReset" />
+      <QueryForm
+        :is-show-tab="true"
+        :ai-options="aiMainOptions"
+        :manual-options="manualMainOptions"
+        :location-options="locationOptions"
+        @on-search="handleSearch"
+        @on-reset="handleReset"
+      />
       <div class="button-group">
         <el-button type="primary" :icon="Plus" @click="handleAdd">添加</el-button>
       </div>
@@ -10,342 +16,363 @@
     <div class="table-list">
       <div v-if="showActionBar" class="action-bar">
         <span class="num-text">已选{{ chooseNum }}项</span>
-        <el-button :class="isActiveCancelHide ? 'btn-active' : 'btn-normal'"
-          @click="handleCancelHideAll">全部生效</el-button>
-        <el-button :class="isActiveHide ? 'btn-active' : 'btn-normal'" @click="handleHideAll">全部失效</el-button>
-        <el-button :class="isActiveDelete ? 'btn-active' : 'btn-normal'" @click="handleDeleteAll">删除</el-button>
+        <el-button
+          :class="isActiveCancelHide ? 'btn-active' : 'btn-normal'"
+          @click="handleCancelHideAll"
+          >全部生效</el-button
+        >
+        <el-button :class="isActiveHide ? 'btn-active' : 'btn-normal'" @click="handleHideAll"
+          >全部失效</el-button
+        >
+        <el-button :class="isActiveDelete ? 'btn-active' : 'btn-normal'" @click="handleDeleteAll"
+          >删除</el-button
+        >
         <span class="close-btn" @click="handleSelectNone"></span>
       </div>
-      <AlertTable ref="alertTableRef" class="table-bar" :is-show-tab="true" :table-data="tableData"
-        :on-detail="handleDetail" :on-edit="handleEdit" :on-show="handleShow" :on-delete="handleDelete"
-        @update:selection="handlePop" />
+      <AlertTable
+        ref="alertTableRef"
+        class="table-bar"
+        :is-show-tab="true"
+        :table-data="tableData"
+        :on-detail="handleDetail"
+        :on-edit="handleEdit"
+        :on-show="handleShow"
+        :on-delete="handleDelete"
+        @update:selection="handlePop"
+      />
     </div>
     <div class="pagination-box">
-      <Pagination v-model:page="query.pageNumber" v-model:size="query.pageSize" :total="total"
-        @update:page="handlePageChange" @update:size="handleSizeChange" />
+      <Pagination
+        v-model:page="query.pageNumber"
+        v-model:size="query.pageSize"
+        :total="total"
+        @update:page="handlePageChange"
+        @update:size="handleSizeChange"
+      />
     </div>
-    <DetailDialog v-if="isDetailDialogShow" :description="detailDescription" :image-paths="detailPictures"
-      :video-paths="detailVideos" @close="closeDetailDialog" />
+    <DetailDialog
+      v-if="isDetailDialogShow"
+      :description="detailDescription"
+      :image-paths="detailPictures"
+      :video-paths="detailVideos"
+      @close="closeDetailDialog"
+    />
     <AddDrawer v-if="isAddDrawer" @close="handleAddDrawerClose" />
     <EditDrawer v-if="isEditDrawer" :initial-data="rowData" @close="handleEditDrawerClose" />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, onBeforeMount } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-import { Plus } from '@element-plus/icons-vue';
-import QueryForm from '../common/QueryForm.vue';
-import AlertTable from '../common/AlertTable.vue';
-import DetailDialog from '../common/DetailDialog.vue';
-import Pagination from '../common/Pagination.vue';
-import AddDrawer from '../common/AddDrawer.vue';
-import EditDrawer from '../common/EditDrawer.vue';
-import { useIssueType } from '../../hooks/useIssueType';
-import { useWorkLocation } from '../../hooks/useWorkLocation';
-import {
-  getShowTableData,
-  updateShowTableData,
-  deleteShowTableData
-} from '@/api/datamanagement/alert-show'
+  import { ref, onMounted, onBeforeMount } from 'vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import { Plus } from '@element-plus/icons-vue';
+  import QueryForm from '../common/QueryForm.vue';
+  import AlertTable from '../common/AlertTable.vue';
+  import DetailDialog from '../common/DetailDialog.vue';
+  import Pagination from '../common/Pagination.vue';
+  import AddDrawer from '../common/AddDrawer.vue';
+  import EditDrawer from '../common/EditDrawer.vue';
+  // import { useIssueType } from '../../hooks/useIssueType';
+  import { useWorkLocation } from '../../hooks/useWorkLocation';
+  import { useIssueMainType } from '../../hooks/useIssueMainType';
+  import {
+    getShowTableData,
+    updateShowTableData,
+    deleteShowTableData,
+  } from '@/api/datamanagement/alert-show';
 
-const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
-const { locationOptions, getLocationOptions } = useWorkLocation();
+  // const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
+  const { locationOptions, getLocationOptions } = useWorkLocation();
+  const { aiMainOptions, manualMainOptions, getAIMainOptions, getManualMainOptions } =
+    useIssueMainType();
 
-const alertTableRef = ref<typeof AlertTable>();
-const tableData = ref([]);
-const showActionBar = ref(false);
-const chooseNum = ref(0);
-const chooseId = ref<number[]>([]);
-// const cancelHideFlag = ref(true);   // true取消隐藏 / false全部隐藏
-const isActiveHide = ref(false);
-const isActiveCancelHide = ref(false);
-const isActiveDelete = ref(false);
-// 详情
-const isDetailDialogShow = ref(false);
-const detailDescription = ref('');
-const detailPictures = ref<string[]>([]);
-const detailVideos = ref<string[]>([]);
-// 添加
-const isAddDrawer = ref(false);
-const isEditDrawer = ref(false);
-const rowData = ref();        // 编辑时填充row的tableData
-// 分页
-const total = ref(0);
+  const alertTableRef = ref<typeof AlertTable>();
+  const tableData = ref([]);
+  const showActionBar = ref(false);
+  const chooseNum = ref(0);
+  const chooseId = ref<number[]>([]);
+  // const cancelHideFlag = ref(true);   // true取消隐藏 / false全部隐藏
+  const isActiveHide = ref(false);
+  const isActiveCancelHide = ref(false);
+  const isActiveDelete = ref(false);
+  // 详情
+  const isDetailDialogShow = ref(false);
+  const detailDescription = ref('');
+  const detailPictures = ref<string[]>([]);
+  const detailVideos = ref<string[]>([]);
+  // 添加
+  const isAddDrawer = ref(false);
+  const isEditDrawer = ref(false);
+  const rowData = ref(); // 编辑时填充row的tableData
+  // 分页
+  const total = ref(0);
 
-const query = ref({
-  pageNumber: 1,
-  pageSize: 10
-});
-// 查询
-const handleSearch = (queryForm) => {
-  query.value = queryForm;
-  getTableData();
-};
-// 重置
-const handleReset = (queryForm) => {
-  query.value = queryForm;
-  getTableData();
-};
-
-// 多选
-const handlePop = (selection) => {
-  chooseId.value = [];
-  // cancelHideFlag.value = true;
-  selection.forEach((item) => {
-    if (chooseId.value.indexOf(item.id) === -1)
-      chooseId.value.push(item.id);
-    // 只要有一个item.isHide === false 说明多选的这些选项不是全都隐藏/失效,不用变成“取消隐藏”/全部生效
-    // if (item.isHide === false) cancelHideFlag.value = false;
+  const query = ref({
+    pageNumber: 1,
+    pageSize: 10,
   });
-  chooseNum.value = selection.length;
-  showActionBar.value = chooseNum.value > 0 ? true : false;
-};
-// 取消多选
-const handleSelectNone = () => {
-  chooseId.value = [];
-  chooseNum.value = 0;
-  alertTableRef.value?.clearAll();
-  showActionBar.value = false;
-};
-
-// 全部隐藏
-const handleHideAll = () => {
-  if (showActionBar.value) isActiveHide.value = !isActiveHide.value;
-  const updateList = {
-    id: chooseId.value,
-    isHide: true,
+  // 查询
+  const handleSearch = (queryForm) => {
+    query.value = queryForm;
+    getTableData();
   };
-  updateShowTableData(updateList).then(() => {
-    handleSelectNone();
+  // 重置
+  const handleReset = (queryForm) => {
+    query.value = queryForm;
     getTableData();
-    ElMessage({
-      message: '操作成功',
-      type: 'success',
+  };
+
+  // 多选
+  const handlePop = (selection) => {
+    chooseId.value = [];
+    // cancelHideFlag.value = true;
+    selection.forEach((item) => {
+      if (chooseId.value.indexOf(item.id) === -1) chooseId.value.push(item.id);
+      // 只要有一个item.isHide === false 说明多选的这些选项不是全都隐藏/失效,不用变成“取消隐藏”/全部生效
+      // if (item.isHide === false) cancelHideFlag.value = false;
     });
-    setTimeout(function () {
-      isActiveHide.value = !isActiveHide.value;
-    }, 1000);
-  });
-};
+    chooseNum.value = selection.length;
+    showActionBar.value = chooseNum.value > 0 ? true : false;
+  };
+  // 取消多选
+  const handleSelectNone = () => {
+    chooseId.value = [];
+    chooseNum.value = 0;
+    alertTableRef.value?.clearAll();
+    showActionBar.value = false;
+  };
 
-// 取消隐藏
-const handleCancelHideAll = () => {
-  if (showActionBar.value) isActiveCancelHide.value = !isActiveCancelHide.value;
-  const updateList = {
-    id: chooseId.value,
-    isHide: false,
+  // 全部隐藏
+  const handleHideAll = () => {
+    if (showActionBar.value) isActiveHide.value = !isActiveHide.value;
+    const updateList = {
+      id: chooseId.value,
+      isHide: true,
+    };
+    updateShowTableData(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
+      ElMessage({
+        message: '操作成功',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveHide.value = !isActiveHide.value;
+      }, 1000);
+    });
   };
-  updateShowTableData(updateList).then(() => {
-    handleSelectNone();
-    getTableData();
-    ElMessage({
-      message: '操作成功',
-      type: 'success',
+
+  // 取消隐藏
+  const handleCancelHideAll = () => {
+    if (showActionBar.value) isActiveCancelHide.value = !isActiveCancelHide.value;
+    const updateList = {
+      id: chooseId.value,
+      isHide: false,
+    };
+    updateShowTableData(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
+      ElMessage({
+        message: '操作成功',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveCancelHide.value = !isActiveCancelHide.value;
+      }, 1000);
     });
-    setTimeout(function () {
-      isActiveCancelHide.value = !isActiveCancelHide.value;
-    }, 1000);
-  });
-};
+  };
 
-// 批量删除
-const handleDeleteAll = () => {
-  if (showActionBar.value) isActiveDelete.value = !isActiveDelete.value;
-  ElMessageBox.confirm(
-    '删除之后,数据无法恢复',
-    '请确认是否删除数据',
-    {
+  // 批量删除
+  const handleDeleteAll = () => {
+    if (showActionBar.value) isActiveDelete.value = !isActiveDelete.value;
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning',
       customClass: 'deleteMessage',
-      center: true
-    }
-  )
-    .then(() => {
-      deleteShowTableData(chooseId.value).then(() => {
+      center: true,
+    })
+      .then(() => {
+        deleteShowTableData(chooseId.value).then(() => {
+          ElMessage({
+            type: 'success',
+            message: '删除成功',
+          });
+          getTableData();
+          handleSelectNone();
+          isActiveDelete.value = !isActiveDelete.value;
+        });
+      })
+      .catch(() => {
         ElMessage({
-          type: 'success',
-          message: '删除成功',
+          type: 'info',
+          message: '取消删除',
         });
-        getTableData();
-        handleSelectNone();
         isActiveDelete.value = !isActiveDelete.value;
-      })
-    })
-    .catch(() => {
-      ElMessage({
-        type: 'info',
-        message: '取消删除',
       });
-      isActiveDelete.value = !isActiveDelete.value;
-    })
-};
+  };
 
-// 详情
-const closeDetailDialog = () => {
-  isDetailDialogShow.value = false;
-};
-const handleDetail = (row) => {
-  isDetailDialogShow.value = true;
-  detailDescription.value = row.description;
-  detailPictures.value = row.pictures;
-  detailVideos.value = row.videos;
-};
+  // 详情
+  const closeDetailDialog = () => {
+    isDetailDialogShow.value = false;
+  };
+  const handleDetail = (row) => {
+    isDetailDialogShow.value = true;
+    detailDescription.value = row.description;
+    detailPictures.value = row.pictures;
+    detailVideos.value = row.videos;
+  };
 
-// 添加
-const handleAdd = () => {
-  isAddDrawer.value = true;
-}
-// 编辑
-const handleEdit = (row) => {
-  isEditDrawer.value = true;
-  rowData.value = { ...row };
-};
+  // 添加
+  const handleAdd = () => {
+    isAddDrawer.value = true;
+  };
+  // 编辑
+  const handleEdit = (row) => {
+    isEditDrawer.value = true;
+    rowData.value = { ...row };
+  };
 
-const handleAddDrawerClose = () => {
-  isAddDrawer.value = false;
-  getTableData();
-};
+  const handleAddDrawerClose = () => {
+    isAddDrawer.value = false;
+    getTableData();
+  };
 
-const handleEditDrawerClose = () => {
-  isEditDrawer.value = false;
-  getTableData();
-};
+  const handleEditDrawerClose = () => {
+    isEditDrawer.value = false;
+    getTableData();
+  };
 
-// 单个显示hide=false/隐藏hide=true
-const handleShow = (row) => {
-  const tempHide = row.isHide === false ? true : false;
-  const updateList = {
-    id: [row.id],
-    isHide: tempHide,
+  // 单个显示hide=false/隐藏hide=true
+  const handleShow = (row) => {
+    const tempHide = row.isHide === false ? true : false;
+    const updateList = {
+      id: [row.id],
+      isHide: tempHide,
+    };
+    updateShowTableData(updateList).then(() => {
+      getTableData();
+    });
   };
-  updateShowTableData(updateList).then(() => {
-    getTableData();
-  });
-};
 
-// 删除
-const handleDelete = (row) => {
-  ElMessageBox.confirm(
-    '删除之后,数据无法恢复',
-    '请确认是否删除数据',
-    {
+  // 删除
+  const handleDelete = (row) => {
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning',
       customClass: 'deleteMessage',
-      center: true
-    }
-  )
-    .then(() => {
-      deleteShowTableData([row.id]).then(() => {
-        ElMessage({
-          type: 'success',
-          message: '删除成功',
-        });
-        getTableData();
-      })
+      center: true,
     })
-    .catch(() => {
-      ElMessage({
-        type: 'info',
-        message: '取消删除',
+      .then(() => {
+        deleteShowTableData([row.id]).then(() => {
+          ElMessage({
+            type: 'success',
+            message: '删除成功',
+          });
+          getTableData();
+        });
       })
-    })
-};
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '取消删除',
+        });
+      });
+  };
+
+  // 换页,重新获取表格
+  const handlePageChange = (val) => {
+    query.value.pageNumber = val;
+    getTableData();
+  };
+  const handleSizeChange = (val) => {
+    query.value.pageSize = val;
+    getTableData();
+  };
 
-// 换页,重新获取表格
-const handlePageChange = (val) => {
-  query.value.pageNumber = val;
-  getTableData();
-};
-const handleSizeChange = (val) => {
-  query.value.pageSize = val;
-  getTableData();
-};
+  const getTableData = () => {
+    getShowTableData(query.value).then((res) => {
+      console.log(res);
+      tableData.value = res.records;
+      total.value = res.totalRow;
+    });
+  };
 
-const getTableData = () => {
-  getShowTableData(query.value).then((res) => {
-    console.log(res);
-    tableData.value = res.records;
-    total.value = res.totalRow;
+  onMounted(() => {
+    getTableData();
   });
-};
-
-onMounted(() => {
-  getTableData();
-});
 
-onBeforeMount(() => {
-  getAIOptions();
-  getManualOptions();
-  getLocationOptions();
-});
+  onBeforeMount(() => {
+    // getAIOptions();
+    // getManualOptions();
+    getLocationOptions();
+    getAIMainOptions();
+    getManualMainOptions();
+  });
 </script>
 
 <style scoped lang="scss">
-.box {
-  display: flex;
-  flex-direction: column;
-}
+  .box {
+    display: flex;
+    flex-direction: column;
+  }
 
-.search-form {
-  margin-bottom: 20px;
-}
+  .search-form {
+    margin-bottom: 20px;
+  }
 
-.table-list {
-  height: calc(100vh - 350px);
-  overflow-y: scroll;
+  .table-list {
+    height: calc(100vh - 350px);
+    overflow-y: scroll;
 
-  .action-bar {
-    display: flex;
-    align-items: center;
-    position: absolute;
-    min-width: calc(100vw - 266px);
-    height: 50px;
-    border-radius: 4px 4px 0px 0px;
-    background-color: #DDEFFF;
-    z-index: 10;
+    .action-bar {
+      display: flex;
+      align-items: center;
+      position: absolute;
+      min-width: calc(100vw - 266px);
+      height: 50px;
+      border-radius: 4px 4px 0px 0px;
+      background-color: #ddefff;
+      z-index: 10;
 
-    .num-text {
-      margin: 0 34px 0 25px;
-      color: rgba(0, 0, 0, 0.85);
-      font-weight: 500;
-    }
+      .num-text {
+        margin: 0 34px 0 25px;
+        color: rgba(0, 0, 0, 0.85);
+        font-weight: 500;
+      }
 
-    .btn-normal {
-      color: #1890FF;
-      background: transparent;
-      border: 1px solid #1890FF;
-      border-radius: 2px;
-    }
+      .btn-normal {
+        color: #1890ff;
+        background: transparent;
+        border: 1px solid #1890ff;
+        border-radius: 2px;
+      }
 
-    .btn-active {
-      color: #FFFFFF;
-      background-color: #1890FF;
-    }
+      .btn-active {
+        color: #ffffff;
+        background-color: #1890ff;
+      }
+
+      .close-btn {
+        margin-left: auto;
+        margin-right: 20px;
+      }
 
-    .close-btn {
-      margin-left: auto;
-      margin-right: 20px;
+      .close-btn:before {
+        content: '\2716';
+        color: #000;
+        cursor: pointer;
+      }
     }
 
-    .close-btn:before {
-      content: '\2716';
-      color: #000;
-      cursor: pointer;
+    .table-bar {
+      position: relative;
     }
   }
 
-  .table-bar {
-    position: relative;
+  .pagination-box {
+    height: 50px;
+    margin-top: 10px;
   }
-}
-
-.pagination-box {
-  height: 50px;
-  margin-top: 10px;
-}
-</style>
+</style>

+ 83 - 0
src/views/datamanager/alertformdata/hooks/useIssueMainType.ts

@@ -0,0 +1,83 @@
+import { ref } from 'vue';
+import { getAIMainList, getManualList } from '@/api/datamanagement/alert';
+import { questionMainTypeNameMap } from '@/views/datamanager/alertformdata/components/common/constant.question';
+
+type AIMainOption = {
+  value: number;
+  label: string;
+  children: {
+    value: number;
+    label: string;
+  }[];
+};
+
+type ManualMainOption = {
+  value: number;
+  label: string;
+  children: {
+    value: number;
+    label: string;
+  }[];
+};
+
+export function useIssueMainType() {
+  // AI检测
+  const aiMainOptions = ref<AIMainOption[]>([]);
+  // 人工上报
+  const manualMainOptions = ref<ManualMainOption[]>([]);
+
+  const getAIMainOptions = async () => {
+    await getAIMainList().then((res) => {
+      res.forEach((item) => {
+        // 找不到当前issueMainType,新建一个
+        if (
+          !aiMainOptions.value.find((x) => x.value === item.issueMainTypeId) &&
+          questionMainTypeNameMap[item.issueMainTypeId]
+        ) {
+          aiMainOptions.value.push({
+            value: item.issueMainTypeId,
+            label: questionMainTypeNameMap[item.issueMainTypeId],
+            children: [
+              {
+                value: item.issueTypeId,
+                label: item.issueTypeName,
+              },
+            ],
+          });
+        } else if (aiMainOptions.value.find((x) => x.value === item.issueMainTypeId)) {
+          const existingMainType = aiMainOptions.value.find(
+            (x) => x.value === item.issueMainTypeId,
+          )!;
+          existingMainType.children.push({
+            value: item.issueTypeId,
+            label: item.issueTypeName,
+          });
+        }
+      });
+    });
+  };
+
+  const getManualMainOptions = () => {
+    getManualList().then((res) => {
+      res.forEach((item) => {
+        manualMainOptions.value.push({
+          value: item.id,
+          label: item.name,
+          children: [
+            {
+              value: item.id,
+              label: item.name,
+            },
+          ],
+        });
+      });
+    });
+  };
+
+  return {
+    aiMainOptions,
+    manualMainOptions,
+    getAIMainOptions,
+    getManualMainOptions,
+  };
+}