已修改17个文件
943 ■■■■ 文件已修改
src/utils/ruoyi.js 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/spareParts/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/payable/purchaseReturn.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/salesReturn.vue 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/approveTemplateConstants.js 39 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/contractManagement/index.vue 578 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/employeeRecord/index.vue 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/Edit.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/New.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/processRoute/processRouteItem/index.vue 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/index.vue 26 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrderManagement/index.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPaymentLedger/index.vue 9 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/ruoyi.js
@@ -4,6 +4,47 @@
 */
// 日期格式化
export function parseDate(time, pattern) {
    if (arguments.length === 0 || !time) {
        return null
    }
    const format = pattern || '{y}-{m}-{d}'
    let date
    if (typeof time === 'object') {
        date = time
    } else {
        if ((typeof time === 'string') && (/^[0-9]+$/.test(time))) {
            time = parseInt(time)
        } else if (typeof time === 'string') {
            time = time.replace(new RegExp(/-/gm), '/').replace('T', ' ').replace(new RegExp(/\.[\d]{3}/gm), '')
        }
        if ((typeof time === 'number') && (time.toString().length === 10)) {
            time = time * 1000
        }
        date = new Date(time)
    }
    const formatObj = {
        y: date.getFullYear(),
        m: date.getMonth() + 1,
        d: date.getDate(),
        h: date.getHours(),
        i: date.getMinutes(),
        s: date.getSeconds(),
        a: date.getDay()
    }
    const time_str = format.replace(/{(y|m|d|h|i|s|a)+}/g, (result, key) => {
        let value = formatObj[key]
        // Note: getDay() returns 0 on Sunday
        if (key === 'a') { return ['日', '一', '二', '三', '四', '五', '六'][value] }
        if (result.length > 0 && value < 10) {
            value = '0' + value
        }
        return value || 0
    })
    return time_str
}
// 日期格式化
export function parseTime(time, pattern) {
  if (arguments.length === 0 || !time) {
    return null
src/views/equipmentManagement/spareParts/index.vue
@@ -185,7 +185,7 @@
  { label: "备件名称", prop: "sparePartsName" },
  { label: "领用数量", prop: "quantity" },
  { label: "操作人", prop: "operator" },
  { label: "时间", prop: "createTime" },
  { label: "时间", prop: "createTime",dataType:"date" },
]);
const handleTabChange = async (name) => {
src/views/equipmentManagement/upkeep/index.vue
@@ -349,7 +349,7 @@
      label: "登记日期",
      minWidth: 100,
      formatData: cell =>
        cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
        cell ? dayjs(cell).format("YYYY-MM-DD") : "-",
    },
    {
      fixed: "right",
src/views/financialManagement/payable/purchaseReturn.vue
@@ -85,30 +85,6 @@
  { label: "退货单号", prop: "returnNo", minWidth: "150" },
  { label: "供应商", prop: "supplierName", minWidth: "180" },
  { label: "关联入库单号", prop: "inboundBatches", minWidth: "150" },
  {
    label: "发货类型",
    prop: "shippingType",
    minWidth: "110",
    formatData: (val) => ({ 1: "货车", 2: "快递" }[String(val)] || "--"),
  },
  {
    label: "发货车牌号",
    prop: "truckPlateNo",
    minWidth: "140",
    formatData: (_val, row) => (String(row?.shippingType) === "1" ? row?.truckPlateNo || "--" : "--"),
  },
  {
    label: "快递公司",
    prop: "expressCompany",
    minWidth: "140",
    formatData: (_val, row) => (String(row?.shippingType) === "2" ? row?.expressCompany || "--" : "--"),
  },
  {
    label: "快递单号",
    prop: "expressNo",
    minWidth: "150",
    formatData: (_val, row) => (String(row?.shippingType) === "2" ? row?.expressNo || "--" : "--"),
  },
  { label: "退货日期", prop: "preparedAt", minWidth: "170",dataType: "date"},
  {
    label: "退款总额",
src/views/financialManagement/receivable/salesReturn.vue
@@ -77,30 +77,6 @@
  { label: "退货单号", prop: "returnNo", minWidth: "150" },
  { label: "客户名称", prop: "customerName", minWidth: "180" },
  { label: "关联发货单号", prop: "shippingNo", minWidth: "150" },
  {
    label: "发货类型",
    prop: "shippingType",
    minWidth: "110",
    formatData: (val) => ({ 1: "货车", 2: "快递" }[String(val)] || "--"),
  },
  {
    label: "发货车牌号",
    prop: "truckPlateNo",
    minWidth: "140",
    formatData: (_val, row) => (String(row?.shippingType) === "1" ? row?.truckPlateNo || "--" : "--"),
  },
  {
    label: "快递公司",
    prop: "expressCompany",
    minWidth: "140",
    formatData: (_val, row) => (String(row?.shippingType) === "2" ? row?.expressCompany || "--" : "--"),
  },
  {
    label: "快递单号",
    prop: "expressNo",
    minWidth: "150",
    formatData: (_val, row) => (String(row?.shippingType) === "2" ? row?.expressNo || "--" : "--"),
  },
  { label: "退货日期", prop: "makeTime", minWidth: "170",dataType: "date" },
  {
    label: "退款总额",
src/views/officeProcessAutomation/ApproveManage/approve-template/approveTemplateConstants.js
@@ -155,31 +155,26 @@
  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");
      return dayjs(new Date(y, m - 1, d, h, min, s)).format("YYYY-MM-DD");
/**
 * @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;
  }
  if (typeof val === "number") {
    const d = val > 1e12 ? dayjs(val) : dayjs.unix(val);
    return d.isValid() ? d.format("YYYY-MM-DD") : "";
  }
  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") : s;
}
export function formatDisplayTime(val,onlyDate) {
  const t = normalizeTimeValue(val,onlyDate);
export function formatDisplayTime(val) {
  const t = normalizeTimeValue(val);
  return t || "—";
}
src/views/personnelManagement/contractManagement/index.vue
@@ -3,64 +3,52 @@
    <div class="search_form mb20">
      <div>
        <span class="search_title">姓名:</span>
        <el-input v-model="searchForm.staffName"
                  style="width: 240px"
                  placeholder="请输入姓名搜索"
                  @change="handleQuery"
                  clearable
                  :prefix-icon="Search" />
        <span style="margin-left: 10px"
              class="search_title">合同结束日期:</span>
        <el-date-picker v-model="searchForm.entryDate"
                        value-format="YYYY-MM-DD"
                        format="YYYY-MM-DD"
                        type="daterange"
                        placeholder="请选择"
                        clearable
                        @change="changeDaterange" />
        <el-button type="primary"
                   @click="handleQuery"
                   style="margin-left: 10px">搜索</el-button>
        <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="请输入姓名搜索" @change="handleQuery"
          clearable :prefix-icon="Search" />
        <span style="margin-left: 10px" class="search_title">合同结束日期:</span>
        <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
          placeholder="请选择" clearable @change="changeDaterange" />
        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">搜索</el-button>
      </div>
      <div>
        <!--        <el-button type="primary" @click="openForm('add')">新增入职</el-button>-->
        <!--        <el-button type="info" @click="handleImport">导入</el-button>-->
<!--        <el-button type="info" @click="handleImport">导入</el-button>-->
        <el-button @click="handleOut">导出</el-button>
        <!--        <el-button type="danger" plain @click="handleDelete">删除</el-button>-->
      </div>
    </div>
    <div class="table_list">
      <PIMTable rowKey="id"
                :column="tableColumn"
                :tableData="tableData"
                :page="page"
                :isSelection="true"
                @selection-change="handleSelectionChange"
                :tableLoading="tableLoading"
                @pagination="pagination"
                :total="page.total"></PIMTable>
      <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true"
        @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination"
        :total="page.total"></PIMTable>
    </div>
    <form-dia ref="formDia"
              @close="handleQuery"></form-dia>
    <renew-contract v-if="isShowRenewContractModal"
                    v-model:visible="isShowRenewContractModal"
                    :id="id"
                    @completed="handleQuery" />
    <form-dia ref="formDia" @close="handleQuery"></form-dia>
    <renew-contract
        v-if="isShowRenewContractModal"
        v-model:visible="isShowRenewContractModal"
        :id="id"
        @completed="handleQuery"
    />
    <!-- 合同导入对话框 -->
    <el-dialog :title="upload.title"
               v-model="upload.open"
               width="400px"
               append-to-body>
      <el-upload ref="uploadRef"
                 :limit="1"
                 accept=".xlsx, .xls"
                 :headers="upload.headers"
                 :action="upload.url + '?updateSupport=' + upload.updateSupport"
                 :disabled="upload.isUploading"
                 :on-progress="handleFileUploadProgress"
                 :on-success="handleFileSuccess"
                 :auto-upload="false"
                 drag>
    <el-dialog
      :title="upload.title"
      v-model="upload.open"
      width="400px"
      append-to-body
    >
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url + '?updateSupport=' + upload.updateSupport"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
        <template #tip>
@@ -78,8 +66,7 @@
      </el-upload>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary"
                     @click="submitFileForm">确 定</el-button>
          <el-button type="primary" @click="submitFileForm">确 定</el-button>
          <el-button @click="upload.open = false">取 消</el-button>
        </div>
      </template>
@@ -89,259 +76,258 @@
</template>
<script setup>
  import { Search } from "@element-plus/icons-vue";
  import { onMounted, ref, defineAsyncComponent } from "vue";
  import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
  const RenewContract = defineAsyncComponent(() =>
    import(
      "@/views/personnelManagement/employeeRecord/components/RenewContract.vue"
    )
  );
  import { ElMessageBox } from "element-plus";
  import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
  import dayjs from "dayjs";
  import { getToken } from "@/utils/auth.js";
  import FilesDia from "./filesDia.vue";
  const data = reactive({
    searchForm: {
      staffName: "",
      entryDate: null, // 录入日期
      entryDateStart: undefined,
      entryDateEnd: undefined,
import { Search } from "@element-plus/icons-vue";
import { onMounted, ref, defineAsyncComponent } from "vue";
import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
const RenewContract = defineAsyncComponent(() => import("@/views/personnelManagement/employeeRecord/components/RenewContract.vue"));
import { ElMessageBox } from "element-plus";
import { staffOnJobListPage } from "@/api/personnelManagement/staffOnJob.js";
import dayjs from "dayjs";
import { getToken } from "@/utils/auth.js";
import FilesDia from "./filesDia.vue";
const data = reactive({
  searchForm: {
    staffName: "",
    entryDate: null, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
  },
});
const { searchForm } = toRefs(data);
const tableColumn = ref([
  {
    label: "状态",
    prop: "staffState",
    dataType: "tag",
    formatData: (params) => {
      if (params == 0) {
        return "离职";
      } else if (params == 1) {
        return "在职";
      } else {
        return null;
      }
    },
  });
  const { searchForm } = toRefs(data);
  const tableColumn = ref([
    {
      label: "状态",
      prop: "staffState",
      dataType: "tag",
      formatData: params => {
        if (params == 0) {
          return "离职";
        } else if (params == 1) {
          return "在职";
        } else {
          return null;
        }
      },
      formatType: params => {
        if (params == 0) {
          return "danger";
        } else if (params == 1) {
          return "primary";
        } else {
          return null;
        }
      },
    formatType: (params) => {
      if (params == 0) {
        return "danger";
      } else if (params == 1) {
        return "primary";
      } else {
        return null;
      }
    },
    {
      label: "员工编号",
      prop: "staffNo",
    },
    {
      label: "姓名",
      prop: "staffName",
    },
    {
      label: "性别",
      prop: "sex",
    },
    {
      label: "岗位",
      prop: "postName",
    },
    {
      label: "第一学历",
      prop: "firstStudy",
    },
    {
      label: "专业",
      prop: "profession",
      width: 100,
    },
    {
      label: "年龄",
      prop: "age",
    },
    {
      label: "联系电话",
      prop: "phone",
      width: 150,
    },
    {
      label: "紧急联系人",
      prop: "emergencyContact",
      width: 120,
    },
    {
      label: "紧急联系人电话",
      prop: "emergencyContactPhone",
      width: 150,
    },
    // {
    //   label: "合同年限",
    //   prop: "contractTerm",
    // },
    // {
    //   label: "合同开始日期",
    //   prop: "contractStartTime",
    //   width: 120
    // },
    {
      label: "合同结束日期",
      prop: "contractExpireTime",
      width: 120,
    },
    {
      dataType: "action",
      label: "操作",
      align: "center",
      fixed: "right",
      width: 160,
      operation: [
        {
          name: "详情",
          type: "text",
          clickFun: row => {
            openForm("edit", row);
          },
  },
  {
    label: "员工编号",
    prop: "staffNo",
  },
  {
    label: "姓名",
    prop: "staffName",
  },
  {
    label: "性别",
    prop: "sex",
  },
  {
    label: "户籍住址",
    prop: "nativePlace",
  },
  // {
  //   label: "岗位",
  //   prop: "postName",
  // },
  // {
  //   label: "现住址",
  //   prop: "adress",
  //   width: 200
  // },
  {
    label: "第一学历",
    prop: "firstStudy",
  },
  {
    label: "专业",
    prop: "profession",
    width: 100
  },
  {
    label: "年龄",
    prop: "age",
  },
  {
    label: "联系电话",
    prop: "phone",
    width: 150
  },
  // {
  //   label: "紧急联系人",
  //   prop: "emergencyContact",
  //   width: 120
  // },
  // {
  //   label: "紧急联系人电话",
  //   prop: "emergencyContactPhone",
  //   width: 150
  // },
  // {
  //   label: "合同年限",
  //   prop: "contractTerm",
  // },
  // {
  //   label: "合同开始日期",
  //   prop: "contractStartTime",
  //   width: 120
  // },
  {
    label: "合同结束日期",
    prop: "contractExpireTime",
    width: 120
  },
  {
    dataType: "action",
    label: "操作",
    align: "center",
    fixed: 'right',
    width: 160,
    operation: [
      {
        name: "详情",
        type: "text",
        clickFun: (row) => {
          openForm("edit", row);
        },
        {
          name: "续签合同",
          type: "text",
          showHide: row => row.staffState === 1,
          clickFun: row => {
            isShowRenewContractModal.value = true;
            id.value = row.id;
          },
      },
      {
        name: "续签合同",
        type: "text",
        showHide: row => row.staffState === 1,
        clickFun: (row) => {
          isShowRenewContractModal.value = true;
          id.value = row.id;
        },
      ],
    },
  ]);
  const filesDia = ref();
  const isShowRenewContractModal = ref(false);
  const id = ref(0);
  const tableData = ref([]);
  const selectedRows = ref([]);
  const tableLoading = ref(false);
  const page = reactive({
    current: 1,
    size: 100,
    total: 0,
  });
  const formDia = ref();
  const { proxy } = getCurrentInstance();
      }
    ],
  },
]);
const filesDia = ref()
const isShowRenewContractModal = ref(false);
const id = ref(0);
const tableData = ref([]);
const selectedRows = ref([]);
const tableLoading = ref(false);
const page = reactive({
  current: 1,
  size: 100,
  total: 0,
});
const formDia = ref()
const { proxy } = getCurrentInstance()
  const changeDaterange = value => {
    searchForm.value.entryDateStart = undefined;
    searchForm.value.entryDateEnd = undefined;
    if (value) {
      searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
      searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
    }
    getList();
  };
  // 打开附件弹框
  const openFilesFormDia = row => {
    console.log(row);
    nextTick(() => {
      filesDia.value?.openDialog(row, "合同");
    });
  };
  // 查询列表
  /** 搜索按钮操作 */
  const handleQuery = () => {
    page.current = 1;
    getList();
  };
  const pagination = obj => {
    page.current = obj.page;
    page.size = obj.limit;
    getList();
  };
  const getList = () => {
    tableLoading.value = true;
    const params = { ...searchForm.value, ...page };
    params.entryDate = undefined;
    params.staffState = 1;
    staffOnJobListPage(params)
      .then(res => {
        tableLoading.value = false;
        tableData.value = res.data.records;
        page.total = res.data.total;
      })
      .catch(err => {
        tableLoading.value = false;
      });
  };
  // 表格选择数据
  const handleSelectionChange = selection => {
    selectedRows.value = selection;
  };
const changeDaterange = (value) => {
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
  if (value) {
    searchForm.value.entryDateStart = dayjs(value[0]).format("YYYY-MM-DD");
    searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
  }
  getList();
};
// 打开附件弹框
const openFilesFormDia = (row) => {
  console.log(row)
  nextTick(() => {
    filesDia.value?.openDialog( row,'合同')
  })
};
// 查询列表
/** 搜索按钮操作 */
const handleQuery = () => {
  page.current = 1;
  getList();
};
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
  getList();
};
const getList = () => {
  tableLoading.value = true;
  const params = { ...searchForm.value, ...page };
  params.entryDate = undefined
  params.staffState = 1
  staffOnJobListPage(params).then(res => {
    tableLoading.value = false;
    tableData.value = res.data.records
    page.total = res.data.total;
  }).catch(err => {
    tableLoading.value = false;
  })
};
// 表格选择数据
const handleSelectionChange = (selection) => {
  selectedRows.value = selection;
};
  // 打开弹框
  const openForm = (type, row) => {
    nextTick(() => {
      formDia.value?.openDialog(type, row);
    });
  };
  // 导出
  const handleOut = () => {
    ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
      confirmButtonText: "确认",
      cancelButtonText: "取消",
      type: "warning",
// 打开弹框
const openForm = (type, row) => {
  nextTick(() => {
    formDia.value?.openDialog(type, row)
  })
};
// 导出
const handleOut = () => {
  ElMessageBox.confirm("选中的内容将被导出,是否确认导出?", "导出", {
    confirmButtonText: "确认",
    cancelButtonText: "取消",
    type: "warning",
  })
    .then(() => {
      proxy.download("/staff/staffOnJob/export", {staffState: 1}, "合同管理.xlsx");
    })
      .then(() => {
        proxy.download(
          "/staff/staffOnJob/export",
          { staffState: 1 },
          "合同管理.xlsx"
        );
      })
      .catch(() => {
        proxy.$modal.msg("已取消");
      });
  };
  const upload = reactive({
    // 是否显示弹出层(合同导入)
    open: false,
    // 弹出层标题(合同导入)
    title: "",
    // 是否禁用上传
    isUploading: false,
    // 是否更新已经存在的用户数据
    updateSupport: 1,
    // 设置上传的请求头部
    headers: { Authorization: "Bearer " + getToken() },
    // 上传的地址
    url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import",
  });
  /** 导入按钮操作 */
  function handleImport() {
    upload.title = "合同导入";
    upload.open = true;
  }
  /** 提交上传文件 */
  function submitFileForm() {
    console.log(upload.url + "?updateSupport=" + upload.updateSupport);
    proxy.$refs["uploadRef"].submit();
  }
  /**文件上传中处理 */
  const handleFileUploadProgress = (event, file, fileList) => {
    upload.isUploading = true;
  };
  /** 文件上传成功处理 */
  const handleFileSuccess = (response, file, fileList) => {
    upload.open = false;
    upload.isUploading = false;
    proxy.$refs["uploadRef"].handleRemove(file);
    getList();
  };
  onMounted(() => {
    getList();
  });
    .catch(() => {
      proxy.$modal.msg("已取消");
    });
};
const upload = reactive({
  // 是否显示弹出层(合同导入)
  open: false,
  // 弹出层标题(合同导入)
  title: "",
  // 是否禁用上传
  isUploading: false,
  // 是否更新已经存在的用户数据
  updateSupport: 1,
  // 设置上传的请求头部
  headers: { Authorization: "Bearer " + getToken() },
  // 上传的地址
  url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import",
});
/** 导入按钮操作 */
function handleImport() {
  upload.title = "合同导入";
  upload.open = true;
}
/** 提交上传文件 */
function submitFileForm() {
  console.log(upload.url + '?updateSupport=' + upload.updateSupport)
  proxy.$refs["uploadRef"].submit();
}
/**文件上传中处理 */
const handleFileUploadProgress = (event, file, fileList) => {
  upload.isUploading = true;
};
/** 文件上传成功处理 */
const handleFileSuccess = (response, file, fileList) => {
  upload.open = false;
  upload.isUploading = false;
  proxy.$refs["uploadRef"].handleRemove(file);
  getList();
};
onMounted(() => {
  getList();
});
</script>
<style scoped></style>
src/views/personnelManagement/employeeRecord/components/BasicInfoSection.vue
@@ -79,12 +79,14 @@
            placeholder="请选择"
            style="width: 100%"
            clearable
            @change="handleBirthDateChange"
          />
        </el-form-item>
      </el-col>
      <el-col :span="5">
        <el-form-item label="年龄" prop="age">
          <el-input-number
              disabled
            v-model="form.age"
            :min="0"
            :max="150"
@@ -158,6 +160,7 @@
<script setup>
import { toRefs } from "vue";
import dayjs from "dayjs";
const props = defineProps({
  form: { type: Object, required: true },
@@ -166,6 +169,21 @@
});
const { form, operationType, roleOptions } = toRefs(props);
const calcAge = (birth) => {
  if (!birth) return undefined;
  const birthDay = dayjs(birth);
  const now = dayjs();
  let age = now.year() - birthDay.year();
  if (now.month() < birthDay.month() || (now.month() === birthDay.month() && now.date() < birthDay.date())) {
    age--;
  }
  return age;
};
const handleBirthDateChange = (val) => {
  form.value.age = calcAge(val);
};
</script>
<style scoped>
src/views/personnelManagement/employeeRecord/components/NewOrEditFormDia.vue
@@ -40,7 +40,9 @@
  onMounted,
  getCurrentInstance,
  nextTick,
  computed,
} from "vue";
import dayjs from "dayjs";
import FormDialog from "@/components/Dialog/FormDialog.vue";
import { findPostOptions } from "@/api/system/post.js";
import { deptTreeSelect, getUser } from "@/api/system/user.js";
@@ -160,6 +162,17 @@
const { form, rules, postOptions, deptOptions } = toRefs(state);
const roleOptions = ref([]);
const calcAge = (birth) => {
  if (!birth) return undefined;
  const birthDay = dayjs(birth);
  const now = dayjs();
  let age = now.year() - birthDay.year();
  if (now.month() < birthDay.month() || (now.month() === birthDay.month() && now.date() < birthDay.date())) {
    age--;
  }
  return age;
};
const resetForm = () => {
  Object.assign(form.value, createDefaultForm());
  nextTick(() => {
@@ -238,6 +251,7 @@
      if (form.value.sysDeptId === 0) {
        form.value.sysDeptId = undefined;
      }
      form.value.age = calcAge(form.value.birthDate);
    });
  }
};
src/views/personnelManagement/employeeRecord/index.vue
@@ -12,21 +12,21 @@
            :prefix-icon="Search"
        />
        <span class="search_title search_title2">部门:</span>
          <el-tree-select
        <el-tree-select
            v-model="searchForm.sysDeptId"
            :data="deptOptions"
            check-strictly
            :render-after-expand="false"
            style="width: 240px"
            placeholder="请选择"
          />
          <span class="search_title search_title2">入职日期:</span>
          <el-date-picker
        />
        <span class="search_title search_title2">入职日期:</span>
        <el-date-picker
            v-model="searchForm.contractStartTime"
            value-format="YYYY-MM-DD"
            format="YYYY-MM-DD"
            placeholder="请选择"
          />
        />
        <!-- <span  style="margin-left: 10px" class="search_title">合同结束日期:</span> -->
        <!-- <el-date-picker  v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                         placeholder="请选择" clearable @change="changeDaterange" /> -->
@@ -56,24 +56,27 @@
        <template #positiveDate="{ row }">
          <span :class="getPositiveDateClass(row.positiveDate)">{{ row.positiveDate }}</span>
        </template>
        <template #age="{ row }">
          <span>{{ calcAge(row.birthDate) }}</span>
        </template>
      </PIMTable>
    </div>
    <show-form-dia ref="formDia" @close="handleQuery"></show-form-dia>
    <new-or-edit-form-dia ref="formDiaNewOrEditFormDia" @close="handleQuery"></new-or-edit-form-dia>
    <!-- 导入对话框 -->
    <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
      <el-upload
        ref="uploadRef"
        :limit="1"
        accept=".xlsx, .xls"
        :headers="upload.headers"
        :action="upload.url"
        :disabled="upload.isUploading"
        :on-progress="handleFileUploadProgress"
        :on-success="handleFileSuccess"
        :auto-upload="false"
        drag
          ref="uploadRef"
          :limit="1"
          accept=".xlsx, .xls"
          :headers="upload.headers"
          :action="upload.url"
          :disabled="upload.isUploading"
          :on-progress="handleFileUploadProgress"
          :on-success="handleFileSuccess"
          :auto-upload="false"
          drag
      >
        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
        <div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
@@ -96,7 +99,7 @@
<script setup>
import { Search, UploadFilled } from "@element-plus/icons-vue";
import {onMounted, ref} from "vue";
import {onMounted, ref, reactive, toRefs, nextTick, getCurrentInstance} from "vue";
import {ElMessageBox} from "element-plus";
import { deptTreeSelect } from "@/api/system/user.js";
import {batchDeleteStaffOnJobs, staffOnJobListPage} from "@/api/personnelManagement/staffOnJob.js";
@@ -109,6 +112,8 @@
const data = reactive({
  searchForm: {
    staffName: "",
    sysDeptId: undefined,
    contractStartTime: undefined,
    entryDate: undefined, // 录入日期
    entryDateStart: undefined,
    entryDateEnd: undefined,
@@ -185,6 +190,8 @@
  {
    label: "年龄",
    prop: "age",
    dataType: "slot",
    slot: "age"
  },
  {
    label: "籍贯",
@@ -244,6 +251,23 @@
  url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import"
})
/**
 * 根据出生日期字符串计算周岁
 * @param {String} birth  YYYY‑MM‑DD
 * @returns {string|number}
 */
const calcAge = (birth) => {
  if (!birth) return "-";
  const birthDay = dayjs(birth);
  const now = dayjs();
  let age = now.year() - birthDay.year();
  // 生日还没过,减一岁
  if (now.month() < birthDay.month() || (now.month() === birthDay.month() && now.date() < birthDay.date())) {
    age--;
  }
  return age;
};
// 判断转正日期是否在7天内
const getPositiveDateClass = (positiveDate) => {
  if (!positiveDate) return '';
@@ -261,24 +285,23 @@
};
const fetchDeptOptions = () => {
    deptTreeSelect().then(response => {
      console.log(response.data)
      deptOptions.value = filterDisabledDept(
  deptTreeSelect().then(response => {
    deptOptions.value = filterDisabledDept(
        JSON.parse(JSON.stringify(response.data))
      );
    });
  };
    );
  });
};
const filterDisabledDept = deptList => {
    return deptList.filter(dept => {
      if (dept.disabled) {
        return false;
      }
      if (dept.children && dept.children.length) {
        dept.children = filterDisabledDept(dept.children);
      }
      return true;
    });
  };
  return deptList.filter(dept => {
    if (dept.disabled) {
      return false;
    }
    if (dept.children && dept.children.length) {
      dept.children = filterDisabledDept(dept.children);
    }
    return true;
  });
};
const changeDaterange = (value) => {
  searchForm.value.entryDateStart = undefined;
  searchForm.value.entryDateEnd = undefined;
src/views/productionManagement/processRoute/Edit.vue
@@ -52,9 +52,9 @@
          </el-select>
        </el-form-item>
        <el-form-item label="备注" prop="description">
          <el-input v-model="formState.description" type="textarea" />
        </el-form-item>
<!--        <el-form-item label="备注" prop="description">-->
<!--          <el-input v-model="formState.description" type="textarea" />-->
<!--        </el-form-item>-->
      </el-form>
      
      <!-- 产品选择弹窗 -->
src/views/productionManagement/processRoute/New.vue
@@ -44,11 +44,11 @@
                       :value="item.id" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注"
                      prop="description">
          <el-input v-model="formState.description"
                    type="textarea" />
        </el-form-item>
<!--        <el-form-item label="备注"-->
<!--                      prop="description">-->
<!--          <el-input v-model="formState.description"-->
<!--                    type="textarea" />-->
<!--        </el-form-item>-->
      </el-form>
      <!-- 产品选择弹窗 -->
      <ProductSelectDialog v-model="showProductSelectDialog"
src/views/productionManagement/processRoute/index.vue
@@ -92,10 +92,10 @@
      label: "BOM编号",
      prop: "bomNo",
    },
    {
      label: "描述",
      prop: "description",
    },
    // {
    //   label: "描述",
    //   prop: "description",
    // },
    {
      dataType: "action",
      label: "操作",
src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -47,14 +47,14 @@
            <span class="info-value">{{ routeInfo.quantity || '-' }}</span>
          </div>
        </div>
        <div class="info-item">
          <div class="info-label-wrapper">
            <span class="info-label">备注</span>
          </div>
          <div class="info-value-wrapper">
            <span class="info-value">{{ routeInfo.description }}</span>
          </div>
        </div>
<!--        <div class="info-item">-->
<!--          <div class="info-label-wrapper">-->
<!--            <span class="info-label">备注</span>-->
<!--          </div>-->
<!--          <div class="info-value-wrapper">-->
<!--            <span class="info-value">{{ routeInfo.description }}</span>-->
<!--          </div>-->
<!--        </div>-->
      </div>
    </el-card>
    <!-- 附件模块 -->
src/views/productionManagement/productStructure/index.vue
@@ -85,14 +85,14 @@
                    placeholder="请输入版本号"
                    clearable />
        </el-form-item>
        <el-form-item label="备注"
                      prop="remark">
          <el-input v-model="form.remark"
                    type="textarea"
                    :rows="3"
                    placeholder="请输入备注"
                    clearable />
        </el-form-item>
<!--        <el-form-item label="备注"-->
<!--                      prop="remark">-->
<!--          <el-input v-model="form.remark"-->
<!--                    type="textarea"-->
<!--                    :rows="3"-->
<!--                    placeholder="请输入备注"-->
<!--                    clearable />-->
<!--        </el-form-item>-->
      </el-form>
      <template #footer>
        <el-button type="primary"
@@ -174,11 +174,11 @@
      prop: "version",
      width: 100,
    },
    {
      label: "备注",
      prop: "remark",
      minWidth: 160,
    },
    // {
    //   label: "备注",
    //   prop: "remark",
    //   minWidth: 160,
    // },
    {
      dataType: "action",
      label: "操作",
src/views/productionManagement/workOrderManagement/index.vue
@@ -133,7 +133,7 @@
          <el-input v-model.number="reportForm.quantity"
                    type="number"
                    min="0"
                    step="1"
                    step="0.001"
                    style="width: 300px"
                    placeholder="请输入生产合格数量"
                    @input="handleQuantityInput" />
@@ -336,16 +336,16 @@
      slot: "completionStatus",
      width: "140",
    },
    {
      label: "计划开始时间",
      prop: "planStartTime",
      width: "140",
    },
    {
      label: "计划结束时间",
      prop: "planEndTime",
      width: "140",
    },
    // {
    //   label: "计划开始时间",
    //   prop: "planStartTime",
    //   width: "140",
    // },
    // {
    //   label: "计划结束时间",
    //   prop: "planEndTime",
    //   width: "140",
    // },
    {
      label: "实际开始时间",
      prop: "actualStartTime",
@@ -446,7 +446,7 @@
    }
    const num = Number(value);
    // 整数且大于等于1
    if (isNaN(num) || !Number.isInteger(num) || num < 0) {
    if (isNaN(num) || num < 0) {
      callback(new Error("生产合格数量必须大于等于0"));
      return;
    }
@@ -461,7 +461,7 @@
    }
    const num = Number(value);
    // 整数且大于等于0
    if (isNaN(num) || !Number.isInteger(num) || num < 0) {
    if (isNaN(num) || num < 0) {
      callback(new Error("报废数量必须大于等于0"));
      return;
    }
@@ -487,17 +487,6 @@
    // 如果小于1,清除
    if (num < 0) {
      reportForm.quantity = null;
      return;
    }
    // 如果是小数取整数部分
    if (!Number.isInteger(num)) {
      const intValue = Math.floor(num);
      // 如果取整后小于1,清除
      if (intValue < 0) {
        reportForm.quantity = null;
        return;
      }
      reportForm.quantity = intValue;
      return;
    }
    reportForm.quantity = num;
src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -141,18 +141,14 @@
          <el-date-picker style="width:100%" v-model="receiptForm.paymentDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="date" placeholder="请选择回款日期" clearable />
        </el-form-item>
        <el-form-item label="回款金额:" prop="paymentAmount">
          <el-input-number style="width:100%" v-model="receiptForm.paymentAmount" :precision="2" :min="0.01" :max="Math.max(0, (Number(currentRow.receiptableAmount)||0) - (Number(currentRow.receiptPaymentAmount)||0))" placeholder="请输入回款金额" controls-position="right" />
          <el-input-number style="width:100%" v-model="receiptForm.paymentAmount" :precision="2" :min="0.01" :max="Math.max(0.01, (Number(currentRow.receiptableAmount)||0) - (Number(currentRow.receiptPaymentAmount)||0))" placeholder="请输入回款金额" controls-position="right" />
          <div style="color:#e6a23c;font-size:12px;margin-top:4px">
            当前可回款余额:{{ formattedNumber(null, null, Math.max(0, (Number(currentRow.receiptableAmount)||0) - (Number(currentRow.receiptPaymentAmount)||0))) }} 元
          </div>
        </el-form-item>
        <el-form-item label="回款方式:" prop="paymentMethod">
          <el-select v-model="receiptForm.paymentMethod" placeholder="请选择回款方式" style="width:100%" clearable>
            <el-option label="银行转账" value="银行转账" />
            <el-option label="现金" value="现金" />
            <el-option label="支票" value="支票" />
            <el-option label="微信/支付宝" value="微信/支付宝" />
            <el-option label="其他" value="其他" />
            <el-option v-for="item in payment_methods" :key="item.value" :label="item.label" :value="item.value" />
          </el-select>
        </el-form-item>
        <el-form-item label="备注:" prop="remark">
@@ -176,6 +172,7 @@
  } from "@/api/salesManagement/indicatorStats.js";
  import Pagination from "../../../components/PIMTable/Pagination.vue";
  const { proxy } = getCurrentInstance();
  const { payment_methods } = proxy.useDict("payment_methods");
  const tableData = ref([]);
  const receiptRecord = ref([]);
  const tableLoading = ref(false);