فهرست منبع

需要整理任务模板的数据结构

chauncey 11 ماه پیش
والد
کامیت
35049c65dc
31فایلهای تغییر یافته به همراه661 افزوده شده و 810 حذف شده
  1. 36 0
      mock/disaster-precaution/info.ts
  2. 95 0
      mock/disaster-precaution/table.ts
  3. 0 178
      mock/task-execution/table.ts
  4. 52 0
      src/api/disaster-precaution/index.ts
  5. 0 68
      src/api/task-execution/tableData.ts
  6. 2 2
      src/components/BasicTable.vue
  7. 31 0
      src/types/disaster-precaution/index.ts
  8. 0 22
      src/types/task-execution/tableData.ts
  9. 7 1
      src/views/disaster/WorkRecord.md
  10. 8 1
      src/views/disaster/components/User.vue
  11. 127 21
      src/views/disaster/disaster-precaution/PageTaskExecution.vue
  12. 93 19
      src/views/disaster/disaster-precaution/PageTaskManagement.vue
  13. 2 20
      src/views/disaster/disaster-precaution/PageTaskTemplateDetail.vue
  14. 1 0
      src/views/disaster/disaster-precaution/src/components/Compliance.vue
  15. 4 11
      src/views/disaster/disaster-precaution/src/components/CreateTaskItem.vue
  16. 5 12
      src/views/disaster/disaster-precaution/src/components/EditTaskItem.vue
  17. 0 59
      src/views/disaster/disaster-precaution/src/components/Search.vue
  18. 0 126
      src/views/disaster/disaster-precaution/src/components/TaskExecutionDoing.vue
  19. 0 141
      src/views/disaster/disaster-precaution/src/components/TaskExecutionDone.vue
  20. 7 28
      src/views/disaster/disaster-precaution/src/components/TemplateTableMerge.vue
  21. 4 4
      src/views/disaster/disaster-precaution/src/components/ViewTaskItem.vue
  22. 71 30
      src/views/disaster/disaster-precaution/src/config/form.ts
  23. 23 5
      src/views/disaster/disaster-precaution/src/config/index.ts
  24. 28 5
      src/views/disaster/disaster-precaution/src/config/search.ts
  25. 56 23
      src/views/disaster/disaster-precaution/src/config/table.ts
  26. 2 18
      src/views/disaster/disaster-precaution/src/constants/task-execution.ts
  27. 0 1
      src/views/disaster/disaster-precaution/src/constants/template-detail.ts
  28. 2 10
      src/views/disaster/disaster-precaution/src/type.ts
  29. 1 1
      src/views/disaster/disaster-precaution/src/utils/format-data.ts
  30. 2 2
      src/views/disaster/disaster-warning/PageDefenseNotice.vue
  31. 2 2
      src/views/disaster/disaster-warning/PageWarningInfo.vue

+ 36 - 0
mock/disaster-precaution/info.ts

@@ -0,0 +1,36 @@
+import { resultSuccess } from '../_util';
+
+const taskManagementItem = {
+  id: 1001,
+  taskName: '日常检查任务2024',
+  selfCheckUnit: '安全生产部',
+  taskType: 2,
+  taskTemplate: 2,
+  shouldCompleteTime: '2024-03-20 10:00',
+  checkRequirement: '检查要求',
+  checkUser: [
+    {
+      id: 1,
+      realname: 'test111',
+      username: '3133',
+    },
+    {
+      id: 3,
+      realname: 'test333',
+      username: '3135',
+    },
+  ],
+  isPush: true,
+  createUser: '张三',
+};
+
+export default [
+  {
+    url: '/eye_api_bak/api/admin/task/getTaskManagementItem',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(taskManagementItem);
+    },
+  }
+];

+ 95 - 0
mock/disaster-precaution/table.ts

@@ -0,0 +1,95 @@
+import { resultSuccess } from '../_util';
+
+const taskManagement = [
+  {
+    id: 1002,
+    taskName: '专项检查任务2025',
+    selfCheckUnit: '运维部',
+    taskType: 0,
+    shouldCompleteTime: '2024-03-25 15:30:00',
+    activeStatus: 1,
+    taskStage: 1,
+    isOverdue: 0,
+  },
+  {
+    id: 1003,
+    taskName: '季度检查任务2026',
+    selfCheckUnit: '技术部',
+    taskType: 2,
+    shouldCompleteTime: '2024-06-30 18:00:00',
+    activeStatus: 0,
+    taskStage: 1,
+    isOverdue: 0,
+  },
+  {
+    id: 1005,
+    taskName: '日常检查任务20295123458111111',
+    selfCheckUnit: '质量部',
+    taskType: 2,
+    shouldCompleteTime: '2024-03-21 14:00:00',
+    activeStatus: 2,
+    taskStage: 4,
+    isOverdue: 1,
+  },
+];
+const taskExecution = [
+  {
+    id: 1002,
+    taskName: '专项检查任务2025',
+    selfCheckUnit: '运维部',
+    taskType: 0,
+    shouldCompleteTime: '2024-03-25 15:30:00',
+    taskStage: 3,
+    isOverdue: 0,
+    checkUser: [],
+  },
+  {
+    id: 1003,
+    taskName: '季度检查任务2026',
+    selfCheckUnit: '技术部',
+    taskType: 1,
+    shouldCompleteTime: '2024-06-30 18:00:00',
+    taskStage: 2,
+    isOverdue: 0,
+    checkUser: [],
+  },
+  {
+    id: 1004,
+    taskName: '年度检查任务2027',
+    selfCheckUnit: '工程部',
+    taskType: 2,
+    shouldCompleteTime: '2024-12-31 23:59:59',
+    taskStage: 2,
+    isOverdue: 0,
+    checkUser: [],
+  },
+  {
+    id: 1005,
+    taskName: '日常检查任务20295123458111111',
+    selfCheckUnit: '质量部',
+    taskType: 0,
+    shouldCompleteTime: '2024-03-21 14:00:00',
+    taskStage: 4,
+    isOverdue: 1,
+    checkUser: [],
+  },
+];
+
+export default [
+  {
+    url: '/eye_api_bak/api/admin/task/getTaskManagementList',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(taskManagement);
+    },
+  },
+  {
+    url: '/eye_api_bak/api/admin/task/getTaskExecutionList',
+    timeout: 1000,
+    method: 'get',
+    response: () => {
+      return resultSuccess(taskExecution);
+    },
+  }
+];

+ 0 - 178
mock/task-execution/table.ts

@@ -1,178 +0,0 @@
-import { resultSuccess } from '../_util';
-
-const taskManagement = [
-  {
-    id: 1002,
-    taskName: '专项检查任务2025',
-    selfCheckUnit: '运维部',
-    taskType: 0,
-    shouldCompleteTime: '2024-03-25 15:30:00',
-    activeStatus: 1,
-    taskStage: 1,
-    isOverdue: 0,
-  },
-  {
-    id: 1003,
-    taskName: '季度检查任务2026',
-    selfCheckUnit: '技术部',
-    taskType: 2,
-    shouldCompleteTime: '2024-06-30 18:00:00',
-    activeStatus: 0,
-    taskStage: 1,
-    isOverdue: 0,
-  },
-  {
-    id: 1005,
-    taskName: '日常检查任务20295123458111111',
-    selfCheckUnit: '质量部',
-    taskType: 2,
-    shouldCompleteTime: '2024-03-21 14:00:00',
-    activeStatus: 2,
-    taskStage: 4,
-    isOverdue: 1,
-  },
-];
-const taskManagementItem = {
-  id: 1001,
-  taskName: '日常检查任务2024',
-  selfCheckUnit: '安全生产部',
-  taskType: 2,
-  taskTemplate: 2,
-  shouldCompleteTime: '2024-03-20 10:00',
-  checkRequirement: '检查要求',
-  checkUser: [
-    {
-      id: 1,
-      realname: 'test111',
-      username: '3133',
-    },
-    {
-      id: 3,
-      realname: 'test333',
-      username: '3135',
-    },
-  ],
-  isPush: true,
-  createUser: '张三',
-};
-const taskExecutionDoing = [
-  {
-    id: 1001,
-    taskName: '日常检查任务2024',
-    selfCheckUnit: '安全生产部',
-    taskType: '日常检查',
-    shouldCompleteTime: '2024-03-20 10:00:00',
-    activeStatus: 1,
-    taskStage: 0,
-    createTime: '2024-03-19 10:00:00',
-    updateTime: '2024-03-19 10:00:00',
-    isOverdue: 0,
-  },
-  {
-    id: 1002,
-    taskName: '专项检查任务2025',
-    selfCheckUnit: '运维部',
-    taskType: '专项检查',
-    shouldCompleteTime: '2024-03-25 15:30:00',
-    activeStatus: 1,
-    taskStage: 0,
-    createTime: '2024-03-19 11:00:00',
-    updateTime: '2024-03-19 11:00:00',
-    isOverdue: 0,
-  },
-  {
-    id: 1003,
-    taskName: '季度检查任务2026',
-    selfCheckUnit: '技术部',
-    taskType: '季度检查',
-    shouldCompleteTime: '2024-06-30 18:00:00',
-    activeStatus: 0,
-    taskStage: 1,
-    createTime: '2024-03-19 12:00:00',
-    updateTime: '2024-03-19 12:00:00',
-    isOverdue: 0,
-  },
-  {
-    id: 1004,
-    taskName: '年度检查任务2027',
-    selfCheckUnit: '工程部',
-    taskType: '年度检查',
-    shouldCompleteTime: '2024-12-31 23:59:59',
-    activeStatus: 0,
-    taskStage: 2,
-    createTime: '2024-03-19 13:00:00',
-    updateTime: '2024-03-19 13:00:00',
-    isOverdue: 0,
-  },
-  {
-    id: 1005,
-    taskName: '日常检查任务20295123458111111',
-    selfCheckUnit: '质量部',
-    taskType: '日常检查',
-    shouldCompleteTime: '2024-03-21 14:00:00',
-    activeStatus: 1,
-    taskStage: 2,
-    createTime: '2024-03-19 14:00:00',
-    updateTime: '2024-03-19 16:00:00',
-    isOverdue: 1,
-  },
-];
-const taskExecutionDone = [
-  {
-    id: 1001,
-    taskName: '任务1',
-    selfCheckUnit: '单位1',
-    taskType: '类型1',
-    shouldCompleteTime: '2021-01-01',
-    submitTime: '2021-01-01',
-    activeStatus: 1,
-    taskStage: 0,
-    isOverdue: 1,
-  },
-  {
-    id: 1002,
-    taskName: '任务2',
-    selfCheckUnit: '单位2',
-    taskType: '类型2',
-    shouldCompleteTime: '2021-01-01',
-    submitTime: '2021-01-01',
-    activeStatus: 0,
-    taskStage: 0,
-    isOverdue: 1,
-  },
-];
-
-export default [
-  {
-    url: '/eye_api_bak/api/admin/task/getTaskManagementList',
-    timeout: 1000,
-    method: 'get',
-    response: () => {
-      return resultSuccess(taskManagement);
-    },
-  },
-  {
-    url: '/eye_api_bak/api/admin/task/getTaskManagementItem',
-    timeout: 1000,
-    method: 'get',
-    response: () => {
-      return resultSuccess(taskManagementItem);
-    },
-  },
-  {
-    url: '/eye_api_bak/api/admin/task/getTaskDoingList',
-    timeout: 1000,
-    method: 'get',
-    response: () => {
-      return resultSuccess(taskExecutionDoing);
-    },
-  },
-  {
-    url: '/eye_api_bak/api/admin/task/getTaskDoneList',
-    timeout: 1000,
-    method: 'get',
-    response: () => {
-      return resultSuccess(taskExecutionDone);
-    },
-  },
-];

+ 52 - 0
src/api/disaster-precaution/index.ts

@@ -0,0 +1,52 @@
+import { http } from '@/utils/http/axios';
+import type {
+  TaskManagementListResponse,
+  TaskExecutionListResponse,
+  TaskManagementItemResponse,
+} from '@/types/disaster-precaution';
+/**
+ * 获取任务管理表格数据
+ */
+export function getTaskManagementListData() {
+  return http.request<TaskManagementListResponse[]>(
+    {
+      url: '/admin/task/getTaskManagementList',
+      method: 'get',
+    },
+    {
+      ignoreTargetTenantId: true,
+    },
+  );
+}
+
+/**
+ * 获取任务管理详情
+ */
+export function getTaskManagementItem(id: number) {
+  return http.request<TaskManagementItemResponse>(
+    {
+      url: '/admin/task/getTaskManagementItem',
+      method: 'get',
+      params: {
+        id,
+      },
+    },
+    {
+      ignoreTargetTenantId: true,
+    },
+  );
+}
+/**
+ * 获取任务执行表格数据
+ */
+export function getTaskExecutionListData() {
+  return http.request<TaskExecutionListResponse[]>(
+    {
+      url: '/admin/task/getTaskExecutionList',
+      method: 'get',
+    },
+    {
+      ignoreTargetTenantId: true,
+    },
+  );
+}

+ 0 - 68
src/api/task-execution/tableData.ts

@@ -1,68 +0,0 @@
-import { http } from '@/utils/http/axios';
-import type {
-  TaskExecutionTableData,
-  TaskManagementItemResponse,
-  DoingTaskExecutionTableDataResponse,
-  DoneTaskExecutionTableDataResponse,
-} from '@/types/task-execution/tableData';
-/**
- * 获取任务管理表格数据
- */
-export function getTaskManagementTableData() {
-  return http.request<TaskExecutionTableData[]>(
-    {
-      url: '/admin/task/getTaskManagementList',
-      method: 'get',
-    },
-    {
-      ignoreTargetTenantId: true,
-    },
-  );
-}
-
-/**
- * 获取任务管理详情
- */
-export function getTaskManagementItem(id: number) {
-  return http.request<TaskManagementItemResponse>(
-    {
-      url: '/admin/task/getTaskManagementItem',
-      method: 'get',
-      params: {
-        id,
-      },
-    },
-    {
-      ignoreTargetTenantId: true,
-    },
-  );
-}
-/**
- * 获取任务执行进行中表格数据
- */
-export function getTaskExecutionDoingTableData() {
-  return http.request<DoingTaskExecutionTableDataResponse[]>(
-    {
-      url: '/admin/task/getTaskDoingList',
-      method: 'get',
-    },
-    {
-      ignoreTargetTenantId: true,
-    },
-  );
-}
-
-/**
- * 获取任务执行已完成表格数据
- */
-export function getTaskExecutionDoneTableData() {
-  return http.request<DoneTaskExecutionTableDataResponse[]>(
-    {
-      url: 'admin/task/getTaskDoneList',
-      method: 'get',
-    },
-    {
-      ignoreTargetTenantId: true,
-    },
-  );
-}

+ 2 - 2
src/components/BasicTable.vue

@@ -50,7 +50,7 @@
   const emits = defineEmits<{
     (e: 'update:pageSize', value: number): void;
     (e: 'update:pageNumber', value: number): void;
-    (e: 'update:selectedIds', value: number[]): void;
+    (e: 'update:selection', value: any[]): void;
   }>();
   const handleSizeChange = (value: number) => {
     emits('update:pageSize', value);
@@ -62,7 +62,7 @@
 
   const handleSelectionChange = (selection: any[]) => {
     selectedIds.value = selection.map((item) => item.id);
-    emits('update:selectedIds', selectedIds.value);
+    emits('update:selection', selection);
   };
   defineExpose({
     selectedIds,

+ 31 - 0
src/types/disaster-precaution/index.ts

@@ -0,0 +1,31 @@
+import type { UserInfo } from '@/types/push-object';
+interface BasicResponse {
+  id: number;
+  taskName: string;
+  selfCheckUnit: string;
+  taskType: number;
+  shouldCompleteTime: string;
+  taskStage: number;
+  isOverdue: number;
+}
+
+interface checkUser {
+  checkUser: UserInfo[];
+}
+
+export interface TaskManagementListResponse extends BasicResponse {
+  activeStatus: number;
+}
+
+export interface TaskExecutionListResponse extends BasicResponse, checkUser {}
+
+export interface TaskManagementItemResponse
+  extends checkUser,
+    Omit<TaskManagementListResponse, 'selfCheckUnit' | 'taskStage' | 'isOverdue' | 'activeStatus' | 'taskType'> {
+  taskType: number | null;
+  selfCheckUnit: string[] | string;
+  checkRequirement: string;
+  createUser: string;
+  isPush: boolean | null;
+  taskTemplate: number | null;
+}

+ 0 - 22
src/types/task-execution/tableData.ts

@@ -1,22 +0,0 @@
-import type { TaskManagementRuleForm } from '@/views/disaster/disaster-precaution/src/type';
-export interface TaskExecutionTableData {
-  id: number;
-  taskName: string;
-  selfCheckUnit: string;
-  taskType: number | null;
-  shouldCompleteTime: string;
-  activeStatus: number;
-  taskStage: number;
-  isOverdue: number;
-}
-
-export interface TaskManagementItemResponse extends TaskManagementRuleForm {
-  id: number;
-}
-export interface DoingTaskExecutionTableDataResponse extends TaskExecutionTableData {
-  createTime: string;
-  updateTime: string;
-}
-export interface DoneTaskExecutionTableDataResponse extends TaskExecutionTableData {
-  submitTime: string;
-}

+ 7 - 1
src/views/disaster/WorkRecord.md

@@ -20,4 +20,10 @@
 - [x] search引用配置项来开发
 - [x] form引用配置来开发
 - [x] 预警信息做添加页面,将表单数据进行拆分(通用项和定制项)
-- [x] 完成灾害预警模块
+- [x] 完成灾害预警模块
+
+### 25/5/16
+### 预防检查模块
+- [x] 任务管理静态页面完成
+- [x] 任务模板页面完成
+- [ ] 任务执行页面完成

+ 8 - 1
src/views/disaster/components/User.vue

@@ -124,7 +124,14 @@
   };
   const emit = defineEmits(['cancel', 'submit']);
   const handleSubmit = () => {
-    emit('submit', selectedPersonList.value);
+    const userList = selectedPersonList.value.map((item) => {
+      return {
+        id: item.id,
+        username: item.name.split('-')[0],
+        realname: item.name.split('-')[1],
+      };
+    });
+    emit('submit', userList);
     emit('cancel');
   };
   watch(

+ 127 - 21
src/views/disaster/disaster-precaution/PageTaskExecution.vue

@@ -2,35 +2,141 @@
   <div class="disaster-precaution-container">
     <header class="disaster-precaution-container__header">
       <span class="disaster-precaution-container__title">检查任务执行</span>
-      <el-tabs v-model="activeName">
-        <el-tab-pane label="待执行任务" name="doing" />
-        <el-tab-pane label="已提交任务" name="done" />
-      </el-tabs>
     </header>
     <main class="disaster-precaution-container__main">
-      <component :is="dynamicComponent" />
+      <div class="disaster-precaution">
+        <header class="disaster-precaution__header">
+          <Search
+            :searchConfig="TASK_EXECUTION_SEARCH_CONFIG"
+            :searchData="searchData"
+            @update:searchData="handleSearch"
+          />
+        </header>
+        <BasicTable
+          :table-config="tableConfig"
+          :table-data="tableData"
+          @update:pageSize="handleSizeChange"
+          @update:pageNumber="handleCurrentChange"
+        >
+          <template #taskName="scope">
+            <div class="task-name--div">
+              <el-tooltip :content="scope.row.taskName" placement="top" effect="light">
+                <span>{{ scope.row.taskName }}</span>
+              </el-tooltip>
+              <img :src="OverdueIcon" alt="overdue" v-if="scope.row.isOverdue === OVERDUE_STATUS.OVERDUE" />
+            </div>
+          </template>
+          <template #taskType="scope">
+            <span>{{ TASK_TYPE_MAP[scope.row.taskType] }}</span>
+          </template>
+          <template #taskStage="scope">
+            <span>{{ TASK_STAGE_MAP[scope.row.taskStage] }}</span>
+          </template>
+          <!-- action button 不仅分任务情况 还要分 人物权限 -->
+          <template #action="scope">
+            <!-- 检查任务操作入口 -->
+            <div class="action-container" v-if="scope.row.taskStage === TASK_STAGE.PENDING_CHECK">
+              <ActionButton text="去检查" />
+              <!-- 仅检查责任人可以看到 -->
+              <ActionButton text="添加检查人" @click="handleAddCheckUser(scope.row)" />
+            </div>
+            <!-- 审批任务操作入口 -->
+            <div class="action-container" v-else-if="scope.row.taskStage === TASK_STAGE.PENDING_APPROVAL">
+              <!-- 审批人员可以看到 -->
+              <ActionButton text="去审批" />
+              <!-- 检查责任人、检查执行人员可以看到 -->
+              <ActionButton
+                text="撤回"
+                :popconfirm="{
+                  title: '确定撤回吗?',
+                }"
+              />
+            </div>
+            <!-- 完成任务操作入口 -->
+            <div class="action-container" v-else-if="scope.row.taskStage === TASK_STAGE.COMPLETED">
+              <ActionButton text="查看" />
+              <!-- 仅审批人员可以看到 -->
+              <ActionButton
+                text="撤回"
+                :popconfirm="{
+                  title: '确定撤回吗?',
+                }"
+              />
+            </div>
+          </template>
+        </BasicTable>
+      </div>
     </main>
+    <el-dialog
+      v-model="userInfo"
+      title="添加人员"
+      align-center
+      :close-on-click-modal="false"
+      :destroy-on-close="true"
+      class="customDialog--pushObject"
+    >
+      <User :customUserList="currentRow?.checkUser || []" @cancel="userInfo = false" @submit="handleSubmit"/>
+    </el-dialog>
   </div>
 </template>
 
-<script lang="ts" setup>
-  import { ref, computed } from 'vue';
-  import { defineAsyncComponent } from 'vue';
-  const activeName = ref('doing');
-  const dynamicComponent = computed(() => {
-    if (activeName.value === 'doing') {
-      return defineAsyncComponent(() => import('./src/components/TaskExecutionDoing.vue'));
-    }
-    return defineAsyncComponent(() => import('./src/components/TaskExecutionDone.vue'));
+<script setup lang="ts">
+  import { ref, onMounted, reactive } from 'vue';
+  import BasicTable from '@/components/BasicTable.vue';
+  import ActionButton from '@/components/ActionButton.vue';
+  import Search from '@/views/disaster/components/Search.vue';
+  import useTableConfig from '@/hooks/useTableConfigHook';
+  import { getTaskExecutionListData } from '@/api/disaster-precaution';
+  import type { TaskExecutionListResponse } from '@/types/disaster-precaution';
+  import OverdueIcon from '@/assets/svg/overdue.svg';
+  import { TASK_STAGE } from './src/constants/task-execution';
+  import { OVERDUE_STATUS, TASK_TYPE_MAP, TASK_STAGE_MAP } from './src/constants/task-execution';
+  import { TABLE_OPTIONS_EXECUTION, TASK_EXECUTION_TABLE_COLUMNS, TASK_EXECUTION_SEARCH_CONFIG } from './src/config';
+  import User from '@/views/disaster/components/User.vue';
+  import type { UserInfo } from '@/types/push-object';
+
+  const userInfo = ref(false);
+  const searchData = reactive({
+    taskType: '',
+    taskStage: '',
+  });
+  const handleSearch = (data: any) => {
+    console.log(data);
+    getTableData();
+  };
+
+  const tableData = ref<TaskExecutionListResponse[]>([]);
+  const { tableConfig, pagination } = useTableConfig(TASK_EXECUTION_TABLE_COLUMNS, TABLE_OPTIONS_EXECUTION);
+  const handleSizeChange = (value: number) => {
+    pagination.pageSize = value;
+    getTableData();
+  };
+  const handleCurrentChange = (value: number) => {
+    pagination.pageNumber = value;
+    getTableData();
+  };
+  const currentRow = ref<TaskExecutionListResponse>();
+  const handleAddCheckUser = (row: TaskExecutionListResponse) => {
+    currentRow.value = row;
+    userInfo.value = true;
+  };
+  const handleSubmit = (userList: UserInfo[]) => {
+    const currentIndex = tableData.value.findIndex((item) => item.id === currentRow.value?.id);
+    tableData.value[currentIndex].checkUser = userList;
+  };
+  const getTableData = async () => {
+    tableConfig.loading = true;
+    const res = await getTaskExecutionListData();
+    tableData.value = res;
+    pagination.total = tableData.value.length;
+    tableConfig.loading = false;
+  };
+  onMounted(() => {
+    getTableData();
   });
 </script>
 
-<style lang="scss" scoped>
+<style scoped lang="scss">
   @use '../style/disaster.scss' as *;
-  .disaster-precaution-container__header {
-    padding: 16cpx 0 0 22cpx !important;
-  }
-  :deep(.el-tabs__header) {
-    margin: 0;
-  }
+  @use './src/style/task-execution.scss' as *;
 </style>

+ 93 - 19
src/views/disaster/disaster-precaution/PageTaskManagement.vue

@@ -14,19 +14,22 @@
             :searchData="searchData"
             @update:searchData="handleSearch"
           />
-          <div
-            style="width: 100%; height: 20px; background-color: red; margin-top: 20px"
-            v-show="selectedIds.length > 0"
-          >
-            <span>{{ selectedIds.length }}项</span>
+          <div class="batch-operation--div fadeIn" v-show="selectionItems.length > 0">
+            <span>已选{{ selectionItems.length }}项</span>
+            <div class="batch-operation--div--button">
+              <el-button type="success" v-show="isBatchPublish" @click="handleBatchPublish">批量发布</el-button>
+              <el-button type="primary" v-show="isBatchWithdraw" @click="handleBatchWithdraw">批量撤回</el-button>
+              <el-button type="danger" @click="handleBatchDelete">批量删除</el-button>
+            </div>
           </div>
         </header>
         <BasicTable
+          ref="basicTableRef"
           :table-config="tableConfig"
           :table-data="tableData"
           @update:pageSize="handleSizeChange"
           @update:pageNumber="handleCurrentChange"
-          @update:selectedIds="handleSelectedIds"
+          @update:selection="handleSelectionChange"
         >
           <template #taskName="scope">
             <div class="task-name--div">
@@ -87,18 +90,25 @@
 </template>
 
 <script setup lang="ts">
-  import { ref, onMounted, reactive } from 'vue';
+  import { ref, onMounted, reactive, watch } from 'vue';
   import { Plus } from '@element-plus/icons-vue';
   import BasicTable from '@/components/BasicTable.vue';
   import ActionButton from '@/components/ActionButton.vue';
   import Search from '@/views/disaster/components/Search.vue';
   import useTableConfig from '@/hooks/useTableConfigHook';
-  import { getTaskManagementTableData } from '@/api/task-execution/tableData';
-  import type { TaskExecutionTableData } from '@/types/task-execution/tableData';
+  import { getTaskManagementListData } from '@/api/disaster-precaution';
+  import type { TaskManagementListResponse } from '@/types/disaster-precaution';
   import OverdueIcon from '@/assets/svg/overdue.svg';
+  import { ElMessageBox, ElMessage } from 'element-plus';
   import { OVERDUE_STATUS, TASK_TYPE_MAP, TASK_STAGE_MAP } from './src/constants/task-execution';
   import { ACTIVE_STATUS, ACTIVE_STATUS_COLOR, ACTIVE_STATUS_MAP } from '@/views/disaster/constant';
-  import { TABLE_OPTIONS, TASK_MANAGEMENT_TABLE_COLUMNS, TASK_MANAGEMENT_SEARCH_CONFIG } from './src/config';
+  import {
+    TABLE_OPTIONS_MANAGEMENT,
+    TASK_MANAGEMENT_TABLE_COLUMNS,
+    TASK_MANAGEMENT_SEARCH_CONFIG,
+    TABLE_MANAGEMENT_HEIGHT_DEFAULT,
+    TABLE_MANAGEMENT_HEIGHT_BATCH_OPERATION,
+  } from './src/config';
   import { useRouter } from 'vue-router';
   const router = useRouter();
   const searchData = reactive({
@@ -108,12 +118,56 @@
   });
   const handleSearch = (data: any) => {
     console.log(data);
+    getTableData();
+  };
+  const selectionItems = ref<any[]>([]);
+  const isBatchPublish = ref(false);
+  const isBatchWithdraw = ref(false);
+  const getSelectionIds = (option: ACTIVE_STATUS) => {
+    return selectionItems.value.filter((item) => item.activeStatus === option).map((item) => item.id);
+  };
+  const handleSelectionChange = (selection: any[]) => {
+    selectionItems.value = selection;
+    const publishIds = getSelectionIds(ACTIVE_STATUS.NOT_EFFECTIVE);
+    isBatchPublish.value = Boolean(publishIds.length);
+    const withdrawIds = getSelectionIds(ACTIVE_STATUS.ACTIVE);
+    isBatchWithdraw.value = Boolean(withdrawIds.length);
+  };
+  const openMessageBox = (title: string) => {
+    return ElMessageBox.confirm('', title, {
+      confirmButtonText: '确定',
+      cancelButtonText: '取消',
+    })
+      .then(() => {
+        return true;
+      })
+      .catch(() => {
+        return false;
+      });
+  };
+  const handleBatchPublish = async () => {
+    const confirmed = await openMessageBox('确认发布任务吗?');
+    if (!confirmed) return;
+    const publishIds = getSelectionIds(ACTIVE_STATUS.NOT_EFFECTIVE);
+    ElMessage.success('批量发布成功');
+    getTableData();
   };
-  const selectedIds = ref<number[]>([]);
-  const handleSelectedIds = (ids: number[]) => {
-    selectedIds.value = ids;
-    console.log(ids);
+  const handleBatchWithdraw = async () => {
+    const confirmed = await openMessageBox('确认撤回已发布任务吗?');
+    if (!confirmed) return;
+    const withdrawIds = getSelectionIds(ACTIVE_STATUS.ACTIVE);
+    ElMessage.success('批量撤回成功');
+    getTableData();
+  };
+  const basicTableRef = ref<InstanceType<typeof BasicTable>>();
+  const handleBatchDelete = async () => {
+    const confirmed = await openMessageBox('删除后任务不可恢复,确认删除吗?');
+    if (!confirmed) return;
+    const deleteIds = getSelectionIds(ACTIVE_STATUS.NOT_EFFECTIVE);
+    ElMessage.success('批量删除成功');
+    getTableData();
   };
+
   const defaultPath = '/disaster-prevention/disaster-precaution/task-item';
   const handleCreateTask = () => {
     router.push({
@@ -135,20 +189,19 @@
       query: { id },
     });
   };
-  const tableData = ref<TaskExecutionTableData[]>([]);
-  const { tableConfig, pagination } = useTableConfig(TASK_MANAGEMENT_TABLE_COLUMNS, TABLE_OPTIONS);
+  const tableData = ref<TaskManagementListResponse[]>([]);
+  const { tableConfig, pagination } = useTableConfig(TASK_MANAGEMENT_TABLE_COLUMNS, TABLE_OPTIONS_MANAGEMENT);
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const handleCurrentChange = (value: number) => {
     pagination.pageNumber = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const getTableData = async () => {
-    const res = await getTaskManagementTableData();
+    tableConfig.loading = true;
+    const res = await getTaskManagementListData();
     tableData.value = res;
     pagination.total = tableData.value.length;
     tableConfig.loading = false;
@@ -156,9 +209,30 @@
   onMounted(() => {
     getTableData();
   });
+  watch(
+    () => selectionItems.value.length,
+    (newLength) => {
+      if (newLength > 0) {
+        tableConfig.height = TABLE_MANAGEMENT_HEIGHT_BATCH_OPERATION;
+      } else {
+        tableConfig.height = TABLE_MANAGEMENT_HEIGHT_DEFAULT;
+      }
+    },
+  );
 </script>
 
 <style scoped lang="scss">
   @use '../style/disaster.scss' as *;
   @use './src/style/task-execution.scss' as *;
+  .batch-operation--div {
+    @include flex-center;
+    justify-content: flex-start;
+    gap: 60cpx;
+    width: 100%;
+    height: 54cpx;
+    border: 4cpx;
+    padding: 16cpx 25cpx;
+    background-color: #ddefff;
+    margin-top: 20cpx;
+  }
 </style>

+ 2 - 20
src/views/disaster/disaster-precaution/PageTaskTemplateDetail.vue

@@ -5,10 +5,7 @@
       <span class="disaster-precaution-container__title">{{ name }}</span>
     </header>
     <main class="disaster-precaution-container__main">
-      <div class="template-container">
-        <span class="title">被检查(自查)单位名称:</span>
-        <TemplateTableMerge :operation-type="operationType" :main-table="data!" height="62vh" />
-      </div>
+      <TemplateTableMerge :operation-type="operationType" :main-table="data!" height="calc(70vh - 40px)" />
     </main>
   </div>
 </template>
@@ -36,25 +33,10 @@
 </script>
 
 <style lang="scss" scoped>
-    @use '../style/disaster.scss' as *;
-  .back-icon {
-    width: 16cpx;
-    cursor: pointer;
-  }
+  @use '../style/disaster.scss' as *;
   .disaster-precaution-container__header {
     flex-direction: row !important;
     justify-content: flex-start !important;
     gap: 8cpx !important;
   }
-  .template-container {
-    display: flex;
-    flex-direction: column;
-    gap: 16cpx;
-    width: 100%;
-    height: 100%;
-    .title {
-      font-size: 14cpx;
-      color: rgba(0, 0, 0, 0.85);
-    }
-  }
 </style>

+ 1 - 0
src/views/disaster/disaster-precaution/src/components/Compliance.vue

@@ -19,6 +19,7 @@
   const radioOptions = [
     { label: '符合', value: 1 },
     { label: '不符合', value: 0 },
+    { label: '不涉及', value: 2 },
   ];
   const props = defineProps<{
     radioValue: number;

+ 4 - 11
src/views/disaster/disaster-precaution/src/components/CreateTaskItem.vue

@@ -50,14 +50,13 @@
 <script setup lang="ts">
   import BasicForm from '@/components/BasicForm.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
-  import { TASK_MANAGEMENT_FROM_CONFIG, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
+  import { TASK_MANAGEMENT_FROM_CONFIG_CREATE, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
   import { onMounted, ref } from 'vue';
   import { TaskManagementRuleForm } from '../type';
   import { TASK_TYPE_OPTIONS } from '../constants/task-execution';
   import { TASK_TEMPLATE_LIST } from '../constants/template-detail';
   import User from '@/views/disaster/components/User.vue';
   import type { UserInfo } from '@/types/push-object';
-  import type { TreeNodeData } from '@/views/disaster/types';
 
   const userInfo = ref(false);
   const userOptions = ref<UserInfo[]>([]);
@@ -69,19 +68,13 @@
 
   const { ruleFormConfig, ruleFormData, formRules, cloneRuleFormData, beforeRouteLeave } =
     useFormConfigHook<TaskManagementRuleForm>(
-      TASK_MANAGEMENT_FROM_CONFIG,
+      TASK_MANAGEMENT_FROM_CONFIG_CREATE,
       TASK_MANAGEMENT_FROM_DATA,
       TASK_MANAGEMENT_FROM_RULES,
     );
 
-  const handleSubmit = (selectedPersonList: TreeNodeData[]) => {
-    ruleFormData.checkUser = selectedPersonList.map((user) => {
-      return {
-        id: user.id,
-        username: user.name.split('-')[0],
-        realname: user.name.split('-')[1],
-      };
-    });
+  const handleSubmit = (selectedPersonList: UserInfo[]) => {
+    ruleFormData.checkUser = selectedPersonList;
     userOptions.value = ruleFormData.checkUser;
   };
 

+ 5 - 12
src/views/disaster/disaster-precaution/src/components/EditTaskItem.vue

@@ -51,14 +51,13 @@
   import BasicForm from '@/components/BasicForm.vue';
   import User from '@/views/disaster/components/User.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
-  import { TASK_MANAGEMENT_FROM_CONFIG, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
+  import { TASK_MANAGEMENT_FROM_CONFIG_EDIT, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
   import { onMounted, ref } from 'vue';
   import { TaskManagementRuleForm } from '../type';
   import { TASK_TYPE_OPTIONS } from '../constants/task-execution';
   import { TASK_TEMPLATE_LIST } from '../constants/template-detail';
-  import { getTaskManagementItem } from '@/api/task-execution/tableData';
+  import { getTaskManagementItem } from '@/api/disaster-precaution';
   import type { UserInfo } from '@/types/push-object';
-  import type { TreeNodeData } from '@/views/disaster/types';
 
   const props = defineProps<{
     id: number;
@@ -75,19 +74,13 @@
 
   const { ruleFormConfig, ruleFormData, formRules,cloneRuleFormData, beforeRouteLeave } =
     useFormConfigHook<TaskManagementRuleForm>(
-      TASK_MANAGEMENT_FROM_CONFIG,
+      TASK_MANAGEMENT_FROM_CONFIG_EDIT,
       TASK_MANAGEMENT_FROM_DATA,
       TASK_MANAGEMENT_FROM_RULES,
     );
 
-  const handleSubmit = (selectedPersonList: TreeNodeData[]) => {
-    ruleFormData.checkUser = selectedPersonList.map((user) => {
-      return {
-        id: user.id,
-        username: user.name.split('-')[0],
-        realname: user.name.split('-')[1],
-      };
-    });
+  const handleSubmit = (selectedPersonList: UserInfo[]) => {
+    ruleFormData.checkUser = selectedPersonList;
     userOptions.value = ruleFormData.checkUser;
   };
 

+ 0 - 59
src/views/disaster/disaster-precaution/src/components/Search.vue

@@ -1,59 +0,0 @@
-<template>
-  <div class="search-box">
-    <section class="select-box">
-      <div class="select-box--item">
-        <span>检查类型:</span>
-        <el-select v-model="selectTaskType" placeholder="请选择检查类型">
-          <el-option v-for="item in TASK_TYPE_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
-        </el-select>
-      </div>
-      <div class="select-box--item">
-        <span>生效状态:</span>
-        <el-select v-model="selectActiveStatus" placeholder="请选择生效状态">
-          <el-option v-for="item in ACTIVE_STATUS_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
-        </el-select>
-      </div>
-      <div class="select-box--item">
-        <span>任务阶段:</span>
-        <el-select v-model="selectTaskStage" placeholder="请选择任务阶段">
-          <el-option v-for="item in TASK_STAGE_OPTIONS" :key="item.value" :label="item.label" :value="item.value" />
-        </el-select>
-      </div>
-    </section>
-    <section class="search-btn">
-      <el-button type="primary">查询</el-button>
-      <el-button>重置</el-button>
-    </section>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, computed } from 'vue';
-  import {
-    TASK_TYPE_OPTIONS,
-    TASK_STAGE_OPTIONS_DOING,
-    TASK_STAGE_OPTIONS_DONE,
-    TASK_STAGE_OPTIONS_MANAGEMENT,
-  } from '../constants/task-execution';
-  import { ACTIVE_STATUS_OPTIONS_DEFAULT, ACTIVE_STATUS_OPTIONS_MANAGEMENT } from '@/views/disaster/constant';
-  const selectTaskType = ref('');
-  const selectActiveStatus = ref('');
-  const selectTaskStage = ref('');
-  const props = defineProps<{
-    type: 'doing' | 'done' | 'management';
-  }>();
-  const ACTIVE_STATUS_OPTIONS = computed(() => {
-    return props.type === 'management' ? ACTIVE_STATUS_OPTIONS_MANAGEMENT : ACTIVE_STATUS_OPTIONS_DEFAULT;
-  });
-  const TASK_STAGE_OPTIONS = computed(() => {
-    return props.type === 'management'
-      ? TASK_STAGE_OPTIONS_MANAGEMENT
-      : props.type === 'doing'
-      ? TASK_STAGE_OPTIONS_DOING
-      : TASK_STAGE_OPTIONS_DONE;
-  });
-</script>
-
-<style lang="scss" scoped>
-  @use '@/views/disaster/style/search.scss' as *;
-</style>

+ 0 - 126
src/views/disaster/disaster-precaution/src/components/TaskExecutionDoing.vue

@@ -1,126 +0,0 @@
-<template>
-  <div class="disaster-precaution">
-    <header class="disaster-precaution__header">
-      <Search type="doing" />
-    </header>
-    <BasicTable
-      :table-config="tableConfig"
-      :table-data="tableData"
-      @update:pageSize="handleSizeChange"
-      @update:pageNumber="handleCurrentChange"
-    >
-      <template #taskName="scope">
-        <div class="task-name--div">
-          <el-tooltip :content="scope.row.taskName" placement="top" effect="light">
-            <span>{{ scope.row.taskName }}</span>
-          </el-tooltip>
-          <img :src="OverdueIcon" alt="overdue" v-if="scope.row.isOverdue === OVERDUE_STATUS.OVERDUE" />
-        </div>
-      </template>
-      <template #activeStatus="scope">
-        <div class="active-status--div">
-          <div
-            class="dot"
-            :style="{ backgroundColor: ACTIVE_STATUS_COLOR[scope.row.activeStatus as ACTIVE_STATUS] }"
-          ></div>
-          <span>{{ ACTIVE_STATUS_MAP[scope.row.activeStatus] }}</span>
-        </div>
-      </template>
-      <template #taskStage="scope">
-        <span>{{ TASK_STAGE_MAP[scope.row.taskStage] }}</span>
-      </template>
-      <template #action="scope">
-        <ActionButton
-          :text="TASK_STAGE_ACTION_TEXT[scope.row.taskStage]"
-          :disabled="scope.row.activeStatus === ACTIVE_STATUS.INACTIVE"
-        />
-      </template>
-    </BasicTable>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { onMounted, ref } from 'vue';
-  import BasicTable from '@/components/BasicTable.vue';
-  import ActionButton from '@/components/ActionButton.vue';
-  import Search from './Search.vue';
-  import type { TableColumnProps } from '@/types/basic-table';
-  import useTableConfig from '@/hooks/useTableConfigHook';
-  import { TASK_STAGE_MAP, TASK_STAGE_ACTION_TEXT, OVERDUE_STATUS } from '../constants/task-execution';
-  import { ACTIVE_STATUS, ACTIVE_STATUS_MAP, ACTIVE_STATUS_COLOR } from '@/views/disaster/constant';
-  import { getTaskExecutionDoingTableData } from '@/api/task-execution/tableData';
-  import type { DoingTaskExecutionTableDataResponse } from '@/types/task-execution/tableData';
-  import OverdueIcon from '@/assets/svg/overdue.svg';
-  const tableData = ref<DoingTaskExecutionTableDataResponse[]>([]);
-  const columns: TableColumnProps[] = [
-    {
-      prop: 'taskName',
-      label: '任务名称',
-      align: 'center',
-      slot: 'taskName',
-    },
-    {
-      prop: 'selfCheckUnit',
-      label: '自查/被检查单位',
-      align: 'center',
-    },
-    {
-      prop: 'taskType',
-      label: '检查类型',
-      align: 'center',
-    },
-    {
-      prop: 'shouldCompleteTime',
-      label: '应完成时间',
-      align: 'center',
-    },
-    {
-      prop: 'activeStatus',
-      label: '生效状态',
-      align: 'center',
-      slot: 'activeStatus',
-    },
-    {
-      prop: 'taskStage',
-      label: '任务阶段',
-      align: 'center',
-      slot: 'taskStage',
-    },
-    {
-      prop: 'action',
-      label: '操作',
-      align: 'center',
-      slot: 'action',
-    },
-  ];
-  const options = {
-    emptyText: '暂无数据',
-    height: '60vh',
-    loading: true,
-    stripe: true,
-  };
-  const { tableConfig, pagination } = useTableConfig(columns, options);
-  const handleSizeChange = (value: number) => {
-    pagination.pageSize = value;
-    tableConfig.loading = true;
-    getTableData();
-  };
-  const handleCurrentChange = (value: number) => {
-    pagination.pageNumber = value;
-    tableConfig.loading = true;
-    getTableData();
-  };
-  const getTableData = async () => {
-    const res = await getTaskExecutionDoingTableData();
-    tableData.value = res;
-    pagination.total = tableData.value.length;
-    tableConfig.loading = false;
-  };
-  onMounted(() => {
-    getTableData();
-  });
-</script>
-
-<style lang="scss" scoped>
-  @use '../style/task-execution.scss' as *;
-</style>

+ 0 - 141
src/views/disaster/disaster-precaution/src/components/TaskExecutionDone.vue

@@ -1,141 +0,0 @@
-<template>
-  <div class="disaster-precaution">
-    <header class="disaster-precaution__header">
-      <Search type="done" />
-    </header>
-    <BasicTable
-      :table-config="tableConfig"
-      :table-data="tableData"
-      @update:pageSize="handleSizeChange"
-      @update:pageNumber="handleCurrentChange"
-    >
-      <template #taskName="scope">
-        <div class="task-name--div">
-          <el-tooltip :content="scope.row.taskName" placement="top" effect="light">
-            <span>{{ scope.row.taskName }}</span>
-          </el-tooltip>
-          <img :src="OverdueIcon" alt="overdue" v-if="scope.row.isOverdue === OVERDUE_STATUS.OVERDUE" />
-        </div>
-      </template>
-      <template #activeStatus="scope">
-        <div class="active-status--div">
-          <div
-            class="dot"
-            :style="{ backgroundColor: ACTIVE_STATUS_COLOR[scope.row.activeStatus as ACTIVE_STATUS] }"
-          ></div>
-          <span>{{ ACTIVE_STATUS_MAP[scope.row.activeStatus] }}</span>
-        </div>
-      </template>
-      <template #taskStage="scope">
-        <span>{{ TASK_STAGE_MAP[scope.row.taskStage] }}</span>
-      </template>
-      <template #action="scope">
-        <ActionButton text="查看" />
-        <ActionButton
-          text="撤回"
-          :popconfirm="{
-            title: '是否撤回提交?',
-          }"
-          @confirm="handleWithdraw(scope.row)"
-          v-if="scope.row.taskStage !== TASK_STAGE.COMPLETED && scope.row.activeStatus === ACTIVE_STATUS.ACTIVE"
-        />
-      </template>
-    </BasicTable>
-  </div>
-</template>
-
-<script lang="ts" setup>
-  import { ref, onMounted } from 'vue';
-  import BasicTable from '@/components/BasicTable.vue';
-  import ActionButton from '@/components/ActionButton.vue';
-  import Search from './Search.vue';
-  import type { TableColumnProps } from '@/types/basic-table';
-  import useTableConfig from '@/hooks/useTableConfigHook';
-  import { TASK_STAGE, TASK_STAGE_MAP, OVERDUE_STATUS } from '../constants/task-execution';
-  import { ACTIVE_STATUS, ACTIVE_STATUS_MAP, ACTIVE_STATUS_COLOR } from '@/views/disaster/constant';
-  import type { DoneTaskExecutionTableDataResponse } from '@/types/task-execution/tableData';
-  import { getTaskExecutionDoneTableData } from '@/api/task-execution/tableData';
-  const tableData = ref<DoneTaskExecutionTableDataResponse[]>([]);
-  import OverdueIcon from '@/assets/svg/overdue.svg';
-  const columns: TableColumnProps[] = [
-    {
-      prop: 'taskName',
-      label: '任务名称',
-      align: 'center',
-      slot: 'taskName',
-    },
-    {
-      prop: 'selfCheckUnit',
-      label: '被检查(自查)单位',
-      align: 'center',
-    },
-    {
-      prop: 'taskType',
-      label: '检查类型',
-      align: 'center',
-    },
-    {
-      prop: 'shouldCompleteTime',
-      label: '应完成时间',
-      align: 'center',
-    },
-    {
-      prop: 'submitTime',
-      label: '提交时间',
-      align: 'center',
-    },
-    {
-      prop: 'activeStatus',
-      label: '生效状态',
-      align: 'center',
-      slot: 'activeStatus',
-    },
-    {
-      prop: 'taskStage',
-      label: '任务阶段',
-      align: 'center',
-      slot: 'taskStage',
-    },
-    {
-      prop: 'action',
-      label: '操作',
-      align: 'center',
-      slot: 'action',
-      width: '130cpx',
-      fixed: 'right',
-    },
-  ];
-  const options = {
-    emptyText: '暂无数据',
-    height: '60vh',
-    loading: true,
-    stripe: true,
-  };
-  const { tableConfig, pagination } = useTableConfig(columns, options);
-  const handleSizeChange = (value: number) => {
-    pagination.pageSize = value;
-    tableConfig.loading = true;
-    getTableData();
-  };
-  const handleCurrentChange = (value: number) => {
-    pagination.pageNumber = value;
-    tableConfig.loading = true;
-    getTableData();
-  };
-  const getTableData = async () => {
-    const res = await getTaskExecutionDoneTableData();
-    tableData.value = res;
-    pagination.total = tableData.value.length;
-    tableConfig.loading = false;
-  };
-  const handleWithdraw = (row: any) => {
-    console.log(row);
-  };
-  onMounted(() => {
-    getTableData();
-  });
-</script>
-
-<style lang="scss" scoped>
-  @use '../style/task-execution.scss' as *;
-</style>

+ 7 - 28
src/views/disaster/disaster-precaution/src/components/TemplateTableMerge.vue

@@ -28,19 +28,6 @@
                 v-show="operationType === 'edit'"
               />
             </div>
-
-            <div v-if="scope.row.footerType === 'reviewResult'" class="inspection-result--div">
-              <span>复查结论:</span>
-              <el-input
-                v-model="scope.row.reviewResult"
-                maxlength="200"
-                style="width: 100%"
-                placeholder="必填,输入复查结论,1-200字"
-                type="textarea"
-                :rows="2"
-                v-show="operationType === 'edit'"
-              />
-            </div>
           </template>
 
           <!-- 底部表格内容 - 第二列 -->
@@ -82,7 +69,12 @@
   import { ref, computed, onMounted } from 'vue';
   import type { SpanTableData, MainRow, MergedRow } from '../type';
   import { formatSpanTableData } from '../utils/format-data';
-  import { TASK_TEMPLATE_HEADER, TASK_TEMPLATE_FOOTER, TASK_TEMPLATE_MAIN_COLUMNS, MERGE_FIELDS } from '../constants/template-detail';
+  import {
+    TASK_TEMPLATE_HEADER,
+    TASK_TEMPLATE_FOOTER,
+    TASK_TEMPLATE_MAIN_COLUMNS,
+    MERGE_FIELDS,
+  } from '../constants/template-detail';
   import Compliance from './Compliance.vue';
   import ActualSituation from './ActualSituation.vue';
 
@@ -104,11 +96,6 @@
         rowType: 'footer' as const,
         footerType: 'inspectionAndSelftest' as const, // 合并为一行
       },
-      {
-        ...TASK_TEMPLATE_FOOTER[0],
-        rowType: 'footer' as const,
-        footerType: 'reviewResult' as const,
-      },
     ];
 
     return [...formattedMainData, ...footerData];
@@ -171,8 +158,6 @@
         if (row.footerType === 'inspectionAndSelftest') {
           // 第一个单元格占据左半部分
           return { rowspan: 1, colspan: 3 };
-        } else if (row.footerType === 'reviewResult') {
-          return { rowspan: 1, colspan: 6 };
         }
       } else if (column.property === 'checkStandard' && row.footerType === 'inspectionAndSelftest') {
         // 第二个单元格占据右半部分
@@ -219,9 +204,6 @@
     if (row.footerType === 'inspectionAndSelftest') {
       return 'sticky-footer-inspection';
     }
-    if (row.footerType === 'reviewResult') {
-      return 'sticky-footer-review';
-    }
     return;
   };
 
@@ -262,11 +244,8 @@
   }
 
   :deep(.sticky-footer-inspection) {
-    @extend .sticky-footer;
-    bottom: 107cpx;
-  }
-  :deep(.sticky-footer-review) {
     @extend .sticky-footer;
     bottom: 0;
+    box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1);
   }
 </style>

+ 4 - 4
src/views/disaster/disaster-precaution/src/components/ViewTaskItem.vue

@@ -39,12 +39,12 @@
 <script setup lang="ts">
   import BasicForm from '@/components/BasicForm.vue';
   import { useFormConfigHook } from '@/hooks/useFormConfigHook';
-  import { TASK_MANAGEMENT_FROM_CONFIG, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
+  import { TASK_MANAGEMENT_FROM_CONFIG_EDIT, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from '../config';
   import { onMounted, ref } from 'vue';
   import { TaskManagementRuleForm } from '../type';
   import { TASK_TYPE_OPTIONS } from '../constants/task-execution';
   import { TASK_TEMPLATE_LIST } from '../constants/template-detail';
-  import { getTaskManagementItem } from '@/api/task-execution/tableData';
+  import { getTaskManagementItem } from '@/api/disaster-precaution';
   import type { UserInfo } from '@/types/push-object';
   import { cloneDeep } from 'lodash-es';
 
@@ -59,7 +59,7 @@
     ruleFormData.taskTemplate = taskType;
   };
 
-  const TASK_MANAGEMENT_FROM_CONFIG_DISABLED = cloneDeep(TASK_MANAGEMENT_FROM_CONFIG).map((item) => {
+  const TASK_MANAGEMENT_FROM_CONFIG_VIEW = cloneDeep(TASK_MANAGEMENT_FROM_CONFIG_EDIT).map((item) => {
     if (item.componentProps) {
       item.componentProps = { ...item.componentProps, disabled: true };
     }
@@ -67,7 +67,7 @@
   });
 
   const { ruleFormConfig, ruleFormData, cloneRuleFormData } = useFormConfigHook<TaskManagementRuleForm>(
-    TASK_MANAGEMENT_FROM_CONFIG_DISABLED,
+    TASK_MANAGEMENT_FROM_CONFIG_VIEW,
     TASK_MANAGEMENT_FROM_DATA,
     TASK_MANAGEMENT_FROM_RULES,
   );

+ 71 - 30
src/views/disaster/disaster-precaution/src/config/form.ts

@@ -3,9 +3,10 @@
  */
 import type { FormConfig } from '@/types/basic-form';
 import type { TaskManagementRuleForm } from '../type';
-// 任务管理表单信息
-export const TASK_MANAGEMENT_FROM_CONFIG: FormConfig[] = [
-  {
+
+// 通用表单配置
+const BASIC_FORM_CONFIG = {
+  TASK_NAME: {
     label: '任务名称',
     prop: 'taskName',
     component: 'ElInput',
@@ -15,21 +16,12 @@ export const TASK_MANAGEMENT_FROM_CONFIG: FormConfig[] = [
       showWordLimit: true,
     },
   },
-  {
-    label: '被检查(自查)单位',
-    prop: 'selfCheckUnit',
-    component: 'ElSelect',
-    componentProps: {
-      placeholder: '请选择被检查(自查)单位',
-      multiple: true,
-    },
-  },
-  {
+  TASK_TYPE: {
     label: '检查类型',
     prop: 'taskType',
     slot: 'taskType',
   },
-  {
+  SHOULD_COMPLETE_TIME: {
     label: '应完成时间',
     prop: 'shouldCompleteTime',
     component: 'ElDatePicker',
@@ -41,29 +33,17 @@ export const TASK_MANAGEMENT_FROM_CONFIG: FormConfig[] = [
       timeFormat: 'HH:mm',
     },
   },
-  {
-    label: '检查要求',
-    prop: 'checkRequirement',
-    component: 'ElInput',
-    componentProps: {
-      placeholder: '请输入检查要求',
-      type: 'textarea',
-      rows: 5,
-      maxlength: 1000,
-      showWordLimit: true,
-    },
-  },
-  {
+  CHECK_USER: {
     label: '检查人员',
     prop: 'checkUser',
     slot: 'checkUser',
   },
-  {
+  IS_PUSH: {
     label: '是否推送',
     prop: 'isPush',
     slot: 'isPush',
   },
-  {
+  CREATE_USER: {
     label: '创建人',
     prop: 'createUser',
     component: 'ElInput',
@@ -71,12 +51,73 @@ export const TASK_MANAGEMENT_FROM_CONFIG: FormConfig[] = [
       disabled: true,
     },
   },
+};
+// 任务管理表单信息 创建
+export const TASK_MANAGEMENT_FROM_CONFIG_CREATE: FormConfig[] = [
+  BASIC_FORM_CONFIG.TASK_NAME,
+  {
+    label: '被检查(自查)单位',
+    prop: 'selfCheckUnit',
+    component: 'ElSelect',
+    componentProps: {
+      placeholder: '请选择被检查(自查)单位',
+      multiple: true,
+    },
+  },
+  {
+    label: '应完成时间',
+    prop: 'shouldCompleteTime',
+    component: 'ElDatePicker',
+    componentProps: {
+      placeholder: '请选择应完成时间',
+      type: 'datetime',
+      format: 'YYYY-MM-DD HH:mm',
+      dateFormat: 'MMM DD, YYYY',
+      timeFormat: 'HH:mm',
+    },
+  },
+  BASIC_FORM_CONFIG.TASK_TYPE,
+  BASIC_FORM_CONFIG.SHOULD_COMPLETE_TIME,
+  BASIC_FORM_CONFIG.CHECK_USER,
+  BASIC_FORM_CONFIG.IS_PUSH,
+  BASIC_FORM_CONFIG.CREATE_USER,
+];
+
+// 任务管理表单信息 编辑
+export const TASK_MANAGEMENT_FROM_CONFIG_EDIT: FormConfig[] = [
+  BASIC_FORM_CONFIG.TASK_NAME,
+  {
+    label: '被检查(自查)单位',
+    prop: 'selfCheckUnit',
+    component: 'ElInput',
+    componentProps: {
+      placeholder: '请输入被检查(自查)单位',
+      disabled: true,
+    },
+  },
+  {
+    label: '应完成时间',
+    prop: 'shouldCompleteTime',
+    component: 'ElDatePicker',
+    componentProps: {
+      placeholder: '请选择应完成时间',
+      type: 'datetime',
+      format: 'YYYY-MM-DD HH:mm',
+      dateFormat: 'MMM DD, YYYY',
+      timeFormat: 'HH:mm',
+    },
+  },
+  BASIC_FORM_CONFIG.TASK_TYPE,
+  BASIC_FORM_CONFIG.SHOULD_COMPLETE_TIME,
+  BASIC_FORM_CONFIG.CHECK_USER,
+  BASIC_FORM_CONFIG.IS_PUSH,
+  BASIC_FORM_CONFIG.CREATE_USER,
 ];
 
 // 任务管理表单数据
 export const TASK_MANAGEMENT_FROM_DATA: TaskManagementRuleForm = {
   taskName: '',
-  selfCheckUnit: [],
+  selfCheckUnit: '',
   taskType: null,
   taskTemplate: null,
   shouldCompleteTime: '',

+ 23 - 5
src/views/disaster/disaster-precaution/src/config/index.ts

@@ -1,12 +1,30 @@
-import { TABLE_OPTIONS, TASK_MANAGEMENT_TABLE_COLUMNS } from './table';
-import { TASK_MANAGEMENT_SEARCH_CONFIG } from './search';
-import { TASK_MANAGEMENT_FROM_CONFIG, TASK_MANAGEMENT_FROM_DATA, TASK_MANAGEMENT_FROM_RULES } from './form';
+import {
+  TABLE_OPTIONS_MANAGEMENT,
+  TABLE_OPTIONS_EXECUTION,
+  TASK_MANAGEMENT_TABLE_COLUMNS,
+  TASK_EXECUTION_TABLE_COLUMNS,
+  TABLE_MANAGEMENT_HEIGHT_DEFAULT,
+  TABLE_MANAGEMENT_HEIGHT_BATCH_OPERATION,
+} from './table';
+import { TASK_MANAGEMENT_SEARCH_CONFIG, TASK_EXECUTION_SEARCH_CONFIG } from './search';
+import {
+  TASK_MANAGEMENT_FROM_CONFIG_CREATE,
+  TASK_MANAGEMENT_FROM_CONFIG_EDIT,
+  TASK_MANAGEMENT_FROM_DATA,
+  TASK_MANAGEMENT_FROM_RULES,
+} from './form';
 
 export {
-  TABLE_OPTIONS,
+  TABLE_OPTIONS_MANAGEMENT,
+  TABLE_OPTIONS_EXECUTION,
   TASK_MANAGEMENT_TABLE_COLUMNS,
+  TASK_EXECUTION_TABLE_COLUMNS,
   TASK_MANAGEMENT_SEARCH_CONFIG,
-  TASK_MANAGEMENT_FROM_CONFIG,
+  TASK_EXECUTION_SEARCH_CONFIG,
+  TASK_MANAGEMENT_FROM_CONFIG_CREATE,
+  TASK_MANAGEMENT_FROM_CONFIG_EDIT,
   TASK_MANAGEMENT_FROM_DATA,
   TASK_MANAGEMENT_FROM_RULES,
+  TABLE_MANAGEMENT_HEIGHT_DEFAULT,
+  TABLE_MANAGEMENT_HEIGHT_BATCH_OPERATION,
 };

+ 28 - 5
src/views/disaster/disaster-precaution/src/config/search.ts

@@ -2,12 +2,16 @@
  * 预防检查任务单搜索配置
  */
 import type { SearchConfig } from '@/views/disaster/types';
-import { TASK_TYPE_OPTIONS, TASK_STAGE_OPTIONS_MANAGEMENT } from '../constants/task-execution';
+import {
+  TASK_TYPE_OPTIONS,
+  TASK_STAGE_OPTIONS_MANAGEMENT,
+  TASK_STAGE_OPTIONS_EXECUTION,
+} from '../constants/task-execution';
 import { ACTIVE_STATUS_OPTIONS } from '@/views/disaster/constant';
 
-// 任务管理搜索配置
-export const TASK_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
-  {
+// 通用搜索配置
+const BASIC_SEARCH_CONFIG = {
+  TASK_TYPE: {
     label: '检查类型',
     prop: 'taskType',
     component: 'ElSelect',
@@ -16,6 +20,11 @@ export const TASK_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
       placeholder: '请选择检查类型',
     },
   },
+};
+
+// 任务管理搜索配置
+export const TASK_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
+  BASIC_SEARCH_CONFIG.TASK_TYPE,
   {
     label: '生效状态',
     prop: 'activeStatus',
@@ -26,7 +35,7 @@ export const TASK_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
     },
   },
   {
-    label: '检查阶段',
+    label: '任务阶段',
     prop: 'taskStage',
     component: 'ElSelect',
     selectOptions: TASK_STAGE_OPTIONS_MANAGEMENT,
@@ -35,3 +44,17 @@ export const TASK_MANAGEMENT_SEARCH_CONFIG: SearchConfig[] = [
     },
   },
 ];
+
+// 任务执行搜索配置
+export const TASK_EXECUTION_SEARCH_CONFIG: SearchConfig[] = [
+  BASIC_SEARCH_CONFIG.TASK_TYPE,
+  {
+    label: '任务阶段',
+    prop: 'taskStage',
+    component: 'ElSelect',
+    selectOptions: TASK_STAGE_OPTIONS_EXECUTION,
+    componentProps: {
+      placeholder: '请选择任务阶段',
+    },
+  },
+];

+ 56 - 23
src/views/disaster/disaster-precaution/src/config/table.ts

@@ -2,58 +2,58 @@
  * 预防检查任务单表格配置
  */
 import type { TableColumnProps } from '@/types/basic-table';
+
+export const TABLE_MANAGEMENT_HEIGHT_DEFAULT = '60vh';
+export const TABLE_MANAGEMENT_HEIGHT_BATCH_OPERATION = 'calc(60vh - 50px)';
+
 // 基础表格样式配置
-export const TABLE_OPTIONS = {
+const TABLE_OPTIONS_DEFAULT = {
   emptyText: '暂无数据',
-  height: '60vh',
   loading: true,
   stripe: true,
 };
+// 任务管理表格样式配置
+export const TABLE_OPTIONS_MANAGEMENT = {
+  ...TABLE_OPTIONS_DEFAULT,
+  height: TABLE_MANAGEMENT_HEIGHT_DEFAULT,
+};
+// 任务执行表格样式配置
+export const TABLE_OPTIONS_EXECUTION = {
+  ...TABLE_OPTIONS_DEFAULT,
+  height: 'calc(70vh - 50px)',
+};
 
-// 任务管理表格列配置
-export const TASK_MANAGEMENT_TABLE_COLUMNS: TableColumnProps[] = [
-  {
-    prop: 'select',
-    label: '',
-    type: 'selection',
-    align: 'center',
-    width: '80cpx',
-  },
-  {
+// 基础表格列配置
+const BASIC_TABLE_COLUMNS = {
+  TASK_NAME: {
     prop: 'taskName',
     label: '任务名称',
     align: 'center',
     slot: 'taskName',
   },
-  {
+  SELF_CHECK_UNIT: {
     prop: 'selfCheckUnit',
     label: '被检查(自查)单位',
     align: 'center',
   },
-  {
+  TASK_TYPE: {
     prop: 'taskType',
     label: '检查类型',
     align: 'center',
     slot: 'taskType',
   },
-  {
+  SHOUDLE_COMPLETE_TIME: {
     prop: 'shouldCompleteTime',
     label: '应完成时间',
     align: 'center',
   },
-  {
-    prop: 'activeStatus',
-    label: '生效状态',
-    align: 'center',
-    slot: 'activeStatus',
-  },
-  {
+  TASK_STAGE: {
     prop: 'taskStage',
     label: '任务阶段',
     align: 'center',
     slot: 'taskStage',
   },
-  {
+  ACTION: {
     prop: 'action',
     label: '操作',
     align: 'center',
@@ -61,4 +61,37 @@ export const TASK_MANAGEMENT_TABLE_COLUMNS: TableColumnProps[] = [
     width: '250cpx',
     fixed: 'right',
   },
+};
+
+// 任务管理表格列配置
+export const TASK_MANAGEMENT_TABLE_COLUMNS: TableColumnProps[] = [
+  {
+    prop: 'select',
+    label: '',
+    type: 'selection',
+    align: 'center',
+    width: '80cpx',
+  },
+  BASIC_TABLE_COLUMNS.TASK_NAME,
+  BASIC_TABLE_COLUMNS.SELF_CHECK_UNIT,
+  BASIC_TABLE_COLUMNS.TASK_TYPE,
+  BASIC_TABLE_COLUMNS.SHOUDLE_COMPLETE_TIME,
+  {
+    prop: 'activeStatus',
+    label: '生效状态',
+    align: 'center',
+    slot: 'activeStatus',
+  },
+  BASIC_TABLE_COLUMNS.TASK_STAGE,
+  BASIC_TABLE_COLUMNS.ACTION,
+];
+
+// 任务执行表格列配置
+export const TASK_EXECUTION_TABLE_COLUMNS: TableColumnProps[] = [
+  BASIC_TABLE_COLUMNS.TASK_NAME,
+  BASIC_TABLE_COLUMNS.SELF_CHECK_UNIT,
+  BASIC_TABLE_COLUMNS.TASK_TYPE,
+  BASIC_TABLE_COLUMNS.SHOUDLE_COMPLETE_TIME,
+  BASIC_TABLE_COLUMNS.TASK_STAGE,
+  BASIC_TABLE_COLUMNS.ACTION,
 ];

+ 2 - 18
src/views/disaster/disaster-precaution/src/constants/task-execution.ts

@@ -32,11 +32,6 @@ export const TASK_STAGE_MAP: Record<number, string> = {
   [TASK_STAGE.COMPLETED]: '已完成',
 };
 
-export const TASK_STAGE_ACTION_TEXT: Record<number, string> = {
-  [TASK_STAGE.PENDING_CHECK]: '去查看',
-  [TASK_STAGE.PENDING_APPROVAL]: '去审批',
-};
-
 export const TASK_TYPE_OPTIONS = [
   {
     label: '台讯前期',
@@ -52,18 +47,11 @@ export const TASK_TYPE_OPTIONS = [
   },
 ];
 
-export const TASK_STAGE_OPTIONS_DOING = [
+export const TASK_STAGE_OPTIONS_EXECUTION = [
   {
     label: '待检查',
     value: TASK_STAGE.PENDING_CHECK,
   },
-  {
-    label: '待审批',
-    value: TASK_STAGE.PENDING_APPROVAL,
-  }
-];
-
-export const TASK_STAGE_OPTIONS_DONE = [
   {
     label: '待审批',
     value: TASK_STAGE.PENDING_APPROVAL,
@@ -79,9 +67,5 @@ export const TASK_STAGE_OPTIONS_MANAGEMENT = [
     label: '待发布',
     value: TASK_STAGE.NOT_RELEASE,
   },
-  {
-    label: '待检查',
-    value: TASK_STAGE.PENDING_CHECK,
-  },
-  ...TASK_STAGE_OPTIONS_DONE,
+  ...TASK_STAGE_OPTIONS_EXECUTION,
 ];

+ 0 - 1
src/views/disaster/disaster-precaution/src/constants/template-detail.ts

@@ -478,7 +478,6 @@ export const TASK_TEMPLATE_FOOTER = [
   {
     inspectionResult: '检查结论及存在问题',
     selfExamination: '自检意见',
-    reviewResult: '复查结果',
   },
 ];
 export const TASK_TEMPLATE_MAIN_COLUMNS = [

+ 2 - 10
src/views/disaster/disaster-precaution/src/type.ts

@@ -22,16 +22,8 @@ export interface FooterRow {
 }
 export type MergedRow = MainRow | FooterRow;
 
-import { TaskExecutionTableData } from '@/types/task-execution/tableData';
-import type { UserInfo } from '@/types/push-object';
+import type { TaskManagementItemResponse } from '@/types/disaster-precaution';
 // 任务管理表单类型
-export interface TaskManagementRuleForm
-  extends Omit<TaskExecutionTableData, 'id' | 'selfCheckUnit' | 'activeStatus' | 'taskStage' | 'isOverdue'> {
-  taskTemplate: number | null;
-  selfCheckUnit: string[];
-  checkRequirement: string;
-  checkUser: UserInfo[];
-  isPush: boolean | null;
-  createUser: string;
+export interface TaskManagementRuleForm extends Omit<TaskManagementItemResponse, 'id'> {
   [key: string]: any;
 }

+ 1 - 1
src/views/disaster/disaster-precaution/src/utils/format-data.ts

@@ -1,4 +1,4 @@
-import type { SpanTableData } from '../types/SpanTableData';
+import type { SpanTableData } from '../type';
 const formatSpanTableData = (data: SpanTableData[]) => {
   const spanData: SpanTableData[] = [];
   const uniqueItems: string[] = [];

+ 2 - 2
src/views/disaster/disaster-warning/PageDefenseNotice.vue

@@ -116,19 +116,19 @@
   });
   const handleSearch = (data: any) => {
     console.log(data);
+    getTableData();
   };
   const { tableConfig, pagination } = useTableConfig(DEFENSE_NOTICE_TABLE_COLUMNS, TABLE_OPTIONS);
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const handleCurrentChange = (value: number) => {
     pagination.pageNumber = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const getTableData = async () => {
+    tableConfig.loading = true;
     const res = await getDefenseNoticeList();
     tableData.value = res;
     pagination.total = tableData.value.length;

+ 2 - 2
src/views/disaster/disaster-warning/PageWarningInfo.vue

@@ -97,6 +97,7 @@
   });
   const handleSearch = (data: any) => {
     console.log(data);
+    getTableData();
   };
   const getWarningIcon = (disasterType: string) => {
     const icon = WEATHER_DISASTER_ALERT_TYPE.find((item) => item.label === disasterType)?.icon;
@@ -124,15 +125,14 @@
   const { tableConfig, pagination } = useTableConfig(WARNING_INFO_TABLE_COLUMNS, TABLE_OPTIONS);
   const handleSizeChange = (value: number) => {
     pagination.pageSize = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const handleCurrentChange = (value: number) => {
     pagination.pageNumber = value;
-    tableConfig.loading = true;
     getTableData();
   };
   const getTableData = async () => {
+    tableConfig.loading = true;
     const res = await getWarningInfoList();
     tableData.value = res;
     pagination.total = tableData.value.length;