| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254 |
- <template>
- <div class="safety-platform-container">
- <header class="safety-platform-container__header">
- <span class="breadcrumb-title">灾害预防检查任务</span>
- </header>
- <main class="safety-platform-container__main">
- <div class="search-table-container">
- <header class="disaster-precaution__header">
- <BasicSearch
- :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.name"
- placement="top"
- effect="light"
- v-if="isToolTip(scope.row.overdue, scope.row.name)"
- >
- <span>{{ scope.row.name }}</span>
- </el-tooltip>
- <span v-else>{{ scope.row.name }}</span>
- <div class="overdue-icon">
- <img :src="OverdueIcon" alt="overdue" v-if="scope.row.overdue" />
- </div>
- </div>
- </template>
- <template #inspectType="scope">
- <span>{{ INSPECT_TYPE_MAP[scope.row.inspectType] }}</span>
- </template>
- <template #taskStage="scope">
- <span>{{ TASK_STAGE_MAP[scope.row.taskState] }}</span>
- </template>
- <!-- action button 不仅分任务情况 还要分 人物权限 -->
- <template #action="scope">
- <!-- 检查任务操作入口 -->
- <div class="action-container--div" v-if="scope.row.taskState === TASK_STAGE.PENDING_CHECK">
- <ActionButton text="去检查" @click="handleCheckItem(scope.row.id, 'check')" />
- <!-- 仅检查责任人可以看到 -->
- <ActionButton
- text="添加检查人"
- @click="handleAddCheckUser(scope.row.id)"
- v-if="scope.row.userTypeList.includes(USER_TYPE.CHECK_RESPONSIBLE)"
- />
- </div>
- <!-- 审批任务操作入口 -->
- <div class="action-container--div" v-else-if="scope.row.taskState === TASK_STAGE.PENDING_APPROVAL">
- <!-- 审批人员可以看到 -->
- <ActionButton
- text="去审批"
- v-if="scope.row.userTypeList.includes(USER_TYPE.APPROVER)"
- @click="handleCheckItem(scope.row.id, 'approve')"
- />
- <!-- 检查责任人、检查执行人员可以看到 -->
- <ActionButton
- v-if="
- [USER_TYPE.CHECK_RESPONSIBLE, USER_TYPE.CHECK_PERSON].some((type) =>
- scope.row.userTypeList.includes(type),
- )
- "
- text="撤回"
- :popconfirm="{
- title: '确定撤回吗?',
- }"
- @confirm="handleWithdrawTask(scope.row.id, scope.row.taskState)"
- />
- </div>
- <!-- 完成任务操作入口 -->
- <div class="action-container--div" v-else-if="scope.row.taskState === TASK_STAGE.COMPLETED">
- <ActionButton text="查看" @click="handleCheckItem(scope.row.id, 'view')" />
- <!-- 仅审批人员可以看到 -->
- <ActionButton
- v-if="scope.row.userTypeList.includes(USER_TYPE.APPROVER) && !isOverdue24Hours(scope.row.updatedAt)"
- text="撤回"
- :popconfirm="{
- title: '确定撤回吗?',
- }"
- @confirm="handleWithdrawTask(scope.row.id, scope.row.taskState)"
- />
- </div>
- </template>
- </BasicTable>
- </div>
- </main>
- <el-dialog v-model="userInfo" title="添加检查人" destroy-on-close>
- <InspectorSelect
- :customUserList="currentTaskInspectorList"
- @cancel="userInfo = false"
- @submit="handleSubmitCheckUser"
- />
- </el-dialog>
- </div>
- </template>
- <script setup lang="ts">
- import { useRouter } from 'vue-router';
- import { ref, onMounted, reactive, onUnmounted } from 'vue';
- import { ElMessage } from 'element-plus';
- import BasicTable from '@/components/BasicTable.vue';
- import ActionButton from '@/components/ActionButton.vue';
- import BasicSearch from '@/components/BasicSearch.vue';
- import InspectorSelect from '@/views/disaster/components/InspectorSelect.vue';
- import useTableConfig from '@/hooks/useTableConfigHook';
- import { isToolTip } from './src/utils';
- import type { TaskExecutionListResponse, TaskExecutionListQuery } from '@/types/disaster-precaution';
- import type { QueryPageRequest } from '@/types/disaster';
- import type { PersonGroupItem } from '@/types/person-group/type';
- import {
- getTaskExecutionList,
- getTaskInspectorList,
- withdrawTaskInspect,
- withdrawTaskApproval,
- updateTaskInspector,
- } from '@/api/disaster-precaution';
- import { TABLE_OPTIONS_EXECUTION, TASK_EXECUTION_TABLE_COLUMNS, TASK_EXECUTION_SEARCH_CONFIG } from './src/config';
- import { INSPECT_TYPE_MAP, TASK_STAGE_MAP, TASK_STAGE, USER_TYPE } from './src/constants/task-execution';
- import OverdueIcon from '@/assets/svg/overdue.svg';
- const router = useRouter();
- const userInfo = ref(false);
- const searchData = reactive({
- inspectType: '',
- taskState: '',
- });
- const tableData = ref<TaskExecutionListResponse[]>([]);
- const { tableConfig, pagination } = useTableConfig(TASK_EXECUTION_TABLE_COLUMNS, TABLE_OPTIONS_EXECUTION);
- // 添加刷新时间变量,用于触发视图更新
- const refreshTime = ref(Date.now());
- let refreshTimer: number | null = null;
- let taskManagementListQuery: QueryPageRequest<TaskExecutionListQuery> = {
- pageNumber: pagination.pageNumber,
- pageSize: pagination.pageSize,
- queryParam: {},
- };
- const handleSearch = () => {
- taskManagementListQuery.queryParam = {};
- if (searchData.inspectType !== '') {
- taskManagementListQuery.queryParam.inspectType = searchData.inspectType;
- }
- if (searchData.taskState !== '') {
- taskManagementListQuery.queryParam.taskState = searchData.taskState;
- }
- getTableData();
- };
- const handleSizeChange = (value: number) => {
- pagination.pageSize = value;
- taskManagementListQuery.pageSize = value;
- getTableData();
- };
- const handleCurrentChange = (value: number) => {
- pagination.pageNumber = value;
- taskManagementListQuery.pageNumber = value;
- getTableData();
- };
- const currentTaskId = ref<number>();
- const currentTaskInspectorList = ref<PersonGroupItem[]>([]);
- const handleAddCheckUser = async (id: number) => {
- currentTaskId.value = id;
- const res = await getTaskInspectorList(currentTaskId.value);
- currentTaskInspectorList.value = res.map((item) => {
- return {
- ...item,
- checked: true,
- };
- });
- userInfo.value = true;
- };
- const defaultRouterName = 'disaster-precaution-task-execution-detail';
- const handleCheckItem = (id: number, operationType: 'check' | 'approve' | 'view') => {
- router.push({
- name: defaultRouterName,
- params: {
- id,
- },
- query: {
- operationType,
- },
- });
- };
- const handleWithdrawTask = async (id: number, state: number) => {
- let message;
- if (state === TASK_STAGE.PENDING_APPROVAL) {
- await withdrawTaskInspect(id);
- message = '已成功撤回检查';
- } else if (state === TASK_STAGE.COMPLETED) {
- await withdrawTaskApproval(id);
- message = '已成功撤回审批';
- }
- ElMessage.success(message);
- getTableData();
- };
- const getTableData = async () => {
- tableConfig.loading = true;
- const res = await getTaskExecutionList(taskManagementListQuery);
- tableData.value = res.records;
- pagination.total = res.totalRow;
- tableConfig.loading = false;
- };
- const handleSubmitCheckUser = async (ids: number[]) => {
- if (!currentTaskId.value) return;
- await updateTaskInspector({
- id: currentTaskId.value,
- inspectorIdList: ids,
- });
- ElMessage.success('添加检查人员成功!');
- userInfo.value = false;
- getTableData();
- };
- // 判断是否超过应完成时间24小时
- const isOverdue24Hours = (updatedAt: string) => {
- if (!updatedAt) return false;
- const dueTime = new Date(updatedAt).getTime();
- const currentTime = refreshTime.value;
- // 计算24小时的毫秒数: 24 * 60 * 60 * 1000 = 86400000
- return currentTime > dueTime + 86400000;
- };
- onMounted(() => {
- getTableData();
- // 设置定时器,每秒更新一次时间
- refreshTimer = window.setInterval(() => {
- refreshTime.value = Date.now();
- }, 1000);
- });
- // 组件销毁时清除定时器
- onUnmounted(() => {
- if (refreshTimer !== null) {
- clearInterval(refreshTimer);
- refreshTimer = null;
- }
- });
- </script>
- <style scoped lang="scss">
- @use '@/styles/page-details-layout.scss' as *;
- @use '@/styles/page-main-layout.scss' as *;
- @use './src/style/task-execution.scss' as *;
- @use '@/views/disaster/style/disaster.scss' as *;
- </style>
|