Merge remote-tracking branch 'origin/dev_新疆_大罗素马铃薯new' into dev_新疆_大罗素马铃薯new
已添加1个文件
已修改47个文件
946 ■■■■ 文件已修改
doc/20260618_customer_transactions_optimization.md 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260618_shipping_info_for_return.md 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/customerService/index.js 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/equipmentManagement/ledger.js 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/returnOrder.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesLedger.js 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/components/AIChatSidebar/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/purchaseApproval/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/shipmentReview/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/customerService/afterSalesHandling/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/customerService/feedbackRegistration/components/formDia.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/customerService/feedbackRegistration/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/spareParts/index.vue 32 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/invoiceApply.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/receipt.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/salesOut.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/receivable/salesReturn.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/Record.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/BatchNoQtyDetail.vue 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/New.vue 142 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Record.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalModuleRegistry.js 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/index.vue 22 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/officeProcessAutomation/AttendManage/compensatory-leave/index.vue 314 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/personnelManagement/classsSheduling/index.vue 55 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentLedger/index.vue 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 145 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/receivingManagement/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionOrder/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/workOrderManagement/index.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionPlan/productionPlan/index.vue 10 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/afterSalesTraceability/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/components/formDia.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/index.vue 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/reportAnalysis/projectProfit/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/safeWorkApproval/components/approvalDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/deliveryLedger/index.vue 37 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPaymentLedger/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/returnOrder/components/detailDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/returnOrder/components/formDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/returnOrder/index.vue 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260618_customer_transactions_optimization.md
@@ -113,7 +113,7 @@
| å­—段 | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| salesLedgerId | Long | é”€å”®å°è´¦ID |
| salesContractNo | String | é”€å”®åˆåŒå· |
| salesContractNo | String | è®¢å•号 |
| productId | Long | äº§å“ID |
| productName | String | äº§å“åç§° |
| model | String | è§„格型号 |
@@ -179,7 +179,7 @@
| å­—段 | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| salesLedgerId | Long | é”€å”®å°è´¦ID |
| salesContractNo | String | é”€å”®åˆåŒå· |
| salesContractNo | String | è®¢å•号 |
| shippingId | Long | å‘货单ID |
| shippingNo | String | å‘货单号 |
| productName | String | äº§å“åç§° |
doc/20260618_shipping_info_for_return.md
@@ -27,7 +27,7 @@
|------|------|------|
| shippingId | Long | å‘货单ID |
| shippingNo | String | å‘货单号 |
| salesContractNo | String | é”€å”®åˆåŒå· |
| salesContractNo | String | è®¢å•号 |
| customerName | String | å®¢æˆ·åç§° |
| productName | String | äº§å“åç§° |
| model | String | è§„格型号 |
@@ -257,7 +257,7 @@
          </el-form-item>
        </el-col>
        <el-col :span="8">
          <el-form-item label="销售合同号">
          <el-form-item label="订单号">
            <el-input v-model="form.salesContractNo" disabled />
          </el-form-item>
        </el-col>
src/api/customerService/index.js
@@ -111,7 +111,7 @@
    })
}
// æ ¹æ®å®¢æˆ·æŸ¥è¯¢é”€å”®è®¢å•号
// æ ¹æ®å®¢æˆ·æŸ¥è¯¢è®¢å•号号
// afterSalesService/listSalesLedger
export function getSalesLedger(query) {
    return request({
@@ -121,7 +121,7 @@
    })
}
// æ ¹æ®é”€å”®è®¢å•号查询销售订单详情
// æ ¹æ®è®¢å•号号查询订单号详情
// afterSalesService/count
export function getSalesLedgerDetail(query) {
    return request({
src/api/equipmentManagement/ledger.js
@@ -42,3 +42,10 @@
    method: "get",
  });
};
export const getIotDeviceList = () => {
  return request({
    url: "/device/ledger/iotDeviceList",
    method: "get",
  });
};
src/api/salesManagement/returnOrder.js
@@ -51,7 +51,7 @@
  });
}
// é”€å”®é€€è´§-根据出库单查询销售订单以及产品信息
// é”€å”®é€€è´§-根据出库单查询订单号以及产品信息
// /returnManagement/getByShippingId
export function returnManagementGetByShippingId(query) {
  return request({
src/api/salesManagement/salesLedger.js
@@ -101,7 +101,7 @@
  });
}
// æ ¹æ®é”€å”®åˆåŒå·æŸ¥äº§å“ä¿¡æ¯
// æ ¹æ®è®¢å•号查产品信息
export function getProductInfoByContractNo(query) {
  return request({
    url: "/purchase/ledger/getProductBySalesNo",
src/components/AIChatSidebar/index.vue
@@ -1147,7 +1147,7 @@
  collectionStrategy: '回款策略',
  quotationStrategy: '报价策略',
  nextAction: '下一步动作',
  salesContractNo: '销售合同号',
  salesContractNo: '订单号',
  revenue: '收入',
  materialCost: '材料成本',
  laborCost: '人工成本',
@@ -1188,9 +1188,9 @@
  purchaseContractNumber: '采购合同号',
  purchaseContractNo: '采购合同号',
  purchaseOrderNumber: '采购合同号',
  salesContractNo: '销售合同号',
  salesContractNumber: '销售合同号',
  salesOrderNumber: '销售合同号',
  salesContractNo: '订单号',
  salesContractNumber: '订单号',
  salesOrderNumber: '订单号',
  salesContractNoId: '销售合同ID',
  approveUserIds: '审批用户ID列表',
  entryDateStart: '录入开始日期',
@@ -1253,9 +1253,9 @@
  é‡‡è´­åˆåŒå·: 'purchaseContractNumber',
  é‡‡è´­å•号: 'purchaseContractNumber',
  é‡‡è´­è®¢å•号: 'purchaseContractNumber',
  é”€å”®åˆåŒå·: 'salesContractNo',
  é”€å”®å•号: 'salesContractNo',
  é”€å”®è®¢å•号: 'salesContractNo',
  è®¢å•号: 'salesContractNo',
  è®¢å•号: 'salesContractNo',
  è®¢å•号号: 'salesContractNo',
  é”€å”®åˆåŒID: 'salesContractNoId',
  å®¡æ‰¹ç”¨æˆ·ID列表: 'approveUserIds',
  å½•入开始日期: 'entryDateStart',
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -128,7 +128,7 @@
                <el-descriptions-item label="采购合同号">{{ currentPurchase.purchaseContractNumber }}</el-descriptions-item>
                <el-descriptions-item label="供应商名称">{{ currentPurchase.supplierName }}</el-descriptions-item>
                <el-descriptions-item label="项目名称">{{ currentPurchase.projectName }}</el-descriptions-item>
                <el-descriptions-item label="销售合同号">{{ currentPurchase.salesContractNo }}</el-descriptions-item>
                <el-descriptions-item label="订单号">{{ currentPurchase.salesContractNo }}</el-descriptions-item>
                <el-descriptions-item label="签订日期">{{ currentPurchase.executionDate }}</el-descriptions-item>
                <el-descriptions-item label="录入日期">{{ currentPurchase.entryDate }}</el-descriptions-item>
                <el-descriptions-item label="付款方式">{{ currentPurchase.paymentMethod }}</el-descriptions-item>
@@ -186,7 +186,7 @@
            <template v-else>
              <el-descriptions :column="2"
                               border>
                <el-descriptions-item label="销售订单">{{ currentDelivery.shippingInfo.salesContractNo || '--' }}</el-descriptions-item>
                <el-descriptions-item label="订单号">{{ currentDelivery.shippingInfo.salesContractNo || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货订单号">{{ currentDelivery.shippingInfo.shippingNo || '--' }}</el-descriptions-item>
                <el-descriptions-item label="客户名称">{{ currentDelivery.shippingInfo.customerName || '--' }}</el-descriptions-item>
                <el-descriptions-item label="发货类型">{{ currentDelivery.shippingInfo.type || '--' }}</el-descriptions-item>
src/views/collaborativeApproval/purchaseApproval/index.vue
@@ -19,7 +19,7 @@
                      clearable
                      :prefix-icon="Search" />
          </el-form-item>
          <el-form-item label="销售合同号:">
          <el-form-item label="订单号:">
            <el-input v-model="searchForm.salesContractNo"
                      placeholder="请输入"
                      clearable
@@ -101,7 +101,7 @@
                         prop="purchaseContractNumber"
                         width="200"
                         show-overflow-tooltip />
        <el-table-column label="销售合同号"
        <el-table-column label="订单号"
                         prop="salesContractNo"
                         width="200"
                         show-overflow-tooltip />
src/views/collaborativeApproval/shipmentReview/index.vue
@@ -2,11 +2,11 @@
  <div class="app-container">
    <div class="search_form">
      <div>
        <span class="search_title">销售合同号:</span>
        <span class="search_title">订单号:</span>
        <el-input
            v-model="searchForm.salesContractNo"
            style="width: 240px"
            placeholder="请输入销售合同号搜索"
            placeholder="请输入订单号搜索"
            @change="handleQuery"
            clearable
            :prefix-icon="Search"
@@ -110,7 +110,7 @@
    },
  },
  {
    label: "销售合同号",
    label: "订单号",
    prop: "salesContractNo",
    width: 170
  },
src/views/customerService/afterSalesHandling/index.vue
@@ -67,7 +67,7 @@
              <el-form-item>
                <el-input
                    v-model="searchForm.orderNo"
                    placeholder="请输入销售单号"
                    placeholder="请输入订单号"
                    clearable
                />
              </el-form-item>
@@ -146,7 +146,7 @@
    align: "center"
  },
  {
    label: "销售单号",
    label: "订单号",
    prop:"salesContractNo",
    width: 150,
    align: "center"
src/views/customerService/feedbackRegistration/components/formDia.vue
@@ -38,7 +38,7 @@
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="关联销售单号:"
              <el-form-item label="关联订单号:"
                            prop="salesContractNo">
                <el-select v-model="form.salesContractNo"
                           @change="associatedSalesOrderNumberChange"
@@ -231,8 +231,8 @@
      dataType: "slot",
      slot: "shippingStatus",
    },
    { label: "快递公司", prop: "expressCompany", width: 140 },
    { label: "快递单号", prop: "expressNumber", width: 160 },
    // { label: "快递公司", prop: "expressCompany", width: 140 },
    // { label: "快递单号", prop: "expressNumber", width: 160 },
    {
      label: "发货车牌",
      prop: "shippingCarNumber",
src/views/customerService/feedbackRegistration/index.vue
@@ -67,7 +67,7 @@
          <el-col :span="4">
            <el-form-item>
              <el-input v-model="searchForm.orderNo"
                        placeholder="请输入销售单号"
                        placeholder="请输入订单号"
                        clearable />
            </el-form-item>
          </el-col>
@@ -182,7 +182,7 @@
      align: "center",
    },
    {
      label: "销售单号",
      label: "订单号",
      prop: "salesContractNo",
      width: 150,
      align: "center",
src/views/equipmentManagement/spareParts/index.vue
@@ -241,26 +241,26 @@
    slot: "status",
    dataType: "slot",
  },
  {
    label: "ä»·æ ¼",
    prop: "price",
  },
  // {
  //   label: "ä»·æ ¼",
  //   prop: "price",
  // },
  {
    label: "数量",
    prop: "quantity",
  },
  {
    label: "库存预警数量",
    prop: "warnNum",
  },
  {
    label: "预警通知人",
    prop: "notifyPersonName",
  },
  {
    label: "描述",
    prop: "description",
  },
  // {
  //   label: "库存预警数量",
  //   prop: "warnNum",
  // },
  // {
  //   label: "预警通知人",
  //   prop: "notifyPersonName",
  // },
  // {
  //   label: "描述",
  //   prop: "description",
  // },
  {
    label: "操作",
    prop: "operation",
src/views/financialManagement/receivable/invoiceApply.vue
@@ -240,7 +240,7 @@
        <el-table-column prop="customerName" label="客户名称" min-width="120" show-overflow-tooltip />
        <el-table-column prop="productName" label="产品名称" min-width="120" show-overflow-tooltip />
        <el-table-column prop="specificationModel" label="规格型号" min-width="140" show-overflow-tooltip />
        <el-table-column prop="salesContractNo" label="销售合同号" min-width="140" show-overflow-tooltip />
        <el-table-column prop="salesContractNo" label="订单号" min-width="140" show-overflow-tooltip />
        <el-table-column prop="shippingNo" label="发货单号" min-width="130" show-overflow-tooltip />
        <el-table-column prop="shippingDate" label="发货日期" width="110" align="center" />
        <el-table-column prop="outboundAmount" label="出库金额" width="110" align="right">
src/views/financialManagement/receivable/receipt.vue
@@ -257,7 +257,7 @@
                         min-width="140"
                         show-overflow-tooltip />
        <el-table-column prop="salesContractNo"
                         label="销售合同号"
                         label="订单号"
                         min-width="140"
                         show-overflow-tooltip />
        <el-table-column prop="shippingNo"
src/views/financialManagement/receivable/salesOut.vue
@@ -96,7 +96,7 @@
            }),
    },
    { label: "发货编号", prop: "shippingNo", minWidth: "140" },
    { label: "销售订单号", prop: "salesContractNo", minWidth: "150" },
    { label: "订单号号", prop: "salesContractNo", minWidth: "150" },
  ];
  const dataList = ref([]);
src/views/financialManagement/receivable/salesReturn.vue
@@ -87,7 +87,7 @@
        : Number(val).toLocaleString("zh-CN", { minimumFractionDigits: 2, maximumFractionDigits: 2 }),
  },
  { label: "退货原因", prop: "returnReason", minWidth: "150", showOverflowTooltip: true },
  { label: "销售订单号", prop: "salesContractNo", minWidth: "150" },
  { label: "订单号号", prop: "salesContractNo", minWidth: "150" },
];
const dataList = ref([]);
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -122,6 +122,9 @@
        <el-table-column label="单位"
                         prop="unit"
                         show-overflow-tooltip />
        <el-table-column label="库位"
                         prop="warehouse"
                         show-overflow-tooltip />
        <el-table-column label="入库数量"
                         prop="stockInNum"
                         show-overflow-tooltip />
src/views/inventoryManagement/stockManagement/BatchNoQtyDetail.vue
@@ -24,6 +24,7 @@
          <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
          <el-table-column label="单位" prop="unit" show-overflow-tooltip />
          <el-table-column label="批号" prop="batchNo" show-overflow-tooltip />
          <el-table-column label="库位" prop="warehouse" show-overflow-tooltip />
          <el-table-column
            label="合格库存数量"
            prop="qualifiedQuantity"
src/views/inventoryManagement/stockManagement/New.vue
@@ -8,6 +8,8 @@
               :model="formState"
               label-position="top"
               ref="formRef">
        <el-row :gutter="20">
          <el-col :span="12">
        <el-form-item label="产品名称"
                      prop="productModelId"
                      :rules="[
@@ -22,16 +24,24 @@
            {{ formState.productName ? formState.productName : '选择产品' }}
          </el-button>
        </el-form-item>
          </el-col>
          <el-col :span="12">
        <el-form-item label="规格"
                      prop="productModelName">
          <el-input v-model="formState.productModelName"
                    disabled />
        </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
        <el-form-item label="单位"
                      prop="unit">
          <el-input v-model="formState.unit"
                    disabled />
        </el-form-item>
          </el-col>
          <el-col :span="12">
        <el-form-item label="库存类型"
                      prop="type"
                      :rules="[
@@ -49,6 +59,10 @@
                       value="unqualified" />
          </el-select>
        </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
        <el-form-item label="库存数量"
                      prop="qualitity">
          <el-input-number v-model="formState.qualitity"
@@ -56,20 +70,17 @@
                           :min="1"
                           style="width: 100%" />
        </el-form-item>
          </el-col>
          <el-col :span="12">
        <el-form-item label="批号"
                      prop="batchNo">
          <el-input v-model="formState.batchNo"
                    placeholder="请输入批号" />
        </el-form-item>
        <el-form-item v-if="formState.type === 'qualified'"
                      label="库存预警数量"
                      prop="warnNum">
          <el-input-number v-model="formState.warnNum"
                           :step="1"
                           :min="0"
                           :max="formState.qualitity"
                           style="width: 100%" />
        </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
        <el-form-item label="入库时间"
                      prop="createTime">
          <el-date-picker v-model="formState.createTime"
@@ -79,6 +90,65 @@
                          format="YYYY-MM-DD HH:mm:ss"
                          style="width: 100%" />
        </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="formState.type === 'qualified'"
                          label="库存预警数量"
                          prop="warnNum">
              <el-input-number v-model="formState.warnNum"
                               :step="1"
                               :min="0"
                               :max="formState.qualitity"
                               style="width: 100%" />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="是否质检"
                          prop="needInspect">
              <el-switch v-model="formState.needInspect"
                         active-text="需要质检"
                         inactive-text="直接入库" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item v-if="formState.needInspect"
                          label="质检类型"
                          prop="inspectType">
              <el-radio-group v-model="formState.inspectType">
                <el-radio :value="0">原材料检验</el-radio>
                <el-radio :value="1">过程检验</el-radio>
              </el-radio-group>
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="选择设备"
                          prop="deviceId">
              <el-select v-model="formState.deviceId"
                         placeholder="请选择设备"
                         filterable
                         clearable
                         style="width: 100%"
                         @change="handleDeviceChange">
                <el-option v-for="device in iotDeviceList"
                           :key="device.id"
                           :label="device.deviceName"
                           :value="device.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="库位"
                          prop="warehouse">
              <el-input v-model="formState.warehouse"
                        placeholder="选择设备后自动获取"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-form-item label="备注"
                      prop="remark">
          <el-input v-model="formState.remark"
@@ -102,10 +172,11 @@
</template>
<script setup>
  import { ref, computed, watch, getCurrentInstance } from "vue";
  import { ref, computed, watch, getCurrentInstance, onMounted } from "vue";
  import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue";
  import { addStockInRecordOnly } from "@/api/inventoryManagement/stockInventory.js";
  import { createStockUnInventory } from "@/api/inventoryManagement/stockUninventory.js";
  import { getIotDeviceList as getIotDeviceListApi } from "@/api/equipmentManagement/ledger.js";
  const props = defineProps({
    visible: {
@@ -134,7 +205,14 @@
    warnNum: 0,
    createTime: "",
    remark: "",
    needInspect: false,
    inspectType: 0,
    deviceId: "",
    warehouse: "",
  });
  // IoT设备列表
  const iotDeviceList = ref([]);
  const isShow = computed({
    get() {
@@ -173,6 +251,10 @@
      warnNum: 0,
      createTime: "",
      remark: "",
      needInspect: false,
      inspectType: 0,
      deviceId: "",
      warehouse: "",
    };
    isShow.value = false;
  };
@@ -192,6 +274,32 @@
    }
  };
  // èŽ·å–IoT设备列表
  const getIotDeviceList = async () => {
    try {
      const res = await getIotDeviceListApi();
      if (res.data) {
        iotDeviceList.value = res.data;
      }
    } catch (error) {
      console.error("获取IoT设备列表失败:", error);
    }
  };
  // è®¾å¤‡é€‰æ‹©å˜æ›´æ—¶ï¼Œè‡ªåŠ¨å¡«å……åº“ä½
  const handleDeviceChange = (deviceId) => {
    const device = iotDeviceList.value.find(d => d.id === deviceId);
    if (device) {
      formState.value.warehouse = device.storageLocation || '';
    } else {
      formState.value.warehouse = '';
    }
  };
  onMounted(() => {
    getIotDeviceList();
  });
  const handleSubmit = () => {
    proxy.$refs["formRef"].validate(valid => {
      if (valid) {
@@ -204,17 +312,21 @@
          proxy.$modal.msgError("请选择规格");
          return;
        }
        // æž„建请求参数
        const params = {
          ...formState.value,
          // å¦‚果不需要质检,不传 inspectType
          inspectType: formState.value.needInspect ? formState.value.inspectType : undefined,
        };
        if (formState.value.type === "qualified") {
          addStockInRecordOnly(formState.value).then(res => {
            // å…³é—­æ¨¡æ€æ¡†
          addStockInRecordOnly(params).then(res => {
            isShow.value = false;
            // å‘ŠçŸ¥çˆ¶ç»„件已完成
            emit("completed");
            proxy.$modal.msgSuccess("提交成功");
          });
        } else {
          formState.value.warnNum = 0;
          createStockUnInventory(formState.value).then(res => {
          params.warnNum = 0;
          createStockUnInventory(params).then(res => {
            // å…³é—­æ¨¡æ€æ¡†
            isShow.value = false;
            // å‘ŠçŸ¥çˆ¶ç»„件已完成
src/views/inventoryManagement/stockManagement/Record.vue
@@ -87,6 +87,9 @@
        <el-table-column label="批号"
                         prop="batchNo"
                         show-overflow-tooltip />
        <el-table-column label="库位"
                         prop="warehouse"
                         show-overflow-tooltip />
        <el-table-column label="物联设备"
                         prop="warehouse"
                         show-overflow-tooltip
src/views/officeProcessAutomation/ApproveManage/approve-list/components/ApproveDetailPanel.vue
@@ -60,7 +60,7 @@
        <div v-if="detailData.shippingInfo" class="shipment-detail">
          <el-divider content-position="left">发货详情</el-divider>
          <el-descriptions :column="2" border>
            <el-descriptions-item label="销售订单">{{
            <el-descriptions-item label="订单号">{{
              detailData.shippingInfo.salesContractNo || "--"
            }}</el-descriptions-item>
            <el-descriptions-item label="出库批号">{{
@@ -142,7 +142,7 @@
            <el-descriptions-item label="项目名称">{{
              detailData.projectName || "--"
            }}</el-descriptions-item>
            <el-descriptions-item label="销售合同号">{{
            <el-descriptions-item label="订单号">{{
              detailData.salesContractNo || "--"
            }}</el-descriptions-item>
            <el-descriptions-item label="签订日期">{{
@@ -167,6 +167,7 @@
              <el-table-column prop="specificationModel" label="规格型号" />
              <el-table-column prop="unit" label="单位" />
              <el-table-column prop="quantity" label="数量" />
              <el-table-column prop="storageLocation" label="库位" />
              <el-table-column prop="taxInclusiveUnitPrice" label="含税单价">
                <template #default="scope"
                  >Â¥{{
src/views/officeProcessAutomation/ApproveManage/approve-shared/approvalModuleRegistry.js
@@ -8,6 +8,7 @@
  RESIGN: "resign",
  WORK_HANDOVER: "work_handover",
  LEAVE: "leave",
  COMPENSATORY: "compensatory",
  OVERTIME: "overtime",
  TRAVEL_REIMBURSE: "travel_reimburse",
  COST_REIMBURSE: "cost_reimburse",
@@ -20,6 +21,7 @@
  [APPROVAL_MODULE_KEYS.TRANSFER]: 11,
  [APPROVAL_MODULE_KEYS.WORK_HANDOVER]: 13,
  [APPROVAL_MODULE_KEYS.LEAVE]: 14,
  [APPROVAL_MODULE_KEYS.COMPENSATORY]: 19,
  [APPROVAL_MODULE_KEYS.OVERTIME]: 15,
  [APPROVAL_MODULE_KEYS.TRAVEL_REIMBURSE]: 16,
  [APPROVAL_MODULE_KEYS.COST_REIMBURSE]: 17,
@@ -57,6 +59,12 @@
    businessType: APPROVAL_BUSINESS_TYPE[APPROVAL_MODULE_KEYS.LEAVE],
    typeLabels: ["请假", "请假申请", "请假审批"],
  },
  [APPROVAL_MODULE_KEYS.COMPENSATORY]: {
    label: "调休申请",
    approvalType: "compensatory",
    businessType: APPROVAL_BUSINESS_TYPE[APPROVAL_MODULE_KEYS.COMPENSATORY],
    typeLabels: ["调休", "调休申请", "调休审批"],
  },
  [APPROVAL_MODULE_KEYS.OVERTIME]: {
    label: "加班申请",
    approvalType: "overtime",
src/views/officeProcessAutomation/ApproveManage/approve-template/index.vue
@@ -167,26 +167,6 @@
        </el-row>
        <el-form-item label="模板说明">
          <el-input
            v-model="form.description"
            type="textarea"
            :rows="2"
            placeholder="简要说明该模板的适用场景"
            maxlength="200"
            show-word-limit
          />
        </el-form-item>
        <el-form-item label="填报配置">
          <FormConfigEditor
@@ -259,8 +239,6 @@
          </el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="说明" :span="2">{{ detailRow.description || "—" }}</el-descriptions-item>
        <el-descriptions-item label="填报提示" :span="2">
src/views/officeProcessAutomation/ApproveManage/approve-template/useApproveTemplate.js
@@ -94,7 +94,6 @@
      align: "center",
      formatData: (v) => templateTypeLabel(v),
    },
    { label: "说明", prop: "description", minWidth: 160, showOverflowTooltip: true },
    {
      label: "节点数",
      prop: "flowNodes",
src/views/officeProcessAutomation/AttendManage/compensatory-leave/index.vue
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,314 @@
<!--OA模块:调休申请-->
<template>
  <div class="app-container">
    <div class="search_form mb20">
      <div>
        <span class="search_title">审批单号:</span>
        <el-input
          v-model="searchForm.instanceNo"
          style="width: 220px"
          placeholder="请输入审批单号"
          clearable
          @keyup.enter="onSearch"
        />
        <span class="search_title" style="margin-left: 12px">申请人:</span>
        <el-input
          v-model="searchForm.applicantKeyword"
          style="width: 220px"
          placeholder="姓名或编号"
          clearable
          :prefix-icon="Search"
          @keyup.enter="onSearch"
        />
        <el-button type="primary" style="margin-left: 10px" @click="onSearch">搜索</el-button>
        <el-button @click="resetSearch">重置</el-button>
      </div>
      <div>
        <el-button type="primary" @click="openAddWithTemplate">新增调休申请</el-button>
      </div>
    </div>
    <div class="table_list">
      <PIMTable
        rowKey="id"
        :column="tableColumn"
        :tableData="tableData"
        :page="page"
        :isSelection="false"
        :tableLoading="tableLoading"
        @pagination="onPagination"
        :total="page.total"
      />
    </div>
    <ApprovalInstanceSubmitDialog
      v-model="submitDialog.visible"
      :title="submitDialogTitle"
      :form="submitForm"
      :rules="submitFormRules"
      :fields="submitFormFields"
      :active-template="activeTemplate"
      :user-options="flowUserOptions"
      :is-edit="isSubmitEdit"
      :saving="submitSaving"
      :form-ref="submitFormRef"
      flow-attachments-only
      @submit="onSubmit"
    >
      <template #before="{ form, fields }">
        <FormPayloadFields :fields="displayTemplateFields(fields)" :form-payload="form.formPayload" />
        <el-row :gutter="24">
          <el-col :span="12">
            <el-form-item label="调休余额" prop="compensatoryBalanceHours">
              <el-input-number
                v-model="form.compensatoryBalanceHours"
                :min="0"
                :max="9999"
                :precision="2"
                :step="1"
                controls-position="right"
                placeholder="小时"
                style="width: 100%"
              />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="调休时长">
              <el-input :model-value="compensatoryDurationDisplay(form)" readonly placeholder="根据模板中调休时间自动计算">
                <template #append>小时</template>
              </el-input>
            </el-form-item>
          </el-col>
        </el-row>
      </template>
    </ApprovalInstanceSubmitDialog>
    <ApprovalTemplateBindDialog
      v-model:visible="templateBindVisible"
      :module-key="APPROVAL_MODULE_KEYS.COMPENSATORY"
      skip-form-confirm
      @confirm="onTemplateBound"
      @closed="onTemplateBindClosed"
    />
    <ApprovalInstanceDetailDialog
      v-model="detailDialog.visible"
      title="调休申请详情"
      :row="detailRow"
      @edit="openEditFromDetail"
    />
  </div>
</template>
<script setup>
import { Search } from "@element-plus/icons-vue";
import dayjs from "dayjs";
import { userListNoPageByTenantId } from "@/api/system/user.js";
import { ElMessage } from "element-plus";
import { computed, onMounted, reactive, ref, watch } from "vue";
import FormPayloadFields from "../../ApproveManage/approve-list/components/FormPayloadFields.vue";
import ApprovalInstanceDetailDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceDetailDialog.vue";
import ApprovalInstanceSubmitDialog from "../../ApproveManage/approve-shared/components/ApprovalInstanceSubmitDialog.vue";
import ApprovalTemplateBindDialog from "../../ApproveManage/approve-shared/components/ApprovalTemplateBindDialog.vue";
import { buildInstanceTableColumns } from "../../ApproveManage/approve-shared/approvalInstanceFormConfigTable.js";
import { APPROVAL_MODULE_KEYS } from "../../ApproveManage/approve-shared/approvalModuleRegistry.js";
import { useApprovalInstanceModule } from "../../ApproveManage/approve-shared/useApprovalInstanceModule.js";
import { useFlowUserOptions } from "../../ApproveManage/approve-shared/useFlowUserOptions.js";
import { SELECT_OPTION_SOURCE } from "../../ApproveManage/approve-template/selectOptionSource.js";
function isCompensatoryBalanceField(field) {
  const label = String(field?.label || "");
  return label.includes("调休余额") || field?.key === "compensatoryBalanceHours";
}
function isCompensatoryDurationField(field) {
  const label = String(field?.label || "");
  return label.includes("调休时长") || field?.key === "compensatoryDurationHours";
}
function displayTemplateFields(fields = []) {
  return (fields || []).filter((f) => !isCompensatoryBalanceField(f) && !isCompensatoryDurationField(f));
}
function findCompensatoryTimeTemplateField(fields = []) {
  return (
    fields.find((f) => f?.type === "datetimerange" && String(f?.label || "").includes("调休时间")) ||
    fields.find((f) => f?.type === "datetimerange" && f?.key === "dateRange") ||
    fields.find((f) => f?.type === "datetimerange") ||
    null
  );
}
function findApplicantTemplateField(fields = []) {
  return (
    fields.find((f) => String(f?.label || "").includes("申请人")) ||
    fields.find((f) => f?.type === "select" && f?.optionSource === SELECT_OPTION_SOURCE.USER) ||
    null
  );
}
function resolveCompensatoryTimeRange(payload, compensatoryTimeField) {
  if (!compensatoryTimeField?.key) return { start: "", end: "" };
  const val = payload?.[compensatoryTimeField.key];
  if (!Array.isArray(val) || val.length < 2) return { start: "", end: "" };
  return { start: val[0] || "", end: val[1] || "" };
}
function computeCompensatoryHours(startStr, endStr) {
  if (!startStr || !endStr) return null;
  const t0 = dayjs(startStr);
  const t1 = dayjs(endStr);
  if (!t0.isValid() || !t1.isValid() || !t1.isAfter(t0)) return null;
  const hours = t1.diff(t0, "millisecond") / (60 * 60 * 1000);
  return Math.round(hours * 100) / 100;
}
function compensatoryDurationDisplay(form) {
  const compensatoryTimeField = findCompensatoryTimeTemplateField(form.formFieldDefs);
  const { start, end } = resolveCompensatoryTimeRange(form.formPayload, compensatoryTimeField);
  const h = computeCompensatoryHours(start, end);
  return h == null ? "" : String(h);
}
const searchForm = reactive({
  instanceNo: "",
  applicantKeyword: "",
});
function validateCompensatoryBeforeSave() {
  const compensatoryTimeField = findCompensatoryTimeTemplateField(submitForm.formFieldDefs);
  const { start, end } = resolveCompensatoryTimeRange(submitForm.formPayload, compensatoryTimeField);
  if (computeCompensatoryHours(start, end) == null) {
    ElMessage.warning("请检查模板中的调休时间,结束时间须晚于开始时间");
    throw new Error("invalid compensatory time");
  }
}
const mod = useApprovalInstanceModule({
  moduleKey: APPROVAL_MODULE_KEYS.COMPENSATORY,
  beforeSave: validateCompensatoryBeforeSave,
  extraFormRules: {
    compensatoryBalanceHours: [{ required: true, message: "请填写调休余额", trigger: "blur" }],
  },
});
const {
  tableData,
  tableLoading,
  page,
  detailDialog,
  detailRow,
  submitDialog,
  submitEditRow,
  submitForm,
  submitFormRef,
  submitSaving,
  isSubmitEdit,
  activeTemplate,
  submitFormFields,
  submitFormRules,
  submitDialogTitle,
  templateBindVisible,
  handleQuery,
  initModuleList,
  pagination,
  openAddWithTemplate,
  onTemplateBound,
  onTemplateBindClosed,
  openEditFromDetail,
  submitInstanceForm,
  buildTableActions,
} = mod;
const { flowUserOptions, loadFlowUsers } = useFlowUserOptions();
const allUsersCache = ref([]);
const applicantTemplateField = computed(() =>
  findApplicantTemplateField(submitForm.formFieldDefs)
);
function unwrapArray(payload) {
  if (Array.isArray(payload)) return payload;
  if (payload && Array.isArray(payload.data)) return payload.data;
  return [];
}
async function loadUserPool() {
  try {
    const res = await userListNoPageByTenantId();
    allUsersCache.value = unwrapArray(res);
  } catch {
    allUsersCache.value = [];
  }
}
watch(
  () => submitDialog.visible,
  (v) => {
    if (!v) return;
    if (submitForm.compensatoryBalanceHours == null && isSubmitEdit.value) {
      submitForm.compensatoryBalanceHours =
        submitEditRow.value?.formPayload?.compensatoryBalanceHours ??
        submitEditRow.value?.compensatoryBalanceHours;
    }
    if (submitForm.compensatoryBalanceHours == null && !isSubmitEdit.value) {
      submitForm.compensatoryBalanceHours = undefined;
    }
  }
);
watch(
  () => {
    const key = applicantTemplateField.value?.key;
    return key ? submitForm.formPayload[key] : undefined;
  },
  async (uid) => {
    if (!applicantTemplateField.value || !uid) return;
    if (!allUsersCache.value.length) await loadUserPool();
  }
);
const tableColumn = buildInstanceTableColumns(tableData, buildTableActions, {
  moduleKey: APPROVAL_MODULE_KEYS.COMPENSATORY,
});
function onSearch() {
  handleQuery(searchForm);
}
function resetSearch() {
  searchForm.instanceNo = "";
  searchForm.applicantKeyword = "";
  onSearch();
}
function onPagination(obj) {
  pagination(obj, searchForm);
}
async function onSubmit() {
  const ok = await submitInstanceForm({ skipValidate: true });
  if (ok) ElMessage.success(isSubmitEdit.value ? "修改成功" : "提交成功");
}
onMounted(async () => {
  loadFlowUsers();
  await initModuleList(searchForm);
});
</script>
<style scoped>
.mb20 {
  margin-bottom: 20px;
}
.search_form {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.search_title {
  font-size: 14px;
  color: var(--el-text-color-regular);
}
</style>
src/views/personnelManagement/classsSheduling/index.vue
@@ -101,14 +101,16 @@
            </div>
            <div class="user-details">
              <h4 class="user-name">{{ item.name }}</h4>
              <!-- <div class="user-stats">
                <span class="stat-item">早:{{ item.day0 }}</span>
                <span class="stat-item">中:{{ item.day1 }}</span>
                <span class="stat-item">夜:{{ item.day2 }}</span>
                <span class="stat-item">休:{{ item.day3 }}</span>
                <span class="stat-item">假:{{ item.day4 }}</span>
                <span class="stat-item">å·®:{{ item.day6 }}</span>
              </div> -->
              <div class="user-stats">
                <span v-if="item.monthlyAttendance?.['休息']" class="stat-item stat-rest">休:{{ item.monthlyAttendance['休息'] }}</span>
                <el-tooltip v-if="item.holidayDates?.length > 0" placement="top">
                  <template #content>
                    <div>请假日期:</div>
                    <div v-for="date in item.holidayDates" :key="date">{{ date }}</div>
                  </template>
                  <span class="stat-item stat-holiday">假:{{ item.holidayDates.length }}</span>
                </el-tooltip>
              </div>
              <div class="user-total">
                <span class="total-label">合计出勤:</span>
                <span class="total-value">{{ item.monthlyAttendance.totalAttendance }}天</span>
@@ -153,6 +155,7 @@
                      'shift-box-leave': m.shift === '请假',
                      'shift-box-other': m.shift === '夜11',
                      'shift-box-business': m.shift === '夜12',
                      'holiday-cell': m.isHoliday,
                    }">
                      <span class="shift-text">{{ getShiftNameByValue(m.shift) || '—' }}</span>
                    </div>
@@ -1280,4 +1283,40 @@
    margin-bottom: 8px;
    margin-top: 12px;
  }
  /* è¯·å‡ä¼‘息日期特殊样式 */
  .holiday-cell {
    background-color: #fff3cd !important;
    color: #856404 !important;
    border: 1px solid #ffc107 !important;
  }
  /* ç”¨æˆ·ç»Ÿè®¡åŒºåŸŸ */
  .user-stats {
    display: flex;
    flex-wrap: wrap;
    gap: 4px;
    margin-bottom: 4px;
  }
  .stat-item {
    font-size: 12px;
    color: #666;
    padding-right: 4px;
  }
  .stat-rest {
    color: #10b981;
    background-color: rgba(16, 185, 129, 0.1);
    padding: 1px 6px;
    border-radius: 10px;
  }
  .stat-holiday {
    color: #f59e0b;
    background-color: rgba(245, 158, 11, 0.1);
    padding: 1px 6px;
    border-radius: 10px;
    cursor: pointer;
  }
</style>
src/views/procurementManagement/paymentLedger/index.vue
@@ -84,6 +84,9 @@
            <el-table-column label="采购合同号"
                             prop="purchaseContractNumber"
                             show-overflow-tooltip/>
            <el-table-column label="采购总合同号"
                             prop="masterContractNo"
                             show-overflow-tooltip/>
            <el-table-column label="项目名称"
                             prop="projectName"
                             show-overflow-tooltip/>
src/views/procurementManagement/procurementLedger/index.vue
@@ -27,13 +27,13 @@
                      clearable
                      :prefix-icon="Search" />
          </el-form-item>
          <el-form-item label="销售合同号:">
            <el-input v-model="searchForm.salesContractNo"
                      placeholder="请输入"
                      clearable
                      prefix-icon="Search"
                      @change="handleQuery" />
          </el-form-item>
<!--          <el-form-item label="订单号:">-->
<!--            <el-input v-model="searchForm.salesContractNo"-->
<!--                      placeholder="请输入"-->
<!--                      clearable-->
<!--                      prefix-icon="Search"-->
<!--                      @change="handleQuery" />-->
<!--          </el-form-item>-->
          <el-form-item label="项目名称:">
            <el-input v-model="searchForm.projectName"
                      placeholder="请输入"
@@ -217,10 +217,10 @@
                         prop="purchaseContractNumber"
                         width="160"
                         show-overflow-tooltip />
        <el-table-column label="销售合同号"
                         prop="salesContractNo"
                         width="160"
                         show-overflow-tooltip />
<!--        <el-table-column label="订单号"-->
<!--                         prop="salesContractNo"-->
<!--                         width="160"-->
<!--                         show-overflow-tooltip />-->
        <el-table-column label="供应商名称"
                         prop="supplierName"
                         width="160"
@@ -324,21 +324,21 @@
                        clearable />
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="销售合同号:"
                          prop="salesLedgerId">
              <el-select v-model="form.salesLedgerId"
                         placeholder="请选择"
                         filterable
                         clearable
                         @change="salesLedgerChange">
                <el-option v-for="item in salesContractList"
                           :key="item.id"
                           :label="item.salesContractNo"
                           :value="item.id" />
              </el-select>
            </el-form-item>
          </el-col>
<!--          <el-col :span="12">-->
<!--            <el-form-item label="订单号:"-->
<!--                          prop="salesLedgerId">-->
<!--              <el-select v-model="form.salesLedgerId"-->
<!--                         placeholder="请选择"-->
<!--                         filterable-->
<!--                         clearable-->
<!--                         @change="salesLedgerChange">-->
<!--                <el-option v-for="item in salesContractList"-->
<!--                           :key="item.id"-->
<!--                           :label="item.salesContractNo"-->
<!--                           :value="item.id" />-->
<!--              </el-select>-->
<!--            </el-form-item>-->
<!--          </el-col>-->
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
@@ -585,6 +585,35 @@
              <el-tag v-else :type="scope.row.isChecked ? 'success' : 'info'">
                {{ scope.row.isChecked ? '是' : '否' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="选择设备"
                           prop="deviceId"
                           width="150">
            <template #default="scope">
              <span v-if="scope.row.productType === 2">--</span>
              <el-select v-else
                         v-model="scope.row.deviceId"
                         placeholder="请选择设备"
                         filterable
                         clearable
                         @change="handleDeviceChange(scope.row, scope.$index)">
                <el-option v-for="device in iotDeviceList"
                           :key="device.id"
                           :label="device.deviceName"
                           :value="device.id" />
              </el-select>
            </template>
          </el-table-column>
          <el-table-column label="库位"
                           prop="storageLocation"
                           width="120">
            <template #default="scope">
              <span v-if="scope.row.productType === 2">--</span>
              <el-input v-else
                        v-model="scope.row.storageLocation"
                        placeholder="自动获取"
                        disabled />
            </template>
          </el-table-column>
          <el-table-column label="入库审核状态"
@@ -853,6 +882,32 @@
        </el-row>
        <el-row :gutter="30" v-if="productForm.productType !== 2">
          <el-col :span="12">
            <el-form-item label="选择设备:"
                          prop="deviceId">
              <el-select v-model="productForm.deviceId"
                         placeholder="请选择设备"
                         filterable
                         clearable
                         style="width: 100%"
                         @change="handleProductDeviceChange">
                <el-option v-for="device in iotDeviceList"
                           :key="device.id"
                           :label="device.deviceName"
                           :value="device.id" />
              </el-select>
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="库位:"
                          prop="storageLocation">
              <el-input v-model="productForm.storageLocation"
                        placeholder="选择设备后自动获取"
                        disabled />
            </el-form-item>
          </el-col>
        </el-row>
        <el-row :gutter="30" v-if="productForm.productType !== 2">
          <el-col :span="12">
            <el-form-item label="是否质检:"
                          prop="isChecked">
              <el-radio-group v-model="productForm.isChecked">
@@ -950,6 +1005,7 @@
  const salesContractList = ref([]);
  const supplierList = ref([]);
  const contractList = ref([]); // ä¾›åº”商合同列表
  const iotDeviceList = ref([]); // IoT设备列表
  const contractFileDialogVisible = ref(false);
  const contractFileList = ref([]);
  const tableLoading = ref(false);
@@ -965,6 +1021,7 @@
  import { modelList, productTreeList } from "@/api/basicData/product.js";
  import { getSparePartsList } from "@/api/equipmentManagement/spareParts.js";
  import { getSupplierContractList, getSupplierContractFilesByNo } from "@/api/basicData/supplierContract.js";
  import { getIotDeviceList as getIotDeviceListApi } from "@/api/equipmentManagement/ledger.js";
  import dayjs from "dayjs";
  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
@@ -1185,6 +1242,8 @@
      invoiceType: "",
      warnNum: "",
      isChecked: false,
      deviceId: "",
      storageLocation: "",
    },
    productRules: {
      productId: [{ required: true, message: "请选择", trigger: "change" }],
@@ -2284,6 +2343,39 @@
    }
  };
  // èŽ·å–IoT设备列表
  // èŽ·å–IoT设备列表
  const getIotDeviceList = async () => {
    try {
      const res = await getIotDeviceListApi();
      if (res.data) {
        iotDeviceList.value = res.data;
      }
    } catch (error) {
      console.error("获取IoT设备列表失败:", error);
    }
  };
  // è®¾å¤‡é€‰æ‹©å˜æ›´æ—¶ï¼Œè‡ªåŠ¨å¡«å……åº“ä½
  const handleDeviceChange = (row, index) => {
    const device = iotDeviceList.value.find(d => d.id === row.deviceId);
    if (device) {
      row.storageLocation = device.storageLocation || '';
    } else {
      row.storageLocation = '';
    }
  };
  // äº§å“å¼¹çª—中设备选择变更时,自动填充库位
  const handleProductDeviceChange = (deviceId) => {
    const device = iotDeviceList.value.find(d => d.id === deviceId);
    if (device) {
      productForm.value.storageLocation = device.storageLocation || '';
    } else {
      productForm.value.storageLocation = '';
    }
  };
  // æ ¼å¼åŒ–文件大小
  const formatFileSize = (bytes) => {
    if (!bytes) return '0 B';
@@ -2296,6 +2388,7 @@
  onMounted(() => {
    getList();
    getTemplateList();
    getIotDeviceList();
  });
</script>
src/views/procurementManagement/purchaseReturnOrder/index.vue
@@ -275,6 +275,11 @@
    width: 160,
  },
  {
    label: "采购总合同号",
    prop: "masterContractNo",
    width: 160,
  },
  {
    label: "制作日期",
    prop: "preparedAt",
    width: 130,
src/views/procurementManagement/receivingManagement/index.vue
@@ -21,7 +21,7 @@
            @change="handleQuery"
          />
        </el-form-item>
        <el-form-item label="销售合同号:">
        <el-form-item label="订单号:">
          <el-input
            v-model="searchForm.salesContractNo"
            placeholder="请输入"
@@ -92,7 +92,8 @@
        </el-table-column>
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="采购合同号" prop="purchaseContractNumber" width="160" show-overflow-tooltip />
        <el-table-column label="销售合同号" prop="salesContractNo" width="160" show-overflow-tooltip />
        <el-table-column label="采购总合同号" prop="masterContractNo" width="160" show-overflow-tooltip />
        <el-table-column label="订单号" prop="salesContractNo" width="160" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="supplierName" width="160" show-overflow-tooltip />
        <el-table-column label="项目名称" prop="projectName" width="320" show-overflow-tooltip />
        <el-table-column label="收货状态" prop="status" width="100" show-overflow-tooltip>
src/views/procurementManagement/receivingManagement/modal/ReceiptForm.vue
@@ -16,7 +16,7 @@
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="销售合同号:">
          <el-form-item label="订单号:">
            <el-input :model-value="detailData.salesContractNo || ''" disabled />
          </el-form-item>
        </el-col>
src/views/productionManagement/productionOrder/index.vue
@@ -278,6 +278,11 @@
      prop: "npsNo",
      width: "150px",
    },
    {
      label: "销售总合同号",
      prop: "masterContractNo",
      width: "150px",
    },
    // 1.待开始、2.进行中、3.已完成、4.已取消、5.已结束
    {
      label: "状态",
src/views/productionManagement/productionReporting/index.vue
@@ -202,7 +202,7 @@
      width: 120,
    },
    {
      label: "销售合同号",
      label: "订单号",
      prop: "salesContractNo",
      width: 120,
    },
src/views/productionManagement/workOrderManagement/index.vue
@@ -302,6 +302,11 @@
      width: "140",
    },
    {
      label: "销售总合同号",
      prop: "masterContractNo",
      width: "140",
    },
    {
      label: "产品名称",
      prop: "productName",
      width: "140",
src/views/productionPlan/productionPlan/index.vue
@@ -13,7 +13,7 @@
                    style="width: 160px;"
                    @keyup.enter="handleQuery" />
        </el-form-item>
        <el-form-item label="销售合同号:"
        <el-form-item label="订单号:"
                      prop="salesContractNo">
          <el-input v-model="searchForm.salesContractNo"
                    placeholder="请输入"
@@ -318,13 +318,17 @@
      },
    },
    {
      label: "销售合同号",
      label: "订单号",
      prop: "salesContractNo",
      width: "200px",
      dataType: "slot",
      slot: "salesContractNo",
    },
    {
      label: "销售总合同号",
      prop: "masterContractNo",
      width: "150px",
    },
    {
      label: "产品名称",
      prop: "productName",
src/views/qualityManagement/afterSalesTraceability/index.vue
@@ -116,7 +116,7 @@
    >
      <el-table-column type="selection" width="55" align="center" />
      <el-table-column label="序号" type="index" width="55" align="center" />
      <el-table-column label="销售合同号" prop="contractNo" width="160" />
      <el-table-column label="订单号" prop="contractNo" width="160" />
      <el-table-column label="产品编号" prop="productCode" width="140" />
      <el-table-column label="产品型号" prop="productModel" width="140" />
      <el-table-column label="客户名称" prop="customerName" width="160" />
@@ -172,10 +172,10 @@
      >
        <el-row>
          <el-col :span="12">
            <el-form-item label="销售合同号" prop="contractNo">
            <el-form-item label="订单号" prop="contractNo">
              <el-input
                v-model="form.contractNo"
                placeholder="请选择关联销售合同号"
                placeholder="请选择关联订单号"
              />
            </el-form-item>
          </el-col>
@@ -387,7 +387,7 @@
  },
  rules: {
    contractNo: [
      { required: true, message: "销售合同号不能为空", trigger: "blur" },
      { required: true, message: "订单号不能为空", trigger: "blur" },
    ],
    productCode: [
      { required: true, message: "产品编号不能为空", trigger: "blur" },
src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -9,10 +9,10 @@
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售订单:" prop="salesLedgerId">
            <el-form-item label="订单号:" prop="salesLedgerId">
              <el-select
                v-model="form.salesLedgerId"
                placeholder="请选择销售订单"
                placeholder="请选择订单号"
                clearable
                filterable
                :disabled="isViewMode"
@@ -330,7 +330,7 @@
const currentProductId = ref(0);
const testStandardOptions = ref([]); // æŒ‡æ ‡é€‰æ‹©ä¸‹æ‹‰æ¡†æ•°æ®
const modelOptions = ref([]);
const salesLedgerOptions = ref([]); // é”€å”®è®¢å•下拉框数据
const salesLedgerOptions = ref([]); // è®¢å•号下拉框数据
// æ‰“开弹框
const openDialog = async (type, row) => {
@@ -471,12 +471,12 @@
  form.value.unit = modelOptions.value.find(item => item.id == value)?.unit || '';
}
// é”€å”®è®¢å•选择变化处理
// è®¢å•号选择变化处理
const handleSalesLedgerChange = async (value) => {
  const selectedItem = salesLedgerOptions.value.find(item => item.id == value);
  if (selectedItem) {
    form.value.salesContractNo = selectedItem.salesContractNo || '';
    // æ ¹æ®é”€å”®è®¢å•ID查询产品信息,只赋值数量
    // æ ¹æ®è®¢å•号ID查询产品信息,只赋值数量
    try {
      const res = await productList({ salesLedgerId: value, type: 1 });
      const productData = res.data && res.data.length > 0 ? res.data[0] : null;
@@ -486,8 +486,8 @@
        calcSampleQuantity();
      }
    } catch (e) {
      console.error('查询销售订单产品信息失败', e);
      proxy.$modal.msgError('查询销售订单产品信息失败');
      console.error('查询订单号产品信息失败', e);
      proxy.$modal.msgError('查询订单号产品信息失败');
    }
  } else {
    form.value.salesContractNo = '';
src/views/qualityManagement/finalInspection/index.vue
@@ -26,11 +26,11 @@
            </el-form-item>
          </el-col>
          <el-col :span="6">
            <el-form-item label="销售单号"
            <el-form-item label="订单号"
                          prop="salesContractNo">
              <el-input v-model="searchForm.salesContractNo"
                        style="width: 240px"
                        placeholder="请输入销售单号搜索"
                        placeholder="请输入订单号搜索"
                        clearable />
            </el-form-item>
          </el-col>
@@ -154,11 +154,16 @@
      width: 120,
    },
    {
      label: "销售单号",
      label: "订单号",
      prop: "salesContractNo",
      width: 120,
    },
    {
      label: "销售总合同号",
      prop: "masterContractNo",
      width: 120,
    },
    {
      label: "检验员",
      prop: "checkName",
    },
src/views/reportAnalysis/projectProfit/index.vue
@@ -57,7 +57,7 @@
    },
    [
        {
            label: "销售合同号",
            label: "订单号",
            align: "center",
            prop: "customerContractNo",
        },
src/views/safeProduction/safeWorkApproval/components/approvalDia.vue
@@ -157,7 +157,7 @@
                <el-descriptions-item label="采购合同号">{{ currentPurchase.purchaseContractNumber }}</el-descriptions-item>
                <el-descriptions-item label="供应商名称">{{ currentPurchase.supplierName }}</el-descriptions-item>
                <el-descriptions-item label="项目名称">{{ currentPurchase.projectName }}</el-descriptions-item>
                <el-descriptions-item label="销售合同号">{{ currentPurchase.salesContractNo }}</el-descriptions-item>
                <el-descriptions-item label="订单号">{{ currentPurchase.salesContractNo }}</el-descriptions-item>
                <el-descriptions-item label="签订日期">{{ currentPurchase.executionDate }}</el-descriptions-item>
                <el-descriptions-item label="录入日期">{{ currentPurchase.entryDate }}</el-descriptions-item>
                <el-descriptions-item label="付款方式">{{ currentPurchase.paymentMethod }}</el-descriptions-item>
src/views/salesManagement/deliveryLedger/index.vue
@@ -2,7 +2,7 @@
  <div class="app-container">
    <div class="search_form">
      <el-form :model="searchForm" :inline="true">
        <el-form-item label="销售订单号:">
        <el-form-item label="订单号号:">
          <el-input
            v-model="searchForm.salesContractNo"
            placeholder="请输入"
@@ -57,8 +57,13 @@
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column
          label="销售订单"
          label="订单号"
          prop="salesContractNo"
          show-overflow-tooltip
        />
        <el-table-column
          label="销售总合同号"
          prop="masterContractNo"
          show-overflow-tooltip
        />
        <el-table-column
@@ -101,16 +106,16 @@
          prop="shippingCarNumber"
          show-overflow-tooltip
        />
        <el-table-column
          label="快递公司"
          prop="expressCompany"
          show-overflow-tooltip
        />
        <el-table-column
          label="快递单号"
          prop="expressNumber"
          show-overflow-tooltip
        />
<!--        <el-table-column-->
<!--          label="快递公司"-->
<!--          prop="expressCompany"-->
<!--          show-overflow-tooltip-->
<!--        />-->
<!--        <el-table-column-->
<!--          label="快递单号"-->
<!--          prop="expressNumber"-->
<!--          show-overflow-tooltip-->
<!--        />-->
        <el-table-column
          label="审核状态"
          prop="status"
@@ -287,7 +292,7 @@
    >
      <div v-if="detailRow" class="detail-wrapper">
        <el-descriptions :column="2" border>
          <el-descriptions-item label="销售订单">{{
          <el-descriptions-item label="订单号">{{
            detailRow.salesContractNo || "--"
          }}</el-descriptions-item>
          <el-descriptions-item label="发货订单号">{{
@@ -403,7 +408,7 @@
const dialogFormVisible = ref(false);
const data = reactive({
  searchForm: {
    salesContractNo: "", // é”€å”®è®¢å•号
    salesContractNo: "", // è®¢å•号号
    shippingCarNumber: "", // è½¦ç‰Œå·
    expressNumber: "", // å¿«é€’单号
  },
@@ -421,7 +426,7 @@
  },
  rules: {
    salesContractNo: [
      { required: true, message: "请选择销售订单", trigger: "change" },
      { required: true, message: "请选择订单号", trigger: "change" },
    ],
    customerName: [
      { required: true, message: "请输入客户名称", trigger: "blur" },
@@ -474,7 +479,7 @@
    });
};
// é”€å”®è®¢å•变化时自动填充客户名称
// è®¢å•号变化时自动填充客户名称
const handleSalesOrderChange = (value) => {
  const selectedOrder = salesOrderOptions.value.find(
    (item) => item.salesContractNo === value
src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -95,10 +95,14 @@
                             label="序号"
                             type="index"
                             width="60" />
            <el-table-column label="销售订单"
            <el-table-column label="订单号"
                             prop="salesContractNo"
                             show-overflow-tooltip
                             width="150" />
            <el-table-column label="销售总合同号"
                             prop="masterContractNo"
                             show-overflow-tooltip
                             width="150" />
            <!-- <el-table-column label="发货订单号"
                             prop="shippingNo"
                             show-overflow-tooltip
src/views/salesManagement/returnOrder/components/detailDia.vue
@@ -8,7 +8,7 @@
          <el-tag :type="getStatusType(detail.status)">{{ getStatusText(detail.status) }}</el-tag>
        </el-descriptions-item>
        <el-descriptions-item label="客户名称">{{ detail.customerName }}</el-descriptions-item>
        <el-descriptions-item label="销售单号">{{ detail.salesContractNo }}</el-descriptions-item>
        <el-descriptions-item label="订单号">{{ detail.salesContractNo }}</el-descriptions-item>
        <el-descriptions-item label="业务员">{{ detail.salesman }}</el-descriptions-item>
        <el-descriptions-item label="关联批号">{{ detail.shippingNo }}</el-descriptions-item>
        <!-- <el-descriptions-item label="项目名称">{{ detail.projectName }}</el-descriptions-item> -->
src/views/salesManagement/returnOrder/components/formDia.vue
@@ -120,7 +120,7 @@
              </el-form-item>
            </el-col>
            <el-col :span="4">
              <el-form-item label="销售合同号:">
              <el-form-item label="订单号:">
                <el-input v-model="form.salesContractNo" disabled placeholder="--" />
              </el-form-item>
            </el-col>
src/views/salesManagement/returnOrder/index.vue
@@ -8,8 +8,8 @@
                <el-form-item label="客户名称">
                    <el-input v-model="searchForm.customerName" placeholder="客户名称" clearable />
                </el-form-item>
                <el-form-item label="销售单号">
                    <el-input v-model="searchForm.salesContractNo" placeholder="销售单号" clearable />
                <el-form-item label="订单号">
                    <el-input v-model="searchForm.salesContractNo" placeholder="订单号" clearable />
                </el-form-item>
                <el-form-item label="关联批号">
                    <el-input v-model="searchForm.shippingNo" placeholder="关联批号" clearable />
@@ -122,7 +122,8 @@
  { label: "退货状态", prop: "returnStatus", minWidth: 100, dataType: "slot", slot: "returnStatus" },
  { label: "制单时间", prop: "makeTime", minWidth: 170 },
  { label: "客户名称", prop: "customerName", minWidth: 220 },
  { label: "销售单号", prop: "salesContractNo", minWidth: 160 },
  { label: "订单号", prop: "salesContractNo", minWidth: 160 },
  { label: "销售总合同号", prop: "masterContractNo", minWidth: 160 },
  { label: "业务员", prop: "salesman", minWidth: 120 },
  { label: "关联批号", prop: "shippingNo", minWidth: 170 },
  { label: "项目名称", prop: "projectName", minWidth: 180 },
src/views/salesManagement/salesLedger/index.vue
@@ -20,7 +20,7 @@
            @change="handleQuery"
          />
        </el-form-item>
        <el-form-item label="销售合同号:">
        <el-form-item label="订单号:">
          <el-input
            v-model="searchForm.salesContractNo"
            placeholder="请输入"
@@ -198,7 +198,7 @@
          show-overflow-tooltip
        />
        <el-table-column
          label="销售合同号"
          label="订单号"
          prop="salesContractNo"
          width="180"
          show-overflow-tooltip
@@ -349,7 +349,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售合同号:" prop="salesContractNo">
            <el-form-item label="订单号:" prop="salesContractNo">
              <div
                style="
                  display: flex;
@@ -1863,7 +1863,7 @@
    form.value.executionDate = getCurrentDate();
    // åˆ›å»ºæ—¶é—´é»˜è®¤ä¸ºå½“天
    form.value.createTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
    // é»˜è®¤è‡ªåŠ¨ç”Ÿæˆé”€å”®åˆåŒå·
    // é»˜è®¤è‡ªåŠ¨ç”Ÿæˆè®¢å•å·
    form.value.autoGenerateContractNo = true;
  } else {
    currentId.value = row.id;
@@ -2220,7 +2220,7 @@
  return status === "已发货" || status === "审核通过";
};
/** åˆ¤æ–­é”€å”®è®¢å•下是否存在已发货/发货完成的产品(不可删除) */
/** åˆ¤æ–­è®¢å•号下是否存在已发货/发货完成的产品(不可删除) */
const hasShippedProducts = (products) => {
  if (!products || !products.length) return false;
  return products.some((p) => {
@@ -2249,7 +2249,7 @@
  }
  const ids = selectedRows.value.map((item) => item.id);
  // æ£€æŸ¥æ˜¯å¦æœ‰å·²è¿›è¡Œå‘货或发货完成的销售订单,若有则不允许删除
  // æ£€æŸ¥æ˜¯å¦æœ‰å·²è¿›è¡Œå‘货或发货完成的订单号,若有则不允许删除
  const cannotDeleteNames = [];
  for (const row of selectedRows.value) {
    let products =
@@ -2268,7 +2268,7 @@
  }
  if (cannotDeleteNames.length > 0) {
    proxy.$modal.msgWarning(
      "已进行发货或发货完成的销售订单不能删除:" + cannotDeleteNames.join("、")
      "已进行发货或发货完成的订单号不能删除:" + cannotDeleteNames.join("、")
    );
    return;
  }