gongchunyi
7 天以前 a7a9f53ef126659f664f5cbfe4eb10bebdfc4a6a
src/views/equipmentManagement/inspectionManagement/index.vue
@@ -2,12 +2,7 @@
  <div class="app-container">
    <el-form :inline="true" :model="queryParams" class="search-form">
      <el-form-item label="巡检任务名称">
        <el-input
            v-model="queryParams.taskName"
            placeholder="请输入巡检任务名称"
            clearable
            style="width: 200px "
        />
        <el-input v-model="queryParams.taskName" placeholder="请输入巡检任务名称" clearable style="width: 200px " />
      </el-form-item>
      <el-form-item>
        <el-button type="primary" @click="handleQuery">查询</el-button>
@@ -17,10 +12,7 @@
    <el-card>
      <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;">
        <el-radio-group v-model="activeRadio" @change="radioChange">
          <el-radio-button v-for="tab in radios"
                           :key="tab.name"
                           :label="tab.label"
                           :value="tab.name"/>
          <el-radio-button v-for="tab in radios" :key="tab.name" :label="tab.label" :value="tab.name" />
        </el-radio-group>
        <!-- 操作按钮区 -->
        <el-space v-if="activeRadio !== 'task'">
@@ -33,38 +25,36 @@
        </el-space>
      </div>
      <div>
        <PIMTable :table-loading="tableLoading"
                :table-data="tableData"
                :column="tableColumns"
                @selection-change="handleSelectionChange"
                @pagination="handlePagination"
                :is-selection="true"
                :border="true"
                :page="{
                  current: pageNum,
                  size: pageSize,
                  total: total,
                  layout: 'total, sizes, prev, pager, next, jumper'
                }"
                :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }"
        >
        <PIMTable :table-loading="tableLoading" :table-data="tableData" :column="tableColumns"
          @selection-change="handleSelectionChange" @pagination="handlePagination" :is-selection="true" :border="true"
          :page="{
            current: pageNum,
            size: pageSize,
            total: total,
            layout: 'total, sizes, prev, pager, next, jumper'
          }" :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }">
          <template #inspector="{ row }">
            <div class="person-tags">
              <!-- 调试信息,上线时删除 -->
              <!-- {{ console.log('inspector data:', row.inspector) }} -->
              <template v-if="row.inspector && row.inspector.length > 0">
                <el-tag
                  v-for="(person, index) in row.inspector"
                  :key="index"
                  size="small"
                  type="primary"
                  class="person-tag"
                >
                <el-tag v-for="(person, index) in row.inspector" :key="index" size="small" type="primary"
                  class="person-tag">
                  {{ person }}
                </el-tag>
              </template>
              <span v-else class="no-data">--</span>
            </div>
          </template>
          <template #acceptStatusSlot="{ row }">
            <el-tag v-if="row.acceptStatus === 1" type="success">已通过</el-tag>
            <el-tag v-else-if="row.acceptStatus === 2" type="danger">已退回</el-tag>
            <el-tag v-else-if="row.inspectionStatus > 0" type="warning">待验收</el-tag>
            <span v-else>--</span>
          </template>
          <template #statusRef="{ row }">
            <el-tag v-if="row.isActive === true || row.isActive === 1" type="success">启用</el-tag>
            <el-tag v-else type="danger">停用</el-tag>
          </template>
        </PIMTable>
      </div>
@@ -78,6 +68,7 @@
import { Delete, Plus } from "@element-plus/icons-vue";
import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
import { ElMessageBox } from "element-plus";
import dayjs from "dayjs";
// 组件引入
import PIMTable from "@/components/PIMTable/PIMTable.vue";
@@ -88,7 +79,9 @@
import {
  delTimingTask,
  inspectionTaskList,
  timingTaskList
  timingTaskList,
  addOrEditTimingTask,
  acceptInspectionTask,
} from "@/api/inspectionManagement/index.js";
// 全局变量
@@ -104,8 +97,8 @@
// 单选框配置
const activeRadio = ref("taskManage");
const radios = reactive([
  { name: "taskManage", label: "定时任务管理" },
  { name: "task", label: "定时任务记录" },
  { name: "taskManage", label: "巡检任务管理" },
  { name: "task", label: "巡检任务记录" },
]);
// 表格数据
@@ -123,88 +116,160 @@
  { prop: "taskName", label: "巡检任务名称", minWidth: 160 },
  { prop: "remarks", label: "备注", minWidth: 150 },
  { prop: "inspector", label: "执行巡检人", minWidth: 150, slot: "inspector" },
  { prop: "inspectionAcceptor", label: "验收人", minWidth: 100 },
  {
    prop: "frequencyType",
    label: "频次",
    minWidth: 150,
    formatter: (_, __, val) => ({
      DAILY: "每日",
      WEEKLY: "每周",
      MONTHLY: "每月",
      QUARTERLY: "季度"
    }[val] || "")
    minWidth: 100,
    formatData: params => {
      return params === "DAILY"
        ? "每日"
        : params === "WEEKLY"
          ? "每周"
          : params === "MONTHLY"
            ? "每月"
            : params === "QUARTERLY"
              ? "季度"
              : "";
    },
  },
  {
    prop: "frequencyDetail",
    label: "开始日期与时间",
    minWidth: 150,
    label: "开始时间",
    minWidth: 120,
    formatter: (row, column, cellValue) => {
      // 先判断是否是字符串
      if (typeof cellValue !== 'string') return '';
      if (typeof cellValue !== "string") return "";
      let val = cellValue;
      const replacements = {
        MON: '周一',
        TUE: '周二',
        WED: '周三',
        THU: '周四',
        FRI: '周五',
        SAT: '周六',
        SUN: '周日'
        MON: "周一",
        TUE: "周二",
        WED: "周三",
        THU: "周四",
        FRI: "周五",
        SAT: "周六",
        SUN: "周日",
      };
      // 使用正则一次性替换所有匹配项
      return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]);
    }
      return val.replace(
        /MON|TUE|WED|THU|FRI|SAT|SUN/g,
        match => replacements[match]
      );
    },
  },
  { prop: "registrant", label: "登记人", minWidth: 100 },
  { prop: "createTime", label: "登记日期", minWidth: 100 },
  { prop: "createTime", label: "登记日期", minWidth: 120, formatData: (cell) => cell ? dayjs(cell).format("YYYY-MM-DD") : "-" },
]);
const inspectionStatusColumn = {
  prop: "inspectionStatus",
  label: "巡检状态",
  minWidth: 100,
  dataType: "tag",
  formatData: params => {
    if (params === 0) return "未巡检";
    if (params === 1) return "正常";
    if (params === 2) return "异常";
    return "--";
  },
  formatType: params => {
    if (params === 0) return "warning";
    if (params === 1) return "success";
    if (params === 2) return "danger";
    return "info";
  }
};
const inspectionAcceptorColumn = { prop: "inspectionAcceptor", label: "验收人", minWidth: 100 };
const acceptStatusColumn = {
  prop: "acceptStatus",
  label: "验收状态",
  minWidth: 100,
  dataType: "slot",
  slot: "acceptStatusSlot",
};
const statusColumn = {
  prop: "isActive",
  label: "任务状态",
  minWidth: 100,
  align: "center",
  dataType: "slot",
  slot: "statusRef",
};
// 操作列配置
const getOperationColumn = (operations) => {
const getOperationColumn = operations => {
  if (!operations || operations.length === 0) return null;
  const operationConfig = {
    label: "操作",
    width: 130,
    fixed: "right",
    dataType: "action",
    operation: operations.map(op => {
  const operationList = operations
    .map(op => {
      switch (op) {
        case 'edit':
        case "edit":
          return {
            name: "编辑",
            clickFun: handleAdd,
            color: "#409EFF"
            color: "#409EFF",
          };
        case 'viewFile':
        case "viewFile":
          return {
            name: "查看附件",
            name: "巡检详情",
            clickFun: viewFile,
            color: "#67C23A"
            color: "#67C23A",
          };
        case "accept":
            return {
              name: "验收",
              clickFun: handleAccept,
              color: "#E6A23C",
              showHide: (row) => row.inspectionStatus > 0 && (!row.acceptStatus || row.acceptStatus === 0),
            };
        case "toggleActive":
          return {
            name: (row) => row.isActive === true || row.isActive === 1 ? "停用" : "启用",
            clickFun: handleToggleActive,
            color: (row) => row.isActive === true || row.isActive === 1 ? "#F56C6C" : "#67C23A",
          };
        default:
          return null;
      }
    }).filter(Boolean)
    })
    .filter(Boolean);
  const operationConfig = {
    label: "操作",
    width: 200,
    fixed: "right",
    dataType: "action",
    operation: operationList,
  };
  return operationConfig;
};
onMounted(() => {
  radioChange('taskManage');
  radioChange("taskManage");
});
// 单选变化
const radioChange = (value) => {
const radioChange = value => {
  activeRadio.value = value;
  if (value === "taskManage") {
    const operationColumn = getOperationColumn(['edit']);
    tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
    operationsArr.value = ['edit'];
    const operationColumn = getOperationColumn(["edit", "toggleActive"]);
    tableColumns.value = [
      ...columns.value,
      statusColumn,
      ...(operationColumn ? [operationColumn] : []),
    ];
    operationsArr.value = ["edit", "toggleActive"];
  } else if (value === "task") {
    const operationColumn = getOperationColumn(['viewFile']);
    tableColumns.value = [...columns.value, ...(operationColumn ? [operationColumn] : [])];
    operationsArr.value = ['viewFile'];
    const operationColumn = getOperationColumn(["viewFile", "accept"]);
    tableColumns.value = [
      ...columns.value,
      inspectionStatusColumn,
      acceptStatusColumn,
      ...(operationColumn ? [operationColumn] : []),
    ];
    operationsArr.value = ["viewFile", "accept"];
  }
  pageNum.value = 1;
  pageSize.value = 10;
@@ -218,50 +283,59 @@
  getList();
};
// 分页处理
const handlePagination = (val) => {
   pageNum.value = val.page;
   pageSize.value = val.limit;
   getList();
const handlePagination = val => {
  pageNum.value = val.page;
  pageSize.value = val.limit;
  getList();
};
// 获取列表数据
const getList = () => {
  tableLoading.value = true;
  const params = { ...queryParams, size: pageSize.value, current: pageNum.value };
  const params = {
    ...queryParams,
    size: pageSize.value,
    current: pageNum.value,
  };
  let apiCall;
  if (activeRadio.value === "task") {
    apiCall = inspectionTaskList(params);
  } else {
    apiCall = timingTaskList(params);
  }
  apiCall.then(res => {
    const rawData = res.data.records || [];
    // 处理 inspector 字段,将字符串转换为数组(适用于所有情况)
    tableData.value = rawData.map(item => {
      const processedItem = { ...item };
      // 处理 inspector 字段
      if (processedItem.inspector) {
        if (typeof processedItem.inspector === 'string') {
          // 字符串按逗号分割
          processedItem.inspector = processedItem.inspector.split(',').map(s => s.trim()).filter(s => s);
        } else if (!Array.isArray(processedItem.inspector)) {
          // 非数组转为数组
          processedItem.inspector = [processedItem.inspector];
  apiCall
    .then(res => {
      const rawData = res.data.records || [];
      // 处理 inspector 字段,将字符串转换为数组(适用于所有情况)
      tableData.value = rawData.map(item => {
        const processedItem = { ...item };
        // 处理 inspector 字段
        if (processedItem.inspector) {
          if (typeof processedItem.inspector === "string") {
            // 字符串按逗号分割
            processedItem.inspector = processedItem.inspector
              .split(",")
              .map(s => s.trim())
              .filter(s => s);
          } else if (!Array.isArray(processedItem.inspector)) {
            // 非数组转为数组
            processedItem.inspector = [processedItem.inspector];
          }
        } else {
          // 空值设为空数组
          processedItem.inspector = [];
        }
      } else {
        // 空值设为空数组
        processedItem.inspector = [];
      }
      return processedItem;
        return processedItem;
      });
      total.value = res.data.total || 0;
    })
    .finally(() => {
      tableLoading.value = false;
    });
    total.value = res.data.total || 0;
  }).finally(() => {
    tableLoading.value = false;
  });
};
// 重置查询
@@ -275,19 +349,47 @@
};
// 新增 / 编辑
const handleAdd = (row) => {
  const type = row ? 'edit' : 'add';
const handleAdd = row => {
  const type = row ? "edit" : "add";
  nextTick(() => {
    formDia.value?.openDialog(type, row);
  });
};
// 查看附件
const viewFile = (row) => {
// 巡检详情
const viewFile = row => {
  nextTick(() => {
    viewFiles.value?.openDialog(row);
  });
};
  // 验收操作
  const handleAccept = (row) => {
    ElMessageBox.confirm(`请选择对任务【${row.taskName}】的验收结果`, "系统提示", {
      distinguishCancelAndClose: true,
      confirmButtonText: '验收通过',
      cancelButtonText: '退回重检',
      type: 'warning'
    }).then(async () => {
      try {
        await acceptInspectionTask({ id: row.id, acceptStatus: 1 });
        proxy.$modal.msgSuccess("已验收通过");
        handleQuery();
      } catch (error) {
        console.error("验收失败:", error);
      }
    }).catch(async (action) => {
      if (action === 'cancel') {
        try {
          await acceptInspectionTask({ id: row.id, acceptStatus: 2 });
          proxy.$modal.msgWarning("已退回,等待重新巡检");
          handleQuery();
        } catch (error) {
          console.error("退回失败:", error);
        }
      }
    });
  };
// 删除操作
const handleDelete = () => {
@@ -295,19 +397,52 @@
    proxy.$modal.msgWarning("请选择要删除的数据");
    return;
  }
  const deleteIds = selectedRows.value.map(item => item.id);
  proxy.$modal.confirm('是否确认删除所选数据项?').then(() => {
    return delTimingTask(deleteIds);
  }).then(() => {
    proxy.$modal.msgSuccess("删除成功");
    handleQuery();
  }).catch(() => {});
  proxy.$modal
    .confirm("是否确认删除所选数据项?")
    .then(() => {
      return delTimingTask(deleteIds);
    })
    .then(() => {
      proxy.$modal.msgSuccess("删除成功");
      handleQuery();
    })
    .catch(() => { });
};
// 启用/停用切换
const handleToggleActive = async (row) => {
  const newStatus = row.isActive === true || row.isActive === 1 ? 0 : 1;
  const actionText = newStatus === 1 ? "启用" : "停用";
  try {
    await proxy.$modal.confirm(`是否确认${actionText}该任务?`)
  } catch {
    return
  }
  try {
    await addOrEditTimingTask({
      id: row.id,
      taskId: row.taskId,
      taskName: row.taskName,
      inspectorIds: row.inspectorIds,
      remarks: row.remarks,
      frequencyType: row.frequencyType,
      frequencyDetail: row.frequencyDetail,
      isActive: newStatus,
    })
    proxy.$modal.msgSuccess(`${actionText}成功`)
    handleQuery()
  } catch (error) {
    console.error(`${actionText}失败:`, error)
  }
};
// 多选变更
const handleSelectionChange = (selection) => {
const handleSelectionChange = selection => {
  selectedRows.value = selection;
};
@@ -321,11 +456,11 @@
    .then(() => {
      // 根据当前选中的标签页调用不同的导出接口
      if (activeRadio.value === "taskManage") {
        // 定时任务管理
        proxy.download("/timingTask/export", {}, "定时任务管理.xlsx");
        // 保养任务管理
        proxy.download("/timingTask/export", {}, "保养任务管理.xlsx");
      } else if (activeRadio.value === "task") {
        // 定时任务记录
        proxy.download("/inspectionTask/export", {}, "定时任务记录.xlsx");
        proxy.download("/inspectionTask/export", {}, "保养任务记录.xlsx");
      }
    })
    .catch(() => {