Przeglądaj źródła

feat: 中建材version报警问题管理

bxy 1 rok temu
rodzic
commit
a374b39ce7

+ 2 - 0
src/hooks/setting/index.ts

@@ -16,6 +16,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
     VITE_GLOB_LOGIN_APP,
     VITE_GLOB_APP_PC,
     VITE_GLOB_TENANT_CODE,
+    VITE_GLOB_QUESTION_LIST_VERSION
   } = getAppEnvConfig();
 
   // Take global configuration
@@ -31,6 +32,7 @@ export const useGlobSetting = (): Readonly<GlobConfig> => {
     loginApp: VITE_GLOB_LOGIN_APP,
     appPCUrl: VITE_GLOB_APP_PC,
     tenantCode: VITE_GLOB_TENANT_CODE,
+    questionListVersion: VITE_GLOB_QUESTION_LIST_VERSION
   };
   return glob as Readonly<GlobConfig>;
 };

+ 21 - 13
src/views/datamanager/alertformdata/AlertformData.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="container-box">
-    <div class="control-btn" v-if="hasPermisson()">
+    <!-- <div class="control-btn" v-if="hasPermisson()">
       <div
         class="btn"
         :class="{ 'btn-active': activeName === 'default' }"
@@ -22,15 +22,13 @@
     </div>
 
     <Default class="content-box" v-if="activeName === 'default'" />
-    <Show class="content-box" v-else />
+    <Show class="content-box" v-else /> -->
+    <component :is="com" />
   </div>
 </template>
 
 <script setup lang="ts">
   import { ref } from 'vue';
-  import Default from './components/default/Default.vue';
-  import Show from './components/show/Show.vue';
-  import { useUserStore } from '@/store/modules/user';
   import { getDevMode, switchDevMode as SDM } from '@/api/datamanagement/getDevMode';
 
   const devMode = ref(true);
@@ -42,16 +40,16 @@
     SDM();
     devMode.value = !devMode.value;
   };
+  import { useGlobSetting } from '@/hooks/setting';
+  import { computed } from 'vue';
+  import SimpleDefault from './components/default-simple/Default.vue';
+  import AlertformDataComplex from './AlertformDataComplex.vue';
 
-  const activeName = ref('default');
+  const { questionListVersion } = useGlobSetting();
 
-  const userStore = useUserStore();
-  const hasPermisson = () => {
-    return userStore.checkPermission('question_mock_edit_admin');
-  };
-  const hasDevModePermisson = () => {
-    return userStore.checkPermission('control_activation');
-  };
+  const com = computed(() => {
+    return questionListVersion === 'simple' ? SimpleDefault : AlertformDataComplex;
+  });
 </script>
 
 <style scoped lang="scss">
@@ -103,4 +101,14 @@
   .content-box {
     flex: 1;
   }
+  .container-box {
+    width: 100%;
+    height: 100%;
+    display: flex;
+    flex-direction: column;
+    min-height: calc(100vh - 90px);
+    padding: 21px;
+    background-color: rgba(255, 255, 255, 1);
+    border-radius: 10px;
+  }
 </style>

+ 62 - 0
src/views/datamanager/alertformdata/AlertformDataComplex.vue

@@ -0,0 +1,62 @@
+<template>
+  <div class="control-btn" v-if="hasPermisson()">
+    <div class="btn" :class="{ 'btn-active': activeName === 'default' }" @click="activeName = 'default'">默认数据</div>
+    <div class="btn" :class="{ 'btn-active': activeName === 'show' }" @click="activeName = 'show'">展示数据</div>
+  </div>
+  <Default class="content-box" v-if="activeName === 'default'" />
+  <Show class="content-box" v-else />
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import Default from './components/default/Default.vue';
+import Show from './components/show/Show.vue';
+import { useUserStore } from '@/store/modules/user';
+
+const activeName = ref('default');
+
+const userStore = useUserStore();
+const hasPermisson = () => {
+  return userStore.checkPermission("question_mock_edit_admin");
+};
+</script>
+
+<style scoped lang="scss">
+.control-btn {
+  display: flex;
+  margin-bottom: 20px;
+
+  .btn {
+    display: flex;
+    justify-content: center;
+    align-items: center;
+    width: 188px;
+    height: 38px;
+    font-size: 14px;
+    font-weight: 400;
+    color: rgba(0, 0, 0, 0.88);
+    border: 1px solid #D9D9D9;
+    background: rgba(0, 0, 0, 0.02);
+    cursor: pointer;
+  }
+
+  :first-child {
+    border-radius: 8px 0px 0px 8px;
+  }
+
+  :last-child {
+    border-radius: 0px 8px 8px 0px;
+  }
+
+  .btn-active {
+    font-weight: 500;
+    color: #1890FF;
+    border: 1px solid #1890FF;
+    background-color: rgba(24, 144, 255, 0.15);
+  }
+}
+
+.content-box {
+  flex: 1;
+}
+</style>

+ 9 - 3
src/views/datamanager/alertformdata/components/common/AlertTable.vue

@@ -10,7 +10,7 @@
       </el-table-column>
       <el-table-column label="类型" prop="issueType" width="150">
         <template #default="{ row }">
-          {{ getNameByType(row.source, row.issueType, [aiOptions, manualOptions]) }}
+          {{ getNameByType(row.source, row.issueType) }}
         </template>
       </el-table-column>
       <el-table-column label="问题描述" prop="description" width="400" show-overflow-tooltip>
@@ -24,7 +24,7 @@
           {{ getNameByWorkid(row.workshopId, row.workspaceId, locationOptions) }}
         </template>
       </el-table-column>
-      <el-table-column label="时间" prop="createdAt" width="250"></el-table-column>
+      <el-table-column label="时间" prop="createdAt" width="180"></el-table-column>
       <el-table-column label="负责人" prop="personNameInCharge" width="100"></el-table-column>
       <el-table-column label="处理状态" prop="issueState">
         <template #default="{ row }">
@@ -67,7 +67,7 @@ import { getNameBySource, getNameByState } from './constant.question';
 import { useIssueType } from '../../hooks/useIssueType';
 import { useWorkLocation } from '../../hooks/useWorkLocation';
 
-const { aiOptions, manualOptions, getAIOptions, getManualOptions, getNameByType } = useIssueType();
+const { getAIOptions, getManualOptions, getNameByType } = useIssueType();
 const { locationOptions, getLocationOptions, getNameByWorkid } = useWorkLocation();
 
 const multipleTableRef = ref<InstanceType<typeof ElTable>>();
@@ -178,4 +178,10 @@ onBeforeMount(() => {
     cursor: pointer;
   }
 }
+
+:deep(.el-table) {
+  ::before {
+    height: 0px;
+  }
+}
 </style>

+ 140 - 0
src/views/datamanager/alertformdata/components/common/AlertTableSimple.vue

@@ -0,0 +1,140 @@
+<template>
+  <div class="alert-table-box">
+    <el-table ref="multipleTableRef" :data="tableData" style="width: 100%" height="100%" stripe
+      :cell-style="colorOfState" @selection-change="handleSelectionChange">
+      <el-table-column type="selection" width="55"></el-table-column>
+      <el-table-column label="类型" prop="issueType" width="150">
+        <template #default="{ row }">
+          {{ getNameByType(row.source, row.issueType) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="问题描述" prop="description" width="400" show-overflow-tooltip>
+        <template #default="{ row }">
+          <span>{{ getSplicedDes(row.description) }}</span>
+          <span class="detail-text" @click="handleDetailClick(row)"> 详情</span>
+        </template>
+      </el-table-column>
+      <el-table-column label="地点" prop="workspaceId" width="300">
+        <template #default="{ row }">
+          {{ getNameByWorkid(row.workshopId, row.workspaceId, locationOptions) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="时间" prop="createdAt" width="180"></el-table-column>
+      <el-table-column label="负责人" prop="personNameInCharge" width="100"></el-table-column>
+      <el-table-column label="处理状态" prop="issueState">
+        <template #default="{ row }">
+          {{ getNameByStateZJC(row.issueState) }}
+        </template>
+      </el-table-column>
+      <el-table-column label="操作" width="60" fixed="right">
+        <template #default="{ row }">
+          <img src="/src/assets/images/alert/delete.png" alt="" title="点击删除问题数据" @click="handleDelete(row)">
+        </template>
+      </el-table-column>
+    </el-table>
+  </div>
+</template>
+
+<script setup lang="ts">
+import { ElTable } from 'element-plus';
+import { onBeforeMount, ref } from 'vue';
+import { getNameByStateZJC } from './constant.question';
+import { useIssueType } from '../../hooks/useIssueType';
+import { useWorkLocation } from '../../hooks/useWorkLocation';
+
+const { getAIOptions, getManualOptions, getNameByType } = useIssueType();
+const { locationOptions, getLocationOptions, getNameByWorkid } = useWorkLocation();
+
+const multipleTableRef = ref<InstanceType<typeof ElTable>>();
+
+interface DataSourceItem {
+  source: Number,         // 问题单来源:1-AI检测、2-人工上报
+  issueType: Number,      // 问题单类型
+  description: String,    // 问题描述
+  workspaceId: Number[],  // 工位id(地点=车间+工位?)
+  createdAt: String,
+  personNameInCharge: String,
+  issueState: Number,     // 问题单状态:1-待审核、2-待处理、3-待复核、4-已退回、5-已处理
+};
+
+interface Props {
+  tableData: Array<DataSourceItem>;
+  onDetail: (row: DataSourceItem) => unknown; // 详情事件
+  onDelete: (row: DataSourceItem) => unknown; // 删除按钮事件
+};
+
+const props = defineProps<Props>();
+
+const emits = defineEmits(['update:selection'])
+const handleSelectionChange = (selection: any[]) => {
+  emits("update:selection", selection);
+};
+
+const handleDetailClick = (row) => {
+  props.onDetail(row);
+};
+const handleDelete = (row) => {
+  props.onDelete(row);
+};
+
+const getSplicedDes = (val) => {
+  if (val.length < 20) return val;
+  else {
+    const temp = val.substring(0, 20);
+    return temp + '…';
+  }
+};
+
+const colorOfState = ({ row, columnIndex }) => {
+  if (columnIndex === 6) {
+    if (row.issueState === 7 || row.issueState === 8) return { color: "#52C41A " };
+    else return { color: "#FF4D4F" };
+  };
+  if (row.isHide) {
+    return { color: "#A8ABB2" };
+  }
+};
+
+const clearAll = () => {
+  multipleTableRef.value!.clearSelection();
+};
+
+defineExpose({ clearAll })
+
+onBeforeMount(() => {
+  getAIOptions();
+  getManualOptions();
+  getLocationOptions();
+});
+</script>
+
+<style scoped lang="scss">
+.alert-table-box {
+  display: flex;
+  flex-direction: column;
+  height: calc(100vh - 290px);
+}
+
+.detail-text {
+  color: #1890FF;
+  font-weight: 500;
+  cursor: pointer;
+}
+
+:deep(.el-table-fixed-column--right) {
+  .cell {
+    display: flex;
+  }
+
+  img {
+    margin-right: 20px;
+    cursor: pointer;
+  }
+}
+
+:deep(.el-table) {
+  ::before {
+    height: 0px;
+  }
+}
+</style>

+ 149 - 0
src/views/datamanager/alertformdata/components/common/QueryFormSimple.vue

@@ -0,0 +1,149 @@
+<template>
+  <div>
+    <el-form :model="queryForm" label-width="auto" :inline="true" ref="formRef">
+      <div class="select-group">
+        <el-form-item label="类型:" prop="issueType">
+          <el-select v-model="queryForm.issueType" placeholder="全部" clearable>
+            <el-option v-for="item in props.aiOptions" :label="item.name" :value="item.id" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="地点:" prop="workspaceId">
+          <el-cascader v-model="workLocation" :options="props.locationOptions" :props="location" clearable
+            @change="handleCascaderChange" />
+        </el-form-item>
+        <el-form-item label="状态:" prop="issueState">
+          <el-select v-model="tempState" clearable @change="handleIssueStateChange">
+            <el-option v-for="item in issueStateOptionsZJC" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="日期:">
+          <el-date-picker v-model="dateRange" type="daterange" range-separator="~" start-placeholder="开始时间"
+            end-placeholder="结束时间" clearable unlink-panels value-format="YYYY-MM-DD HH:mm:ss.SSS"
+            :default-time="defaultTime" @change="handleDateChange" />
+        </el-form-item>
+      </div>
+      <div class="btn-group">
+        <el-form-item>
+          <el-button class="search-btn" type="primary" @click="handleSearch">查询</el-button>
+          <el-button class="reset-btn" @click="handleReset">重置</el-button>
+        </el-form-item>
+      </div>
+    </el-form>
+  </div>
+</template>
+
+<script setup lang="ts">
+import type { FormInstance } from 'element-plus';
+import { reactive, ref } from 'vue';
+import { issueStateOptionsZJC } from './constant.question';
+
+interface Props {
+  aiOptions: Array<any>
+  locationOptions: Array<any>
+};
+const props = defineProps<Props>();
+const emits = defineEmits(['onSearch', 'onReset']);
+
+interface QueryModel {
+  pageNumber: number,
+  pageSize: number,
+  source?: number,         // 来源
+  issueType?: number,      // 类型
+  workspaceId?: number[],  // 地点=工位id
+  issueState?: number[],   // 状态
+  startTime?: string,      // 开始时间(默认)
+  endTime?: string,        // 结束时间(默认)
+};
+
+const formRef = ref<FormInstance>();
+const queryForm = reactive<QueryModel>({
+  pageNumber: 1,
+  pageSize: 10,
+});
+
+const location = { multiple: true };  // 级联选择器(打开多选)
+const workLocation = ref([]);   // 级联选择器,为二维数组(提取workspaceId)
+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 handleSearch = () => {
+  emits('onSearch', queryForm);
+};
+
+const handleReset = () => {
+  workLocation.value = [];
+  tempState.value = '';
+  dateRange.value = [];
+  Reflect.deleteProperty(queryForm, "source");
+  Reflect.deleteProperty(queryForm, "startTime");
+  Reflect.deleteProperty(queryForm, "endTime");
+  formRef.value?.resetFields();
+  emits('onReset', queryForm);
+};
+
+const handleCascaderChange = () => {
+  const arr = [];
+  workLocation.value.forEach((item) => {
+    arr.push(item[1]);
+  });
+  queryForm.workspaceId = arr;
+};
+
+const handleIssueStateChange = () => {
+  if (tempState.value === undefined)
+    queryForm.issueState = [];
+  if (tempState.value)
+    queryForm.issueState = JSON.parse(tempState.value);
+};
+
+const handleDateChange = () => {
+  if (dateRange.value != null) {
+    queryForm.startTime = dateRange.value[0];
+    queryForm.endTime = dateRange.value[1];
+  } else {
+    Reflect.deleteProperty(queryForm, "startTime");
+    Reflect.deleteProperty(queryForm, "endTime");
+  }
+};
+</script>
+
+<style scoped lang="scss">
+.el-form {
+  display: flex;
+  justify-content: space-between;
+}
+
+:deep(.el-form-item__label) {
+  padding: 0;
+}
+
+.select-group {
+  flex: 1;
+}
+
+.btn-group {
+
+  .search-btn {
+    width: 65px;
+    height: 32px;
+    background: #1890FF;
+    border-radius: 2px;
+  }
+
+  .reset-btn {
+    width: 65px;
+    height: 32px;
+    border-radius: 2px;
+    border: 1px solid #1890FF;
+    color: #1890FF;
+  }
+}
+
+.el-select {
+  --el-select-width: 215px;
+}
+</style>

+ 30 - 2
src/views/datamanager/alertformdata/components/common/constant.question.ts

@@ -49,16 +49,44 @@ export const issueStateOptions = [
   { label: issueStateNameMap[IssueState.hasDone7], value: '[7,8]' },
   { 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] || '-'
 }
 
+// 中建材 —— 待处理(0123456),已处理(78)
+export enum IssueStateZJC {
+  toDeal0 = 0,
+  toDeal1 = 1,
+  toDeal2 = 2,
+  toDeal3 = 3,
+  toDeal4 = 4,
+  toDeal5 = 5,
+  toDeal6 = 6,
+  hasDone7 = 7,
+  hasDone8 = 8,
+}
+export const issueStateNameMapZJC = {
+  [IssueStateZJC.toDeal0]: '待处理',
+  [IssueStateZJC.toDeal1]: '待处理',
+  [IssueStateZJC.toDeal2]: '待处理',
+  [IssueStateZJC.toDeal3]: '待处理',
+  [IssueStateZJC.toDeal4]: '待处理',
+  [IssueStateZJC.toDeal5]: '待处理',
+  [IssueStateZJC.toDeal6]: '待处理',
+  [IssueStateZJC.hasDone7]: '已处理',
+  [IssueStateZJC.hasDone8]: '已处理',
+}
+export const issueStateOptionsZJC = [
+  { label: issueStateNameMapZJC[IssueStateZJC.toDeal0], value: '[0, 1, 2, 3, 4, 5, 6]' },
+  { label: issueStateNameMapZJC[IssueStateZJC.hasDone7], value: '[7, 8]' },
+]
+export const getNameByStateZJC = (issueState: IssueStateZJC) => {
+  return issueStateNameMapZJC[issueState] || '-'
+}

+ 290 - 0
src/views/datamanager/alertformdata/components/default-simple/Default.vue

@@ -0,0 +1,290 @@
+<template>
+  <div class="box">
+    <div class="search-form">
+      <QueryFormSimple
+        :is-show-tab="false"
+        :ai-options="aiOptions"
+        :manual-options="manualOptions"
+        :location-options="locationOptions"
+        @on-search="handleSearch"
+        @on-reset="handleReset"
+      />
+    </div>
+    <div class="table-list">
+      <div v-if="showActionBar" class="action-bar">
+        <span class="num-text">已选{{ chooseNum }}项</span>
+        <el-button :class="isActiveDelete ? 'btn-active' : 'btn-normal'" @click="handleDeleteAll"
+          >删除</el-button
+        >
+        <span class="close-btn" @click="handleSelectNone"></span>
+      </div>
+      <AlertTableSimple
+        ref="alertTableRef"
+        class="table-bar"
+        :table-data="tableData"
+        :on-detail="handleDetail"
+        :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"
+      />
+    </div>
+    <DetailDialog
+      v-if="isDetailDialogShow"
+      :description="detailDescription"
+      :image-paths="detailPictures"
+      @toggle-status="switchDetailDialog"
+    />
+  </div>
+</template>
+
+<script setup lang="ts">
+  import { ref, onMounted, onBeforeMount } from 'vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  import QueryFormSimple from '../common/QueryFormSimple.vue';
+  import AlertTableSimple from '../common/AlertTableSimple.vue';
+  import DetailDialog from '../common/DetailDialog.vue';
+  import Pagination from '../common/Pagination.vue';
+  import { useIssueType } from '../../hooks/useIssueType';
+  import { useWorkLocation } from '../../hooks/useWorkLocation';
+  import { getDefaultTableData, deleteDefaultTableData } from '@/api/datamanagement/alert-default';
+
+  const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
+  const { locationOptions, getLocationOptions } = useWorkLocation();
+
+  const alertTableRef = ref<typeof AlertTableSimple>();
+  const tableData = ref([]);
+  const showActionBar = ref(false);
+  const chooseNum = ref(0);
+  const chooseId = ref<number[]>([]);
+  const isActiveDelete = ref(false);
+  // 详情
+  const isDetailDialogShow = ref(false);
+  const detailDescription = ref('');
+  const detailPictures = ref<string[]>([]);
+  // 分页
+  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 = [];
+    selection.forEach((item) => {
+      if (chooseId.value.indexOf(item.id) === -1) chooseId.value.push(item.id);
+    });
+    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 handleDeleteAll = () => {
+    if (showActionBar.value) isActiveDelete.value = !isActiveDelete.value;
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+      customClass: 'deleteMessage',
+      center: true,
+    })
+      .then(() => {
+        deleteDefaultTableData(chooseId.value).then(() => {
+          ElMessage({
+            type: 'success',
+            message: '删除成功',
+          });
+          getTableData();
+          handleSelectNone();
+          isActiveDelete.value = !isActiveDelete.value;
+        });
+      })
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '取消删除',
+        });
+        isActiveDelete.value = !isActiveDelete.value;
+      });
+  };
+
+  // 详情
+  const switchDetailDialog = (show: boolean) => {
+    isDetailDialogShow.value = show;
+  };
+  const handleDetail = (row) => {
+    isDetailDialogShow.value = true;
+    detailDescription.value = row.description;
+    detailPictures.value = row.pictures;
+  };
+
+  // 删除
+  const handleDelete = (row) => {
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+      type: 'warning',
+      customClass: 'deleteMessage',
+      center: true,
+    })
+      .then(() => {
+        deleteDefaultTableData([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 getTableData = () => {
+    getDefaultTableData(query.value).then((res) => {
+      console.log(res);
+      tableData.value = res.records;
+      total.value = res.totalRow;
+    });
+  };
+
+  onMounted(() => {
+    getTableData();
+  });
+
+  onBeforeMount(() => {
+    getAIOptions();
+    getManualOptions();
+    getLocationOptions();
+  });
+</script>
+
+<style scoped lang="scss">
+  .box {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .table-list {
+    flex: 1;
+
+    .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;
+      }
+
+      .btn-normal {
+        color: #1890ff;
+        background: transparent;
+        border: 1px solid #1890ff;
+        border-radius: 2px;
+      }
+
+      .btn-active {
+        color: #ffffff;
+        background-color: #1890ff;
+      }
+
+      .close-btn {
+        margin-left: auto;
+        margin-right: 20px;
+      }
+
+      .close-btn:before {
+        content: '\2716';
+        color: #000;
+        cursor: pointer;
+      }
+    }
+
+    .table-bar {
+      position: relative;
+    }
+  }
+
+  .pagination-box {
+    height: 50px;
+    margin-top: 10px;
+  }
+</style>
+<style lang="scss">
+  .deleteMessage {
+    padding: 20px 24px;
+    box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 9px 28px 0px rgba(0, 0, 0, 0.05),
+      0px 6px 16px -8px rgba(0, 0, 0, 0.08);
+    border-radius: 8px;
+
+    .el-message-box__headerbtn {
+      margin-top: 12px;
+      margin-right: 12px;
+    }
+
+    .el-message-box__title {
+      justify-content: start;
+      color: rgba(0, 0, 0, 0.88);
+      font-size: 16px;
+      font-weight: 500;
+    }
+
+    .el-message-box__container {
+      justify-content: start;
+      margin-left: 23px;
+    }
+
+    .el-message-box__btns {
+      display: block;
+      float: right;
+    }
+  }
+</style>

+ 425 - 372
src/views/datamanager/alertformdata/components/default/Default.vue

@@ -1,435 +1,488 @@
 <template>
   <div class="box">
+    <div style="margin-bottom: 10px; display: flex" v-if="hasDevModePermisson()">
+      <div style="line-height: 33px">预审后生效模式:</div>
+      <el-switch :model-value="devMode" @change="switchDevMode" />
+    </div>
     <div class="search-form">
-      <QueryForm :ai-options="aiOptions" :manual-options="manualOptions" :location-options="locationOptions"
-        @on-search="handleSearch" @on-reset="handleReset" />
+      <QueryForm
+        :ai-options="aiOptions"
+        :manual-options="manualOptions"
+        :location-options="locationOptions"
+        @on-search="handleSearch"
+        @on-reset="handleReset"
+      />
     </div>
     <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 v-if="!cancelUrgentFlag" :class="isActiveUrgent ? 'btn-active' : 'btn-normal'"
-          @click="handleUrgentAll">标记加急</el-button>
-        <el-button v-if="cancelUrgentFlag" :class="isActiveCancelUrgent ? 'btn-active' : 'btn-normal'"
-          @click="handleCancelUrgentAll">取消加急</el-button>
-        <el-button v-if="hasPermisson()" :class="isActiveCopy ? 'btn-active' : 'btn-normal'"
-          @click="handleCopyToShow">复制到展示数据</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
+        >
+        <el-button
+          v-if="!cancelUrgentFlag"
+          :class="isActiveUrgent ? 'btn-active' : 'btn-normal'"
+          @click="handleUrgentAll"
+          >标记加急</el-button
+        >
+        <el-button
+          v-if="cancelUrgentFlag"
+          :class="isActiveCancelUrgent ? 'btn-active' : 'btn-normal'"
+          @click="handleCancelUrgentAll"
+          >取消加急</el-button
+        >
+        <el-button
+          v-if="hasPermisson()"
+          :class="isActiveCopy ? 'btn-active' : 'btn-normal'"
+          @click="handleCopyToShow"
+          >复制到展示数据</el-button
+        >
         <span class="close-btn" @click="handleSelectNone"></span>
       </div>
-      <AlertTable ref="alertTableRef" class="table-bar" :is-show-tab="false" :table-data="tableData"
-        :on-detail="handleDetail" :on-urgent="handleUrgent" :on-show="handleShow" :on-delete="handleDelete"
-        @update:selection="handlePop" />
+      <AlertTable
+        ref="alertTableRef"
+        class="table-bar"
+        :is-show-tab="false"
+        :table-data="tableData"
+        :on-detail="handleDetail"
+        :on-urgent="handleUrgent"
+        :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"
+    />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref, onMounted, onBeforeMount } from 'vue';
-import { ElMessage, ElMessageBox } from 'element-plus';
-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 { useWorkLocation } from '../../hooks/useWorkLocation';
-import {
-  getDefaultTableData,
-  deleteDefaultTableData,
-  copyToShowTableData,
-  updateDefaultHide,
-  updateDefaultHideAll,
-  updateDefaultPriority,
-  updateDefaultPriorityAll
-} from '@/api/datamanagement/alert-default';
-import { useUserStore } from '@/store/modules/user';
-
-const userStore = useUserStore();
-const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
-const { locationOptions, getLocationOptions } = useWorkLocation();
-
-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 cancelUrgentFlag = ref(true); // true取消加急 / false全部加急
-const isActiveHide = ref(false);
-const isActiveCancelHide = ref(false);
-const isActiveDelete = ref(false);
-const isActiveUrgent = ref(false);
-const isActiveCancelUrgent = ref(false);
-const isActiveCopy = ref(false);
-// 详情
-const isDetailDialogShow = ref(false);
-const detailDescription = ref('');
-const detailPictures = ref<string[]>([]);
-const detailVideos = ref<string[]>([]);
-// 分页
-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;
-  cancelUrgentFlag.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;
-    // 只要有一个item.priority === 0 说明不是全都加急状态,不用变成“取消加急”
-    if (item.priority === 0) cancelUrgentFlag.value = false;
+  import { ref, onMounted, onBeforeMount } from 'vue';
+  import { ElMessage, ElMessageBox } from 'element-plus';
+  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 { useWorkLocation } from '../../hooks/useWorkLocation';
+  import {
+    getDefaultTableData,
+    deleteDefaultTableData,
+    copyToShowTableData,
+    updateDefaultHide,
+    updateDefaultHideAll,
+    updateDefaultPriority,
+    updateDefaultPriorityAll,
+  } from '@/api/datamanagement/alert-default';
+  import { getDevMode, switchDevMode as SDM } from '@/api/datamanagement/getDevMode';
+  import { useUserStore } from '@/store/modules/user';
+
+  const userStore = useUserStore();
+  const { aiOptions, manualOptions, getAIOptions, getManualOptions } = useIssueType();
+  const { locationOptions, getLocationOptions } = useWorkLocation();
+
+  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 cancelUrgentFlag = ref(true); // true取消加急 / false全部加急
+  const isActiveHide = ref(false);
+  const isActiveCancelHide = ref(false);
+  const isActiveDelete = ref(false);
+  const isActiveUrgent = ref(false);
+  const isActiveCancelUrgent = ref(false);
+  const isActiveCopy = ref(false);
+  // 详情
+  const isDetailDialogShow = ref(false);
+  const detailDescription = ref('');
+  const detailPictures = ref<string[]>([]);
+  const detailVideos = ref<string[]>([]);
+  // 分页
+  const total = ref(0);
+
+  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 = {
-    ids: chooseId.value,
-    hide: true,
+  // 查询
+  const handleSearch = (queryForm) => {
+    query.value = queryForm;
+    getTableData();
   };
-  updateDefaultHideAll(updateList).then(() => {
-    handleSelectNone();
+  // 重置
+  const handleReset = (queryForm) => {
+    query.value = queryForm;
     getTableData();
-    ElMessage({
-      message: '操作成功',
-      type: 'success',
-    });
-    setTimeout(function () {
-      isActiveHide.value = !isActiveHide.value;
-    }, 1000);
+  };
+
+  const devMode = ref(true);
+  getDevMode().then((res) => {
+    devMode.value = res;
   });
-};
-
-// 取消隐藏
-const handleCancelHideAll = () => {
-  if (showActionBar.value) isActiveCancelHide.value = !isActiveCancelHide.value;
-  const updateList = {
-    ids: chooseId.value,
-    hide: false,
+
+  const switchDevMode = () => {
+    SDM();
+    devMode.value = !devMode.value;
   };
-  updateDefaultHideAll(updateList).then(() => {
-    handleSelectNone();
-    getTableData();
-    ElMessage({
-      message: '操作成功',
-      type: 'success',
+
+  const hasDevModePermisson = () => {
+    return userStore.checkPermission('control_activation');
+  };
+
+  // 多选
+  const handlePop = (selection) => {
+    chooseId.value = [];
+    // cancelHideFlag.value = true;
+    cancelUrgentFlag.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;
+      // 只要有一个item.priority === 0 说明不是全都加急状态,不用变成“取消加急”
+      if (item.priority === 0) cancelUrgentFlag.value = false;
     });
-    setTimeout(function () {
-      isActiveCancelHide.value = !isActiveCancelHide.value;
-    }, 1000);
-  });
-}
-
-// 批量删除
-const handleDeleteAll = () => {
-  if (showActionBar.value) isActiveDelete.value = !isActiveDelete.value;
-  ElMessageBox.confirm(
-    '删除之后,数据无法恢复',
-    '请确认是否删除数据',
-    {
+    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 = {
+      ids: chooseId.value,
+      hide: true,
+    };
+    updateDefaultHideAll(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
+      ElMessage({
+        message: '操作成功',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveHide.value = !isActiveHide.value;
+      }, 1000);
+    });
+  };
+
+  // 取消隐藏
+  const handleCancelHideAll = () => {
+    if (showActionBar.value) isActiveCancelHide.value = !isActiveCancelHide.value;
+    const updateList = {
+      ids: chooseId.value,
+      hide: false,
+    };
+    updateDefaultHideAll(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
+      ElMessage({
+        message: '操作成功',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveCancelHide.value = !isActiveCancelHide.value;
+      }, 1000);
+    });
+  };
+
+  // 批量删除
+  const handleDeleteAll = () => {
+    if (showActionBar.value) isActiveDelete.value = !isActiveDelete.value;
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning',
       customClass: 'deleteMessage',
-      center: true
-    }
-  )
-    .then(() => {
-      deleteDefaultTableData(chooseId.value).then(() => {
+      center: true,
+    })
+      .then(() => {
+        deleteDefaultTableData(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(() => {
+      });
+  };
+
+  // 标记加急,设置priority = 1
+  const handleUrgentAll = () => {
+    if (showActionBar.value) isActiveUrgent.value = !isActiveUrgent.value;
+    const updateList = {
+      ids: chooseId.value,
+      priority: 1,
+    };
+    updateDefaultPriorityAll(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
       ElMessage({
-        type: 'info',
-        message: '取消删除',
+        message: '已加急',
+        type: 'success',
       });
-      isActiveDelete.value = !isActiveDelete.value;
-    })
-};
-
-// 标记加急,设置priority = 1
-const handleUrgentAll = () => {
-  if (showActionBar.value) isActiveUrgent.value = !isActiveUrgent.value;
-  const updateList = {
-    ids: chooseId.value,
-    priority: 1,
+      setTimeout(function () {
+        isActiveUrgent.value = !isActiveUrgent.value;
+      }, 1000);
+    });
   };
-  updateDefaultPriorityAll(updateList).then(() => {
-    handleSelectNone();
-    getTableData();
-    ElMessage({
-      message: '已加急',
-      type: 'success',
+
+  // 取消加急
+  const handleCancelUrgentAll = () => {
+    if (showActionBar.value) isActiveCancelUrgent.value = !isActiveCancelUrgent.value;
+    const updateList = {
+      ids: chooseId.value,
+      priority: 0,
+    };
+    updateDefaultPriorityAll(updateList).then(() => {
+      handleSelectNone();
+      getTableData();
+      ElMessage({
+        message: '已取消加急',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveCancelUrgent.value = !isActiveCancelUrgent.value;
+      }, 1000);
     });
-    setTimeout(function () {
-      isActiveUrgent.value = !isActiveUrgent.value;
-    }, 1000);
-  });
-};
-
-// 取消加急
-const handleCancelUrgentAll = () => {
-  if (showActionBar.value) isActiveCancelUrgent.value = !isActiveCancelUrgent.value;
-  const updateList = {
-    ids: chooseId.value,
-    priority: 0,
   };
-  updateDefaultPriorityAll(updateList).then(() => {
-    handleSelectNone();
-    getTableData();
-    ElMessage({
-      message: '已取消加急',
-      type: 'success',
+
+  // 复制到展示数据
+  const handleCopyToShow = () => {
+    if (showActionBar.value) isActiveCopy.value = !isActiveCopy.value;
+    copyToShowTableData(chooseId.value).then(() => {
+      ElMessage({
+        message: '复制成功',
+        type: 'success',
+      });
+      setTimeout(function () {
+        isActiveCopy.value = !isActiveCopy.value;
+      }, 1000);
+      handleSelectNone();
     });
-    setTimeout(function () {
-      isActiveCancelUrgent.value = !isActiveCancelUrgent.value;
-    }, 1000);
-  });
-};
-
-// 复制到展示数据
-const handleCopyToShow = () => {
-  if (showActionBar.value) isActiveCopy.value = !isActiveCopy.value;
-  copyToShowTableData(chooseId.value).then(() => {
-    ElMessage({
-      message: '复制成功',
-      type: 'success',
+  };
+
+  // 详情
+  const closeDetailDialog = () => {
+    isDetailDialogShow.value = false;
+  };
+  const handleDetail = (row) => {
+    isDetailDialogShow.value = true;
+    detailDescription.value = row.description;
+    detailPictures.value = row.pictures;
+    detailVideos.value = row.videos;
+  };
+
+  // 单个加急priority=1/取消加急priority=0
+  const handleUrgent = (row) => {
+    const tempPriority = row.priority === 0 ? 1 : 0;
+    const updateList = {
+      id: row.id,
+      priority: tempPriority,
+    };
+    updateDefaultPriority(updateList).then(() => {
+      getTableData();
     });
-    setTimeout(function () {
-      isActiveCopy.value = !isActiveCopy.value;
-    }, 1000);
-    handleSelectNone();
-  })
-};
-
-// 详情
-const closeDetailDialog = () => {
-  isDetailDialogShow.value = false;
-};
-const handleDetail = (row) => {
-  isDetailDialogShow.value = true;
-  detailDescription.value = row.description;
-  detailPictures.value = row.pictures;
-  detailVideos.value = row.videos;
-};
-
-// 单个加急priority=1/取消加急priority=0
-const handleUrgent = (row) => {
-  const tempPriority = row.priority === 0 ? 1 : 0;
-  const updateList = {
-    id: row.id,
-    priority: tempPriority,
   };
-  updateDefaultPriority(updateList).then(() => {
-    getTableData();
-  });
-};
-
-// 单个显示hide=false/隐藏hide=true
-const handleShow = (row) => {
-  const tempHide = row.isHide === false ? true : false;
-  const updateList = {
-    id: row.id,
-    hide: tempHide,
+
+  // 单个显示hide=false/隐藏hide=true
+  const handleShow = (row) => {
+    const tempHide = row.isHide === false ? true : false;
+    const updateList = {
+      id: row.id,
+      hide: tempHide,
+    };
+    updateDefaultHide(updateList).then(() => {
+      getTableData();
+    });
   };
-  updateDefaultHide(updateList).then(() => {
-    getTableData();
-  });
-};
-
-// 删除
-const handleDelete = (row) => {
-  ElMessageBox.confirm(
-    '删除之后,数据无法恢复',
-    '请确认是否删除数据',
-    {
+
+  // 删除
+  const handleDelete = (row) => {
+    ElMessageBox.confirm('删除之后,数据无法恢复', '请确认是否删除数据', {
       confirmButtonText: '确定',
       cancelButtonText: '取消',
       type: 'warning',
       customClass: 'deleteMessage',
-      center: true
-    }
-  )
-    .then(() => {
-      deleteDefaultTableData([row.id]).then(() => {
-        ElMessage({
-          type: 'success',
-          message: '删除成功',
-        });
-        getTableData();
-      })
+      center: true,
     })
-    .catch(() => {
-      ElMessage({
-        type: 'info',
-        message: '取消删除',
+      .then(() => {
+        deleteDefaultTableData([row.id]).then(() => {
+          ElMessage({
+            type: 'success',
+            message: '删除成功',
+          });
+          getTableData();
+        });
       })
-    })
-};
-
-// 换页,重新获取表格
-const handlePageChange = (val) => {
-  query.value.pageNumber = val;
-  getTableData();
-};
-const handleSizeChange = (val) => {
-  query.value.pageSize = val;
-  getTableData();
-};
-
-const getTableData = () => {
-  getDefaultTableData(query.value).then((res) => {
-    console.log(res);
-    tableData.value = res.records;
-    total.value = res.totalRow;
-  })
-};
-
-const hasPermisson = () => {
-  return userStore.checkPermission("question_mock_edit_admin");
-};
-
-onMounted(() => {
-  getTableData();
-});
-
-onBeforeMount(() => {
-  getAIOptions();
-  getManualOptions();
-  getLocationOptions();
-});
-</script>
+      .catch(() => {
+        ElMessage({
+          type: 'info',
+          message: '取消删除',
+        });
+      });
+  };
 
-<style scoped lang="scss">
-.box {
-  display: flex;
-  flex-direction: column;
-}
+  // 换页,重新获取表格
+  const handlePageChange = (val) => {
+    query.value.pageNumber = val;
+    getTableData();
+  };
+  const handleSizeChange = (val) => {
+    query.value.pageSize = val;
+    getTableData();
+  };
 
-.table-list {
-  flex: 1;
-  // height: calc(100vh - 350px);
-  // overflow-y: scroll;
+  const getTableData = () => {
+    getDefaultTableData(query.value).then((res) => {
+      console.log(res);
+      tableData.value = res.records;
+      total.value = res.totalRow;
+    });
+  };
 
-  .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;
+  const hasPermisson = () => {
+    return userStore.checkPermission('question_mock_edit_admin');
+  };
 
-    .num-text {
-      margin: 0 34px 0 25px;
-      color: rgba(0, 0, 0, 0.85);
-      font-weight: 500;
-    }
+  onMounted(() => {
+    getTableData();
+  });
 
-    .btn-normal {
-      color: #1890FF;
-      background: transparent;
-      border: 1px solid #1890FF;
-      border-radius: 2px;
-    }
+  onBeforeMount(() => {
+    getAIOptions();
+    getManualOptions();
+    getLocationOptions();
+  });
+</script>
 
-    .btn-active {
-      color: #FFFFFF;
-      background-color: #1890FF;
-    }
+<style scoped lang="scss">
+  .box {
+    display: flex;
+    flex-direction: column;
+  }
 
-    .close-btn {
-      margin-left: auto;
-      margin-right: 20px;
+  .table-list {
+    flex: 1;
+    // 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;
+
+      .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-active {
+        color: #ffffff;
+        background-color: #1890ff;
+      }
+
+      .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 lang="scss">
-.deleteMessage {
-  padding: 20px 24px;
-  box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 9px 28px 0px rgba(0, 0, 0, 0.05), 0px 6px 16px -8px rgba(0, 0, 0, 0.08);
-  border-radius: 8px;
-
-  .el-message-box__headerbtn {
-    margin-top: 12px;
-    margin-right: 12px;
-  }
+  .deleteMessage {
+    padding: 20px 24px;
+    box-shadow: 0px 12px 48px 16px rgba(0, 0, 0, 0.03), 0px 9px 28px 0px rgba(0, 0, 0, 0.05),
+      0px 6px 16px -8px rgba(0, 0, 0, 0.08);
+    border-radius: 8px;
+
+    .el-message-box__headerbtn {
+      margin-top: 12px;
+      margin-right: 12px;
+    }
 
-  .el-message-box__title {
-    justify-content: start;
-    color: rgba(0, 0, 0, 0.88);
-    font-size: 16px;
-    font-weight: 500;
-  }
+    .el-message-box__title {
+      justify-content: start;
+      color: rgba(0, 0, 0, 0.88);
+      font-size: 16px;
+      font-weight: 500;
+    }
 
-  .el-message-box__container {
-    justify-content: start;
-    margin-left: 23px;
-  }
+    .el-message-box__container {
+      justify-content: start;
+      margin-left: 23px;
+    }
 
-  .el-message-box__btns {
-    display: block;
-    float: right;
+    .el-message-box__btns {
+      display: block;
+      float: right;
+    }
   }
-}
-</style>
+</style>

+ 10 - 5
src/views/datamanager/alertformdata/hooks/useIssueType.ts

@@ -1,5 +1,6 @@
 import { ref } from 'vue';
 import { getAIList, getManualList } from '@/api/datamanagement/alert'
+import { Source } from '../components/common/constant.question';
 
 type AIOption = {
   id: number
@@ -40,14 +41,18 @@ export function useIssueType() {
   };
 
   // 根据 问题来源id + 问题类型id 决定表格类型栏展示文字
-  const getNameByType = (source, type, arrayOfOptions) => {
-    // arrayOfOptions = [ aiOptions, manualOptions ]
-    const targetArray = arrayOfOptions[source - 1];
+  const getNameByType = (source, type) => {
+    const sourceTypeMap = {
+      [Source.ai]: aiOptions,
+      [Source.manual]: manualOptions,
+    }
+    const targetArray = sourceTypeMap[source];
     if (targetArray) {
-      const foundObject = targetArray.find(obj => obj.id === type);
+      const foundObject = targetArray.value.find(obj => obj.id === type);
       if (foundObject) return foundObject.name;
-      else return '-'
+      return '-'
     }
+    return '-'
   };
 
   return {

+ 5 - 1
src/views/datamanager/alertformdata/hooks/useWorkLocation.ts

@@ -38,7 +38,11 @@ export function useWorkLocation() {
 
     if (!shop.children || !Array.isArray(shop.children)) return '-';
     const space = shop.children.find((item) => item.value === workspaceId);
-    return shop.label + ' - ' + space?.label;
+    let str = shop.label;
+    if (space?.label) {
+      str += ' - ' + space?.label
+    }
+    return str;
   };
 
   return {

+ 3 - 0
types/config.d.ts

@@ -57,6 +57,7 @@ export interface GlobConfig {
   appDownloadUrl?: string;
   loginApp?: string;
   appPCUrl?: string;
+  questionListVersion: string;
 }
 
 export interface GlobEnvConfig {
@@ -84,6 +85,8 @@ export interface GlobEnvConfig {
   VITE_GLOB_APP_PC: string;
 
   VITE_GLOB_TENANT_CODE: string;
+
+  VITE_GLOB_QUESTION_LIST_VERSION: string;
 }
 export interface GlobConfig {
   // 标题