天津宝东
1.销售台账填完信息后,可以导出模版供客户直接盖章
2.销售台账打印报价单,可以多选销售订单,得相同公司名称,样式随意发挥
3.销售台账子表格产品的库存状态改为库存数量
已添加1个文件
已修改79个文件
1256 ■■■■■ 文件已修改
src/api/basicData/product.js 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/salesManagement/salesQuotationProduct.js 48 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/utils/request.js 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/basicData/product/index.vue 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/purchaseApproval/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/collaborativeApproval/shipmentReview/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/customerService/feedbackRegistration/components/formDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/energyArea/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/energyPower/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/energyTrends/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/gasManagement/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/waterManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/waterManagement/waterBill.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/energyManagement/waterManagement/waterTrends.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/calibration/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/deviceInfo/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/ledger/Form.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/ledger/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/operationManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/Modal/RepairModal.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/repair/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/Form/PlanModal.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/Form/formDia.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/equipmentManagement/upkeep/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/accounting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/financialManagement/inventoryAccounting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/dispatchLog/Record.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/issueManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/receiptManagement/Record.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Qualified.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Record.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockManagement/Unqualified.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockReport/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/inventoryManagement/stockWarning/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/advancedPriceManagement/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/invoiceEntry/components/Modal.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/paymentEntry/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/priceManagement/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementInvoiceLedger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementLedger/index.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/procurementReport/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/New.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/ProductList.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/purchaseReturnOrder/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/qualityInspection/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/procurementManagement/transferManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/operationScheduling/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/Detail/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/StructureEdit.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productStructure/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionCosting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/components/formDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionDispatching/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/productionManagement/productionReporting/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectManagement/Management/components/formDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/projectManagement/Management/projectDetail.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/components/formDia.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/finalInspection/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/metricMaintenance/index0.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/components/formDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/nonconformingManagement/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/processInspection/components/formDia.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/processInspection/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/qualityManagement/rawMaterialInspection/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/safeProduction/safeWorkApproval/components/approvalDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/deliveryLedger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/invoiceLedger/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/invoiceRegistration/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/receiptPayment/index.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/returnOrder/components/detailDia.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/returnOrder/components/formDia.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesLedger/index.vue 370 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/salesQuotation/index.vue 543 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/salesManagement/strategyControl/index.vue 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/api/basicData/product.js
@@ -17,7 +17,7 @@
        data: query
    })
}
// è§„格型号新增修改
// å°ºå¯¸æ–°å¢žä¿®æ”¹
export function addOrEditProductModel(query) {
    return request({
        url: '/basic/product/addOrEditProductModel',
@@ -33,7 +33,7 @@
        data: query
    })
}
// è§„格型号删除
// å°ºå¯¸åˆ é™¤
export function delProductModel(query) {
    return request({
        url: '/basic/product/delProductModel',
@@ -41,7 +41,7 @@
        data: query
    })
}
// è§„格型号查询
// å°ºå¯¸æŸ¥è¯¢
export function modelList(query) {
    return request({
        url: '/basic/product/modelList',
src/api/salesManagement/salesQuotationProduct.js
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,48 @@
import request from "@/utils/request";
export function quotationProductListPage(query) {
  return request({
    url: "/sales/quotationProduct/listPage",
    method: "get",
    params: query,
  });
}
export function quotationProductList(query) {
  return request({
    url: "/sales/quotationProduct/list",
    method: "get",
    params: query,
  });
}
export function getQuotationProductInfo(id) {
  return request({
    url: `/sales/quotationProduct/${id}`,
    method: "get",
  });
}
export function addOrUpdateQuotationProduct(data) {
  return request({
    url: "/sales/quotationProduct/addOrUpdate",
    method: "post",
    data,
  });
}
export function editQuotationProduct(data) {
  return request({
    url: "/sales/quotationProduct/edit",
    method: "post",
    data,
  });
}
export function deleteQuotationProduct(ids) {
  return request({
    url: "/sales/quotationProduct/delete",
    method: "delete",
    data: ids,
  });
}
src/utils/request.js
@@ -125,16 +125,25 @@
// é€šç”¨ä¸‹è½½æ–¹æ³•
export function download(url, params, filename, config) {
  downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
  return service.post(url, params, {
    transformRequest: [(params) => { return tansParams(params) }],
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    responseType: 'blob',
    ...config
  }).then(async (data) => {
  const downloadName = config?.filename || filename
  const requestMethod = (config?.method || 'post').toLowerCase()
  const requestPromise = requestMethod === 'get'
    ? service.get(url, {
      params,
      responseType: 'blob',
      ...config
    })
    : service.post(url, params, {
      transformRequest: [(params) => { return tansParams(params) }],
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      responseType: 'blob',
      ...config
    })
  return requestPromise.then(async (data) => {
    const isBlob = blobValidate(data)
    if (isBlob) {
      const blob = new Blob([data])
      saveAs(blob, filename)
      saveAs(blob, downloadName)
    } else {
      const resText = await data.text()
      const rspObj = JSON.parse(resText)
src/views/basicData/product/index.vue
@@ -77,7 +77,7 @@
    <div class="right">
      <div style="margin-bottom: 10px" v-if="isShowButton">
        <el-button type="primary" @click="openModelDia('add')">
          æ–°å¢žè§„格型号
          æ–°å¢žå°ºå¯¸
        </el-button>
        <ImportExcel :product-id="currentId" @uploadSuccess="getModelList" />
        <el-button
@@ -132,7 +132,7 @@
    </el-dialog>
    <el-dialog
      v-model="modelDia"
      title="规格型号"
      title="尺寸"
      width="400px"
      @close="closeModelDia"
      @keydown.enter.prevent
@@ -146,10 +146,10 @@
      >
        <el-row>
          <el-col :span="24">
            <el-form-item label="规格型号:" prop="model">
            <el-form-item label="尺寸:" prop="model">
              <el-input
                v-model="modelForm.model"
                placeholder="请输入规格型号"
                placeholder="请输入尺寸"
                clearable
                @keydown.enter.prevent
              />
@@ -294,7 +294,7 @@
const expandedKeys = ref([]);
const tableColumn = ref([
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
  },
  {
@@ -397,7 +397,7 @@
    form.value.productName = data.productName;
  }
};
// æ‰“开规格型号弹框
// æ‰“开尺寸弹框
const openModelDia = (type, data) => {
  modelOperationType.value = type;
  modelDia.value = true;
@@ -474,7 +474,7 @@
  getModelList();
};
// æäº¤è§„格型号修改
// æäº¤å°ºå¯¸ä¿®æ”¹
const submitModelForm = () => {
  proxy.$refs.modelFormRef.validate((valid) => {
    if (valid) {
@@ -497,7 +497,7 @@
  selectedRows.value = selection;
};
// æŸ¥è¯¢è§„格型号
// æŸ¥è¯¢å°ºå¯¸
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
@@ -516,7 +516,7 @@
    tableLoading.value = false;
  });
};
// åˆ é™¤è§„格型号
// åˆ é™¤å°ºå¯¸
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
src/views/collaborativeApproval/approvalProcess/components/approvalDia.vue
@@ -71,7 +71,7 @@
                <h4>产品明细</h4>
                <el-table :data="currentQuotation.products || []" border style="width: 100%">
                  <el-table-column prop="product" label="产品名称" />
                  <el-table-column prop="specification" label="规格型号" />
                  <el-table-column prop="specification" label="尺寸" />
                  <el-table-column prop="unit" label="单位" />
                  <el-table-column prop="unitPrice" label="单价">
                    <template #default="scope">Â¥{{ Number(scope.row.unitPrice ?? 0).toFixed(2) }}</template>
@@ -119,7 +119,7 @@
                <h4>产品明细</h4>
                <el-table :data="currentPurchase.productData || []" border style="width: 100%">
                  <el-table-column prop="productCategory" label="产品名称" />
                  <el-table-column prop="specificationModel" label="规格型号" />
                  <el-table-column prop="specificationModel" label="尺寸" />
                  <el-table-column prop="unit" label="单位" />
                  <el-table-column prop="quantity" label="数量" />
                  <el-table-column prop="taxInclusiveUnitPrice" label="含税单价">
src/views/collaborativeApproval/purchaseApproval/index.vue
@@ -66,7 +66,7 @@
                width="60"
              />
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="尺寸" prop="specificationModel" />
              <el-table-column label="单位" prop="unit" />
              <el-table-column label="数量" prop="quantity" />
              <el-table-column label="税率(%)" prop="taxRate" />
src/views/collaborativeApproval/shipmentReview/index.vue
@@ -125,7 +125,7 @@
    width: 200
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "specificationModel",
    width: 220
  },
src/views/customerService/feedbackRegistration/components/formDia.vue
@@ -217,7 +217,7 @@
const tableColumn = ref([
  { label: "产品大类", prop: "productCategory" },
  { label: "规格型号", prop: "specificationModel" },
  { label: "尺寸", prop: "specificationModel" },
  { label: "单位", prop: "unit" },
  {
    label: "产品状态",
src/views/energyManagement/energyArea/index.vue
@@ -281,7 +281,7 @@
    form.value.areaName = data.areaName;
  }
};
// æ‰“开规格型号弹框
// æ‰“开尺寸弹框
const openModelDia = (type, data,fatherId) => {
  modelOperationType.value = type;
  modelDia.value = true;
@@ -356,7 +356,7 @@
  getModelList(true);
};
// æäº¤è§„格型号修改
// æäº¤å°ºå¯¸ä¿®æ”¹
const submitModelForm = () => {
  proxy.$refs.modelFormRef.validate((valid) => {
    if (valid) {
@@ -380,7 +380,7 @@
  selectedRows.value = selection;
};
// æŸ¥è¯¢è§„格型号
// æŸ¥è¯¢å°ºå¯¸
const pagination = (obj) => {
  page.current = obj.page;
  page.size = obj.limit;
@@ -406,7 +406,7 @@
    tableLoading.value = false;
  });
};
// åˆ é™¤è§„格型号
// åˆ é™¤å°ºå¯¸
const handleDelete = () => {
  let ids = [];
  if (selectedRows.value.length > 0) {
src/views/energyManagement/energyPower/index.vue
@@ -106,7 +106,7 @@
        width: 200,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "code",
        width: 200,
    },
src/views/energyManagement/energyTrends/index.vue
@@ -55,7 +55,7 @@
        width: 220,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "code",
        width: 220,
    },
src/views/energyManagement/gasManagement/index.vue
@@ -148,7 +148,7 @@
          <el-table-column label="设备编号" prop="deviceCode" width="120" show-overflow-tooltip />
          <el-table-column label="设备名称" prop="deviceName" width="150" show-overflow-tooltip />
          <el-table-column label="设备类型" prop="deviceType" width="120" show-overflow-tooltip />
          <el-table-column label="规格型号" prop="specification" width="150" show-overflow-tooltip />
          <el-table-column label="尺寸" prop="specification" width="150" show-overflow-tooltip />
          <el-table-column label="当前压力(MPa)" prop="currentPressure" width="130" show-overflow-tooltip>
            <template #default="scope">
              <span :class="getPressureClass(scope.row.currentPressure)">
@@ -217,8 +217,8 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号" prop="specification">
              <el-input v-model="deviceForm.specification" placeholder="请输入规格型号" />
            <el-form-item label="尺寸" prop="specification">
              <el-input v-model="deviceForm.specification" placeholder="请输入尺寸" />
            </el-form-item>
          </el-col>
        </el-row>
@@ -284,7 +284,7 @@
  deviceCode: [{ required: true, message: '请输入设备编号', trigger: 'blur' }],
  deviceName: [{ required: true, message: '请输入设备名称', trigger: 'blur' }],
  deviceType: [{ required: true, message: '请选择设备类型', trigger: 'change' }],
  specification: [{ required: true, message: '请输入规格型号', trigger: 'blur' }],
  specification: [{ required: true, message: '请输入尺寸', trigger: 'blur' }],
  designPressure: [{ required: true, message: '请输入设计压力', trigger: 'blur' }],
  volume: [{ required: true, message: '请输入容积', trigger: 'blur' }]
}
src/views/energyManagement/waterManagement/index.vue
@@ -106,7 +106,7 @@
        width: 200,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "deviceModel",
        width: 200,
    },
src/views/energyManagement/waterManagement/waterBill.vue
@@ -59,7 +59,7 @@
        width: 200,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "code",
        width: 200,
    },
src/views/energyManagement/waterManagement/waterTrends.vue
@@ -51,7 +51,7 @@
        width: 220,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "code",
        width: 220,
    },
src/views/equipmentManagement/calibration/index.vue
@@ -114,7 +114,7 @@
        width: 200,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "model",
        width:200
    },
src/views/equipmentManagement/deviceInfo/index.vue
@@ -15,7 +15,7 @@
          <span class="value">{{ deviceInfo.deviceName }}</span>
        </div>
        <div class="info-row">
          <span class="label">规格型号:</span>
          <span class="label">尺寸:</span>
          <span class="value">{{ deviceInfo.deviceModel }}</span>
        </div>
        <div class="info-row">
src/views/equipmentManagement/ledger/Form.vue
@@ -7,8 +7,8 @@
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="规格型号" prop="deviceModel">
          <el-input v-model="form.deviceModel" placeholder="请输入规格型号" />
        <el-form-item label="尺寸" prop="deviceModel">
          <el-input v-model="form.deviceModel" placeholder="请输入尺寸" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
@@ -215,7 +215,7 @@
const { form, resetForm } = useFormData({
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  deviceModel: undefined, // å°ºå¯¸
  deviceBrand: undefined, // è®¾å¤‡å“ç‰Œ
  type: undefined, // è®¾å¤‡ç±»åž‹
  supplierName: undefined, // ä¾›åº”商
src/views/equipmentManagement/ledger/index.vue
@@ -10,11 +10,11 @@
          @change="getTableData"
        />
      </el-form-item>
      <el-form-item label="规格型号">
      <el-form-item label="尺寸">
        <el-input
            v-model="filters.deviceModel"
            style="width: 200px"
            placeholder="请输入规格型号"
            placeholder="请输入尺寸"
            clearable
            @change="getTableData"
        />
@@ -174,7 +174,7 @@
      prop: "deviceName",
    },
    {
      label: "规格型号",
      label: "尺寸",
      prop: "deviceModel",
    },
    {
src/views/equipmentManagement/measurementEquipment/components/rowClickData.vue
@@ -62,7 +62,7 @@
    width: 200,
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
    width:200
  },
src/views/equipmentManagement/operationManagement/index.vue
@@ -34,7 +34,7 @@
          show-overflow-tooltip
        />
        <el-table-column
          label="规格型号"
          label="尺寸"
          prop="deviceModel"
          show-overflow-tooltip
        />
src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -22,10 +22,10 @@
          </el-form-item>
        </el-col>
        <el-col :span="12">
          <el-form-item label="规格型号">
          <el-form-item label="尺寸">
            <el-input
              v-model="form.deviceModel"
              placeholder="请输入规格型号"
              placeholder="请输入尺寸"
              disabled
            />
          </el-form-item>
@@ -115,7 +115,7 @@
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // è®¾å¤‡Id
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  deviceModel: undefined, // å°ºå¯¸
  repairTime: dayjs().format("YYYY-MM-DD"), // æŠ¥ä¿®æ—¥æœŸï¼Œé»˜è®¤å½“天
  repairName: userStore.nickName, // æŠ¥ä¿®äºº
  remark: undefined, // æ•…障现象
src/views/equipmentManagement/repair/index.vue
@@ -11,11 +11,11 @@
            @change="getTableData"
        />
      </el-form-item>
      <el-form-item label="规格型号">
      <el-form-item label="尺寸">
        <el-input
            v-model="filters.deviceModel"
            style="width: 240px"
            placeholder="请选择规格型号"
            placeholder="请选择尺寸"
            clearable
            :prefix-icon="Search"
            @change="getTableData"
@@ -183,7 +183,7 @@
        prop: "deviceName",
      },
      {
        label: "规格型号",
        label: "尺寸",
        align: "center",
        prop: "deviceModel",
      },
src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -25,10 +25,10 @@
          ></el-option>
        </el-select>
      </el-form-item>
      <el-form-item label="规格型号">
      <el-form-item label="尺寸">
        <el-input
          v-model="form.deviceModel"
          placeholder="请输入规格型号"
          placeholder="请输入尺寸"
          disabled
        />
      </el-form-item>
@@ -110,7 +110,7 @@
const { form, resetForm } = useFormData({
  deviceLedgerId: undefined, // è®¾å¤‡Id
  deviceName: undefined, // è®¾å¤‡åç§°
  deviceModel: undefined, // è§„格型号
  deviceModel: undefined, // å°ºå¯¸
  maintenancePlanTime: undefined, // è®¡åˆ’保养日期
  createUser: undefined, // å½•入人
  status: 0, //保修状态
src/views/equipmentManagement/upkeep/Form/formDia.vue
@@ -23,10 +23,10 @@
                    </el-form-item>
                </el-col>
                <el-col :span="12">
                    <el-form-item label="规格型号">
                    <el-form-item label="尺寸">
                        <el-input
                            v-model="form.deviceModel"
                            placeholder="请输入规格型号"
                            placeholder="请输入尺寸"
                            disabled
                        />
                    </el-form-item>
@@ -159,7 +159,7 @@
        frequencyDetail: '',
        week: '',
        time: '',
        deviceModel: undefined, // è§„格型号
        deviceModel: undefined, // å°ºå¯¸
        registrationDate: ''
    },
    rules: {
@@ -176,7 +176,7 @@
    deviceOptions.value = data;
};
// é€‰æ‹©è®¾å¤‡æ—¶ï¼Œå›žå¡«è®¾å¤‡åç§°(taskName)和规格型号(deviceModel)
// é€‰æ‹©è®¾å¤‡æ—¶ï¼Œå›žå¡«è®¾å¤‡åç§°(taskName)和尺寸(deviceModel)
const setDeviceModel = (id) => {
    const option = deviceOptions.value.find((item) => item.id === id);
    if (option) {
src/views/equipmentManagement/upkeep/index.vue
@@ -301,7 +301,7 @@
const scheduledColumns = ref([
    { prop: "taskName", label: "设备名称"},
    {
        label: "规格型号",
        label: "尺寸",
        prop: "deviceModel",
    },
    {
@@ -357,7 +357,7 @@
        prop: "deviceName",
    },
    {
        label: "规格型号",
        label: "尺寸",
        align: "center",
        prop: "deviceModel",
    },
src/views/financialManagement/accounting/index.vue
@@ -157,7 +157,7 @@
        >
          <el-table-column type="index" label="序号" width="60" :index="(index) => (pagination.currentPage - 1) * pagination.pageSize + index + 1" />
          <el-table-column prop="deviceName" label="设备名称" width="250" />
          <el-table-column prop="deviceModel" label="规格型号" min-width="150" />
          <el-table-column prop="deviceModel" label="尺寸" min-width="150" />
          <el-table-column prop="supplierName" label="供应商" min-width="120" />
          <el-table-column prop="unit" label="单位" width="120" />
          <el-table-column prop="number" label="数量" width="120" />
src/views/financialManagement/inventoryAccounting/index.vue
@@ -103,7 +103,7 @@
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="供应商名称" prop="supplierName" width="240" show-overflow-tooltip />
        <el-table-column label="产品" prop="productCategory" min-width="100" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="specificationModel" min-width="200" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="specificationModel" min-width="200" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" width="70" show-overflow-tooltip />
        <el-table-column label="入库数量" prop="inboundNum" width="90" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="inboundNum0" width="90" show-overflow-tooltip />
src/views/inventoryManagement/dispatchLog/Record.vue
@@ -62,7 +62,7 @@
                    show-overflow-tooltip
                />
                <el-table-column
                    label="规格型号"
                    label="尺寸"
                    prop="model"
                    show-overflow-tooltip
                />
@@ -430,7 +430,7 @@
              <thead>
                <tr>
                  <th>产品名称</th>
                  <th>规格型号</th>
                  <th>尺寸</th>
                  <th>单位</th>
                  <th>单价</th>
                  <th>零售数量</th>
src/views/inventoryManagement/issueManagement/index.vue
@@ -33,7 +33,7 @@
        <el-table-column label="入库批次" prop="inboundBatches" width="160" show-overflow-tooltip />
        <el-table-column label="供应商名称" prop="supplierName" width="240" show-overflow-tooltip />
        <el-table-column label="产品大类" prop="productCategory" width="100" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="specificationModel" width="200" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="specificationModel" width="200" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" width="70" show-overflow-tooltip />
        <el-table-column label="入库数量" prop="inboundNum" width="90" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="inboundNum0" width="90" show-overflow-tooltip />
src/views/inventoryManagement/receiptManagement/Record.vue
@@ -64,7 +64,7 @@
        <el-table-column label="产品大类"
                         prop="productName"
                         show-overflow-tooltip/>
        <el-table-column label="规格型号"
        <el-table-column label="尺寸"
                         prop="model"
                         show-overflow-tooltip/>
        <el-table-column label="单位"
src/views/inventoryManagement/stockManagement/Qualified.vue
@@ -24,7 +24,7 @@
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="model" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
src/views/inventoryManagement/stockManagement/Record.vue
@@ -24,7 +24,7 @@
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="model" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="合格库存数量" prop="qualifiedQuantity" show-overflow-tooltip />
        <el-table-column label="不合格库存数量" prop="unQualifiedQuantity" show-overflow-tooltip />
src/views/inventoryManagement/stockManagement/Unqualified.vue
@@ -21,7 +21,7 @@
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column label="产品大类" prop="productName" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="model" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="model" show-overflow-tooltip />
        <el-table-column label="单位" prop="unit" show-overflow-tooltip />
        <el-table-column label="库存数量" prop="qualitity" show-overflow-tooltip />
        <el-table-column label="冻结数量" prop="lockedQuantity" show-overflow-tooltip />
src/views/inventoryManagement/stockReport/index.vue
@@ -181,7 +181,7 @@
             show-overflow-tooltip
           />
           <el-table-column
             label="规格型号"
             label="尺寸"
             prop="model"
             show-overflow-tooltip
           />
src/views/inventoryManagement/stockWarning/index.vue
@@ -59,7 +59,7 @@
        <el-table-column label="储气罐编码" prop="tankCode" width="120" show-overflow-tooltip />
        <el-table-column label="储气罐名称" prop="tankName" width="200" show-overflow-tooltip />
        <el-table-column label="储气罐类型" prop="tankType" width="120" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="specificationModel" width="150" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="specificationModel" width="150" show-overflow-tooltip />
        <el-table-column label="容积(m³)" prop="volume" width="100" show-overflow-tooltip />
        <!-- åº“存相关字段 -->
@@ -171,8 +171,8 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="specificationModel">
              <el-input v-model="form.specificationModel" placeholder="请输入规格型号" />
            <el-form-item label="尺寸:" prop="specificationModel">
              <el-input v-model="form.specificationModel" placeholder="请输入尺寸" />
            </el-form-item>
          </el-col>
        </el-row>
src/views/procurementManagement/advancedPriceManagement/index.vue
@@ -157,8 +157,8 @@
        </el-row>
        <el-row :gutter="20">
          <el-col :span="12">
            <el-form-item label="规格型号" prop="specification">
              <el-input v-model="formData.specification" placeholder="请输入规格型号" />
            <el-form-item label="尺寸" prop="specification">
              <el-input v-model="formData.specification" placeholder="请输入尺寸" />
            </el-form-item>
          </el-col>
          <el-col :span="12">
src/views/procurementManagement/invoiceEntry/components/ExpandTable.vue
@@ -42,7 +42,7 @@
      prop: "productCategory",
    },
    {
      label: "规格型号",
      label: "尺寸",
      prop: "specificationModel",
    },
    {
src/views/procurementManagement/invoiceEntry/components/Modal.vue
@@ -112,7 +112,7 @@
                    </template>
                </el-table-column>
                <el-table-column label="产品大类" prop="productCategory" />
                <el-table-column label="规格型号" prop="specificationModel" width="150" />
                <el-table-column label="尺寸" prop="specificationModel" width="150" />
                <el-table-column label="单位" prop="unit" width="70" />
                <el-table-column label="数量" prop="quantity" width="70" />
                <el-table-column label="税率(%)" prop="taxRate" width="80" />
@@ -264,7 +264,7 @@
        width: 120,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "specificationModel",
        width: 120,
    },
src/views/procurementManagement/paymentEntry/index.vue
@@ -150,7 +150,7 @@
          width="100"
        />
        <el-table-column
          label="规格型号"
          label="尺寸"
          prop="specificationModel"
          show-overflow-tooltip
          width="150"
@@ -280,7 +280,7 @@
        showOverflowTooltip: true,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "specificationModel",
        showOverflowTooltip: true,
        width: 150
src/views/procurementManagement/priceManagement/index.vue
@@ -31,7 +31,7 @@
      <el-table :data="tableData" border v-loading="loading" @selection-change="handleSelectionChange">
        <el-table-column type="selection" width="55" align="center" />
        <el-table-column label="商品名称" prop="productName" />
        <el-table-column label="规格型号" prop="specification" />
        <el-table-column label="尺寸" prop="specification" />
        <el-table-column label="供应商名称" prop="supplierName" />
        <el-table-column label="原价格" prop="oldPrice" width="120">
          <template #default="{ row }">Â¥{{ row.oldPrice.toFixed(2) }}</template>
@@ -71,8 +71,8 @@
            <el-option label="商品C" value="商品C" />
          </el-select>
        </el-form-item>
        <el-form-item label="规格型号">
          <el-input v-model="formData.specification" placeholder="请输入规格型号" />
        <el-form-item label="尺寸">
          <el-input v-model="formData.specification" placeholder="请输入尺寸" />
        </el-form-item>
        <el-form-item label="供应商名称">
          <el-select v-model="formData.supplierName" placeholder="请选择供应商" style="width: 100%">
src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -171,7 +171,7 @@
      width: 150,
    },
    {
      label: "规格型号",
      label: "尺寸",
      prop: "specificationModel",
      width: 150,
    },
src/views/procurementManagement/procurementLedger/index.vue
@@ -84,7 +84,7 @@
                               width="60" />
              <el-table-column label="产品大类"
                               prop="productCategory" />
              <el-table-column label="规格型号"
              <el-table-column label="尺寸"
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit" />
@@ -362,7 +362,7 @@
                           width="60" />
          <el-table-column label="产品大类"
                           prop="productCategory" />
          <el-table-column label="规格型号"
          <el-table-column label="尺寸"
                           prop="specificationModel" />
          <el-table-column label="单位"
                           prop="unit"
@@ -513,7 +513,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="24">
            <el-form-item label="规格型号:"
            <el-form-item label="尺寸:"
                          prop="productModelId">
              <el-select v-model="productForm.productModelId"
                         placeholder="请选择"
@@ -1422,7 +1422,7 @@
            );
            if (modelItem) {
              productForm.value.productModelId = modelItem.id;
              // è®¾ç½®è§„格型号和单位
              // è®¾ç½®å°ºå¯¸å’Œå•位
              getProductModel(modelItem.id);
            }
          }
src/views/procurementManagement/procurementReport/index.vue
@@ -111,7 +111,7 @@
    prop: 'productCategory',
  },
  {
    label: '规格型号',
    label: '尺寸',
    prop: 'specificationModel',
  },
  {
src/views/procurementManagement/purchaseReturnOrder/New.vue
@@ -242,7 +242,7 @@
                               width="60" />
              <el-table-column label="产品大类"
                               prop="productCategory" />
              <el-table-column label="规格型号"
              <el-table-column label="尺寸"
                               prop="specificationModel" />
              <el-table-column label="单位"
                               prop="unit"
src/views/procurementManagement/purchaseReturnOrder/ProductList.vue
@@ -19,7 +19,7 @@
                           width="60" />
          <el-table-column label="产品大类"
                           prop="productCategory" />
          <el-table-column label="规格型号"
          <el-table-column label="尺寸"
                           prop="specificationModel" />
          <el-table-column label="单位"
                           prop="unit"
src/views/procurementManagement/purchaseReturnOrder/index.vue
@@ -79,7 +79,7 @@
        >
          <el-table-column align="center" label="序号" type="index" width="60" />
          <el-table-column label="产品大类" prop="productCategory" min-width="120" show-overflow-tooltip />
          <el-table-column label="规格型号" prop="specificationModel" min-width="140" show-overflow-tooltip />
          <el-table-column label="尺寸" prop="specificationModel" min-width="140" show-overflow-tooltip />
          <el-table-column label="单位" prop="unit" width="80" />
          <el-table-column label="数量" prop="quantity" width="80" />
          <el-table-column label="退货数量" prop="returnQuantity" width="100" />
src/views/procurementManagement/qualityInspection/index.vue
@@ -75,9 +75,9 @@
                  <el-input v-model="row.productName" placeholder="请输入商品名称" />
                </template>
              </el-table-column>
              <el-table-column label="规格型号" width="150">
              <el-table-column label="尺寸" width="150">
                <template #default="{ row }">
                  <el-input v-model="row.specification" placeholder="请输入规格型号" />
                  <el-input v-model="row.specification" placeholder="请输入尺寸" />
                </template>
              </el-table-column>
              <el-table-column label="到货数量" width="150">
src/views/procurementManagement/transferManagement/index.vue
@@ -90,7 +90,7 @@
              width="60"
          />
          <el-table-column label="产品大类" prop="productCategory" />
          <el-table-column label="规格型号" prop="specificationModel" />
          <el-table-column label="尺寸" prop="specificationModel" />
          <el-table-column label="单位" prop="unit" width="70" />
          <el-table-column label="供应商" prop="supplierName" width="100" />
          <el-table-column label="采购数量" prop="quantity" width="100" />
src/views/productionManagement/operationScheduling/index.vue
@@ -133,7 +133,7 @@
        width: 150,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "specificationModel",
        width: 150,
    },
src/views/productionManagement/productStructure/Detail/index.vue
@@ -143,7 +143,7 @@
                       prop="bomNo" />
      <el-table-column label="产品名称"
                       prop="productName" />
      <el-table-column label="规格型号"
      <el-table-column label="尺寸"
                       prop="model" />
    </el-table>
    <product-select-dialog v-if="dataValue.showProductDialog"
src/views/productionManagement/productStructure/StructureEdit.vue
@@ -156,7 +156,7 @@
      </el-table-column>
      <el-table-column label="产品编码" prop="productCode" />
      <el-table-column label="产品名称" prop="productName" />
      <el-table-column label="规格型号" prop="model" />
      <el-table-column label="尺寸" prop="model" />
      <el-table-column label="单位" prop="unit" />
    </el-table>
src/views/productionManagement/productStructure/index.vue
@@ -80,7 +80,7 @@
    minWidth: 160
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "productModelName",
    minWidth: 140
  },
src/views/productionManagement/productionCosting/index.vue
@@ -100,7 +100,7 @@
    minWidth: 100,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "productModelName",
    minWidth: 100,
    },
src/views/productionManagement/productionDispatching/components/autoDispatchDia.vue
@@ -20,7 +20,7 @@
          <el-table-column label="客户名称" prop="customerName" width="200" />
          <!-- <el-table-column label="项目名称" prop="projectName" width="250" /> -->
          <el-table-column label="产品大类" prop="productCategory" width="150" />
          <el-table-column label="规格型号" prop="specificationModel" width="200" />
          <el-table-column label="尺寸" prop="specificationModel" width="200" />
          <el-table-column label="绑定机器" prop="speculativeTradingName" width="120" />
          <el-table-column label="总数量" prop="quantity" width="100" align="right" />
          <el-table-column label="已排产" prop="schedulingNum" width="100" align="right" fixed="right" />
src/views/productionManagement/productionDispatching/components/formDia.vue
@@ -21,7 +21,7 @@
        </el-row> -->
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="specificationModel">
            <el-form-item label="尺寸:" prop="specificationModel">
              <el-input v-model="form.specificationModel" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
@@ -125,7 +125,7 @@
  form: {
        projectName: "",
        productCategory: "",
        specificationModel: "", // è§„格型号
        specificationModel: "", // å°ºå¯¸
        quantity: "",
        schedulingNum: "",
        schedulingUserId: "",
src/views/productionManagement/productionDispatching/index.vue
@@ -128,7 +128,7 @@
        width: 160,
    },
    {
        label: "规格型号",
        label: "尺寸",
        prop: "specificationModel",
        width: 120,
    },
src/views/productionManagement/productionReporting/index.vue
@@ -183,7 +183,7 @@
      width: 120,
    },
    {
      label: "产品规格型号",
      label: "产品尺寸",
      prop: "productModelName",
      width: 120,
    },
src/views/projectManagement/Management/components/formDia.vue
@@ -192,7 +192,7 @@
            <el-table-column v-if="!isView" align="center" type="selection" width="55" />
            <el-table-column align="center" label="序号" type="index" width="60" />
            <el-table-column label="产品大类" prop="productCategory" />
            <el-table-column label="规格型号" prop="specificationModel" />
            <el-table-column label="尺寸" prop="specificationModel" />
            <el-table-column label="单位" prop="unit" />
            <el-table-column label="数量" prop="quantity" />
            <el-table-column label="税率(%)" prop="taxRate" />
@@ -555,7 +555,7 @@
      </el-row>
      <el-row :gutter="30">
        <el-col :span="24">
          <el-form-item label="规格型号:" prop="productModelId">
          <el-form-item label="尺寸:" prop="productModelId">
            <el-select v-model="productForm.productModelId" placeholder="请选择" clearable filterable @change="getProductModel">
              <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
            </el-select>
src/views/projectManagement/Management/projectDetail.vue
@@ -64,7 +64,7 @@
          <el-table :data="productRows" border show-summary :summary-method="summarizeProductTable">
            <el-table-column align="center" label="序号" type="index" width="60" />
            <el-table-column label="产品大类" prop="productCategory" show-overflow-tooltip />
            <el-table-column label="规格型号" prop="specificationModel" show-overflow-tooltip />
            <el-table-column label="尺寸" prop="specificationModel" show-overflow-tooltip />
            <el-table-column label="单位" prop="unit" width="90" />
            <el-table-column label="数量" prop="quantity" width="90" />
            <el-table-column label="税率(%)" prop="taxRate" width="90" />
src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -24,7 +24,7 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productModelId">
            <el-form-item label="尺寸:" prop="productModelId">
              <el-select v-model="form.productModelId" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                         filterable readonly @change="handleChangeModel">
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
@@ -235,12 +235,12 @@
      proxy.$refs.formRef?.clearValidate();
    });
    
    // ç¼–辑模式下,并行加载规格型号和指标选项
    // ç¼–辑模式下,并行加载尺寸和指标选项
    if (currentProductId.value) {
      // è®¾ç½®äº§å“åç§°
      form.value.productName = findNodeById(productOptions.value, currentProductId.value);
      
      // å¹¶è¡ŒåŠ è½½è§„æ ¼åž‹å·å’ŒæŒ‡æ ‡é€‰é¡¹
      // å¹¶è¡ŒåŠ è½½å°ºå¯¸å’ŒæŒ‡æ ‡é€‰é¡¹
      const params = {
        productId: currentProductId.value,
        inspectType: 2
@@ -250,7 +250,7 @@
        modelList({ id: currentProductId.value }),
        qualityInspectDetailByProductId(params)
      ]).then(([modelRes, testStandardRes]) => {
        // è®¾ç½®è§„格型号选项
        // è®¾ç½®å°ºå¯¸é€‰é¡¹
        modelOptions.value = modelRes || [];
        // å¦‚果表单中已有 productModelId,设置对应的 model å’Œ unit
        if (form.value.productModelId && modelOptions.value.length > 0) {
src/views/qualityManagement/finalInspection/index.vue
@@ -115,7 +115,7 @@
    prop: "productName",
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
  },
  {
src/views/qualityManagement/metricMaintenance/index0.vue
@@ -350,7 +350,7 @@
  });
};
// æäº¤è§„格型号修改
// æäº¤å°ºå¯¸ä¿®æ”¹
const submitModelForm = () => {
  proxy.$refs.modelFormRef.validate((valid) => {
    if (valid) {
src/views/qualityManagement/nonconformingManagement/components/formDia.vue
@@ -34,7 +34,7 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="model">
            <el-form-item label="尺寸:" prop="model">
              <el-select v-model="form.model" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                          filterable readonly @change="handleChangeModel">
              <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
src/views/qualityManagement/nonconformingManagement/components/inspectionFormDia.vue
@@ -35,7 +35,7 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="model">
            <el-form-item label="尺寸:" prop="model">
              <el-input v-model="form.model" placeholder="请输入" clearable disabled/>
            </el-form-item>
          </el-col>
src/views/qualityManagement/nonconformingManagement/index.vue
@@ -140,7 +140,7 @@
    prop: "productName",
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
  },
  {
src/views/qualityManagement/processInspection/components/formDia.vue
@@ -33,7 +33,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productModelId">
            <el-form-item label="尺寸:" prop="productModelId">
              <el-select v-model="form.productModelId" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                         filterable readonly @change="handleChangeModel">
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
@@ -248,7 +248,7 @@
    }
    testStandardOptions.value = [];
    tableData.value = [];
    // å…ˆç¡®ä¿äº§å“æ ‘已加载,否则编辑时产品/规格型号无法反显
    // å…ˆç¡®ä¿äº§å“æ ‘已加载,否则编辑时产品/尺寸无法反显
    await getProductOptions();
    if (operationType.value === 'edit') {
        // å…ˆä¿å­˜ testStandardId,避免被清空
@@ -256,7 +256,7 @@
        // å…ˆè®¾ç½®è¡¨å•数据,但暂时清空 testStandardId,等选项加载完成后再设置
        form.value = {...row, testStandardId: ''}
        currentProductId.value = row.productId || 0
        // å…³é”®ï¼šç¼–辑时加载规格型号下拉选项,才能反显 productModelId
        // å…³é”®ï¼šç¼–辑时加载尺寸下拉选项,才能反显 productModelId
        if (currentProductId.value) {
            try {
                const res = await modelList({ id: currentProductId.value });
@@ -266,7 +266,7 @@
                    handleChangeModel(form.value.productModelId);
                }
            } catch (e) {
                console.error("加载规格型号失败", e);
                console.error("加载尺寸失败", e);
                modelOptions.value = [];
            }
        }
src/views/qualityManagement/processInspection/index.vue
@@ -114,7 +114,7 @@
    prop: "productName",
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
  },
  {
src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -43,7 +43,7 @@
        </el-row>
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="规格型号:" prop="productModelId">
            <el-form-item label="尺寸:" prop="productModelId">
              <el-select v-model="form.productModelId" placeholder="请选择" clearable :disabled="operationType === 'edit'"
                         filterable readonly @change="handleChangeModel">
                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
@@ -258,14 +258,14 @@
  }
  testStandardOptions.value = [];
  tableData.value = [];
  // å…ˆç¡®ä¿äº§å“æ ‘已加载,否则编辑时产品/规格型号无法反显
  // å…ˆç¡®ä¿äº§å“æ ‘已加载,否则编辑时产品/尺寸无法反显
  await getProductOptions();
  if (operationType.value === 'edit') {
    // å…ˆä¿å­˜ testStandardId,避免被清空
    const savedTestStandardId = row.testStandardId;
    form.value = {...row}
    currentProductId.value = row.productId || 0
    // å…³é”®ï¼šç¼–辑时加载规格型号下拉选项,才能反显 productModelId
    // å…³é”®ï¼šç¼–辑时加载尺寸下拉选项,才能反显 productModelId
    if (currentProductId.value) {
      try {
        const res = await modelList({ id: currentProductId.value });
@@ -275,7 +275,7 @@
          handleChangeModel(form.value.productModelId);
        }
      } catch (e) {
        console.error("加载规格型号失败", e);
        console.error("加载尺寸失败", e);
        modelOptions.value = [];
      }
    }
src/views/qualityManagement/rawMaterialInspection/index.vue
@@ -116,7 +116,7 @@
    prop: "productName",
  },
  {
    label: "规格型号",
    label: "尺寸",
    prop: "model",
  },
  {
src/views/safeProduction/safeWorkApproval/components/approvalDia.vue
@@ -116,7 +116,7 @@
                  <el-table-column prop="product"
                                   label="产品名称" />
                  <el-table-column prop="specification"
                                   label="规格型号" />
                                   label="尺寸" />
                  <el-table-column prop="unit"
                                   label="单位" />
                  <el-table-column prop="unitPrice"
@@ -176,7 +176,7 @@
                  <el-table-column prop="productCategory"
                                   label="产品名称" />
                  <el-table-column prop="specificationModel"
                                   label="规格型号" />
                                   label="尺寸" />
                  <el-table-column prop="unit"
                                   label="单位" />
                  <el-table-column prop="quantity"
src/views/salesManagement/deliveryLedger/index.vue
@@ -31,7 +31,7 @@
        <el-table-column label="发货订单号" prop="shippingNo" show-overflow-tooltip />
        <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip />
        <el-table-column label="产品名称" prop="productCategory" show-overflow-tooltip />
        <el-table-column label="规格型号" prop="specificationModel" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="specificationModel" show-overflow-tooltip />
                <el-table-column label="发货进度" align="center" width="150">
                    <template #default="scope">
                        <el-progress
src/views/salesManagement/invoiceLedger/index.vue
@@ -33,7 +33,7 @@
        <el-table-column label="销售合同号" prop="salesContractNo" show-overflow-tooltip width="180" />
        <el-table-column label="客户名称" prop="customerName" show-overflow-tooltip width="240" />
        <el-table-column label="产品大类" prop="productCategory" width="200" />
        <el-table-column label="规格型号" prop="specificationModel" width="160" show-overflow-tooltip />
        <el-table-column label="尺寸" prop="specificationModel" width="160" show-overflow-tooltip />
        <el-table-column label="发票号" prop="invoiceNo" width="200" show-overflow-tooltip />
        <el-table-column label="发票金额(元)" prop="invoiceTotal" show-overflow-tooltip :formatter="formattedNumber"
          width="200" />
src/views/salesManagement/invoiceRegistration/index.vue
@@ -69,7 +69,7 @@
                            />
                            <el-table-column label="产品大类" prop="productCategory" />
                            <el-table-column
                                label="规格型号"
                                label="尺寸"
                                prop="specificationModel"
                                width="150"
                            />
@@ -274,7 +274,7 @@
                    </el-table-column>
                    <el-table-column label="产品大类" prop="productCategory" />
                    <el-table-column
                        label="规格型号"
                        label="尺寸"
                        prop="specificationModel"
                        width="150"
                    />
src/views/salesManagement/receiptPayment/index.vue
@@ -155,7 +155,7 @@
          width="100"
        />
        <el-table-column
          label="规格型号"
          label="尺寸"
          prop="specificationModel"
          show-overflow-tooltip
          width="200"
@@ -215,7 +215,7 @@
                    width="100"
                />
                <el-table-column
                    label="规格型号"
                    label="尺寸"
                    prop="specificationModel"
                    show-overflow-tooltip
                    width="200"
src/views/salesManagement/returnOrder/components/detailDia.vue
@@ -43,7 +43,7 @@
const tableColumn = [
  {align: "center", label: "产品大类", prop: "productCategory"},
  {align: "center", label: "规格型号", prop: "specificationModel"},
  {align: "center", label: "尺寸", prop: "specificationModel"},
  {align: "center", label: "单位", prop: "unit", width: 80},
  {align: "center", label: "总数量", prop: "quantity", width: 120},
  {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120},
src/views/salesManagement/returnOrder/components/formDia.vue
@@ -146,7 +146,7 @@
      >
        <el-table-column align="center" type="selection" width="55" />
        <el-table-column align="center" prop="productCategory" label="产品大类" />
        <el-table-column align="center" prop="specificationModel" label="规格型号" />
        <el-table-column align="center" prop="specificationModel" label="尺寸" />
        <el-table-column align="center" prop="unit" label="单位" />
        <el-table-column align="center" prop="quantity" label="总数量" />
        <el-table-column align="center" prop="unQuantity" label="未退货数量" />
@@ -216,7 +216,7 @@
const tableColumn = ref([
  {align: "center", label: "产品大类", prop: "productCategory" },
  {align: "center", label: "规格型号", prop: "specificationModel" },
  {align: "center", label: "尺寸", prop: "specificationModel" },
  {align: "center", label: "单位", prop: "unit", width: 80 },
  {align: "center", label: "总数量", prop: "quantity", width: 120 },
  {align: "center", label: "已退货数量", prop: "totalReturnNum", width: 120 },
src/views/salesManagement/salesLedger/index.vue
@@ -30,6 +30,9 @@
          <el-button type="primary" @click="openForm('add')">
            æ–°å¢žå°è´¦
          </el-button>
          <el-button type="primary" plain :disabled="selectedRows.length === 0" @click="handleBatchExportContract">
            å¯¼å‡ºåˆåŒ
          </el-button>
          <el-button type="primary" plain @click="handleImport">导入</el-button>
          <el-button @click="handleOut">导出</el-button>
          <el-button type="danger" plain @click="handleDelete">删除</el-button>
@@ -45,18 +48,10 @@
            <el-table :data="props.row.children" border show-summary :summary-method="(param) => summarizeChildrenTable(param, props.row)">
              <el-table-column align="center" label="序号" type="index"/>
              <el-table-column label="产品大类" prop="productCategory" />
              <el-table-column label="规格型号" prop="specificationModel" />
              <el-table-column label="尺寸" prop="specificationModel" />
              <el-table-column label="纸张" prop="paper" />
              <el-table-column label="单位" prop="unit" />
                            <el-table-column label="产品状态"
                                                             width="100px"
                                                             align="center">
                <template #default="scope">
                                    <el-tag v-if="scope.row.approveStatus === 1"
                                                    type="success">充足</el-tag>
                                    <el-tag v-else
                                                    type="danger">不足</el-tag>
                </template>
              </el-table-column>
                            <el-table-column label="产品数量" width="100px" align="center" prop="productNum"></el-table-column>
                            <el-table-column label="发货状态" width="140" align="center">
                                <template #default="scope">
                                    <el-tag :type="getShippingStatusType(scope.row)" size="small">
@@ -121,13 +116,13 @@
      :operation-type="operationType" @close="closeDia" @confirm="submitForm" @cancel="closeDia">
      <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
                <!-- æŠ¥ä»·å•导入入口:放在表单顶部,选择后反显客户/业务员等 -->
                <el-row v-if="operationType === 'add'" style="margin-bottom: 10px;">
                    <el-col :span="24" style="text-align: right;">
                        <el-button type="primary" plain @click="openQuotationDialog">
                            ä»Žé”€å”®æŠ¥ä»·å¯¼å…¥
                        </el-button>
                    </el-col>
                </el-row>
<!--                <el-row v-if="operationType === 'add'" style="margin-bottom: 10px;">-->
<!--                    <el-col :span="24" style="text-align: right;">-->
<!--                        <el-button type="primary" plain @click="openQuotationDialog">-->
<!--                            ä»Žé”€å”®æŠ¥ä»·å¯¼å…¥-->
<!--                        </el-button>-->
<!--                    </el-col>-->
<!--                </el-row>-->
        <el-row :gutter="30">
          <el-col :span="12">
            <el-form-item label="销售合同号:" prop="salesContractNo">
@@ -147,11 +142,7 @@
          <el-col :span="12">
            <el-form-item label="客户名称:" prop="customerId">
              <el-select v-model="form.customerId" placeholder="请选择" clearable :disabled="operationType === 'view'" filterable>
                <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id">
                  {{
                    item.customerName + "——" + item.taxpayerIdentificationNumber
                  }}
                </el-option>
                <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
              </el-select>
            </el-form-item>
          </el-col>
@@ -161,7 +152,7 @@
                        </el-form-item>
                    </el-col>
        </el-row>
        <el-row :gutter="30">
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="签订日期:" prop="executionDate">
                            <el-date-picker style="width: 100%" v-model="form.executionDate" value-format="YYYY-MM-DD"
@@ -171,6 +162,36 @@
                    <el-col :span="12">
                        <el-form-item label="付款方式">
                            <el-input v-model="form.paymentMethod" placeholder="请输入" clearable :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="价格类型:">
                            <el-input v-model="form.priceType" placeholder="请输入" clearable :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="6">
                        <el-form-item label="定金比例(%):">
                            <el-input-number v-model="form.depositRatio" :min="0" :max="100" :precision="2" :step="0.1" style="width: 100%" :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="6">
                        <el-form-item label="定金金额(元):">
                            <el-input-number v-model="form.depositAmount" :min="0" :precision="2" :step="0.01" style="width: 100%" :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="12">
                        <el-form-item label="送货地址:">
                            <el-input v-model="form.deliveryAddress" placeholder="请输入" clearable :disabled="operationType === 'view'" />
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="发货周期:">
                            <el-input-number v-model="form.deliveryCycle" :min="0" :precision="0" style="width: calc(100% - 68px)" :disabled="operationType === 'view'" />
                            <span style="margin-left: 8px; color: #606266;">工作日</span>
                        </el-form-item>
                    </el-col>
                </el-row>
@@ -212,13 +233,15 @@
                        :selectable="(row) => !isProductShipped(row)" />
                    <el-table-column align="center" label="序号" type="index" width="60" />
                    <el-table-column label="产品大类" prop="productCategory" />
                    <el-table-column label="规格型号" prop="specificationModel" />
                    <el-table-column label="尺寸" prop="specificationModel" />
                    <el-table-column label="纸张" prop="paper" />
                    <el-table-column label="单位" prop="unit" />
                    <el-table-column label="数量" prop="quantity" />
                    <el-table-column label="税率(%)" prop="taxRate" />
                    <el-table-column label="含税单价(元)" prop="taxInclusiveUnitPrice" :formatter="formattedNumber" />
                    <el-table-column label="含税总价(元)" prop="taxInclusiveTotalPrice" :formatter="formattedNumber" />
                    <el-table-column label="不含税总价(元)" prop="taxExclusiveTotalPrice" :formatter="formattedNumber" />
                    <el-table-column label="备注" prop="remark" show-overflow-tooltip />
                    <el-table-column fixed="right" label="操作" min-width="60" align="center" v-if="operationType !== 'view'">
                        <template #default="scope">
                            <el-button link type="primary" size="small" 
@@ -263,13 +286,6 @@
        >
            <div style="margin-bottom: 12px; display:flex; gap: 12px; align-items:center;">
                <el-input
                    v-model="quotationSearchForm.quotationNo"
                    placeholder="请输入报价单号"
                    clearable
                    style="max-width: 260px;"
                    @change="fetchQuotationList"
                />
                <el-input
                    v-model="quotationSearchForm.customer"
                    placeholder="请输入客户名称"
                    clearable
@@ -288,10 +304,46 @@
                height="420px"
            >
                <el-table-column align="center" label="序号" type="index" width="60" />
                <el-table-column prop="quotationNo" label="报价单号" width="180" show-overflow-tooltip />
                <el-table-column prop="customer" label="客户名称" min-width="220" show-overflow-tooltip />
                <el-table-column prop="salesperson" label="业务员" width="120" show-overflow-tooltip />
                <el-table-column prop="quotationDate" label="报价日期" width="140" />
                <el-table-column label="产品名称" min-width="180" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ getPrimaryQuotationProductField(row, "product") }}
                    </template>
                </el-table-column>
                <el-table-column label="尺寸" min-width="140" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ getPrimaryQuotationProductField(row, "specification") }}
                    </template>
                </el-table-column>
                <el-table-column label="纸张" min-width="120" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ getPrimaryQuotationProductField(row, "paper") }}
                    </template>
                </el-table-column>
                <el-table-column label="定量" min-width="100" show-overflow-tooltip>
                    <template #default="{ row }">
                        {{ getPrimaryQuotationProductField(row, "grammage") }}
                    </template>
                </el-table-column>
                <el-table-column label="单价(元)" width="120" align="right">
                    <template #default="{ row }">
                        {{ formatQuotationMoney(getPrimaryQuotationProductValue(row, "unitPrice")) }}
                    </template>
                </el-table-column>
                <el-table-column label="印版费(元)" width="120" align="right">
                    <template #default="{ row }">
                        {{ formatQuotationMoney(getPrimaryQuotationProductValue(row, "printingPlateFee")) }}
                    </template>
                </el-table-column>
                <el-table-column label="刀版费(元)" width="120" align="right">
                    <template #default="{ row }">
                        {{ formatQuotationMoney(getPrimaryQuotationProductValue(row, "diePlateFee")) }}
                    </template>
                </el-table-column>
                <el-table-column label="磨具费(元)" width="120" align="right">
                    <template #default="{ row }">
                        {{ formatQuotationMoney(getPrimaryQuotationProductValue(row, "moldFee")) }}
                    </template>
                </el-table-column>
                <el-table-column prop="status" label="审批状态" width="120" align="center" />
                <el-table-column prop="totalAmount" label="报价金额(元)" width="160" align="right">
                    <template #default="scope">
@@ -337,10 +389,17 @@
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="规格型号:" prop="productModelId">
                        <el-form-item label="尺寸:" prop="productModelId">
                            <el-select v-model="productForm.productModelId" placeholder="请选择" clearable @change="getProductModel" filterable>
                                <el-option v-for="item in modelOptions" :key="item.id" :label="item.model" :value="item.id" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="纸张:">
                            <el-input v-model="productForm.paper" placeholder="请输入" clearable />
                        </el-form-item>
                    </el-col>
                </el-row>
@@ -351,7 +410,7 @@
                        </el-form-item>
                    </el-col>
                    <el-col :span="12">
                        <el-form-item label="税率(%):" prop="taxRate">
                        <el-form-item label="税率(%)(选填):" prop="taxRate">
                            <el-select v-model="productForm.taxRate" placeholder="请选择" clearable @change="calculateFromTaxRate">
                                <el-option label="1" value="1" />
                                <el-option label="6" value="6" />
@@ -395,6 +454,13 @@
                                <el-option label="增普票" value="增普票" />
                                <el-option label="增专票" value="增专票" />
                            </el-select>
                        </el-form-item>
                    </el-col>
                </el-row>
                <el-row :gutter="30">
                    <el-col :span="24">
                        <el-form-item label="备注:">
                            <el-input v-model="productForm.remark" placeholder="请输入" clearable type="textarea" :rows="2" />
                        </el-form-item>
                    </el-col>
                </el-row>
@@ -493,7 +559,7 @@
                                    <thead>
                                    <tr>
                                        <th>产品名称</th>
                                        <th>规格型号</th>
                                        <th>尺寸</th>
                                        <th>单位</th>
                                        <th>单价</th>
                                        <th>零售数量</th>
@@ -647,12 +713,19 @@
        salesContractNo: "",
        salesman: "",
        customerId: "",
        projectName: "",
        priceType: "",
        depositRatio: null,
        depositAmount: null,
        deliveryAddress: "",
        deliveryCycle: null,
        entryPerson: "",
        entryDate: "",
    deliveryDate: "",
        maintenanceTime: "",
        productData: [],
        executionDate: "",
        remarks: "",
    hasProductionRecord: false,
    },
    rules: {
@@ -674,6 +747,7 @@
    productForm: {
        productCategory: "",
        specificationModel: "",
        paper: "",
        unit: "",
        quantity: "",
        taxInclusiveUnitPrice: "",
@@ -681,6 +755,7 @@
        taxInclusiveTotalPrice: "",
        taxExclusiveTotalPrice: "",
        invoiceType: "",
        remark: "",
    },
    productRules: {
        productCategory: [{ required: true, message: "请选择", trigger: "change" }],
@@ -693,7 +768,6 @@
        taxInclusiveUnitPrice: [
            { required: true, message: "请输入", trigger: "blur" },
        ],
        taxRate: [{ required: true, message: "请选择", trigger: "change" }],
        taxInclusiveTotalPrice: [
            { required: true, message: "请输入", trigger: "blur" },
        ],
@@ -704,6 +778,27 @@
    },
});
const { productForm, productRules } = toRefs(productFormData);
const createDefaultProductForm = () => ({
    productCategory: "",
    specificationModel: "",
    paper: "",
    unit: "",
    quantity: "",
    taxInclusiveUnitPrice: "",
    taxRate: "",
    taxInclusiveTotalPrice: "",
    taxExclusiveTotalPrice: "",
    invoiceType: "",
    remark: "",
});
const normalizeProductItem = (target) => {
    if (!target) return target;
    const remark = target.remark ?? "";
    return {
        ...target,
        remark: remark,
    };
};
// é˜²æ­¢å¾ªçŽ¯è®¡ç®—çš„æ ‡å¿—
const isCalculating = ref(false);
const upload = reactive({
@@ -1022,6 +1117,25 @@
        "taxExclusiveTotalPrice",
    ]);
};
const createDefaultForm = () => ({
    salesContractNo: "",
    salesman: "",
    customerId: "",
    projectName: "",
    priceType: "",
    depositRatio: null,
    depositAmount: null,
    deliveryAddress: "",
    deliveryCycle: null,
    entryPerson: userStore.id,
    entryDate: getCurrentDate(),
    deliveryDate: "",
    maintenanceTime: "",
    productData: [],
    executionDate: getCurrentDate(),
    remarks: "",
    hasProductionRecord: false,
});
// æ‰“开弹框
const openForm = async (type, row) => {
    if (type === "edit" && row && !canEditLedger(row)) {
@@ -1029,7 +1143,7 @@
        return;
    }
    operationType.value = type;
    form.value = {};
    form.value = createDefaultForm();
    productData.value = [];
    selectedQuotation.value = null;
    let userLists = await userListNoPage();
@@ -1037,18 +1151,16 @@
    listCustomerPrivatePool({current: -1,size:-1}).then((res) => {
        customerOption.value = res.data.records;
    });
    form.value.entryPerson = userStore.id;
    if (type === "add") {
        // æ–°å¢žæ—¶è®¾ç½®å½•入日期为当天
        form.value.entryDate = getCurrentDate();
        // ç­¾è®¢æ—¥æœŸé»˜è®¤ä¸ºå½“天
        form.value.executionDate = getCurrentDate();
        // é»˜è®¤å€¼å·²åœ¨ createDefaultForm ä¸­è®¾ç½®
    } else {
        currentId.value = row.id;
        getSalesLedgerWithProducts({ id: row.id, type: 1 }).then((res) => {
            form.value = { ...res };
            form.value = { ...createDefaultForm(), ...res };
            form.value.entryPerson = Number(res.entryPerson);
            productData.value = form.value.productData;
            productData.value = (form.value.productData || []).map((item) =>
                normalizeProductItem(item)
            );
            fileList.value = form.value.salesLedgerFiles;
        });
    }
@@ -1058,7 +1170,6 @@
    //     form.value.entryPerson = userAll.user.userId // è®¾ç½®é»˜è®¤ä¸šåŠ¡å‘˜ä¸ºå½“å‰ç”¨æˆ·
    //   }
    // });
    form.value.entryDate = getCurrentDate(); // è®¾ç½®é»˜è®¤å½•入日期为当前日期
    dialogFormVisible.value = true;
};
@@ -1113,6 +1224,28 @@
    fetchQuotationList();
};
const getPrimaryQuotationProduct = (row) => {
    if (!Array.isArray(row?.products) || row.products.length === 0) return null;
    return row.products[0];
};
const getPrimaryQuotationProductField = (row, field) => {
    const primary = getPrimaryQuotationProduct(row);
    const value = primary?.[field];
    if (value === undefined || value === null || value === "") return "--";
    if ((field === "product" || field === "specification") && Array.isArray(row?.products) && row.products.length > 1) {
        return `${value} ç­‰${row.products.length}项`;
    }
    return value;
};
const getPrimaryQuotationProductValue = (row, field) => {
    const primary = getPrimaryQuotationProduct(row);
    return Number(primary?.[field] || 0);
};
const formatQuotationMoney = (value) => Number(value || 0).toFixed(2);
// é€‰ä¸­æŠ¥ä»·å•后回填到台账表单
const applyQuotation = (row) => {
    if (!row) return;
@@ -1139,13 +1272,18 @@
    productData.value = products.map((p) => {
        const quantity = Number(p.quantity ?? 0) || 0;
        const unitPrice = Number(p.unitPrice ?? 0) || 0;
        const taxRate = "13"; // é»˜è®¤ 13%,便于直接提交(如需可在产品中自行修改)
        const taxRate = p.taxRate !== undefined && p.taxRate !== null && p.taxRate !== ""
            ? String(p.taxRate)
            : "";
        const taxInclusiveTotalPrice = (unitPrice * quantity).toFixed(2);
        const taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate);
        const taxExclusiveTotalPrice = taxRate
            ? proxy.calculateTaxExclusiveTotalPrice(taxInclusiveTotalPrice, taxRate)
            : taxInclusiveTotalPrice;
        return {
            // å°è´¦å­—段
            productCategory: p.product || p.productName || "",
            specificationModel: p.specification || "",
            paper: p.paper || "",
            unit: p.unit || "",
            quantity: quantity,
            taxRate: taxRate,
@@ -1153,6 +1291,7 @@
            taxInclusiveTotalPrice: taxInclusiveTotalPrice,
            taxExclusiveTotalPrice: taxExclusiveTotalPrice,
            invoiceType: "增普票",
            remark: p.remark || "",
        };
    });
    
@@ -1203,7 +1342,10 @@
        if (valid) {
            console.log('productData.value--', productData.value)
            if (productData.value !== null && productData.value.length > 0) {
                form.value.productData = proxy.HaveJson(productData.value);
                const normalizedProductData = productData.value.map((item) =>
                    normalizeProductItem(item)
                );
                form.value.productData = proxy.HaveJson(normalizedProductData);
            } else {
                proxy.$modal.msgWarning("请添加产品信息");
                return;
@@ -1239,12 +1381,12 @@
    }
    
    productOperationType.value = type;
    productForm.value = {};
    productForm.value = createDefaultProductForm();
    proxy.resetForm("productFormRef");
    if (type === "edit") {
        productForm.value = { ...row };
        productForm.value = { ...createDefaultProductForm(), ...normalizeProductItem(row) };
        productIndex.value = index;
        // ç¼–辑时根据产品大类名称反查 tree èŠ‚ç‚¹ id,并加载规格型号列表
        // ç¼–辑时根据产品大类名称反查 tree èŠ‚ç‚¹ id,并加载尺寸列表
        try {
            const options = productOptions.value && productOptions.value.length > 0
                ? productOptions.value
@@ -1253,7 +1395,7 @@
            if (categoryId) {
                const models = await modelList({ id: categoryId });
                modelOptions.value = models || [];
                // æ ¹æ®å½“前规格型号名称反查并设置 productModelId,便于下拉框显示已选值
                // æ ¹æ®å½“前尺寸名称反查并设置 productModelId,便于下拉框显示已选值
                const currentModel = (modelOptions.value || []).find(
                    (m) => m.model === productForm.value.specificationModel
                );
@@ -1263,17 +1405,28 @@
            }
        } catch (e) {
            // åŠ è½½å¤±è´¥æ—¶ä¿æŒå¯ç¼–è¾‘ï¼Œä¸ä¸­æ–­å¼¹çª—
            console.error("加载产品规格型号失败", e);
            console.error("加载产品尺寸失败", e);
        }
    } else {
        getProductOptions()
    }
    productFormVisible.value = true;
};
const normalizeProductTaxFields = (target) => {
    if (!target) return;
    const inclusiveTotalPrice = Number(target.taxInclusiveTotalPrice || 0);
    const taxRate = target.taxRate;
    if (taxRate) {
        target.taxExclusiveTotalPrice = proxy.calculateTaxExclusiveTotalPrice(inclusiveTotalPrice, taxRate);
    } else {
        target.taxExclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
    }
};
// æäº¤äº§å“è¡¨å•
const submitProduct = () => {
    proxy.$refs["productFormRef"].validate((valid) => {
        if (valid) {
            normalizeProductTaxFields(productForm.value);
            if (operationType.value === "edit") {
                submitProductEdit();
            } else {
@@ -1290,11 +1443,11 @@
const submitProductEdit = () => {
    productForm.value.salesLedgerId = currentId.value;
    productForm.value.type = 1
    addOrUpdateSalesLedgerProduct(productForm.value).then((res) => {
    addOrUpdateSalesLedgerProduct(normalizeProductItem(productForm.value)).then((res) => {
        proxy.$modal.msgSuccess("提交成功");
        closeProductDia();
        getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then((res) => {
            productData.value = res.productData;
            productData.value = (res.productData || []).map((item) => normalizeProductItem(item));
        });
    });
};
@@ -1337,7 +1490,7 @@
                    closeProductDia();
                    getSalesLedgerWithProducts({ id: currentId.value, type: 1 }).then(
                        (res) => {
                            productData.value = res.productData;
                            productData.value = (res.productData || []).map((item) => normalizeProductItem(item));
                        }
                    );
                });
@@ -1678,7 +1831,7 @@
              <thead>
                <tr>
                  <th>产品名称</th>
                  <th>规格型号</th>
                  <th>尺寸</th>
                  <th>单位</th>
                  <th>单价</th>
                  <th>零售数量</th>
@@ -1837,6 +1990,8 @@
                productForm.value.taxInclusiveTotalPrice,
                productForm.value.taxRate
            );
    } else {
        productForm.value.taxExclusiveTotalPrice = Number(productForm.value.taxInclusiveTotalPrice || 0).toFixed(2);
    }
};
@@ -1863,6 +2018,8 @@
                totalPrice,
                productForm.value.taxRate
            );
    } else {
        productForm.value.taxExclusiveTotalPrice = totalPrice.toFixed(2);
    }
    
    isCalculating.value = false;
@@ -1870,25 +2027,24 @@
// æ ¹æ®ä¸å«ç¨Žæ€»ä»·è®¡ç®—含税单价和数量
const calculateFromExclusiveTotalPrice = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    if (isCalculating.value) return;
    
    const exclusiveTotalPrice = parseFloat(productForm.value.taxExclusiveTotalPrice);
    const quantity = parseFloat(productForm.value.quantity);
    const taxRate = parseFloat(productForm.value.taxRate);
    
    if (!exclusiveTotalPrice || !quantity || quantity <= 0 || !taxRate) {
    if (!exclusiveTotalPrice || !quantity || quantity <= 0) {
        return;
    }
    
    isCalculating.value = true;
    
    // å…ˆè®¡ç®—含税总价 = ä¸å«ç¨Žæ€»ä»· / (1 - ç¨Žçއ/100)
    const taxRateDecimal = taxRate / 100;
    const inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
    let inclusiveTotalPrice = exclusiveTotalPrice;
    if (taxRate) {
        // å…ˆè®¡ç®—含税总价 = ä¸å«ç¨Žæ€»ä»· / (1 - ç¨Žçއ/100)
        const taxRateDecimal = taxRate / 100;
        inclusiveTotalPrice = exclusiveTotalPrice / (1 - taxRateDecimal);
    }
    productForm.value.taxInclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
    
    // è®¡ç®—含税单价 = å«ç¨Žæ€»ä»· / æ•°é‡
@@ -1899,10 +2055,6 @@
// æ ¹æ®æ•°é‡å˜åŒ–计算总价
const calculateFromQuantity = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    if (isCalculating.value) return;
    
    const quantity = parseFloat(productForm.value.quantity);
@@ -1924,6 +2076,8 @@
                productForm.value.taxInclusiveTotalPrice,
                productForm.value.taxRate
            );
    } else {
        productForm.value.taxExclusiveTotalPrice = Number(productForm.value.taxInclusiveTotalPrice || 0).toFixed(2);
    }
    
    isCalculating.value = false;
@@ -1931,10 +2085,6 @@
// æ ¹æ®å«ç¨Žå•价变化计算总价
const calculateFromUnitPrice = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    if (isCalculating.value) return;
    
    const quantity = parseFloat(productForm.value.quantity);
@@ -1956,6 +2106,8 @@
                productForm.value.taxInclusiveTotalPrice,
                productForm.value.taxRate
            );
    } else {
        productForm.value.taxExclusiveTotalPrice = Number(productForm.value.taxInclusiveTotalPrice || 0).toFixed(2);
    }
    
    isCalculating.value = false;
@@ -1963,27 +2115,27 @@
// æ ¹æ®ç¨ŽçŽ‡å˜åŒ–è®¡ç®—ä¸å«ç¨Žæ€»ä»·
const calculateFromTaxRate = () => {
    if (!productForm.value.taxRate) {
        proxy.$modal.msgWarning("请先选择税率");
        return;
    }
    if (isCalculating.value) return;
    
    const inclusiveTotalPrice = parseFloat(productForm.value.taxInclusiveTotalPrice);
    const taxRate = parseFloat(productForm.value.taxRate);
    
    if (!inclusiveTotalPrice || !taxRate) {
    if (!inclusiveTotalPrice) {
        return;
    }
    
    isCalculating.value = true;
    
    // è®¡ç®—不含税总价
    productForm.value.taxExclusiveTotalPrice =
        proxy.calculateTaxExclusiveTotalPrice(
            inclusiveTotalPrice,
            taxRate
        );
    if (taxRate) {
        // è®¡ç®—不含税总价
        productForm.value.taxExclusiveTotalPrice =
            proxy.calculateTaxExclusiveTotalPrice(
                inclusiveTotalPrice,
                taxRate
            );
    } else {
        productForm.value.taxExclusiveTotalPrice = inclusiveTotalPrice.toFixed(2);
    }
    
    isCalculating.value = false;
};
@@ -2063,6 +2215,11 @@
 * @param row è¡Œæ•°æ®
 */
const canShip = (row) => {
    const productNum = Number(row.productNum);
    const quantity = Number(row.quantity);
    if (!Number.isFinite(productNum) || !Number.isFinite(quantity) || productNum < quantity) {
        return false;
    }
    // äº§å“çŠ¶æ€å¿…é¡»æ˜¯å……è¶³ï¼ˆapproveStatus === 1)
    if (row.approveStatus !== 1) {
        return false;
@@ -2138,11 +2295,46 @@
    });
}
const handleBatchExportContract = () => {
    if (selectedRows.value.length === 0) {
        proxy.$modal.msgWarning("请选择要导出的台账");
        return;
    }
    const firstCustomerKey =
        selectedRows.value[0].customerId ?? selectedRows.value[0].customerName ?? "";
    const hasDifferentCustomer = selectedRows.value.some((row) => {
        const customerKey = row.customerId ?? row.customerName ?? "";
        return String(customerKey) !== String(firstCustomerKey);
    });
    if (hasDifferentCustomer) {
        proxy.$modal.msgWarning("仅支持同一客户同时导出合同");
        return;
    }
    const ids = selectedRows.value
        .map((row) => row.id)
        .filter((id) => id !== null && id !== undefined);
    if (ids.length === 0) {
        proxy.$modal.msgWarning("未获取到合同ID");
        return;
    }
    proxy.download(
        "/sales/ledger/exportContract",
        ids,
        `销售合同_批量_${dayjs().format("YYYYMMDDHHmmss")}.docx`,
        {
            method: "post",
            filename: `销售合同_批量_${dayjs().format("YYYYMMDDHHmmss")}.docx`,
            headers: { "Content-Type": "application/json;charset=utf-8" },
            transformRequest: [(data) => JSON.stringify(data)],
        }
    );
}
// æ‰“开发货弹框
const openDeliveryForm = (row) => {
    // æ£€æŸ¥æ˜¯å¦å¯ä»¥å‘è´§
    if (!canShip(row)) {
        proxy.$modal.msgWarning("只有在产品状态是充足,发货状态是待发货或审核拒绝的时候才可以发货");
        proxy.$modal.msgWarning("产品数量必须大于等于数量,且状态满足发货条件后才可以发货");
        return;
    }
    
src/views/salesManagement/salesQuotation/index.vue
@@ -5,35 +5,18 @@
      <el-row :gutter="20" class="search-row">
        <el-col :span="8">
          <el-input
            v-model="searchForm.quotationNo"
            placeholder="请输入报价单号"
            v-model="searchForm.product"
            placeholder="请输入产品名称"
            clearable
            @keyup.enter="handleSearch"
            @keyup.enter="handleSearch(true)"
          >
            <template #prefix>
              <el-icon><Search /></el-icon>
            </template>
          </el-input>
        </el-col>
        <el-col :span="8">
          <el-select v-model="searchForm.customer" placeholder="请选择客户" clearable>
                        <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.customerName">
                            {{
                                item.customerName + "——" + item.taxpayerIdentificationNumber
                            }}
                        </el-option>
          </el-select>
        </el-col>
<!--        <el-col :span="6">-->
<!--          <el-select v-model="searchForm.status" placeholder="请选择报价状态" clearable>-->
<!--            <el-option label="草稿" value="草稿"></el-option>-->
<!--            <el-option label="已发送" value="已发送"></el-option>-->
<!--            <el-option label="客户确认" value="客户确认"></el-option>-->
<!--            <el-option label="已过期" value="已过期"></el-option>-->
<!--          </el-select>-->
<!--        </el-col>-->
        <el-col :span="8">
          <el-button type="primary" @click="handleSearch">搜索</el-button>
        <el-col :span="4">
          <el-button type="primary" @click="handleSearch(true)">搜索</el-button>
          <el-button @click="resetSearch">重置</el-button>
          <el-button style="float: right;" type="primary" @click="handleAdd">
            æ–°å¢žæŠ¥ä»·
@@ -50,27 +33,27 @@
        stripe
        height="calc(100vh - 22em)"
      >
                <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column prop="quotationNo" label="报价单号" />
        <el-table-column prop="customer" label="客户名称" />
        <el-table-column prop="salesperson" label="业务员" width="100" />
        <el-table-column prop="quotationDate" label="报价日期" width="120" />
        <el-table-column prop="validDate" label="有效期至" width="120" />
        <el-table-column prop="status" label="审批状态" width="120" align="center">
          <template #default="{ row }">
            <el-tag :type="getStatusType(row.status)" disable-transitions>
              {{ row.status || '--' }}
            </el-tag>
          </template>
        <el-table-column align="center" label="序号" type="index" width="60" />
        <el-table-column prop="product" label="产品名称" min-width="180" show-overflow-tooltip />
        <el-table-column prop="specification" label="尺寸" min-width="140" show-overflow-tooltip />
        <el-table-column prop="paper" label="纸张" min-width="120" show-overflow-tooltip />
        <el-table-column prop="paperWeight" label="定量" min-width="100" show-overflow-tooltip />
        <el-table-column prop="unitPrice" label="单价" width="120" align="right">
          <template #default="{ row }">{{ formatMoney(row.unitPrice) }}</template>
        </el-table-column>
        <el-table-column prop="totalAmount" label="报价金额" width="120">
          <template #default="scope">
            Â¥{{ scope.row.totalAmount.toFixed(2) }}
          </template>
        <el-table-column prop="printingFee" label="印版费" width="120" align="right">
          <template #default="{ row }">{{ formatMoney(row.printingFee) }}</template>
        </el-table-column>
        <el-table-column prop="dieCuttingFee" label="刀版费" width="120" align="right">
          <template #default="{ row }">{{ formatMoney(row.dieCuttingFee) }}</template>
        </el-table-column>
        <el-table-column prop="grindingFee" label="磨具费" width="120" align="right">
          <template #default="{ row }">{{ formatMoney(row.grindingFee) }}</template>
        </el-table-column>
        <el-table-column prop="quantity" label="数量" width="90" align="right" />
        <el-table-column label="操作" width="200" fixed="right" align="center">
          <template #default="scope">
            <el-button link type="primary" @click="handleEdit(scope.row)" :disabled="!['待审批','拒绝'].includes(scope.row.status)">编辑</el-button>
            <el-button link type="primary" @click="handleEdit(scope.row)">编辑</el-button>
            <el-button link type="primary" @click="handleView(scope.row)" style="color: #67C23A">查看</el-button>
            <el-button link type="danger" @click="handleDelete(scope.row)">删除</el-button>
          </template>
@@ -91,77 +74,13 @@
    <FormDialog v-model="dialogVisible" :title="dialogTitle" width="85%" :close-on-click-modal="false" @close="dialogVisible = false" @confirm="handleSubmit" @cancel="dialogVisible = false">
      <div class="quotation-form-container">
        <el-form :model="form" :rules="rules" ref="formRef" label-width="120px" class="quotation-form">
        <!-- åŸºæœ¬ä¿¡æ¯ -->
        <el-card class="form-card" shadow="hover">
          <template #header>
            <div class="card-header-wrapper">
              <el-icon class="card-icon"><Document /></el-icon>
              <span class="card-title">基本信息</span>
            </div>
          </template>
          <div class="form-content">
            <el-row :gutter="24">
              <el-col :span="12">
                <el-form-item label="客户名称" prop="customer">
                  <el-select v-model="form.customer" placeholder="请选择客户" style="width: 100%" clearable filterable>
                    <el-option v-for="item in customerOption" :key="item.id" :label="item.customerName" :value="item.id"></el-option>
                  </el-select>
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="业务员" prop="salesperson">
                  <el-select v-model="form.salesperson" placeholder="请选择业务员" style="width: 100%" clearable filterable>
                    <el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
                      :value="item.nickName" />
                  </el-select>
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="24">
              <el-col :span="12">
                <el-form-item label="报价日期" prop="quotationDate">
                  <el-date-picker
                    v-model="form.quotationDate"
                    type="date"
                    placeholder="选择报价日期"
                    style="width: 100%"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    clearable
                  />
                </el-form-item>
              </el-col>
              <el-col :span="12">
                <el-form-item label="有效期至" prop="validDate">
                  <el-date-picker
                    v-model="form.validDate"
                    type="date"
                    placeholder="选择有效期"
                    style="width: 100%"
                    format="YYYY-MM-DD"
                    value-format="YYYY-MM-DD"
                    clearable
                  />
                </el-form-item>
              </el-col>
            </el-row>
            <el-row :gutter="24">
              <el-col :span="12">
                <el-form-item label="付款方式" prop="paymentMethod">
                  <el-input v-model="form.paymentMethod" placeholder="请输入付款方式" clearable />
                </el-form-item>
              </el-col>
            </el-row>
          </div>
        </el-card>
        <!-- äº§å“ä¿¡æ¯ -->
        <el-card class="form-card" shadow="hover">
          <template #header>
            <div class="card-header-wrapper">
              <el-icon class="card-icon"><Box /></el-icon>
              <span class="card-title">产品信息</span>
              <el-button type="primary" size="small" @click="addProduct" class="header-btn">
              <el-button type="primary" size="small" @click="addProduct" class="header-btn" :disabled="isEdit">
                <el-icon><Plus /></el-icon>
                æ·»åŠ äº§å“
              </el-button>
@@ -185,7 +104,7 @@
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="specification" label="规格型号" width="200">
            <el-table-column prop="specification" label="尺寸" width="200">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.specificationId`" class="product-table-form-item">
                  <el-select
@@ -212,10 +131,45 @@
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="paper" label="纸张" width="180">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.paper`" class="product-table-form-item">
                  <el-input v-model="scope.row.paper" placeholder="纸张" clearable />
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="paperWeight" label="定量" width="140">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.paperWeight`" class="product-table-form-item">
                  <el-input v-model="scope.row.paperWeight" placeholder="定量" clearable />
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="unitPrice" label="单价">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.unitPrice`" class="product-table-form-item">
                  <el-input-number v-model="scope.row.unitPrice" :min="0" :precision="2" style="width: 100%" />
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="printingFee" label="印版费" width="140">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.printingFee`" class="product-table-form-item">
                  <el-input-number v-model="scope.row.printingFee" :min="0" :precision="2" style="width: 100%" />
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="dieCuttingFee" label="刀版费" width="140">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.dieCuttingFee`" class="product-table-form-item">
                  <el-input-number v-model="scope.row.dieCuttingFee" :min="0" :precision="2" style="width: 100%" />
                </el-form-item>
              </template>
            </el-table-column>
            <el-table-column prop="grindingFee" label="磨具费" width="140">
              <template #default="scope">
                <el-form-item :prop="`products.${scope.$index}.grindingFee`" class="product-table-form-item">
                  <el-input-number v-model="scope.row.grindingFee" :min="0" :precision="2" style="width: 100%" />
                </el-form-item>
              </template>
            </el-table-column>
@@ -256,36 +210,37 @@
    <!-- æŸ¥çœ‹è¯¦æƒ…对话框 -->
    <el-dialog v-model="viewDialogVisible" title="报价详情" width="800px">
      <el-descriptions :column="2" border>
        <el-descriptions-item label="报价单号">{{ currentQuotation.quotationNo }}</el-descriptions-item>
        <el-descriptions-item label="客户名称">{{ currentQuotation.customer }}</el-descriptions-item>
        <el-descriptions-item label="业务员">{{ currentQuotation.salesperson }}</el-descriptions-item>
        <el-descriptions-item label="报价日期">{{ currentQuotation.quotationDate }}</el-descriptions-item>
        <el-descriptions-item label="有效期至">{{ currentQuotation.validDate }}</el-descriptions-item>
        <el-descriptions-item label="付款方式">{{ currentQuotation.paymentMethod }}</el-descriptions-item>
<!--        <el-descriptions-item label="报价状态">-->
<!--          <el-tag :type="getStatusType(currentQuotation.status)">{{ currentQuotation.status }}</el-tag>-->
<!--        </el-descriptions-item>-->
        <el-descriptions-item label="报价总额" :span="2">
          <span style="font-size: 18px; color: #e6a23c; font-weight: bold;">Â¥{{ currentQuotation.totalAmount?.toFixed(2) }}</span>
        </el-descriptions-item>
      </el-descriptions>
      <div style="margin: 20px 0;">
        <h4>产品明细</h4>
        <el-table :data="currentQuotation.products" border style="width: 100%">
          <el-table-column prop="product" label="产品名称" />
          <el-table-column prop="specification" label="规格型号" />
          <el-table-column prop="specification" label="尺寸" />
          <el-table-column prop="unit" label="单位" />
          <el-table-column prop="paper" label="纸张" />
          <el-table-column prop="paperWeight" label="定量" />
          <el-table-column prop="unitPrice" label="单价">
            <template #default="scope">
              Â¥{{ scope.row.unitPrice.toFixed(2) }}
            </template>
          </el-table-column>
          <el-table-column prop="printingFee" label="印版费">
            <template #default="scope">
              Â¥{{ Number(scope.row.printingFee || 0).toFixed(2) }}
            </template>
          </el-table-column>
          <el-table-column prop="dieCuttingFee" label="刀版费">
            <template #default="scope">
              Â¥{{ Number(scope.row.dieCuttingFee || 0).toFixed(2) }}
            </template>
          </el-table-column>
          <el-table-column prop="grindingFee" label="磨具费">
            <template #default="scope">
              Â¥{{ Number(scope.row.grindingFee || 0).toFixed(2) }}
            </template>
          </el-table-column>
        </el-table>
      </div>
      <div v-if="currentQuotation.remark" style="margin-top: 20px;">
      <div v-if="currentQuotation.remark" style="margin-top: 12px;">
        <h4>备注</h4>
        <p>{{ currentQuotation.remark }}</p>
      </div>
@@ -296,11 +251,16 @@
<script setup>
import { ref, reactive, computed, onMounted, markRaw, shallowRef } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Search, Document, Box, EditPen, Plus } from '@element-plus/icons-vue'
import { Search, Box, EditPen, Plus } from '@element-plus/icons-vue'
import Pagination from '@/components/PIMTable/Pagination.vue'
import FormDialog from '@/components/Dialog/FormDialog.vue'
import {getQuotationList,addQuotation,updateQuotation,deleteQuotation} from '@/api/salesManagement/salesQuotation.js'
import {customerList} from "@/api/salesManagement/salesLedger.js";
import {
  quotationProductListPage,
  getQuotationProductInfo,
  addOrUpdateQuotationProduct,
  editQuotationProduct,
  deleteQuotationProduct
} from '@/api/salesManagement/salesQuotationProduct.js'
import {modelList, productTreeList} from "@/api/basicData/product.js";
import {listCustomerPrivatePool} from "@/api/basicData/customerFile.js";
import { userListNoPage } from "@/api/system/user.js";
@@ -308,9 +268,7 @@
// å“åº”式数据
const loading = ref(false)
const searchForm = reactive({
  quotationNo: '',
  customer: '',
  status: ''
  product: ''
})
const quotationList = ref([])
@@ -344,17 +302,11 @@
  totalAmount: 0
})
const baseRules = {
  customer: [{ required: true, message: '请选择客户', trigger: 'change' }],
  salesperson: [{ required: true, message: '请选择业务员', trigger: 'change' }],
  quotationDate: [{ required: true, message: '请选择报价日期', trigger: 'change' }],
  validDate: [{ required: true, message: '请选择有效期', trigger: 'change' }],
  paymentMethod: [{ required: true, message: '请输入付款方式', trigger: 'blur' }]
}
const baseRules = {}
const productRowRules = {
  productId: [{ required: true, message: '请选择产品名称', trigger: 'change' }],
  specificationId: [{ required: true, message: '请选择规格型号', trigger: 'change' }],
  specificationId: [{ required: true, message: '请选择尺寸', trigger: 'change' }],
  unit: [{ required: true, message: '请填写单位', trigger: 'blur' }],
  unitPrice: [{ required: true, message: '请填写单价', trigger: 'change' }]
}
@@ -377,25 +329,19 @@
// è®¡ç®—属性
const filteredList = computed(() => {
  let list = quotationList.value
  return list
  const keyword = String(searchForm.product || '').trim()
  if (!keyword) return quotationList.value
  return quotationList.value.filter((row) => {
    const p = String(row?.product || '').toLowerCase()
    return p.includes(keyword.toLowerCase())
  })
})
// æ–¹æ³•
const getStatusType = (status) => {
  const statusMap = {
    '待审批': 'info',
    '审核中': 'primary',
    '通过': 'success',
    '拒绝': 'danger'
  }
  return statusMap[status] || 'info'
}
const formatMoney = (value) => `Â¥${Number(value || 0).toFixed(2)}`
const resetSearch = () => {
  searchForm.quotationNo = ''
  searchForm.customer = ''
  searchForm.status = ''
  searchForm.product = ''
  // é‡ç½®åˆ°ç¬¬ä¸€é¡µå¹¶é‡æ–°æŸ¥è¯¢
  pagination.currentPage = 1
  handleSearch()
@@ -464,7 +410,7 @@
    if (label) {
        row.product = label;
    }
    // èŽ·å–è§„æ ¼åž‹å·åˆ—è¡¨ï¼Œè®¾ç½®åˆ°å½“å‰è¡Œçš„ modelOptions
    // èŽ·å–å°ºå¯¸åˆ—è¡¨ï¼Œè®¾ç½®åˆ°å½“å‰è¡Œçš„ modelOptions
    modelList({ id: value }).then((res) => {
        row.modelOptions = res || [];
    });
@@ -504,29 +450,105 @@
    }
    return null; // æ²¡æœ‰æ‰¾åˆ°èŠ‚ç‚¹ï¼Œè¿”å›žnull
};
const handleView = (row) => {
  // åªå¤åˆ¶éœ€è¦çš„字段,避免将组件引用放入响应式对象
  currentQuotation.value = {
    quotationNo: row.quotationNo || '',
    customer: row.customer || '',
    salesperson: row.salesperson || '',
    quotationDate: row.quotationDate || '',
    validDate: row.validDate || '',
    paymentMethod: row.paymentMethod || '',
    status: row.status || '',
    remark: row.remark || '',
    products: row.products ? row.products.map(product => ({
      productId: product.productId || '',
      product: product.product || product.productName || '',
      specificationId: product.specificationId || '',
      specification: product.specification || '',
      quantity: product.quantity || 0,
      unit: product.unit || '',
      unitPrice: product.unitPrice || 0,
      amount: product.amount || 0
    })) : [],
    totalAmount: row.totalAmount || 0
const mapProductItem = (product) => ({
  id: product?.id || '',
  salesQuotationId: product?.salesQuotationId || '',
  productId: product?.productId || '',
  product: product?.product || product?.productName || '',
  specificationId: product?.specificationId || '',
  specification: product?.specification || '',
  quantity: product?.quantity || 0,
  unit: product?.unit || '',
  paper: product?.paper || '',
  paperWeight: product?.paperWeight || '',
  unitPrice: product?.unitPrice || 0,
  printingFee: Number(product?.printingFee || 0),
  dieCuttingFee: Number(product?.dieCuttingFee || 0),
  grindingFee: Number(product?.grindingFee || 0),
  amount: product?.amount || 0
})
const mapQuotationItem = (item) => ({
  id: item?.id,
  salesQuotationId: item?.salesQuotationId || '',
  product: item?.product || '',
  specification: item?.specification || '',
  unit: item?.unit || '',
  paper: item?.paper || '',
  paperWeight: item?.paperWeight || '',
  unitPrice: Number(item?.unitPrice || 0),
  printingFee: Number(item?.printingFee || 0),
  dieCuttingFee: Number(item?.dieCuttingFee || 0),
  grindingFee: Number(item?.grindingFee || 0),
  quantity: Number(item?.quantity || 0),
  amount: Number(item?.amount || 0),
  createTime: item?.createTime || '',
  quotationNo: item?.quotationNo || '',
  customer: item?.customer || '',
  salesperson: item?.salesperson || '',
  quotationDate: item?.quotationDate || '',
  validDate: item?.validDate || '',
  paymentMethod: item?.paymentMethod || '',
  status: item?.status || '草稿',
  approveUserIds: item?.approveUserIds || '',
  remark: item?.remark || '',
  products: Array.isArray(item?.products) && item.products.length > 0
    ? item.products.map(mapProductItem)
    : [mapProductItem(item)],
  subtotal: item?.subtotal || 0,
  freight: item?.freight || 0,
  otherFee: item?.otherFee || 0,
  discountRate: item?.discountRate || 0,
  discountAmount: item?.discountAmount || 0,
  totalAmount: item?.totalAmount || 0
})
const calcTotalAmountFromProducts = (products) => {
  return (products || []).reduce((sum, product) => {
    const price = Number(product.unitPrice) || 0
    const printingFee = Number(product.printingFee) || 0
    const dieCuttingFee = Number(product.dieCuttingFee) || 0
    const grindingFee = Number(product.grindingFee) || 0
    return sum + price + printingFee + dieCuttingFee + grindingFee
  }, 0)
}
const buildProductPayload = (product) => {
  const quantity = Number(product?.quantity || 0)
  const unitPrice = Number(product?.unitPrice || 0)
  const printingFee = Number(product?.printingFee || 0)
  const dieCuttingFee = Number(product?.dieCuttingFee || 0)
  const grindingFee = Number(product?.grindingFee || 0)
  return {
    id: product?.id || undefined,
    salesQuotationId: product?.salesQuotationId || form.salesQuotationId || null,
    product: product?.product || '',
    specification: product?.specification || '',
    unit: product?.unit || '',
    paper: product?.paper || '',
    paperWeight: product?.paperWeight || '',
    unitPrice,
    printingFee,
    dieCuttingFee,
    grindingFee,
    quantity,
    amount: Number(product?.amount ?? quantity * unitPrice),
    remark: product?.remark ?? form.remark ?? ''
  }
}
const handleView = async (row) => {
  let source = row
  if (row?.id) {
    try {
      const res = await getQuotationProductInfo(row.id)
      source = res?.data || row
    } catch (error) {
      source = row
    }
  }
  source.totalAmount = source.totalAmount || calcTotalAmountFromProducts(source?.products || [source])
  currentQuotation.value = mapQuotationItem(source)
  viewDialogVisible.value = true
}
@@ -537,24 +559,38 @@
  form.id = row.id || form.id || null
  // å…ˆåŠ è½½äº§å“æ ‘æ•°æ®ï¼Œå¦åˆ™ el-tree-select æ— æ³•反显产品名称
  await getProductOptions()
  let source = row
  if (row?.id) {
    try {
      const res = await getQuotationProductInfo(row.id)
      source = res?.data || row
    } catch (error) {
      source = row
    }
  }
  source.totalAmount = source.totalAmount || calcTotalAmountFromProducts(source?.products || [source])
  const sourceProducts = Array.isArray(source?.products) && source.products.length > 0
    ? source.products
    : [source]
  // åªå¤åˆ¶éœ€è¦çš„字段,避免将组件引用放入响应式对象
  form.quotationNo = row.quotationNo || ''
  form.customer = row.customer || ''
  form.salesperson = row.salesperson || ''
  form.quotationDate = row.quotationDate || ''
  form.validDate = row.validDate || ''
  form.paymentMethod = row.paymentMethod || ''
  form.status = row.status || '草稿'
  form.remark = row.remark || ''
  form.products = row.products ? await Promise.all(row.products.map(async (product) => {
  form.quotationNo = source.quotationNo || ''
  form.customer = source.customer || ''
  form.salesperson = source.salesperson || ''
  form.quotationDate = source.quotationDate || ''
  form.validDate = source.validDate || ''
  form.paymentMethod = source.paymentMethod || ''
  form.status = source.status || '草稿'
  form.remark = source.remark || ''
  form.products = await Promise.all(sourceProducts.map(async (product) => {
    const productName = product.product || product.productName || ''
    // ä¼˜å…ˆç”¨ productId;如果只有名称,尝试反查 id ä»¥ä¾¿æ ‘选择器反显
    const resolvedProductId = product.productId
      ? Number(product.productId)
      : findNodeIdByLabel(productOptions.value, productName) || ''
    
    // å¦‚果有产品ID,加载对应的规格型号列表
    // å¦‚果有产品ID,加载对应的尺寸列表
    let modelOptions = [];
    let resolvedSpecificationId = product.specificationId || '';
    
@@ -571,7 +607,7 @@
          }
        }
      } catch (error) {
        console.error('加载规格型号失败:', error);
        console.error('加载尺寸失败:', error);
      }
    }
    
@@ -582,17 +618,22 @@
      specification: product.specification || '',
      quantity: product.quantity || 0,
      unit: product.unit || '',
      paper: product.paper || '',
      paperWeight: product.paperWeight || '',
      unitPrice: product.unitPrice || 0,
      printingFee: Number(product.printingFee || 0),
      dieCuttingFee: Number(product.dieCuttingFee || 0),
      grindingFee: Number(product.grindingFee || 0),
      amount: product.amount || 0,
      modelOptions: modelOptions // ä¸ºæ¯è¡Œæ·»åŠ ç‹¬ç«‹çš„è§„æ ¼åž‹å·åˆ—è¡¨
      modelOptions: modelOptions // ä¸ºæ¯è¡Œæ·»åŠ ç‹¬ç«‹çš„å°ºå¯¸åˆ—è¡¨
    }
  })) : []
  form.subtotal = row.subtotal || 0
  form.freight = row.freight || 0
  form.otherFee = row.otherFee || 0
  form.discountRate = row.discountRate || 0
  form.discountAmount = row.discountAmount || 0
  form.totalAmount = row.totalAmount || 0
  }))
  form.subtotal = source.subtotal || 0
  form.freight = source.freight || 0
  form.otherFee = source.otherFee || 0
  form.discountRate = source.discountRate || 0
  form.discountAmount = source.discountAmount || 0
  form.totalAmount = source.totalAmount || 0
  dialogVisible.value = true
}
@@ -604,23 +645,21 @@
    cancelButtonText: '取消',
    type: 'warning'
  }).then(() => {
    const index = quotationList.value.findIndex(item => item.id === row.id)
    if (index > -1) {
      deleteQuotation(row.id).then(res=>{
        // console.log(res)
        if(res.code===200){
          ElMessage.success('删除成功')
          handleSearch()
        }
      })
      // quotationList.value.splice(index, 1)
      // pagination.total--
      // ElMessage.success('删除成功')
    if (!row?.id) {
      ElMessage.warning('未获取到可删除的产品ID')
      return
    }
    deleteQuotationProduct([row.id]).then(res=>{
      if(res.code===200){
        ElMessage.success('删除成功')
        handleSearch()
      }
    })
  })
}
const resetForm = () => {
  form.id = null
  form.customer = ''
  form.salesperson = ''
  form.quotationDate = ''
@@ -638,6 +677,10 @@
}
const addProduct = () => {
  if (isEdit.value) {
    ElMessage.warning('编辑时不允许新增产品')
    return
  }
  form.products.push({
    productId: '',
    product: '',
@@ -646,9 +689,14 @@
    specification: '',
    quantity: 1,
    unit: '',
    paper: '',
    paperWeight: '',
    unitPrice: 0,
    printingFee: 0,
    dieCuttingFee: 0,
    grindingFee: 0,
    amount: 0,
    modelOptions: [] // ä¸ºæ¯è¡Œæ·»åŠ ç‹¬ç«‹çš„è§„æ ¼åž‹å·åˆ—è¡¨
    modelOptions: [] // ä¸ºæ¯è¡Œæ·»åŠ ç‹¬ç«‹çš„å°ºå¯¸åˆ—è¡¨
  })
}
@@ -683,26 +731,28 @@
      // è®¡ç®—所有产品的单价总和
      form.totalAmount = form.products.reduce((sum, product) => {
        const price = Number(product.unitPrice) || 0
        return sum + price
        const printingFee = Number(product.printingFee) || 0
        const dieCuttingFee = Number(product.dieCuttingFee) || 0
        const grindingFee = Number(product.grindingFee) || 0
        return sum + price + printingFee + dieCuttingFee + grindingFee
      }, 0)
      if (isEdit.value) {
        // ç¼–辑
        const index = quotationList.value.findIndex(item => item.id === editId.value)
        if (index > -1) {
          updateQuotation(form).then(res=>{
            // console.log(res)
            if(res.code===200){
              ElMessage.success('编辑成功')
              dialogVisible.value = false
              handleSearch()
            }
          })
        }
        const editingItem = form.products[0] || {}
        const payload = buildProductPayload({
          ...editingItem,
          id: editingItem.id || form.id
        })
        editQuotationProduct(payload).then((res) => {
          if (res?.code === 200) {
            ElMessage.success('编辑成功')
            dialogVisible.value = false
            handleSearch()
          }
        })
      } else {
        // æ–°å¢ž
        addQuotation(form).then(res=>{
          if(res.code===200){
        const payloadList = form.products.map((item) => buildProductPayload(item))
        addOrUpdateQuotationProduct(payloadList).then((res) => {
          if (res?.code === 200) {
            ElMessage.success('新增成功')
            dialogVisible.value = false
            handleSearch()
@@ -720,52 +770,27 @@
  // åˆ†é¡µå˜åŒ–时重新查询列表
  handleSearch()
}
const handleSearch = ()=>{
const handleSearch = (resetPage = false)=>{
  if (resetPage) {
    pagination.currentPage = 1
  }
  const params = {
    // åŽç«¯åˆ†é¡µå‚数:current / size
    current: pagination.currentPage,
    size: pagination.pageSize,
    ...searchForm
  }
  getQuotationList(params).then(res=>{
    // console.log(res)
  quotationProductListPage(params).then(res=>{
    if(res.code===200){
      // åªå¤åˆ¶éœ€è¦çš„字段,避免将组件引用或其他对象放入响应式对象
      quotationList.value = (res.data.records || []).map(item => ({
        id: item.id,
        quotationNo: item.quotationNo || '',
        customer: item.customer || '',
        salesperson: item.salesperson || '',
        quotationDate: item.quotationDate || '',
        validDate: item.validDate || '',
        paymentMethod: item.paymentMethod || '',
        status: item.status || '草稿',
        // å®¡æ‰¹äººï¼ˆç”¨äºŽç¼–辑时反显)
        approveUserIds: item.approveUserIds || '',
        remark: item.remark || '',
        products: item.products ? item.products.map(product => ({
          productId: product.productId || '',
          product: product.product || product.productName || '',
          specificationId: product.specificationId || '',
          specification: product.specification || '',
          quantity: product.quantity || 0,
          unit: product.unit || '',
          unitPrice: product.unitPrice || 0,
          amount: product.amount || 0
        })) : [],
        subtotal: item.subtotal || 0,
        freight: item.freight || 0,
        otherFee: item.otherFee || 0,
        discountRate: item.discountRate || 0,
        discountAmount: item.discountAmount || 0,
        totalAmount: item.totalAmount || 0
      }))
      const records = res.data.records || []
      quotationList.value = records.map((item) => {
        const mapped = mapQuotationItem(item)
        mapped.totalAmount = calcTotalAmountFromProducts(mapped.products)
        return mapped
      })
      pagination.total = res.data.total
    }
  })
    // customerList().then((res) => {
    //     customerOption.value = res;
    // });
}
const getUserList = async () => {
src/views/salesManagement/strategyControl/index.vue
@@ -48,7 +48,7 @@
            </el-table-column>
            <el-table-column prop="customerName" label="客户名称" width="180"/>
            <el-table-column prop="productName" label="产品名称" width="200"/>
            <el-table-column prop="specification" label="规格型号" width="120"/>
            <el-table-column prop="specification" label="尺寸" width="120"/>
            <el-table-column prop="basePrice" label="基础价格" width="100">
              <template #default="scope">
                Â¥{{ scope.row.basePrice }}/吨
@@ -628,8 +628,8 @@
            </el-form-item>
          </el-col>
          <el-col :span="12">
            <el-form-item label="规格型号" prop="specification">
              <el-input v-model="priceStrategyForm.specification" placeholder="请输入规格型号" :disabled="priceStrategyDialogMode === 'view'" />
            <el-form-item label="尺寸" prop="specification">
              <el-input v-model="priceStrategyForm.specification" placeholder="请输入尺寸" :disabled="priceStrategyDialogMode === 'view'" />
            </el-form-item>
          </el-col>
        </el-row>