zhang_nuo
2026-08-11 1be6a8fc84764d7e816737b365f9e1c8869db9a7
提交意博凯信删除各个模块表格的时分秒
已修改19个文件
2326 ■■■■ 文件已修改
src/components/PIMTable/PIMTable.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/parameterMaintenance/index.vue 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/knowledgeBase/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/rulesRegulationsManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/sealManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/spareParts/index.vue 930 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/index.vue 1283 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/payable/purchaseReturn.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/salesReturn.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/dispatchLog/Record.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/Record.vue 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/BatchNoQtyDetail.vue 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Qualified.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Record.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Unqualified.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/approveTemplateConstants.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/socialSecuritySet/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/dangerInvestigation/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/PIMTable/PIMTable.vue
@@ -112,6 +112,10 @@
            {{ formatters(scope.row[item.prop], item.formatData) }}
          </el-tag>
        </div>
        <!-- 时间类型 -->
        <div v-else-if="item.dataType === 'date'">
          {{ scope.row[item.prop] ? dayjs(scope.row[item.prop]).format('YYYY-MM-DD') : '' }}
        </div>
        <!-- 按钮 -->
        <div v-else-if="item.dataType == 'action'"
             @click.stop>
@@ -204,6 +208,7 @@
  import pagination from "./Pagination.vue";
  import { computed, ref, inject, getCurrentInstance } from "vue";
  import { ElMessage } from "element-plus";
  import dayjs from "dayjs";
  // 获取全局的 uploadHeader
  const { proxy } = getCurrentInstance();
src/views/basicData/parameterMaintenance/index.vue
@@ -302,6 +302,7 @@
    {
      label: "创建时间",
      prop: "createTime",
      dataType:"date"
    },
    {
      label: "操作",
@@ -374,7 +375,7 @@
  const formCreateTimeDate = computed({
    get: () => (formData.createTime ? String(formData.createTime).split(" ")[0] : ""),
    set: (value) => {
      formData.createTime = value ? `${value} ${dayjs().format("HH:mm:ss")}` : "";
        formData.createTime = value ? dayjs(value).format("YYYY-MM-DD") : "";
    },
  });
  // const productTypes = ref([]);
src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -555,6 +555,7 @@
    label: "创建时间",
    prop: "createTime",
    width: 180,
    dataType:"date"
  },
  {
    dataType: "action",
src/views/collaborativeApproval/rulesRegulationsManagement/index.vue
@@ -309,7 +309,7 @@
    },
    { label: "版本", prop: "version", width: 120 },
    { label: "发布人", prop: "createUserName", width: 120 },
    { label: "发布时间", prop: "createTime", width: 180 },
    { label: "发布时间", prop: "createTime", width: 180,dataType: "date" },
    {
      label: "状态",
      prop: "status",
src/views/collaborativeApproval/sealManagement/index.vue
@@ -252,7 +252,7 @@
    formatData: (v) => getSealTypeText(v),
    formatType: () => 'info'
  },
  { label: '申请时间', prop: 'createTime', width: 180 },
  { label: '申请时间', prop: 'createTime', width: 180,dataType: "date" },
  {
    label: '状态',
    prop: 'status',
src/views/equipmentManagement/spareParts/index.vue
@@ -1,26 +1,26 @@
<template>
    <div class="spare-part-category">
        <el-tabs v-model="activeTab" @tab-change="handleTabChange">
            <el-tab-pane label="备件列表" name="list">
                <div class="search_form">
                    <el-form :inline="true" :model="queryParams" class="search-form">
                        <el-form-item label="备件名称">
                            <el-input
                                v-model="queryParams.name"
                                placeholder="请输入备件名称"
                                clearable
                                style="width: 240px"
                            />
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="handleQuery">查询</el-button>
                            <el-button @click="resetQuery">重置</el-button>
                        </el-form-item>
                    </el-form>
                    <div>
                        <el-button type="primary" @click="addCategory">新增</el-button>
                    </div>
                </div>
  <div class="spare-part-category">
    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
      <el-tab-pane label="备件列表" name="list">
        <div class="search_form">
          <el-form :inline="true" :model="queryParams" class="search-form">
            <el-form-item label="备件名称">
              <el-input
                v-model="queryParams.name"
                placeholder="请输入备件名称"
                clearable
                style="width: 240px"
              />
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleQuery">查询</el-button>
              <el-button @click="resetQuery">重置</el-button>
            </el-form-item>
          </el-form>
          <div>
            <el-button type="primary" @click="addCategory">新增</el-button>
          </div>
        </div>
                <div class="table_list">
                    <PIMTable
                        rowKey="id"
@@ -36,87 +36,83 @@
                        </template>
                    </PIMTable>
                </div>
                <el-dialog title="分类管理" v-model="dialogVisible" width="60%">
                    <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
                        <el-form-item label="设备" prop="deviceLedgerIds">
                            <el-select
                                v-model="form.deviceLedgerIds"
                                placeholder="请选择设备"
                                filterable
                                default-first-option
                                :reserve-keyword="false"
                                multiple
                                style="width: 100%"
                            >
                                <el-option
                                    v-for="(item, index) in deviceOptions"
                                    :key="index"
                                    :label="item.deviceName"
                                    :value="item.id"
                                ></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="备件名称" prop="name">
                            <el-input v-model="form.name"></el-input>
                        </el-form-item>
                        <el-form-item label="备件编号" prop="sparePartsNo">
                            <el-input v-model="form.sparePartsNo"></el-input>
                        </el-form-item>
                        <el-form-item label="数量" prop="quantity">
                            <el-input type="number" v-model="form.quantity"></el-input>
                        </el-form-item>
                        <el-form-item label="状态" prop="status">
                            <el-select v-model="form.status" placeholder="请选择状态">
                                <el-option label="正常" value="正常"></el-option>
                                <el-option label="禁用" value="禁用"></el-option>
                            </el-select>
                        </el-form-item>
                        <el-form-item label="描述" prop="description">
                            <el-input v-model="form.description"></el-input>
                        </el-form-item>
                        <el-form-item label="价格" prop="price">
                            <el-input-number
                                v-model="form.price"
                                placeholder="请输入价格"
                                :min="0"
                                :step="0.01"
                                :precision="2"
                                style="width: 100%"
                            ></el-input-number>
                        </el-form-item>
                    </el-form>
                    <template #footer>
        <el-dialog title="分类管理" v-model="dialogVisible" width="60%">
          <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
            <el-form-item label="设备" prop="deviceLedgerIds">
              <el-select
                v-model="form.deviceLedgerIds"
                placeholder="请选择设备"
                filterable
                default-first-option
                :reserve-keyword="false"
                multiple
                style="width: 100%"
              >
                <el-option
                  v-for="(item, index) in deviceOptions"
                  :key="index"
                  :label="item.deviceName"
                  :value="item.id"
                ></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="备件名称" prop="name">
              <el-input v-model="form.name"></el-input>
            </el-form-item>
            <el-form-item label="备件编号" prop="sparePartsNo">
              <el-input v-model="form.sparePartsNo"></el-input>
            </el-form-item>
            <el-form-item label="数量" prop="quantity">
              <el-input type="number" v-model="form.quantity"></el-input>
            </el-form-item>
            <el-form-item label="状态" prop="status">
              <el-select v-model="form.status" placeholder="请选择状态">
                <el-option label="正常" value="正常"></el-option>
                <el-option label="禁用" value="禁用"></el-option>
              </el-select>
            </el-form-item>
            <el-form-item label="描述" prop="description">
              <el-input v-model="form.description"></el-input>
            </el-form-item>
            <el-form-item label="价格" prop="price">
              <el-input-number
                v-model="form.price"
                placeholder="请输入价格"
                :min="0"
                :step="0.01"
                :precision="2"
                style="width: 100%"
              ></el-input-number>
            </el-form-item>
          </el-form>
          <template #footer>
            <span class="dialog-footer">
              <el-button type="primary" @click="submitForm" :loading="formLoading">确定</el-button>
              <el-button @click="dialogVisible = false" :disabled="formLoading">取消</el-button>
            </span>
                    </template>
                </el-dialog>
            </el-tab-pane>
            <el-tab-pane label="备件领用记录" name="usage">
                <div class="search_form">
                    <el-form :inline="true" :model="usageQuery" class="search-form">
                        <el-form-item label="备件名称">
                            <el-input v-model="usageQuery.sparePartsName" placeholder="请输入备件名称" clearable style="width: 240px" />
                        </el-form-item>
                        <el-form-item label="来源">
                            <el-select v-model="usageQuery.sourceType" placeholder="请选择" clearable style="width: 200px">
                                <el-option label="维修" :value="0" />
                                <el-option label="保养" :value="1" />
                                <el-option label="直接出库" :value="2" />
                            </el-select>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary" @click="handleUsageQuery">查询</el-button>
                            <el-button @click="resetUsageQuery">重置</el-button>
                        </el-form-item>
                    </el-form>
                    <div>
                        <el-button type="primary" @click="openRequisitionDialog">直接出库</el-button>
                    </div>
                </div>
          </template>
        </el-dialog>
      </el-tab-pane>
      <el-tab-pane label="备件领用记录" name="usage">
        <div class="search_form">
          <el-form :inline="true" :model="usageQuery" class="search-form">
            <el-form-item label="备件名称">
              <el-input v-model="usageQuery.sparePartsName" placeholder="请输入备件名称" clearable style="width: 240px" />
            </el-form-item>
            <el-form-item label="来源">
              <el-select v-model="usageQuery.sourceType" placeholder="请选择" clearable style="width: 200px">
                <el-option label="维修" :value="0" />
                <el-option label="保养" :value="1" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary" @click="handleUsageQuery">查询</el-button>
              <el-button @click="resetUsageQuery">重置</el-button>
            </el-form-item>
          </el-form>
        </div>
                <div class="table_list">
                    <PIMTable
                        rowKey="rowKey"
@@ -128,63 +124,9 @@
                        @pagination="handleUsagePageChange"
                    />
                </div>
            </el-tab-pane>
        </el-tabs>
        <!-- 直接出库弹窗 -->
        <el-dialog title="直接出库" v-model="requisitionDialogVisible" width="500px">
            <el-form :model="requisitionForm" :rules="requisitionRules" ref="requisitionFormRef" label-width="100px">
                <el-form-item label="设备选择" prop="deviceLedgerId">
                    <el-select
                        v-model="requisitionForm.deviceLedgerId"
                        placeholder="请选择设备"
                        filterable
                        clearable
                        style="width: 100%"
                    >
                        <el-option
                            v-for="item in requisitionDeviceOptions"
                            :key="item.id"
                            :label="item.deviceName"
                            :value="item.id"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="备件选择" prop="sparePartsId">
                    <el-select
                        v-model="requisitionForm.sparePartsId"
                        placeholder="请选择备件"
                        filterable
                        clearable
                        style="width: 100%"
                        @change="onRequisitionSparePartChange"
                    >
                        <el-option
                            v-for="item in requisitionSparePartsOptions"
                            :key="item.id"
                            :label="`${item.name}(库存: ${item.quantity})`"
                            :value="item.id"
                        />
                    </el-select>
                </el-form-item>
                <el-form-item label="领用数量" prop="quantity">
                    <el-input-number
                        v-model="requisitionForm.quantity"
                        :min="1"
                        :max="selectedSparePartMaxQty"
                        style="width: 100%"
                    />
                </el-form-item>
                <el-form-item label="备注" prop="remark">
                    <el-input v-model="requisitionForm.remark" placeholder="请输入备注" />
                </el-form-item>
            </el-form>
            <template #footer>
                <el-button type="primary" @click="submitRequisition" :loading="requisitionLoading">确定</el-button>
                <el-button @click="requisitionDialogVisible = false">取消</el-button>
            </template>
        </el-dialog>
    </div>
      </el-tab-pane>
    </el-tabs>
  </div>
</template>
<script setup>
@@ -193,7 +135,7 @@
import { getSparePartsList, addSparePart, editSparePart, delSparePart } from "@/api/equipmentManagement/spareParts";
import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
import PIMTable from "@/components/PIMTable/PIMTable.vue";
import { getSparePartsUsagePage, outboundSpareParts } from "@/api/equipmentManagement/sparePartsUsage";
import { getSparePartsUsagePage } from "@/api/equipmentManagement/sparePartsUsage";
// 加载状态
const loading = ref(false);
@@ -215,456 +157,376 @@
const formRef = ref(null);
// 查询参数
const queryParams = reactive({
    name: ''
  name: ''
});
// 分页参数
const pagination = reactive({
    current: 1,
    size: 10,
    total: 0
  current: 1,
  size: 10,
  total: 0
});
// 备件领用记录
const usageLoading = ref(false);
const usageQuery = reactive({
    sparePartsName: "",
    sourceType: "",
  sparePartsName: "",
  sourceType: "",
});
const usagePagination = reactive({
    current: 1,
    size: 10,
    total: 0,
  current: 1,
  size: 10,
  total: 0,
});
const usageTableData = ref([]);
const usageColumns = ref([
    { label: "来源", prop: "sourceText" },
    { label: "单据/记录ID", prop: "sourceId" },
    { label: "设备名称", prop: "deviceName" },
    { label: "备件名称", prop: "sparePartsName" },
    { label: "领用数量", prop: "quantity" },
    { label: "操作人", prop: "operator" },
    { label: "时间", prop: "createTime" },
  { label: "来源", prop: "sourceText" },
  { label: "单据/记录ID", prop: "sourceId" },
  { label: "设备名称", prop: "deviceName" },
  { label: "备件名称", prop: "sparePartsName" },
  { label: "领用数量", prop: "quantity" },
  { label: "操作人", prop: "operator" },
  { label: "时间", prop: "createTime",dataType: "date"},
]);
const handleTabChange = async (name) => {
    if (name === "usage") {
        usagePagination.current = 1;
        await fetchUsageData();
    }
  if (name === "usage") {
    usagePagination.current = 1;
    await fetchUsageData();
  }
};
const columns = ref([
    {
        label: "设备名称",
        prop: "deviceNameStr",
    },
    {
        label: "备件名称",
        prop: "name",
    },
    {
        label: "备件编号",
        prop: "sparePartsNo",
    },
    {
        label: "状态",
        prop: "status",
        slot: "status",
        dataType: "slot",
    },
    {
        label: "价格",
        prop: "price",
    },
    {
        label: "数量",
        prop: "quantity",
    },
    {
        label: "描述",
        prop: "description",
    },
    {
        label: "操作",
        prop: "operation",
        width: 150,
        fixed: 'right',
        align: "center",
        dataType: "action",
        operation: [
            {
                name: "编辑",
                clickFun: (row) => {
                    editCategory(row)
                },
            },
            {
                name: "删除",
                clickFun: (row) => {
                    deleteCategory(row.id)
                },
            },
        ],
    },
  {
    label: "设备名称",
    prop: "deviceNameStr",
  },
  {
    label: "备件名称",
    prop: "name",
  },
  {
    label: "备件编号",
    prop: "sparePartsNo",
  },
  {
    label: "状态",
    prop: "status",
    slot: "status",
    dataType: "slot",
  },
  {
    label: "价格",
    prop: "price",
  },
  {
    label: "数量",
    prop: "quantity",
  },
  {
    label: "描述",
    prop: "description",
  },
  {
    label: "操作",
    prop: "operation",
    width: 150,
    fixed: 'right',
    align: "center",
    dataType: "action",
    operation: [
      {
        name: "编辑",
        clickFun: (row) => {
          editCategory(row)
        },
      },
      {
        name: "删除",
        clickFun: (row) => {
          deleteCategory(row.id)
        },
      },
    ],
  },
]);
// 表单数据
const form = reactive({
    id:'',
    name: '',
    sparePartsNo: '',
    status: '',
    description: '',
    deviceLedgerIds: [],
    price: null
  id:'',
  name: '',
  sparePartsNo: '',
  status: '',
  description: '',
  deviceLedgerIds: [],
  price: null
});
// 表单验证规则
const rules = reactive({
    name: [
        { required: true, message: '请输入备件名称', trigger: 'blur' }
    ],
    sparePartsNo: [
        { required: true, message: '请输入备件编号', trigger: 'blur' }
    ],
    quantity:[
        { required: true, message: '请输入数量', trigger: 'blur' }
    ],
    status: [
        { required: true, message: '请选择状态', trigger: 'change' }
    ],
    deviceLedgerIds: [
        {
            required: true,
            message: '请选择设备',
            trigger: 'change',
            validator: (rule, value, callback) => {
                if (operationType.value === 'add' && (!value || value.length === 0)) {
                    callback(new Error('请选择设备'));
                } else {
                    callback();
                }
            }
        }
    ]
  name: [
    { required: true, message: '请输入备件名称', trigger: 'blur' }
  ],
  sparePartsNo: [
    { required: true, message: '请输入备件编号', trigger: 'blur' }
  ],
  quantity:[
    { required: true, message: '请输入数量', trigger: 'blur' }
  ],
  status: [
    { required: true, message: '请选择状态', trigger: 'change' }
  ],
  deviceLedgerIds: [
    {
      required: true,
      message: '请选择设备',
      trigger: 'change',
      validator: (rule, value, callback) => {
        if (operationType.value === 'add' && (!value || value.length === 0)) {
          callback(new Error('请选择设备'));
        } else {
          callback();
        }
      }
    }
  ]
});
// 获取缩进量
const getIndentation = (row) => {
    // 这里简单返回 20,可根据实际需求实现层级缩进逻辑
    return 20;
  // 这里简单返回 20,可根据实际需求实现层级缩进逻辑
  return 20;
};
// 定义 buildTree 函数
const buildTree = (flatData) => {
    const map = {};
    const result = [];
    if(flatData){
        return result;
    }
    flatData.forEach(item => {
        map[item.id] = { ...item, children: [] };
    });
    flatData.forEach(item => {
        if (item.parentId === null || !map[item.parentId]) {
            result.push(map[item.id]);
        } else {
            map[item.parentId].children.push(map[item.id]);
        }
    });
    return result;
  const map = {};
  const result = [];
  if(flatData){
    return result;
  }
  flatData.forEach(item => {
    map[item.id] = { ...item, children: [] };
  });
  flatData.forEach(item => {
    if (item.parentId === null || !map[item.parentId]) {
      result.push(map[item.id]);
    } else {
      map[item.parentId].children.push(map[item.id]);
    }
  });
  return result;
};
// 获取列表数据
const fetchListData = async () => {
    loading.value = true;
    try {
        const params = {
            current: pagination.current,
            size: pagination.size
        };
        if (queryParams.name) {
            params.name = queryParams.name;
        }
        const res = await getSparePartsList(params);
        if (res.code === 200) {
            renderTableData.value = res.data.records || [];
            categories.value = res.data.records || [];
            pagination.total = res.data.total || 0;
        }
    } catch (error) {
  loading.value = true;
  try {
    const params = {
      current: pagination.current,
      size: pagination.size
    };
    if (queryParams.name) {
      params.name = queryParams.name;
    }
    const res = await getSparePartsList(params);
    if (res.code === 200) {
      renderTableData.value = res.data.records || [];
      categories.value = res.data.records || [];
      pagination.total = res.data.total || 0;
    }
  } catch (error) {
        loading.value = false;
    } finally {
        loading.value = false;
    }
  } finally {
    loading.value = false;
  }
}
const fetchUsageData = async () => {
    usageLoading.value = true;
    try {
        const res = await getSparePartsUsagePage({
            current: usagePagination.current,
            size: usagePagination.size,
            sparePartsName: usageQuery.sparePartsName || undefined,
            sourceType: usageQuery.sourceType || undefined,
        });
        if (res?.code === 200) {
            const records = res?.data?.records || [];
            usagePagination.total = res?.data?.total || 0;
            usageTableData.value = records.map((r, idx) => ({
                rowKey: r.id ?? `${usagePagination.current}-${idx}`,
                ...r,
                sourceText: r.sourceText === "" ? "-" : r.sourceText,
            }));
        } else {
            usagePagination.total = 0;
            usageTableData.value = [];
        }
    } finally {
        usageLoading.value = false;
    }
  usageLoading.value = true;
  try {
    const res = await getSparePartsUsagePage({
      current: usagePagination.current,
      size: usagePagination.size,
      sparePartsName: usageQuery.sparePartsName || undefined,
      sourceType: usageQuery.sourceType || undefined,
    });
    if (res?.code === 200) {
      const records = res?.data?.records || [];
      usagePagination.total = res?.data?.total || 0;
      usageTableData.value = records.map((r, idx) => ({
        rowKey: r.id ?? `${usagePagination.current}-${idx}`,
        ...r,
        sourceText: r.sourceText === "" ? "-" : r.sourceText,
      }));
    } else {
      usagePagination.total = 0;
      usageTableData.value = [];
    }
  } finally {
    usageLoading.value = false;
  }
};
const handleUsageQuery = () => {
    usagePagination.current = 1;
    fetchUsageData();
  usagePagination.current = 1;
  fetchUsageData();
};
const resetUsageQuery = () => {
    usageQuery.sparePartsName = "";
    usageQuery.sourceType = "";
    usagePagination.current = 1;
    fetchUsageData();
  usageQuery.sparePartsName = "";
  usageQuery.sourceType = "";
  usagePagination.current = 1;
  fetchUsageData();
};
const handleUsagePageChange = (obj) => {
    usagePagination.current = obj.page;
    usagePagination.size = obj.limit;
    fetchUsageData();
  usagePagination.current = obj.page;
  usagePagination.size = obj.limit;
  fetchUsageData();
};
// 查询
const handleQuery = () => {
    pagination.current = 1;
    fetchListData();
  pagination.current = 1;
  fetchListData();
}
// 重置查询
const resetQuery = () => {
    queryParams.name = '';
    pagination.current = 1;
    fetchListData();
  queryParams.name = '';
  pagination.current = 1;
  pagination.size = 10;
  fetchListData();
}
// 分页变化
// 分页大小改变
const handleSizeChange = ({ page, limit }) => {
    pagination.current = page;
    pagination.size = limit;
    fetchListData();
  pagination.current = page;
  pagination.size = limit;
  fetchListData();
}
// 当前页改变
const handleCurrentChange = (current) => {
  pagination.current = current;
  fetchListData();
}
// 加载设备列表(在打开弹框时调用)
const loadDeviceName = async () => {
    try {
        const { data } = await getDeviceLedger();
        deviceOptions.value = data || [];
    } catch (error) {
        ElMessage.error('获取设备列表失败');
    }
  try {
    const { data } = await getDeviceLedger();
    deviceOptions.value = data || [];
  } catch (error) {
    ElMessage.error('获取设备列表失败');
  }
};
// 新增分类
const addCategory = async () => {
    await loadDeviceName();
    form.id = '';
    form.name = '';
    form.sparePartsNo = '';
    form.status = '';
    form.description = '';
    form.deviceLedgerIds = [];
    form.quantity = undefined;
    form.price = null;
    operationType.value = 'add'
    dialogVisible.value = true;
  await loadDeviceName();
  form.id = '';
  form.name = '';
  form.sparePartsNo = '';
  form.status = '';
  form.description = '';
  form.deviceLedgerIds = [];
  form.quantity = undefined;
  form.price = null;
  operationType.value = 'add'
  dialogVisible.value = true;
};
// 编辑分类
const editCategory = async (row) => {
    await loadDeviceName();
    Object.assign(form, row);
    // 如果后端返回的是 deviceIds 字符串,需要转换为数组
    if (row.deviceIds && typeof row.deviceIds === 'string') {
        // 确保ID类型与设备选项中的ID类型一致
        const deviceIdsArray = row.deviceIds.split(',').map(id => id.trim()).filter(id => id);
        // 如果设备选项中的ID是数字类型,则转换为数字
        if (deviceOptions.value.length > 0 && typeof deviceOptions.value[0].id === 'number') {
            form.deviceLedgerIds = deviceIdsArray.map(id => Number(id)).filter(id => !isNaN(id));
        } else {
            form.deviceLedgerIds = deviceIdsArray;
        }
    } else if (row.deviceIds && Array.isArray(row.deviceIds)) {
        form.deviceLedgerIds = row.deviceIds;
    } else {
        form.deviceLedgerIds = [];
    }
    operationType.value = 'edit'
    dialogVisible.value = true;
  await loadDeviceName();
  Object.assign(form, row);
  // 如果后端返回的是 deviceIds 字符串,需要转换为数组
  if (row.deviceIds && typeof row.deviceIds === 'string') {
    // 确保ID类型与设备选项中的ID类型一致
    const deviceIdsArray = row.deviceIds.split(',').map(id => id.trim()).filter(id => id);
    // 如果设备选项中的ID是数字类型,则转换为数字
    if (deviceOptions.value.length > 0 && typeof deviceOptions.value[0].id === 'number') {
      form.deviceLedgerIds = deviceIdsArray.map(id => Number(id)).filter(id => !isNaN(id));
    } else {
      form.deviceLedgerIds = deviceIdsArray;
    }
  } else if (row.deviceIds && Array.isArray(row.deviceIds)) {
    form.deviceLedgerIds = row.deviceIds;
  } else {
    form.deviceLedgerIds = [];
  }
  operationType.value = 'edit'
  dialogVisible.value = true;
};
// 删除分类
const deleteCategory = async (id) => {
    try {
        await ElMessageBox.confirm('此操作将永久删除该分类,是否继续?', '提示', {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'warning'
        });
        loading.value = true;
        const res = await delSparePart(id);
        if (res.code === 200) {
            ElMessage.success('删除成功');
            fetchListData();
        } else {
            ElMessage.error(res.message || '删除失败');
        }
    } catch (error) {
        if (error !== 'cancel') {
            ElMessage.error('删除失败');
        }
    } finally {
        loading.value = false;
    }
  try {
    await ElMessageBox.confirm('此操作将永久删除该分类,是否继续?', '提示', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      type: 'warning'
    });
    loading.value = true;
    const res = await delSparePart(id);
    if (res.code === 200) {
      ElMessage.success('删除成功');
      fetchListData();
    } else {
      ElMessage.error(res.message || '删除失败');
    }
  } catch (error) {
    if (error !== 'cancel') {
      ElMessage.error('删除失败');
    }
  } finally {
    loading.value = false;
  }
};
// 提交表单
const submitForm = async () => {
    if (!formRef.value) return;
    try {
        await formRef.value.validate();
        formLoading.value = true;
        // 构建提交数据
        const submitData = {
            ...form,
            deviceIds: form.deviceLedgerIds && form.deviceLedgerIds.length > 0
                ? form.deviceLedgerIds.join(',')
                : ''
        };
        // 删除不需要的字段
        delete submitData.deviceLedgerIds;
        if (operationType.value === 'edit') {
            let res = await editSparePart(submitData);
            if (res.code === 200) {
                ElMessage.success('编辑成功');
                dialogVisible.value = false;
                fetchListData();
            }
        } else {
            let res = await addSparePart(submitData);
            if (res.code === 200) {
                ElMessage.success('新增成功');
                dialogVisible.value = false;
                fetchListData();
            }
        }
    } catch (error) {
        ElMessage.error('请填写完整表单信息');
    } finally {
        formLoading.value = false;
    }
};
// 直接出库
const requisitionDialogVisible = ref(false);
const requisitionLoading = ref(false);
const requisitionFormRef = ref(null);
const requisitionDeviceOptions = ref([]);
const requisitionSparePartsOptions = ref([]);
const selectedSparePartMaxQty = ref(1);
const requisitionForm = reactive({
    deviceLedgerId: null,
    sparePartsId: null,
    quantity: 1,
    remark: '',
});
const requisitionRules = {
    sparePartsId: [{ required: true, message: '请选择备件', trigger: 'change' }],
    quantity: [{ required: true, message: '请输入领用数量', trigger: 'blur' }],
};
const loadRequisitionOptions = async () => {
    try {
        const [deviceRes, spareRes] = await Promise.all([
            getDeviceLedger(),
            getSparePartsList({ current: 1, size: 9999 }),
        ]);
        requisitionDeviceOptions.value = deviceRes.data || [];
        requisitionSparePartsOptions.value = spareRes.data?.records || [];
    } catch (e) {
        ElMessage.error('加载选项失败');
    }
};
const openRequisitionDialog = async () => {
    requisitionForm.deviceLedgerId = null;
    requisitionForm.sparePartsId = null;
    requisitionForm.quantity = 1;
    requisitionForm.remark = '';
    selectedSparePartMaxQty.value = 1;
    await loadRequisitionOptions();
    requisitionDialogVisible.value = true;
};
const onRequisitionSparePartChange = (val) => {
    const selected = requisitionSparePartsOptions.value.find(item => item.id === val);
    selectedSparePartMaxQty.value = selected ? selected.quantity : 1;
    if (requisitionForm.quantity > selectedSparePartMaxQty.value) {
        requisitionForm.quantity = selectedSparePartMaxQty.value;
    }
};
const submitRequisition = async () => {
    if (!requisitionFormRef.value) return;
    try {
        await requisitionFormRef.value.validate();
    } catch {
        return;
    }
    if (requisitionForm.quantity <= 0) {
        ElMessage.warning('领用数量必须大于0');
        return;
    }
    const selected = requisitionSparePartsOptions.value.find(item => item.id === requisitionForm.sparePartsId);
    if (selected && requisitionForm.quantity > selected.quantity) {
        ElMessage.warning(`库存不足,当前库存为 ${selected.quantity}`);
        return;
    }
    requisitionLoading.value = true;
    try {
        const res = await outboundSpareParts({
            deviceLedgerId: requisitionForm.deviceLedgerId || undefined,
            sparePartsId: requisitionForm.sparePartsId,
            quantity: requisitionForm.quantity,
            remark: requisitionForm.remark || undefined,
        });
        if (res.code === 200) {
            ElMessage.success('领用成功');
            requisitionDialogVisible.value = false;
            fetchUsageData();
        } else {
            ElMessage.error(res.msg || '领用失败');
        }
    } catch {
        ElMessage.error('领用失败');
    } finally {
        requisitionLoading.value = false;
    }
  if (!formRef.value) return;
  try {
    await formRef.value.validate();
    formLoading.value = true;
    // 构建提交数据
    const submitData = {
      ...form,
      deviceIds: form.deviceLedgerIds && form.deviceLedgerIds.length > 0
        ? form.deviceLedgerIds.join(',')
        : ''
    };
    // 删除不需要的字段
    delete submitData.deviceLedgerIds;
    if (operationType.value === 'edit') {
      let res = await editSparePart(submitData);
      if (res.code === 200) {
        ElMessage.success('编辑成功');
        dialogVisible.value = false;
        fetchListData();
      }
    } else {
      let res = await addSparePart(submitData);
      if (res.code === 200) {
        ElMessage.success('新增成功');
        dialogVisible.value = false;
        fetchListData();
      }
    }
  } catch (error) {
    ElMessage.error('请填写完整表单信息');
  } finally {
    formLoading.value = false;
  }
};
// 组件挂载时获取列表数据
onMounted(() => {
    fetchListData();
  fetchListData();
});
</script>
<style scoped>
.spare-part-category {
    padding: 20px;
  padding: 20px;
}
.search_form {
    display: flex;
@@ -672,38 +534,38 @@
    justify-content: space-between;
}
.table_list {
    margin-top: unset;
  margin-top: unset;
}
.pagination-container {
    margin-top: 20px;
    display: flex;
    justify-content: flex-end;
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}
.el-table__header-wrapper th {
    background-color: #f5f7fa;
    font-weight: 600;
  background-color: #f5f7fa;
  font-weight: 600;
}
.el-table__row:hover > td {
    background-color: #fafafa;
  background-color: #fafafa;
}
/* 按钮组样式 */
.actions > div {
    display: flex;
    gap: 10px;
  display: flex;
  gap: 10px;
}
/* 确保表格中的操作按钮不会被截断 */
.el-table-column--fixed-right .el-button {
    margin: 0 2px;
  margin: 0 2px;
}
/* 树形节点内容样式 */
.nested-tree .el-tree-node__expand-icon {
    font-size: 12px;
    margin-right: 4px;
  font-size: 12px;
  margin-right: 4px;
}
</style>
src/views/equipmentManagement/upkeep/index.vue
@@ -1,726 +1,653 @@
<template>
    <div class="app-container">
        <el-tabs v-model="activeTab"
                 @tab-change="handleTabChange">
            <!-- 保养任务tab -->
            <el-tab-pane label="保养任务"
                         name="scheduled">
                <div class="search_form">
                    <el-form :model="scheduledFilters"
                             :inline="true">
                        <el-form-item label="任务名称">
                            <el-input v-model="scheduledFilters.taskName"
                                      style="width: 240px"
                                      placeholder="请输入任务名称"
                                      clearable
                                      :prefix-icon="Search"
                                      @change="getScheduledTableData" />
                        </el-form-item>
                        <el-form-item label="任务状态">
                            <el-select v-model="scheduledFilters.status"
                                       placeholder="请选择任务状态"
                                       clearable
                                       style="width: 200px">
                                <el-option label="启用"
                                           value="1" />
                                <el-option label="停用"
                                           value="0" />
                            </el-select>
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary"
                                       @click="getScheduledTableData">搜索</el-button>
                            <el-button @click="resetScheduledFilters">重置</el-button>
                        </el-form-item>
                    </el-form>
                </div>
                <div class="table_list">
                    <div class="actions">
                        <el-text class="mx-1"
                                 size="large">保养任务</el-text>
                        <div>
                            <el-button type="primary"
                                       icon="Plus"
                                       @click="addScheduledTask">
                                新增任务
                            </el-button>
                            <el-button type="danger"
                                       icon="Delete"
                                       :disabled="scheduledMultipleList.length <= 0"
                                       @click="delScheduledTaskByIds(scheduledMultipleList.map((item) => item.id))">
                                批量删除
                            </el-button>
                        </div>
                    </div>
                    <PIMTable rowKey="id"
                              isSelection
                              :column="scheduledColumns"
                              :tableData="scheduledDataList"
                              :page="{
  <div class="app-container">
    <el-tabs v-model="activeTab"
             @tab-change="handleTabChange">
      <!-- 保养任务tab -->
      <el-tab-pane label="保养任务"
                   name="scheduled">
        <div class="search_form">
          <el-form :model="scheduledFilters"
                   :inline="true">
            <el-form-item label="任务名称">
              <el-input v-model="scheduledFilters.taskName"
                        style="width: 240px"
                        placeholder="请输入任务名称"
                        clearable
                        :prefix-icon="Search"
                        @change="getScheduledTableData" />
            </el-form-item>
            <el-form-item label="任务状态">
              <el-select v-model="scheduledFilters.status"
                         placeholder="请选择任务状态"
                         clearable
                         style="width: 200px">
                <el-option label="启用"
                           value="1" />
                <el-option label="停用"
                           value="0" />
              </el-select>
            </el-form-item>
            <el-form-item>
              <el-button type="primary"
                         @click="getScheduledTableData">搜索</el-button>
              <el-button @click="resetScheduledFilters">重置</el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="table_list">
          <div class="actions">
            <el-text class="mx-1"
                     size="large">保养任务</el-text>
            <div>
              <el-button type="primary"
                         icon="Plus"
                         @click="addScheduledTask">
                新增任务
              </el-button>
              <el-button type="danger"
                         icon="Delete"
                         :disabled="scheduledMultipleList.length <= 0"
                         @click="delScheduledTaskByIds(scheduledMultipleList.map((item) => item.id))">
                批量删除
              </el-button>
            </div>
          </div>
          <PIMTable rowKey="id"
                    isSelection
                    :column="scheduledColumns"
                    :tableData="scheduledDataList"
                    :page="{
              current: scheduledPagination.currentPage,
              size: scheduledPagination.pageSize,
              total: scheduledPagination.total,
            }"
                              @selection-change="handleScheduledSelectionChange"
                              @pagination="changeScheduledPage">
                        <template #statusRef="{ row }">
                            <el-tag v-if="row.status === 1"
                                    type="success">启用</el-tag>
                            <el-tag v-if="row.status === 0"
                                    type="danger">停用</el-tag>
                        </template>
                        <template #operation="{ row }">
                            <el-button type="primary"
                                       link
                                       @click="editScheduledTask(row)">
                                编辑
                            </el-button>
                            <el-button type="danger"
                                       link
                                       @click="delScheduledTaskByIds(row.id)">
                                删除
                            </el-button>
                        </template>
                    </PIMTable>
                </div>
            </el-tab-pane>
            <!-- 保养记录tab(原设备保养页面) -->
            <el-tab-pane label="保养记录"
                         name="record">
                <div class="search_form">
                    <el-form :model="filters"
                             :inline="true">
                        <el-form-item label="设备名称">
                            <el-input v-model="filters.deviceName"
                                      style="width: 240px"
                                      placeholder="请输入设备名称"
                                      clearable
                                      :prefix-icon="Search"
                                      @change="getTableData" />
                        </el-form-item>
                        <el-form-item label="计划保养日期">
                            <el-date-picker v-model="filters.maintenancePlanTime"
                                            type="date"
                                            placeholder="请选择计划保养日期"
                                            size="default"
                                            @change="(date) => handleDateChange(date,2)" />
                        </el-form-item>
                        <el-form-item label="实际保养日期">
                            <el-date-picker v-model="filters.maintenanceActuallyTime"
                                            type="date"
                                            placeholder="请选择实际保养日期"
                                            size="default"
                                            @change="(date) => handleDateChange(date,1)" />
                        </el-form-item>
                        <el-form-item label="实际保养人">
                            <el-input v-model="filters.maintenanceActuallyName"
                                      style="width: 240px"
                                      placeholder="请输入实际保养人"
                                      clearable
                                      :prefix-icon="Search"
                                      @change="getTableData" />
                        </el-form-item>
                        <el-form-item>
                            <el-button type="primary"
                                       @click="getTableData">搜索</el-button>
                            <el-button @click="resetFilters">重置</el-button>
                        </el-form-item>
                    </el-form>
                </div>
                <div class="table_list">
                    <div class="actions">
                        <el-text class="mx-1"
                                 size="large">保养记录</el-text>
                        <div>
                            <el-button type="success"
                                       icon="Van"
                                       @click="addPlan">
                                新增计划
                            </el-button>
                            <el-button @click="handleOut">
                                导出
                            </el-button>
                            <el-button type="danger"
                                       icon="Delete"
                                       :disabled="multipleList.length <= 0"
                                       @click="delRepairByIds(multipleList.map((item) => item.id))">
                                批量删除
                            </el-button>
                        </div>
                    </div>
                    <el-table
                        :data="groupedDataList"
                        border
                        v-loading="tableLoading"
                        @selection-change="handleSelectionChange"
                        :expand-row-keys="expandedRowKeys"
                        :row-key="(row) => row.date"
                        @expand-change="onExpandChange"
                    >
                        <el-table-column type="selection" width="55" />
                        <el-table-column type="expand">
                            <template #default="props">
                                <el-table :data="props.row.children" border row-key="id">
                                    <el-table-column label="设备名称" prop="deviceName" align="center" />
                                    <el-table-column label="规格型号" prop="deviceModel" align="center" />
                                    <el-table-column label="录入人" prop="createUserName" align="center" />
                                    <el-table-column label="保养项目" prop="machineryCategory" align="center">
                                        <template #default="{ row }">
                                            {{ row.machineryCategory || '--' }}
                                        </template>
                                    </el-table-column>
                                    <el-table-column label="实际保养人" prop="maintenanceActuallyName" align="center" />
                                    <el-table-column label="实际保养日期" align="center">
                                        <template #default="{ row }">
                                            {{ row.maintenanceActuallyTime ? dayjs(row.maintenanceActuallyTime).format('YYYY-MM-DD HH:mm:ss') : '-' }}
                                        </template>
                                    </el-table-column>
                                    <el-table-column label="保养结果" align="center">
                                        <template #default="{ row }">
                                            {{ row.maintenanceResult || '-' }}
                                        </template>
                                    </el-table-column>
                                    <el-table-column label="状态" align="center">
                                        <template #default="{ row }">
                                            <el-tag v-if="row.status === 2" type="danger">失败</el-tag>
                                            <el-tag v-if="row.status === 1" type="success">完结</el-tag>
                                            <el-tag v-if="row.status === 0" type="warning">待保养</el-tag>
                                        </template>
                                    </el-table-column>
                                    <el-table-column label="操作" align="center" width="300">
                                        <template #default="{ row }">
                                            <el-button type="primary" link :disabled="row.status === 1" @click="editPlan(row.id)">编辑</el-button>
                                            <el-button type="success" link :disabled="row.status !== 0" @click="handleSingleComplete(row.id)">保养完成</el-button>
                                            <el-button type="success" link :disabled="row.status === 1" @click="addMaintain(row)">保养</el-button>
                                            <el-button type="danger" link :disabled="row.status === 1" @click="delRepairByIds(row.id)">删除</el-button>
                                            <el-button type="primary" link @click="openFileDialog(row)">附件</el-button>
                                        </template>
                                    </el-table-column>
                                </el-table>
                            </template>
                        </el-table-column>
                        <el-table-column label="计划保养日期" prop="date" align="center" />
                        <el-table-column label="保养记录数" prop="count" align="center" />
                        <el-table-column label="待保养数" align="center" width="120">
                            <template #default="{ row }">
                                {{ row.children.filter(c => c.status === 0).length }}
                            </template>
                        </el-table-column>
                        <el-table-column label="操作" align="center" width="200">
                            <template #default="{ row }">
                                <el-button
                                    type="primary"
                                    size="small"
                                    :disabled="!row.children.some(c => c.status === 0)"
                                    @click="handleBatchComplete(row.date)"
                                >
                                    一键保养完成
                                </el-button>
                            </template>
                        </el-table-column>
                    </el-table>
                    <Pagination
                        v-show="pagination.total > 0"
                        :total="pagination.total"
                        layout="total, sizes, prev, pager, next, jumper"
                        :page="pagination.currentPage"
                        :limit="pagination.pageSize"
                        @pagination="changePage"
                    />
                </div>
            </el-tab-pane>
        </el-tabs>
        <PlanModal ref="planModalRef"
                   @ok="getTableData" />
        <MaintenanceModal ref="maintainModalRef"
                          @ok="getTableData" />
        <FormDia ref="formDiaRef"
                 @closeDia="getScheduledTableData" />
        <FileList v-if="fileDialogVisible"
                  v-model:visible="fileDialogVisible"
                  :record-type="'device_maintenance'"
                  :record-id="currentMaintenanceTaskId" />
    </div>
                    @selection-change="handleScheduledSelectionChange"
                    @pagination="changeScheduledPage">
            <template #statusRef="{ row }">
              <el-tag v-if="row.status === 1"
                      type="success">启用</el-tag>
              <el-tag v-if="row.status === 0"
                      type="danger">停用</el-tag>
            </template>
            <template #operation="{ row }">
              <el-button type="primary"
                         link
                         @click="editScheduledTask(row)">
                编辑
              </el-button>
              <el-button type="danger"
                         link
                         @click="delScheduledTaskByIds(row.id)">
                删除
              </el-button>
            </template>
          </PIMTable>
        </div>
      </el-tab-pane>
      <!-- 保养记录tab(原设备保养页面) -->
      <el-tab-pane label="保养记录"
                   name="record">
        <div class="search_form">
          <el-form :model="filters"
                   :inline="true">
            <el-form-item label="设备名称">
              <el-input v-model="filters.deviceName"
                        style="width: 240px"
                        placeholder="请输入设备名称"
                        clearable
                        :prefix-icon="Search"
                        @change="getTableData" />
            </el-form-item>
            <el-form-item label="计划保养日期">
              <el-date-picker v-model="filters.maintenancePlanTime"
                              type="date"
                              placeholder="请选择计划保养日期"
                              size="default"
                              @change="(date) => handleDateChange(date,2)" />
            </el-form-item>
            <el-form-item label="实际保养日期">
              <el-date-picker v-model="filters.maintenanceActuallyTime"
                              type="date"
                              placeholder="请选择实际保养日期"
                              size="default"
                              @change="(date) => handleDateChange(date,1)" />
            </el-form-item>
            <el-form-item label="实际保养人">
              <el-input v-model="filters.maintenanceActuallyName"
                        style="width: 240px"
                        placeholder="请输入实际保养人"
                        clearable
                        :prefix-icon="Search"
                        @change="getTableData" />
            </el-form-item>
            <el-form-item>
              <el-button type="primary"
                         @click="getTableData">搜索</el-button>
              <el-button @click="resetFilters">重置</el-button>
            </el-form-item>
          </el-form>
        </div>
        <div class="table_list">
          <div class="actions">
            <el-text class="mx-1"
                     size="large">保养记录</el-text>
            <div>
              <el-button type="success"
                         icon="Van"
                         @click="addPlan">
                新增计划
              </el-button>
              <el-button @click="handleOut">
                导出
              </el-button>
              <el-button type="danger"
                         icon="Delete"
                         :disabled="multipleList.length <= 0 || hasFinishedStatus"
                         @click="delRepairByIds(multipleList.map((item) => item.id))">
                批量删除
              </el-button>
            </div>
          </div>
          <PIMTable rowKey="id"
                    isSelection
                    :column="columns"
                    :tableData="dataList"
                    :page="{
          current: pagination.currentPage,
          size: pagination.pageSize,
          total: pagination.total,
        }"
                    @selection-change="handleSelectionChange"
                    @pagination="changePage">
            <template #maintenanceResultRef="{ row }">
              <div>{{ row.maintenanceResult || '-' }}</div>
            </template>
            <template #statusRef="{ row }">
              <el-tag v-if="row.status === 2"
                      type="danger">失败</el-tag>
              <el-tag v-if="row.status === 1"
                      type="success">完结</el-tag>
              <el-tag v-if="row.status === 0"
                      type="warning">待保养</el-tag>
            </template>
            <template #operation="{ row }">
              <!-- 这个功能跟新增保养功能一模一样,有啥意义? -->
              <!-- <el-button
              type="primary"
              text
              @click="addMaintain(row)"
          >
            新增保养
          </el-button> -->
              <el-button type="primary"
                         link
                         :disabled="row.status === 1"
                         @click="editPlan(row.id)">
                编辑
              </el-button>
              <el-button type="success"
                         link
                         :disabled="row.status === 1"
                         @click="addMaintain(row)">
                保养
              </el-button>
              <el-button type="danger"
                         link
                         :disabled="row.status === 1"
                         @click="delRepairByIds(row.id)">
                删除
              </el-button>
              <el-button type="primary"
                         link
                         @click="openFileDialog(row)">
                附件
              </el-button>
            </template>
          </PIMTable>
        </div>
      </el-tab-pane>
    </el-tabs>
    <PlanModal ref="planModalRef"
               @ok="getTableData" />
    <MaintenanceModal ref="maintainModalRef"
                      @ok="getTableData" />
    <FormDia ref="formDiaRef"
             @closeDia="getScheduledTableData" />
    <FileList v-if="fileDialogVisible"
              v-model:visible="fileDialogVisible"
              :record-type="'device_maintenance'"
              :record-id="currentMaintenanceTaskId" />
  </div>
</template>
<script setup>
import {
    ref,
    onMounted,
    reactive,
    getCurrentInstance,
    nextTick,
    computed,
    defineAsyncComponent,
} from "vue";
import { Search } from "@element-plus/icons-vue";
import { ElMessage, ElMessageBox } from "element-plus";
import PlanModal from "./Form/PlanModal.vue";
import MaintenanceModal from "./Form/MaintenanceModal.vue";
import FormDia from "./Form/formDia.vue";
import {
    getUpkeepPage,
    delUpkeep,
    deviceMaintenanceTaskList,
    deviceMaintenanceTaskDel,
    batchCompleteMaintenance,
    completeMaintenance,
} from "@/api/equipmentManagement/upkeep";
import dayjs from "dayjs";
import Pagination from "@/components/PIMTable/Pagination.vue";
  import {
    ref,
    onMounted,
    reactive,
    getCurrentInstance,
    nextTick,
    computed,
    defineAsyncComponent,
  } from "vue";
  import { Search } from "@element-plus/icons-vue";
  import { ElMessage, ElMessageBox } from "element-plus";
  import PlanModal from "./Form/PlanModal.vue";
  import MaintenanceModal from "./Form/MaintenanceModal.vue";
  import FormDia from "./Form/formDia.vue";
  import {
    getUpkeepPage,
    delUpkeep,
    deviceMaintenanceTaskList,
    deviceMaintenanceTaskDel,
  } from "@/api/equipmentManagement/upkeep";
  import dayjs from "dayjs";
const { proxy } = getCurrentInstance();
const FileList = defineAsyncComponent(() =>
    import("@/components/Dialog/FileList.vue")
);
  const { proxy } = getCurrentInstance();
  const FileList = defineAsyncComponent(() =>
    import("@/components/Dialog/FileList.vue")
  );
// Tab相关
const activeTab = ref("scheduled");
  // Tab相关
  const activeTab = ref("scheduled");
// 计划弹窗控制器
const planModalRef = ref();
// 保养弹窗控制器
const maintainModalRef = ref();
// 定时任务弹窗控制器
const formDiaRef = ref();
// 附件弹窗
const fileListDialogRef = ref(null);
const fileDialogVisible = ref(false);
const currentMaintenanceTaskId = ref(null);
  // 计划弹窗控制器
  const planModalRef = ref();
  // 保养弹窗控制器
  const maintainModalRef = ref();
  // 定时任务弹窗控制器
  const formDiaRef = ref();
  // 附件弹窗
  const fileListDialogRef = ref(null);
  const fileDialogVisible = ref(false);
  const currentMaintenanceTaskId = ref(null);
// 保养记录tab(原设备保养页面)相关变量
const filters = reactive({
    deviceName: "",
    maintenancePlanTime: "",
    maintenanceActuallyTime: "",
    maintenanceActuallyName: "",
});
  // 保养记录tab(原设备保养页面)相关变量
  const filters = reactive({
    deviceName: "",
    maintenancePlanTime: "",
    maintenanceActuallyTime: "",
    maintenanceActuallyName: "",
  });
const dataList = ref([]);
const pagination = ref({
    currentPage: 1,
    pageSize: 100,
    total: 0,
});
const multipleList = ref([]);
const tableLoading = ref(false);
const expandedRowKeys = ref([]);
  const dataList = ref([]);
  const pagination = ref({
    currentPage: 1,
    pageSize: 10,
    total: 0,
  });
  const multipleList = ref([]);
const groupByDate = (list) => {
    const map = {};
    list.forEach(item => {
        const date = item.dateStr || (item.maintenancePlanTime ? dayjs(item.maintenancePlanTime).format('YYYY-MM-DD') : (item.createTime ? dayjs(item.createTime).format('YYYY-MM-DD') : '未知日期'));
        if (!map[date]) map[date] = [];
        map[date].push(item);
    });
    return Object.entries(map).map(([date, children]) => ({ date, children, count: children.length }));
};
  // 保养任务tab相关变量
  const scheduledFilters = reactive({
    taskName: "",
    status: "",
  });
const groupedDataList = computed(() => groupByDate(dataList.value));
  const scheduledDataList = ref([]);
  const scheduledPagination = reactive({
    currentPage: 1,
    pageSize: 10,
    total: 0,
  });
  const scheduledMultipleList = ref([]);
// 单条保养完成
const handleSingleComplete = async (id) => {
    try {
        await ElMessageBox.confirm('确认将该保养记录标记为完成?', '提示', { type: 'warning' });
        const res = await completeMaintenance(id);
        if (res.code === 200) {
            ElMessage.success('保养完成');
            getTableData();
        } else {
            ElMessage.error(res.msg || '操作失败');
        }
    } catch { /* 取消 */ }
};
  // 保养任务表格列配置
  const scheduledColumns = ref([
    { prop: "taskName", label: "设备名称" },
    {
      label: "规格型号",
      prop: "deviceModel",
    },
    {
      label: "保养项目",
      prop: "machineryCategory",
      minWidth: 120,
      formatData: cell => cell || "--",
    },
    {
      prop: "frequencyType",
      label: "频次",
      minWidth: 150,
      // PIMTable 使用的是 formatData,而不是 Element-Plus 的 formatter
      formatData: cell =>
        ({
          DAILY: "每日",
          WEEKLY: "每周",
          MONTHLY: "每月",
          QUARTERLY: "季度",
        }[cell] || ""),
    },
    {
      prop: "frequencyDetail",
      label: "开始日期与时间",
      minWidth: 150,
      // 同样改用 formatData,PIMTable 内部会把单元格值传进来
      formatData: cell => {
        if (typeof cell !== "string") return "";
        let val = cell;
        const replacements = {
          MON: "周一",
          TUE: "周二",
          WED: "周三",
          THU: "周四",
          FRI: "周五",
          SAT: "周六",
          SUN: "周日",
        };
        // 使用正则一次性替换所有匹配项
        return val.replace(
          /MON|TUE|WED|THU|FRI|SAT|SUN/g,
          match => replacements[match]
        );
      },
    },
    { prop: "maintenancePerson", label: "保养人", minWidth: 100 },
    { prop: "registrant", label: "登记人", minWidth: 100 },
    {
      prop: "registrationDate",
      label: "登记日期",
      minWidth: 100,
      formatData: cell =>
          // cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
      cell ? dayjs(cell).format("YYYY-MM-DD") : "-",
    },
    {
      fixed: "right",
      label: "操作",
      dataType: "slot",
      slot: "operation",
      align: "center",
      width: "200px",
    },
  ]);
// 一键保养完成
const handleBatchComplete = async (dateStr) => {
    try {
        await ElMessageBox.confirm(`确认将 ${dateStr} 的所有待保养记录标记为完成?`, '提示', { type: 'warning' });
        const res = await batchCompleteMaintenance(dateStr);
        if (res.code === 200) {
            ElMessage.success(res.msg || '批量保养完成成功');
            getTableData();
        } else {
            ElMessage.error(res.msg || '批量保养完成失败');
        }
    } catch { /* 取消 */ }
};
  // 保养记录表格列配置(原设备保养表格列)
  const columns = ref([
    {
      label: "设备名称",
      align: "center",
      prop: "deviceName",
    },
    {
      label: "规格型号",
      align: "center",
      prop: "deviceModel",
    },
    {
      label: "计划保养日期",
      align: "center",
      prop: "maintenancePlanTime",
      formatData: cell => {
        return cell == null ? "-" : dayjs(cell).format("YYYY-MM-DD");
      },
    },
    {
      label: "录入人",
      align: "center",
      prop: "createUserName",
    },
    {
      label: "保养项目",
      align: "center",
      prop: "machineryCategory",
      formatData: cell => cell || "--",
    },
    // {
    //   label: "录入日期",
    //   align: "center",
    //   prop: "createTime",
    //   formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
    //   width: 200,
    // },
    {
      label: "实际保养人",
      align: "center",
      prop: "maintenanceActuallyName",
    },
    {
      label: "实际保养日期",
      align: "center",
      prop: "maintenanceActuallyTime",
      formatData: cell =>
        cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
    },
    {
      label: "保养结果",
      align: "center",
      prop: "maintenanceResult",
      dataType: "slot",
      slot: "maintenanceResultRef",
    },
    {
      label: "状态",
      align: "center",
      prop: "status",
      dataType: "slot",
      slot: "statusRef",
    },
    {
      fixed: "right",
      label: "操作",
      dataType: "slot",
      slot: "operation",
      align: "center",
      width: "350px",
    },
  ]);
const onExpandChange = (row, expandedRows) => {
    expandedRowKeys.value = expandedRows.map(r => r.date);
};
  // Tab切换处理
  const handleTabChange = tabName => {
    if (tabName === "record") {
      getTableData();
    } else if (tabName === "scheduled") {
      getScheduledTableData();
    }
  };
// 保养任务tab相关变量
const scheduledFilters = reactive({
    taskName: "",
    status: "",
});
  // 保养任务相关方法
  const getScheduledTableData = async () => {
    try {
      const params = {
        current: scheduledPagination.currentPage,
        size: scheduledPagination.pageSize,
        taskName: scheduledFilters.taskName || undefined,
        status: scheduledFilters.status || undefined,
      };
      const { code, data } = await deviceMaintenanceTaskList(params);
      if (code === 200) {
        scheduledDataList.value = data?.records || [];
        scheduledPagination.total = data?.total || 0;
      }
    } catch (error) {
      ElMessage.error("获取定时任务列表失败");
    }
  };
const scheduledDataList = ref([]);
const scheduledPagination = reactive({
    currentPage: 1,
    pageSize: 10,
    total: 0,
});
const scheduledMultipleList = ref([]);
  const resetScheduledFilters = () => {
    scheduledFilters.taskName = "";
    scheduledFilters.status = "";
    getScheduledTableData();
  };
// 保养任务表格列配置
const scheduledColumns = ref([
    { prop: "taskName", label: "设备名称" },
    {
        label: "规格型号",
        prop: "deviceModel",
    },
    {
        label: "保养项目",
        prop: "machineryCategory",
        minWidth: 120,
        formatData: cell => cell || "--",
    },
    {
        prop: "frequencyType",
        label: "频次",
        minWidth: 150,
        // PIMTable 使用的是 formatData,而不是 Element-Plus 的 formatter
        formatData: cell =>
            ({
                DAILY: "每日",
                WEEKLY: "每周",
                MONTHLY: "每月",
                QUARTERLY: "季度",
            }[cell] || ""),
    },
    {
        prop: "frequencyDetail",
        label: "开始日期与时间",
        minWidth: 150,
        // 同样改用 formatData,PIMTable 内部会把单元格值传进来
        formatData: cell => {
            if (typeof cell !== "string") return "";
            let val = cell;
            const replacements = {
                MON: "周一",
                TUE: "周二",
                WED: "周三",
                THU: "周四",
                FRI: "周五",
                SAT: "周六",
                SUN: "周日",
            };
            // 使用正则一次性替换所有匹配项
            return val.replace(
                /MON|TUE|WED|THU|FRI|SAT|SUN/g,
                match => replacements[match]
            );
        },
    },
    { prop: "maintenancePerson", label: "保养人", minWidth: 100 },
    { prop: "registrant", label: "登记人", minWidth: 100 },
    {
        prop: "registrationDate",
        label: "登记日期",
        minWidth: 100,
        formatData: cell =>
            cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
    },
    {
        fixed: "right",
        label: "操作",
        dataType: "slot",
        slot: "operation",
        align: "center",
        width: "200px",
    },
]);
  const handleScheduledSelectionChange = selection => {
    scheduledMultipleList.value = selection;
  };
// 保养记录表格列配置(原设备保养表格列)
const columns = ref([
    {
        label: "设备名称",
        align: "center",
        prop: "deviceName",
    },
    {
        label: "规格型号",
        align: "center",
        prop: "deviceModel",
    },
    {
        label: "计划保养日期",
        align: "center",
        prop: "maintenancePlanTime",
        formatData: cell => {
            return cell == null ? "-" : dayjs(cell).format("YYYY-MM-DD");
        },
    },
    {
        label: "录入人",
        align: "center",
        prop: "createUserName",
    },
    {
        label: "保养项目",
        align: "center",
        prop: "machineryCategory",
        formatData: cell => cell || "--",
    },
    // {
    //   label: "录入日期",
    //   align: "center",
    //   prop: "createTime",
    //   formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
    //   width: 200,
    // },
    {
        label: "实际保养人",
        align: "center",
        prop: "maintenanceActuallyName",
    },
    {
        label: "实际保养日期",
        align: "center",
        prop: "maintenanceActuallyTime",
        formatData: cell =>
            cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
    },
    {
        label: "保养结果",
        align: "center",
        prop: "maintenanceResult",
        dataType: "slot",
        slot: "maintenanceResultRef",
    },
    {
        label: "状态",
        align: "center",
        prop: "status",
        dataType: "slot",
        slot: "statusRef",
    },
    {
        fixed: "right",
        label: "操作",
        dataType: "slot",
        slot: "operation",
        align: "center",
        width: "350px",
    },
]);
  const changeScheduledPage = page => {
    scheduledPagination.currentPage = page.page;
    scheduledPagination.pageSize = page.limit;
    getScheduledTableData();
  };
// Tab切换处理
const handleTabChange = tabName => {
    if (tabName === "record") {
        getTableData();
    } else if (tabName === "scheduled") {
        getScheduledTableData();
    }
};
  const addScheduledTask = () => {
    nextTick(() => {
      formDiaRef.value?.openDialog("add");
    });
  };
// 保养任务相关方法
const getScheduledTableData = async () => {
    try {
        const params = {
            current: scheduledPagination.currentPage,
            size: scheduledPagination.pageSize,
            taskName: scheduledFilters.taskName || undefined,
            status: scheduledFilters.status || undefined,
        };
        const { code, data } = await deviceMaintenanceTaskList(params);
        if (code === 200) {
            scheduledDataList.value = data?.records || [];
            scheduledPagination.total = data?.total || 0;
        }
    } catch (error) {
        ElMessage.error("获取定时任务列表失败");
    }
};
  const editScheduledTask = row => {
    if (row) {
      nextTick(() => {
        formDiaRef.value?.openDialog("edit", row);
      });
    }
  };
const resetScheduledFilters = () => {
    scheduledFilters.taskName = "";
    scheduledFilters.status = "";
    getScheduledTableData();
};
  const delScheduledTaskByIds = async ids => {
    try {
      await ElMessageBox.confirm("确定删除选中的定时任务吗?", "提示", {
        type: "warning",
      });
      const payload = Array.isArray(ids) ? ids : [ids];
      await deviceMaintenanceTaskDel(payload);
      ElMessage.success("删除定时任务成功");
      getScheduledTableData();
    } catch (error) {
      // 用户取消删除
    }
  };
const handleScheduledSelectionChange = selection => {
    scheduledMultipleList.value = selection;
};
  const handleScheduledOut = () => {
    ElMessage.info("导出定时任务功能待实现");
  };
const changeScheduledPage = page => {
    scheduledPagination.currentPage = page.page;
    scheduledPagination.pageSize = page.limit;
    getScheduledTableData();
};
  // 保养记录相关方法(原设备保养页面方法)
  const getTableData = async () => {
    try {
      const params = {
        current: pagination.value.currentPage,
        size: pagination.value.pageSize,
        deviceName: filters.deviceName || undefined,
        maintenancePlanTime: filters.maintenancePlanTime
          ? dayjs(filters.maintenancePlanTime).format("YYYY-MM-DD")
          : undefined,
        maintenanceActuallyTime: filters.maintenanceActuallyTime
          ? dayjs(filters.maintenanceActuallyTime).format("YYYY-MM-DD")
          : undefined,
        maintenanceActuallyName: filters.maintenanceActuallyName || undefined,
      };
const addScheduledTask = () => {
    nextTick(() => {
        formDiaRef.value?.openDialog("add");
    });
};
      const { code, data } = await getUpkeepPage(params);
      if (code === 200) {
        dataList.value = data.records;
        pagination.value.total = data.total;
      }
    } catch (error) {
      console.log(error);
    }
  };
const editScheduledTask = row => {
    if (row) {
        nextTick(() => {
            formDiaRef.value?.openDialog("edit", row);
        });
    }
};
  const resetFilters = () => {
    filters.deviceName = "";
    filters.maintenancePlanTime = "";
    filters.maintenanceActuallyTime = "";
    filters.maintenanceActuallyName = "";
    getTableData();
  };
const delScheduledTaskByIds = async ids => {
    try {
        await ElMessageBox.confirm("确定删除选中的定时任务吗?", "提示", {
            type: "warning",
        });
        const payload = Array.isArray(ids) ? ids : [ids];
        await deviceMaintenanceTaskDel(payload);
        ElMessage.success("删除定时任务成功");
        getScheduledTableData();
    } catch (error) {
        // 用户取消删除
    }
};
  const handleSelectionChange = selection => {
    multipleList.value = selection;
  };
const handleScheduledOut = () => {
    ElMessage.info("导出定时任务功能待实现");
};
  // 检查选中的记录中是否有完结状态的
  const hasFinishedStatus = computed(() => {
    return multipleList.value.some(item => item.status === 1);
  });
// 保养记录相关方法(原设备保养页面方法)
const getTableData = async () => {
    tableLoading.value = true;
    try {
        const params = {
            current: pagination.value.currentPage,
            size: pagination.value.pageSize,
            deviceName: filters.deviceName || undefined,
            maintenancePlanTime: filters.maintenancePlanTime
                ? dayjs(filters.maintenancePlanTime).format("YYYY-MM-DD")
                : undefined,
            maintenanceActuallyTime: filters.maintenanceActuallyTime
                ? dayjs(filters.maintenanceActuallyTime).format("YYYY-MM-DD")
                : undefined,
            maintenanceActuallyName: filters.maintenanceActuallyName || undefined,
        };
        const { code, data } = await getUpkeepPage(params);
        if (code === 200) {
            dataList.value = data.records;
            pagination.value.total = data.total;
        }
    } catch (error) {
        console.log(error);
    } finally {
        tableLoading.value = false;
    }
};
  const changePage = page => {
    pagination.value.currentPage = page.page;
    pagination.value.pageSize = page.limit;
    getTableData();
  };
const resetFilters = () => {
    filters.deviceName = "";
    filters.maintenancePlanTime = "";
    filters.maintenanceActuallyTime = "";
    filters.maintenanceActuallyName = "";
    getTableData();
};
  const addMaintain = row => {
    maintainModalRef.value.open(row.id, row);
  };
const handleSelectionChange = selection => {
    // 从选中的分组行中收集所有子记录ID
    const ids = [];
    selection.forEach(group => {
        if (group.children) {
            group.children.forEach(child => ids.push(child.id));
        }
    });
    multipleList.value = ids;
};
  const addPlan = () => {
    planModalRef.value.openModal();
  };
const changePage = page => {
    pagination.value.currentPage = page.page;
    pagination.value.pageSize = page.limit;
    getTableData();
};
  const editPlan = id => {
    planModalRef.value.openEdit(id);
  };
const addMaintain = row => {
    maintainModalRef.value.open(row.id, row);
};
  const delRepairByIds = async ids => {
    // 检查是否有完结状态的记录
    const hasFinished = multipleList.value.some(item => item.status === 1);
    if (hasFinished) {
      ElMessage.warning("不能删除状态为完结的记录");
      return;
    }
const addPlan = () => {
    planModalRef.value.openModal();
};
    try {
      await ElMessageBox.confirm("确认删除保养数据, 此操作不可逆?", "警告", {
        confirmButtonText: "确定",
        cancelButtonText: "取消",
        type: "warning",
      });
const editPlan = id => {
    planModalRef.value.openEdit(id);
};
      const { code } = await delUpkeep(ids);
      if (code === 200) {
        ElMessage.success("删除成功");
        getTableData();
      }
    } catch (error) {
      // 用户取消删除
    }
  };
const delRepairByIds = async ids => {
    const idList = Array.isArray(ids) ? ids : [ids];
    if (idList.length === 0) return;
    try {
        await ElMessageBox.confirm("确认删除保养数据, 此操作不可逆?", "警告", {
            confirmButtonText: "确定",
            cancelButtonText: "取消",
            type: "warning",
        });
        const { code } = await delUpkeep(idList);
        if (code === 200) {
            ElMessage.success("删除成功");
            getTableData();
        }
    } catch (error) {
        // 用户取消删除
    }
};
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
    })
      .then(() => {
        proxy.download("/device/maintenance/export", {}, "设备保养.xlsx");
      })
      .catch(() => {
        ElMessage.info("已取消");
      });
  };
const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
        confirmButtonText: "确认",
        cancelButtonText: "取消",
        type: "warning",
    })
        .then(() => {
            proxy.download("/device/maintenance/export", {}, "设备保养.xlsx");
        })
        .catch(() => {
            ElMessage.info("已取消");
        });
};
  const handleDateChange = (date, type) => {
    if (type === 1) {
      filters.maintenanceActuallyTime = date
        ? dayjs(date).format("YYYY-MM-DD")
        : "";
    } else {
      filters.maintenancePlanTime = date ? dayjs(date).format("YYYY-MM-DD") : "";
    }
    getTableData();
  };
const handleDateChange = (date, type) => {
    if (type === 1) {
        filters.maintenanceActuallyTime = date
            ? dayjs(date).format("YYYY-MM-DD")
            : "";
    } else {
        filters.maintenancePlanTime = date ? dayjs(date).format("YYYY-MM-DD") : "";
    }
    getTableData();
};
  // 打开附件弹窗
  const openFileDialog = async row => {
    currentMaintenanceTaskId.value = row.id;
    fileDialogVisible.value = true;
  };
// 打开附件弹窗
const openFileDialog = async row => {
    currentMaintenanceTaskId.value = row.id;
    fileDialogVisible.value = true;
};
onMounted(() => {
    // 根据默认激活的 Tab 调用对应的查询接口
    if (activeTab.value === "scheduled") {
        getScheduledTableData();
    } else {
        getTableData();
    }
});
  onMounted(() => {
    // 根据默认激活的 Tab 调用对应的查询接口
    if (activeTab.value === "scheduled") {
      getScheduledTableData();
    } else {
      getTableData();
    }
  });
</script>
<style lang="scss" scoped>
.table_list {
    margin-top: unset;
}
.actions {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
}
  .table_list {
    margin-top: unset;
  }
  .actions {
    display: flex;
    justify-content: space-between;
    margin-bottom: 10px;
  }
</style>
src/views/financialManagement/payable/purchaseReturn.vue
@@ -85,7 +85,7 @@
  { label: "退货单号", prop: "returnNo", minWidth: "150" },
  { label: "供应商", prop: "supplierName", minWidth: "180" },
  { label: "关联入库单号", prop: "inboundBatches", minWidth: "150" },
  { label: "退货日期", prop: "preparedAt", minWidth: "170" },
  { label: "退货日期", prop: "preparedAt", minWidth: "170",dataType: "date"},
  {
    label: "退款总额",
    prop: "totalAmount",
src/views/financialManagement/receivable/salesReturn.vue
@@ -77,7 +77,7 @@
  { label: "退货单号", prop: "returnNo", minWidth: "150" },
  { label: "客户名称", prop: "customerName", minWidth: "180" },
  { label: "关联发货单号", prop: "shippingNo", minWidth: "150" },
  { label: "退货日期", prop: "makeTime", minWidth: "170" },
  { label: "退货日期", prop: "makeTime", minWidth: "170",dataType: "date" },
  {
    label: "退款总额",
    prop: "refundAmount",
src/views/inventoryManagement/dispatchLog/Record.vue
@@ -108,7 +108,11 @@
                         show-overflow-tooltip />
        <el-table-column label="出库日期"
                         prop="createTime"
                         show-overflow-tooltip />
                         show-overflow-tooltip >
          <template #default="scope">
            {{ scope.row.createTime ? scope.row.createTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="产品大类"
                         prop="productName"
                         show-overflow-tooltip />
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -107,9 +107,11 @@
                         prop="inboundBatches"
                         width="200"
                         show-overflow-tooltip />
        <el-table-column label="入库时间"
                         prop="createTime"
                         show-overflow-tooltip />
        <el-table-column label="入库时间" show-overflow-tooltip>
          <template #default="scope">
            {{ scope.row.createTime ? scope.row.createTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="产品大类"
                         prop="productName"
                         show-overflow-tooltip />
src/views/inventoryManagement/stockManagement/BatchNoQtyDetail.vue
@@ -50,11 +50,13 @@
            show-overflow-tooltip
          />
          <el-table-column label="备注" prop="remark" show-overflow-tooltip />
          <el-table-column
            label="最近更新时间"
            prop="updateTime"
            show-overflow-tooltip
          />
          <el-table-column label="最近更新时间"
                           prop="updateTime"
                           show-overflow-tooltip >
            <template #default="scope">
              {{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] : '-' }}
            </template>
          </el-table-column>
          <el-table-column fixed="right" label="操作" min-width="180" align="center">
            <template #default="scope">
              <el-button
src/views/inventoryManagement/stockManagement/Qualified.vue
@@ -31,7 +31,13 @@
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
        <el-table-column label="库存预警数量" prop="warnNum"  show-overflow-tooltip />
        <el-table-column label="备注" prop="remark"  show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column label="最近更新时间"
                         prop="updateTime"
                         show-overflow-tooltip >
          <template #default="scope">
            {{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" min-width="90" align="center">
          <template #default="scope">
            <el-button link type="primary" @click="showSubtractModal(scope.row)" :disabled="scope.row.unLockedQuantity === 0">领用</el-button>
src/views/inventoryManagement/stockManagement/Record.vue
@@ -107,7 +107,11 @@
                         show-overflow-tooltip />
        <el-table-column label="最近更新时间"
                         prop="updateTime"
                         show-overflow-tooltip />
                         show-overflow-tooltip >
          <template #default="scope">
            {{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column fixed="right"
                         label="操作"
                         min-width="80"
src/views/inventoryManagement/stockManagement/Unqualified.vue
@@ -26,7 +26,13 @@
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
        <el-table-column label="备注" prop="remark"  show-overflow-tooltip />
        <el-table-column label="最近更新时间" prop="updateTime" show-overflow-tooltip />
        <el-table-column label="最近更新时间"
                         prop="updateTime"
                         show-overflow-tooltip >
          <template #default="scope">
            {{ scope.row.updateTime ? scope.row.updateTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column fixed="right" label="操作" min-width="90" align="center">
          <template #default="scope">
            <el-button link type="primary" @click="showSubtractModal(scope.row)" :disabled="scope.row.unLockedQuantity === 0">领用</el-button>
src/views/officeProcessAutomation/ApproveManage/approve-template/approveTemplateConstants.js
@@ -155,24 +155,31 @@
  return { createdTime, updatedTime, createTime: createdTime, updateTime: updatedTime };
}
function normalizeTimeValue(val) {
  if (val == null || val === "") return "";
  if (Array.isArray(val) && val.length >= 3) {
    const [y, m, d, h = 0, min = 0, s = 0] = val;
    return dayjs(new Date(y, m - 1, d, h, min, s)).format("YYYY-MM-DD HH:mm:ss");
  }
  if (typeof val === "number") {
    const d = val > 1e12 ? dayjs(val) : dayjs.unix(val);
    return d.isValid() ? d.format("YYYY-MM-DD HH:mm:ss") : "";
  }
  const s = String(val).trim();
  if (!s) return "";
  const parsed = dayjs(s.includes("T") ? s : s.replace(/-/g, "/"));
  return parsed.isValid() ? parsed.format("YYYY-MM-DD HH:mm:ss") : s;
/**
 * @param {any} val 时间值
 * @param {boolean} [onlyDate=true] true:只年月日,false:年月日时分秒
 */
function normalizeTimeValue(val, onlyDate = true) {
    if (val == null || val === "") return "";
    const fmt = onlyDate ? "YYYY-MM-DD" : "YYYY-MM-DD HH:mm:ss";
    if (Array.isArray(val) && val.length >= 3) {
        const [y, m, d, h = 0, min = 0, s = 0] = val;
        return dayjs(new Date(y, m - 1, d, h, min, s)).format(fmt);
    }
    if (typeof val === "number") {
        const d = val > 1e12 ? dayjs(val) : dayjs.unix(val);
        return d.isValid() ? d.format(fmt) : "";
    }
    const s = String(val).trim();
    if (!s) return "";
    const parsed = dayjs(s.includes("T") ? s : s.replace(/-/g, "/"));
    return parsed.isValid() ? parsed.format(fmt) : s;
}
export function formatDisplayTime(val) {
  const t = normalizeTimeValue(val);
export function formatDisplayTime(val,onlyDate) {
  const t = normalizeTimeValue(val,onlyDate);
  return t || "—";
}
src/views/personnelManagement/socialSecuritySet/index.vue
@@ -65,7 +65,7 @@
  { label: "保险类型", prop: "insuranceTypes", width: 120 },
  { label: "使用范围", prop: "deptNames", width: 120 },
  { label: "备注", prop: "remark", minWidth: 120 },
  { label: "创建时间", prop: "createTime", width: 160 },
  { label: "创建时间", prop: "createTime", width: 160,dataType: "date" },
  { label: "创建人", prop: "createUserName", width: 100 },
  {
    dataType: "action",
src/views/productionManagement/productionReporting/index.vue
@@ -236,6 +236,7 @@
      label: "创建时间",
      prop: "createTime",
      width: 120,
      dataType: "date"
    },
    {
      dataType: "action",
src/views/safeProduction/dangerInvestigation/index.vue
@@ -69,7 +69,11 @@
                         show-overflow-tooltip />
        <el-table-column label="上报时间"
                         prop="createTime"
                         show-overflow-tooltip />
                         show-overflow-tooltip >
          <template #default="scope">
            {{ scope.row.createTime ? scope.row.createTime.split(' ')[0] : '-' }}
          </template>
        </el-table-column>
        <el-table-column label="整改完成期限"
                         prop="rectifyTime"
                         width="120"