1.库存入库新增质检流程
2.销售相关查询返回总合同号
3.采购相关查询返回总合同号
已添加3个文件
已修改31个文件
963 ■■■■■ 文件已修改
doc/20260625_master_contract_no_sync.md 531 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260625_stock_inspect_feature.md 228 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260625_stock_inspect_feature.sql 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseInboundVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/bean/dto/ProcurementPageDto.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/bean/dto/ProcurementPageDtoCopy.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/production/bean/vo/ProductionPlanVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/quality/dto/QualityInspectDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsProductVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsShipmentVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/vo/ShippingInfoForReturnVo.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java 79 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/SupplierManageMapper.xml 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml 8 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionOrderMapper.xml 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionPlanMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/production/ProductionProductMainMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/ShippingInfoMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInRecordMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockOutRecordMapper.xml 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260625_master_contract_no_sync.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,531 @@
# æ€»åˆåŒå·å­—段同步添加
## æ¶‰åŠé¡µé¢
### é”€å”®ç›¸å…³
- ç”Ÿäº§è®¢å•管理页面
- ç”Ÿäº§æŠ¥å·¥ç®¡ç†é¡µé¢
- ç”Ÿäº§è®¡åˆ’管理页面
- å‘货管理页面
- é”€å”®é€€è´§ç®¡ç†é¡µé¢
- å®¢æˆ·å¾€æ¥é¡µé¢ï¼ˆå‘货明细、产品明细、合同明细)
- è´¨æ£€ç®¡ç†é¡µé¢
- è´¢åŠ¡ç®¡ç†-销售出库台账
- è´¢åŠ¡ç®¡ç†-销售退货台账
### é‡‡è´­ç›¸å…³
- é‡‡è´­å…¥åº“管理页面
- é‡‡è´­é€€è´§ç®¡ç†é¡µé¢
- ä¾›åº”商往来页面(采购明细)
- è´¢åŠ¡ç®¡ç†-采购入库台账
- è´¢åŠ¡ç®¡ç†-采购退货台账
## æ–°å¢žå­—段说明
| å­—段名 | ç±»åž‹ | è¯´æ˜Ž |
|--------|------|------|
| masterContractNo | String | æ€»åˆåŒå· |
## æ¶‰åŠæŽ¥å£
### 1. ç”Ÿäº§è®¢å•接口
**GET /productionOrder/pageProductionOrder**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001",
        "customerName": "客户名称"
      }
    ]
  }
}
```
### 2. ç”Ÿäº§æŠ¥å·¥æŽ¥å£
**GET /productionProductMain/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001"
      }
    ]
  }
}
```
### 3. ç”Ÿäº§è®¡åˆ’接口
**GET /productionPlan/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001"
      }
    ]
  }
}
```
### 4. å‘货管理接口
**GET /shippingInfo/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001"
      }
    ]
  }
}
```
**查询参数新增:**
| å‚æ•° | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| masterContractNo | String | æ€»åˆåŒå·ï¼ˆæ¨¡ç³ŠæŸ¥è¯¢ï¼‰ |
### 5. é”€å”®é€€è´§æŽ¥å£
**GET /returnManagement/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "returnNo": "TH202601001",
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001",
        "shippingNo": "FH202601001"
      }
    ]
  }
}
```
**查询参数新增:**
| å‚æ•° | ç±»åž‹ | è¯´æ˜Ž |
|------|------|------|
| masterContractNo | String | æ€»åˆåŒå·ï¼ˆæ¨¡ç³ŠæŸ¥è¯¢ï¼‰ |
### 6. é”€å”®é€€è´§å‘货信息接口
**GET /shippingInfo/getShippingInfoForReturn**
**响应新增字段:**
```json
{
  "code": 200,
  "data": [
    {
      "shippingId": 1,
      "shippingNo": "FH202601001",
      "salesContractNo": "XS202601001",
      "masterContractNo": "ZHT202601001",
      "customerName": "客户名称"
    }
  ]
}
```
### 7. è´¢åŠ¡-销售出库台账接口
**GET /stockOutRecord/listPageAccountSales**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "outboundBatches": "CK202601001",
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001",
        "customerName": "客户名称"
      }
    ]
  }
}
```
### 8. è´¢åŠ¡-销售退货台账接口
**GET /returnManagement/listPageAccountSalesReturn**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "returnNo": "TH202601001",
        "salesContractNo": "XS202601001",
        "masterContractNo": "ZHT202601001",
        "customerName": "客户名称"
      }
    ]
  }
}
```
### 9. é‡‡è´­å…¥åº“管理接口
**GET /stockin/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "inboundBatches": "RK202601001",
        "purchaseContractNumber": "CG202601001",
        "masterContractNo": "ZHT202601001",
        "supplierName": "供应商名称"
      }
    ]
  }
}
```
**GET /stockin/listPageCopy**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "inboundBatches": "RK202601001",
        "purchaseContractNumber": "CG202601001",
        "masterContractNo": "ZHT202601001",
        "supplierName": "供应商名称"
      }
    ]
  }
}
```
### 10. é‡‡è´­é€€è´§æŽ¥å£
**GET /purchaseReturnOrders/listPage**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "no": "CT202601001",
        "purchaseContractNumber": "CG202601001",
        "masterContractNo": "ZHT202601001",
        "supplierName": "供应商名称"
      }
    ]
  }
}
```
### 11. ä¾›åº”商往来明细接口
**GET /supplierManage/supplierTransactionsDetails**
**响应新增字段:**
```json
{
  "code": 200,
  "data": [
    {
      "purchaseLedgerId": 1,
      "purchaseContractNumber": "CG202601001",
      "masterContractNo": "ZHT202601001",
      "executionDate": "2026-01-01",
      "contractAmount": 10000.00
    }
  ]
}
```
### 12. è´¢åŠ¡-采购入库台账接口
**GET /stockInRecord/listPageAccountPurchase**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "inboundBatches": "RK202601001",
        "purchaseContractNumber": "CG202601001",
        "masterContractNo": "ZHT202601001",
        "supplierName": "供应商名称"
      }
    ]
  }
}
```
### 13. è´¢åŠ¡-采购退货台账接口
**GET /purchaseReturnOrders/listPageAccountPurchaseReturn**
**响应新增字段:**
```json
{
  "code": 200,
  "data": {
    "records": [
      {
        "id": 1,
        "returnNo": "CT202601001",
        "purchaseContractNumber": "CG202601001",
        "masterContractNo": "ZHT202601001",
        "supplierName": "供应商名称"
      }
    ]
  }
}
```
## å‰ç«¯ä¿®æ”¹ç‚¹
### 1. è¡¨æ ¼åˆ—添加
在各页面的表格中添加总合同号列:
```html
<el-table-column prop="masterContractNo" label="总合同号" min-width="120" />
```
### 2. æŸ¥è¯¢æ¡ä»¶æ·»åŠ 
在需要支持总合同号查询的页面添加搜索框:
```html
<el-form-item label="总合同号">
  <el-input v-model="queryParams.masterContractNo" placeholder="请输入总合同号" clearable />
</el-form-item>
```
### 3. è¯¦ç»†é¡µé¢ç¤ºä¾‹
#### å‘货管理页面
```html
<!-- æŸ¥è¯¢æ¡ä»¶ -->
<el-form :model="queryParams" ref="queryForm" :inline="true">
  <el-form-item label="销售合同号">
    <el-input v-model="queryParams.salesContractNo" placeholder="请输入销售合同号" clearable />
  </el-form-item>
  <el-form-item label="总合同号">
    <el-input v-model="queryParams.masterContractNo" placeholder="请输入总合同号" clearable />
  </el-form-item>
</el-form>
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="shippingNo" label="发货单号" width="150" />
  <el-table-column prop="salesContractNo" label="销售合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="customerName" label="客户名称" width="150" />
</el-table>
```
#### é”€å”®é€€è´§é¡µé¢
```html
<!-- æŸ¥è¯¢æ¡ä»¶ -->
<el-form :model="queryParams" ref="queryForm" :inline="true">
  <el-form-item label="退货单号">
    <el-input v-model="queryParams.returnNo" placeholder="请输入退货单号" clearable />
  </el-form-item>
  <el-form-item label="销售合同号">
    <el-input v-model="queryParams.salesContractNo" placeholder="请输入销售合同号" clearable />
  </el-form-item>
  <el-form-item label="总合同号">
    <el-input v-model="queryParams.masterContractNo" placeholder="请输入总合同号" clearable />
  </el-form-item>
</el-form>
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="returnNo" label="退货单号" width="150" />
  <el-table-column prop="shippingNo" label="发货单号" width="150" />
  <el-table-column prop="salesContractNo" label="销售合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="customerName" label="客户名称" width="150" />
</el-table>
```
#### é‡‡è´­å…¥åº“管理页面
```html
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="inboundBatches" label="入库批次" width="150" />
  <el-table-column prop="purchaseContractNumber" label="采购合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="supplierName" label="供应商名称" width="150" />
  <el-table-column prop="productCategory" label="产品大类" width="120" />
  <el-table-column prop="specificationModel" label="规格型号" width="120" />
  <el-table-column prop="inboundNum" label="入库数量" width="100" />
</el-table>
```
#### é‡‡è´­é€€è´§é¡µé¢
```html
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="no" label="退货单号" width="150" />
  <el-table-column prop="purchaseContractNumber" label="采购合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="supplierName" label="供应商名称" width="150" />
</el-table>
```
#### ä¾›åº”商往来明细
```html
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="purchaseContractNumber" label="采购合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="executionDate" label="签订日期" width="120" />
  <el-table-column prop="contractAmount" label="合同金额" width="120" />
</el-table>
```
#### è´¢åŠ¡-采购入库台账
```html
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="inboundBatches" label="入库单号" width="150" />
  <el-table-column prop="purchaseContractNumber" label="采购合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="supplierName" label="供应商名称" width="150" />
</el-table>
```
#### è´¢åŠ¡-采购退货台账
```html
<!-- è¡¨æ ¼ -->
<el-table :data="tableData" border>
  <el-table-column prop="returnNo" label="退货单号" width="150" />
  <el-table-column prop="purchaseContractNumber" label="采购合同号" width="150" />
  <el-table-column prop="masterContractNo" label="总合同号" width="150" />
  <el-table-column prop="supplierName" label="供应商名称" width="150" />
</el-table>
```
### 4. data æ•°æ®ä¿®æ”¹
```js
data() {
  return {
    queryParams: {
      pageNum: 1,
      pageSize: 10,
      salesContractNo: '',
      masterContractNo: '',  // æ–°å¢ž
      // ... å…¶ä»–查询参数
    }
  }
}
```
### 5. å¯¼å‡ºåŠŸèƒ½
如需导出功能,需在导出字段中添加总合同号:
```js
// å¯¼å‡ºåˆ—配置
const exportColumns = [
  { prop: 'salesContractNo', label: '销售合同号' },
  { prop: 'purchaseContractNumber', label: '采购合同号' },
  { prop: 'masterContractNo', label: '总合同号' },
  // ... å…¶ä»–列
];
```
## æ³¨æ„äº‹é¡¹
1. **字段位置**:建议将总合同号列放在销售合同号/采购合同号列后面,保持一致性。
2. **查询逻辑**:总合同号支持模糊查询,与合同号查询方式一致。
3. **数据关联**:
   - é”€å”®ç›¸å…³ï¼šæ€»åˆåŒå·æ¥æºäºŽé”€å”®å°è´¦ï¼ˆsales_ledger)表的 master_contract_no å­—段
   - é‡‡è´­ç›¸å…³ï¼šæ€»åˆåŒå·æ¥æºäºŽé‡‡è´­å°è´¦ï¼ˆpurchase_ledger)表的 master_contract_no å­—段
4. **多值处理**:部分查询(如生产订单)可能关联多个销售台账,此时总合同号会以逗号分隔显示多个值。
5. **空值处理**:如果台账未填写总合同号,该字段可能为空,前端需做好空值显示处理。
6. **销售退货选择发货**:在销售退货选择发货信息时,总合同号会一并返回,便于识别。
7. **采购退货选择入库**:在采购退货选择入库信息时,总合同号会一并返回,便于识别。
doc/20260625_stock_inspect_feature.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,228 @@
# åº“存添加质检选择功能
## æ¶‰åŠé¡µé¢
- åº“存管理页面(新增库存弹窗)
## API
| æ–¹æ³• | è·¯å¾„ | è¯´æ˜Ž |
|------|------|------|
| POST | /stockInventory/addStockInRecordOnly | æ–°å¢žå…¥åº“记录(支持质检选择) |
**请求参数:**
| å‚æ•° | ç±»åž‹ | å¿…å¡« | è¯´æ˜Ž |
|------|------|------|------|
| productModelId | Long | æ˜¯ | äº§å“è§„æ ¼ID |
| qualitity | BigDecimal | æ˜¯ | æ•°é‡ |
| batchNo | String | å¦ | æ‰¹å·ï¼ˆä¸å¡«è‡ªåŠ¨ç”Ÿæˆï¼‰ |
| warehouse | String | å¦ | ä»“库 |
| remark | String | å¦ | å¤‡æ³¨ |
| warnNum | BigDecimal | å¦ | é¢„警数量 |
| **needInspect** | Boolean | å¦ | æ˜¯å¦éœ€è¦è´¨æ£€ï¼ˆé»˜è®¤false) |
| **inspectType** | Integer | å¦ | è´¨æ£€ç±»åž‹ï¼š0-原材料检验(默认),1-过程检验 |
**响应:**
```json
{
  "code": 200,
  "msg": "操作成功"
}
```
## ä¸šåŠ¡é€»è¾‘è¯´æ˜Ž
### ä¸éœ€è¦è´¨æ£€ï¼ˆneedInspect = false æˆ–不传)
- ç›´æŽ¥åˆ›å»ºå…¥åº“记录
- åŽŸæœ‰æµç¨‹ä¸å˜
### éœ€è¦è´¨æ£€ï¼ˆneedInspect = true)
- åˆ›å»ºè´¨æ£€å•(quality_inspect è¡¨ï¼‰
- è´¨æ£€å•状态为"未提交"(inspectState = 0)
- **不创建入库记录**,等待质检合格后由质检流程入库
- è´¨æ£€ç±»åž‹ç”± inspectType å†³å®šï¼š
  - **inspectType = 0**:原材料检验
  - **inspectType = 1**:过程检验(适用于成品)
## å‰ç«¯ä¿®æ”¹ç‚¹
### 1. æ–°å¢žåº“存弹窗 - æ·»åŠ è´¨æ£€é€‰æ‹©
```html
<el-dialog title="新增库存" :visible.sync="dialogVisible">
  <el-form :model="form" :rules="rules" ref="formRef">
    <!-- åŽŸæœ‰å­—æ®µ -->
    <el-form-item label="产品规格" prop="productModelId">
      <el-select v-model="form.productModelId" placeholder="请选择产品规格">
        <!-- ... -->
      </el-select>
    </el-form-item>
    <el-form-item label="数量" prop="qualitity">
      <el-input-number v-model="form.qualitity" :min="0" />
    </el-form-item>
    <el-form-item label="批号">
      <el-input v-model="form.batchNo" placeholder="不填自动生成" />
    </el-form-item>
    <el-form-item label="仓库">
      <el-select v-model="form.warehouse" placeholder="请选择仓库">
        <!-- ... -->
      </el-select>
    </el-form-item>
    <el-form-item label="备注">
      <el-input v-model="form.remark" type="textarea" />
    </el-form-item>
    <!-- æ–°å¢žï¼šè´¨æ£€é€‰æ‹© -->
    <el-form-item label="是否质检">
      <el-switch
        v-model="form.needInspect"
        active-text="需要质检"
        inactive-text="直接入库"
      />
    </el-form-item>
    <!-- æ–°å¢žï¼šè´¨æ£€ç±»åž‹é€‰æ‹©ï¼ˆå½“需要质检时显示) -->
    <el-form-item label="质检类型" v-if="form.needInspect">
      <el-radio-group v-model="form.inspectType">
        <el-radio :label="0">原材料检验</el-radio>
        <el-radio :label="1">过程检验(成品)</el-radio>
      </el-radio-group>
    </el-form-item>
  </el-form>
  <div slot="footer">
    <el-button @click="dialogVisible = false">取消</el-button>
    <el-button type="primary" @click="handleSubmit">确定</el-button>
  </div>
</el-dialog>
```
### 2. data æ•°æ®
```js
data() {
  return {
    dialogVisible: false,
    form: {
      productModelId: null,
      qualitity: 0,
      batchNo: '',
      warehouse: '',
      remark: '',
      warnNum: null,
      // æ–°å¢žå­—段
      needInspect: false,
      inspectType: 0,  // é»˜è®¤åŽŸææ–™æ£€éªŒ
    },
    rules: {
      productModelId: [{ required: true, message: '请选择产品规格', trigger: 'change' }],
      qualitity: [{ required: true, message: '请输入数量', trigger: 'blur' }],
    }
  }
}
```
### 3. æ–¹æ³•
```js
methods: {
  // æ‰“开新增弹窗
  handleAdd() {
    this.dialogVisible = true;
    this.form = {
      productModelId: null,
      qualitity: 0,
      batchNo: '',
      warehouse: '',
      remark: '',
      warnNum: null,
      needInspect: false,
      inspectType: 0,
    };
    if (this.$refs.formRef) {
      this.$refs.formRef.resetFields();
    }
  },
  // æäº¤æ–°å¢žåº“å­˜
  handleSubmit() {
    this.$refs.formRef.validate(async (valid) => {
      if (!valid) return;
      try {
        // æž„建请求参数
        const params = {
          ...this.form,
          // å¦‚果不需要质检,不传 inspectType
          inspectType: this.form.needInspect ? this.form.inspectType : undefined,
        };
        const res = await this.$http.post('/stockInventory/addStockInRecordOnly', params);
        if (res.code === 200) {
          this.$message.success(
            this.form.needInspect
              ? '已创建质检单,请前往质检模块处理'
              : '新增库存成功'
          );
          this.dialogVisible = false;
          this.loadData();  // åˆ·æ–°åˆ—表
        } else {
          this.$message.error(res.msg || '操作失败');
        }
      } catch (error) {
        this.$message.error('请求失败');
      }
    });
  },
  // è´¨æ£€ç±»åž‹åˆ‡æ¢æ—¶çš„æç¤º
  handleInspectTypeChange(value) {
    if (value === 0) {
      this.form.inspectTypeTip = '适用于原材料入库检验';
    } else if (value === 1) {
      this.form.inspectTypeTip = '适用于成品过程检验';
    }
  }
}
```
### 4. æ ·å¼ä¼˜åŒ–(可选)
```css
/* è´¨æ£€é€‰æ‹©åŒºåŸŸæ ·å¼ */
.quality-inspect-section {
  margin-top: 20px;
  padding-top: 15px;
  border-top: 1px dashed #eee;
}
.inspect-type-tip {
  margin-left: 10px;
  font-size: 12px;
  color: #909399;
}
```
## æ³¨æ„äº‹é¡¹
1. **质检后入库流程**:当选择质检后,不会创建入库记录,需要质检人员在质检模块完成检验并提交,合格数量才会自动入库。
2. **质检单查看**:选择质检后创建的质检单可以在以下位置查看:
   - åŽŸææ–™æ£€éªŒï¼š`/quality/rawMaterialInspect` æˆ–质检管理-原材料检验
   - è¿‡ç¨‹æ£€éªŒï¼š`/quality/processInspect` æˆ–质检管理-过程检验
3. **质检类型选择建议**:
   - åŽŸææ–™/采购入库 â†’ é€‰æ‹©"原材料检验"(inspectType=0)
   - ç”Ÿäº§æˆå“å…¥åº“ â†’ é€‰æ‹©"过程检验"(inspectType=1)
4. **批号处理**:如果传了批号,质检单关联的入库记录会使用该批号;如果未传批号,系统会自动生成批号。
5. **用户体验优化建议**:
   - å½“切换"需要质检"开关时,可以显示一个提示信息说明后续流程
   - è´¨æ£€ç±»åž‹å¯ä»¥æ ¹æ®äº§å“ç±»åž‹è‡ªåŠ¨æŽ¨èï¼ˆå¦‚æžœå‰ç«¯èƒ½èŽ·å–äº§å“ç±»åž‹ä¿¡æ¯ï¼‰
doc/20260625_stock_inspect_feature.sql
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,11 @@
-- åº“存添加质检选择功能
-- æ—¥æœŸï¼š2026-06-25
-- è¯´æ˜Žï¼šæ–°å¢žåº“存时支持选择是否需要质检,原材料对应原料检验,成品对应过程检验
-- æ³¨æ„ï¼šæœ¬åŠŸèƒ½ä¸éœ€è¦ä¿®æ”¹æ•°æ®åº“è¡¨ç»“æž„
-- needInspect å’Œ inspectType ä¸ºæŽ¥å£è¯·æ±‚参数,用于控制业务逻辑
-- è´¨æ£€å•创建后,质检合格通过后会自动入库到 stock_inventory è¡¨
-- è´¨æ£€ç±»åž‹è¯´æ˜Žï¼š
-- inspectType = 0: åŽŸææ–™æ£€éªŒï¼ˆé»˜è®¤ï¼‰
-- inspectType = 1: è¿‡ç¨‹æ£€éªŒï¼ˆæˆå“ï¼‰
src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseInboundVo.java
@@ -45,4 +45,8 @@
    @Schema(description = "采购订单号")
    @Excel(name = "采购订单号")
    private String purchaseContractNumber;
    @Schema(description = "总合同号")
    @Excel(name = "总合同号")
    private String masterContractNo;
}
src/main/java/com/ruoyi/account/bean/vo/purchase/PurchaseReturnVo.java
@@ -45,4 +45,8 @@
    @Schema(description = "采购订单号")
    @Excel(name = "采购订单号")
    private String purchaseContractNumber;
    @Schema(description = "总合同号")
    @Excel(name = "总合同号")
    private String masterContractNo;
}
src/main/java/com/ruoyi/account/bean/vo/sales/SalesOutboundVo.java
@@ -52,4 +52,8 @@
    @Schema(description = "销售订单号")
    @Excel(name = "销售订单号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    @Excel(name = "总合同号")
    private String masterContractNo;
}
src/main/java/com/ruoyi/account/bean/vo/sales/SalesReturnVo.java
@@ -45,4 +45,8 @@
    @Schema(description = "销售订单号")
    @Excel(name = "销售订单号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    @Excel(name = "总合同号")
    private String masterContractNo;
}
src/main/java/com/ruoyi/procurementrecord/bean/dto/ProcurementPageDto.java
@@ -39,6 +39,11 @@
    private String purchaseContractNumber;
    /**
     * æ€»åˆåŒå·
     */
    private String masterContractNo;
    /**
     * é”€å”®åˆåŒå·
     */
    private String salesContractNo;
src/main/java/com/ruoyi/procurementrecord/bean/dto/ProcurementPageDtoCopy.java
@@ -33,6 +33,11 @@
     */
    private String purchaseContractNumber;
    /**
     * æ€»åˆåŒå·
     */
    private String masterContractNo;
    /**
     * é”€å”®åˆåŒå·
src/main/java/com/ruoyi/procurementrecord/bean/dto/ReturnManagementDto.java
@@ -21,6 +21,9 @@
    @Schema(description = "销售单号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "业务员")
    private String salesman;
src/main/java/com/ruoyi/production/bean/dto/ProductionPlanDto.java
@@ -55,4 +55,7 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
}
src/main/java/com/ruoyi/production/bean/dto/ProductionProductMainDto.java
@@ -51,6 +51,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "排产日期")
    private LocalDate schedulingDate;
src/main/java/com/ruoyi/production/bean/vo/ProductionOrderVo.java
@@ -17,6 +17,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "客户名称")
    private String customerName;
src/main/java/com/ruoyi/production/bean/vo/ProductionPlanVo.java
@@ -25,6 +25,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "客户名称")
    private String customerName;
src/main/java/com/ruoyi/purchase/dto/PurchaseReturnOrderHasAllInfoDto.java
@@ -15,6 +15,9 @@
    // é‡‡è´­åˆåŒå·
    private String purchaseContractNumber;
    // æ€»åˆåŒå·
    private String masterContractNo;
    //退料人姓名
    private String returnUserName;
src/main/java/com/ruoyi/purchase/vo/SupplierTransactionsDetailsVo.java
@@ -17,6 +17,9 @@
    @Schema(description = "采购合同号")
    private String purchaseContractNumber;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "采购合同签订日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date executionDate;
src/main/java/com/ruoyi/quality/dto/QualityInspectDto.java
@@ -25,6 +25,7 @@
    private String salesContractNo;
    private String masterContractNo;
    private String workOrderNo;
    private String purchaseContractNo;
src/main/java/com/ruoyi/sales/pojo/ShippingInfo.java
@@ -24,6 +24,11 @@
    private String salesContractNo;
    @TableField(exist = false)
    @Schema(description = "总合同号")
    @Excel(name = "总合同号")
    private String masterContractNo;
    @TableField(exist = false)
    @Schema(description = "客户名称")
    @Excel(name = "客户名称")
    private String customerName;
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsDetailsVo.java
@@ -17,6 +17,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "销售合同签订日期")
    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate executionDate;
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsProductVo.java
@@ -18,6 +18,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "产品ID")
    private Long productId;
src/main/java/com/ruoyi/sales/vo/CustomerTransactionsShipmentVo.java
@@ -20,6 +20,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "发货单ID")
    private Long shippingId;
src/main/java/com/ruoyi/sales/vo/ShippingInfoForReturnVo.java
@@ -23,6 +23,9 @@
    @Schema(description = "销售合同号")
    private String salesContractNo;
    @Schema(description = "总合同号")
    private String masterContractNo;
    @Schema(description = "客户名称")
    private String customerName;
src/main/java/com/ruoyi/stock/dto/StockInventoryDto.java
@@ -83,4 +83,10 @@
    @Schema(description = "出库批号")
    private String outboundBatches;
    @Schema(description = "是否需要质检")
    private Boolean needInspect;
    @Schema(description = "质检类型:0-原材料检验,1-过程检验")
    private Integer inspectType;
}
src/main/java/com/ruoyi/stock/service/impl/StockInventoryServiceImpl.java
@@ -15,6 +15,8 @@
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.web.domain.R;
import com.ruoyi.project.system.service.ISysDictDataService;
import com.ruoyi.quality.dto.QualityInspectDto;
import com.ruoyi.quality.service.IQualityInspectService;
import com.ruoyi.sales.mapper.SalesLedgerProductMapper;
import com.ruoyi.sales.pojo.SalesLedgerProduct;
import com.ruoyi.stock.dto.StockInRecordDto;
@@ -30,7 +32,8 @@
import com.ruoyi.stock.service.StockOutRecordService;
import com.ruoyi.stock.service.StockUninventoryService;
import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;
@@ -52,7 +55,6 @@
 * @since 2026-01-21 04:16:36
 */
@Service
@RequiredArgsConstructor
public class StockInventoryServiceImpl extends ServiceImpl<StockInventoryMapper, StockInventory> implements StockInventoryService {
    private final StockInventoryMapper stockInventoryMapper;
@@ -62,6 +64,26 @@
    private final SalesLedgerProductMapper salesLedgerProductMapper;
    private final ProductModelMapper productModelMapper;
    private final ISysDictDataService sysDictDataService;
    private final IQualityInspectService qualityInspectService;
    public StockInventoryServiceImpl(
            StockInventoryMapper stockInventoryMapper,
            StockInRecordService stockInRecordService,
            StockOutRecordService stockOutRecordService,
            StockUninventoryService stockUninventoryService,
            SalesLedgerProductMapper salesLedgerProductMapper,
            ProductModelMapper productModelMapper,
            ISysDictDataService sysDictDataService,
            @Lazy IQualityInspectService qualityInspectService) {
        this.stockInventoryMapper = stockInventoryMapper;
        this.stockInRecordService = stockInRecordService;
        this.stockOutRecordService = stockOutRecordService;
        this.stockUninventoryService = stockUninventoryService;
        this.salesLedgerProductMapper = salesLedgerProductMapper;
        this.productModelMapper = productModelMapper;
        this.sysDictDataService = sysDictDataService;
        this.qualityInspectService = qualityInspectService;
    }
    @Override
    public IPage<StockInventoryDto> pagestockInventory(Page page, StockInventoryDto stockInventoryDto) {
@@ -122,6 +144,51 @@
        return true;
    }
    /**
     * åˆ›å»ºè´¨æ£€å•
     * æ ¹æ® inspectType å†³å®šè´¨æ£€ç±»åž‹ï¼š
     * - 0: åŽŸææ–™æ£€éªŒ
     * - 1: è¿‡ç¨‹æ£€éªŒ
     * å¦‚果未指定 inspectType,则根据产品信息自动判断
     */
    private void createQualityInspect(StockInventoryDto stockInventoryDto) {
        // æŸ¥è¯¢äº§å“ä¿¡æ¯
        ProductModel productModel = productModelMapper.selectById(stockInventoryDto.getProductModelId());
        if (productModel == null) {
            throw new ServiceException("产品规格不存在");
        }
        // ç¡®å®š inspectType
        Integer inspectType = stockInventoryDto.getInspectType();
        if (inspectType == null) {
            // é»˜è®¤ä½¿ç”¨åŽŸææ–™æ£€éªŒ
            inspectType = 0;
        }
        // æž„建质检单
        QualityInspectDto qualityInspectDto = new QualityInspectDto();
        qualityInspectDto.setInspectType(inspectType);
        qualityInspectDto.setProductModelId(stockInventoryDto.getProductModelId());
        qualityInspectDto.setProductId(productModel.getProductId());
        qualityInspectDto.setProductName(stockInventoryDto.getProductName());
        qualityInspectDto.setQuantity(stockInventoryDto.getQualitity());
        qualityInspectDto.setInspectState(0); // æœªæäº¤
//        qualityInspectDto.setRemark(stockInventoryDto.getRemark());
        // è®¾ç½®äº§å“ä¿¡æ¯
        if (productModel.getProductName() != null) {
            qualityInspectDto.setProductName(productModel.getProductName());
        }
        qualityInspectDto.setModel(productModel.getModel());
        qualityInspectDto.setUnit(productModel.getUnit());
        // åˆå§‹åŒ–空的检验参数列表
        qualityInspectDto.setQualityInspectParams(new ArrayList<>());
        // ä¿å­˜è´¨æ£€å•
        qualityInspectService.add(qualityInspectDto);
    }
    //出库调用
    @Override
    @Transactional(rollbackFor = Exception.class)
@@ -171,6 +238,14 @@
        }
        stockInventoryDto.setBatchNo(batchNo);
        // åˆ¤æ–­æ˜¯å¦éœ€è¦è´¨æ£€
        if (Boolean.TRUE.equals(stockInventoryDto.getNeedInspect())) {
            // åˆ›å»ºè´¨æ£€å•
            createQualityInspect(stockInventoryDto);
            return true;
        }
        // ä¸éœ€è¦è´¨æ£€ï¼Œç›´æŽ¥åˆ›å»ºå…¥åº“记录
        StockInRecordDto stockInRecordDto = new StockInRecordDto();
        stockInRecordDto.setRecordId(stockInventoryDto.getRecordId());
        stockInRecordDto.setRecordType(stockInventoryDto.getRecordType());
src/main/resources/mapper/basic/SupplierManageMapper.xml
@@ -113,6 +113,7 @@
            resultType="com.ruoyi.purchase.vo.SupplierTransactionsDetailsVo">
       select pl.id  purchaseLedgerId,
              pl.purchase_contract_number,
              pl.master_contract_no,
              pl.execution_date,
              pl.contract_amount,
              IFNULL(T1.paymentAmount, 0) AS paymentAmount,
src/main/resources/mapper/procurementrecord/ProcurementRecordMapper.xml
@@ -32,6 +32,7 @@
        select
        t3.supplier_name,
        t3.purchase_contract_number,
        t3.master_contract_no,
        t2.product_category,
        t1.id,
        t1.sales_ledger_product_id,
@@ -72,6 +73,7 @@
        select
            t3.supplier_name,
            t3.purchase_contract_number,
            t3.master_contract_no,
            t2.product_category,
            t1.id,
            t2.specification_model,
@@ -121,6 +123,7 @@
        select
        t3.supplier_name,
        t3.purchase_contract_number,
        t3.master_contract_no,
        t2.product_category,
        t1.id,
        t1.sales_ledger_product_id,
@@ -179,6 +182,7 @@
        select
            t3.supplier_name,
            t3.purchase_contract_number,
            t3.master_contract_no,
            t2.product_category,
            t1.id,
            t1.sales_ledger_product_id,
src/main/resources/mapper/procurementrecord/ReturnManagementMapper.xml
@@ -8,6 +8,7 @@
               si.shipping_no,
               sl.project_name,
               sl.sales_contract_no,
               sl.master_contract_no,
               sl.salesman,
               IFNULL(sq.shipping_qty, 0) AS shippingQuantity,
               IFNULL(rs.total_return_num, 0) AS returnedQuantity,
@@ -58,6 +59,9 @@
            <if test="req.salesContractNo != null and req.salesContractNo != ''">
                and sl.sales_contract_no like concat('%',#{req.salesContractNo},'%')
            </if>
            <if test="req.masterContractNo != null and req.masterContractNo != ''">
                and sl.master_contract_no like concat('%',#{req.masterContractNo},'%')
            </if>
        </where>
        order by rm.id desc
    </select>
@@ -67,6 +71,7 @@
               si.shipping_no,
               sl.project_name,
               sl.sales_contract_no,
               sl.master_contract_no,
               sl.salesman
        from return_management rm
                 left join shipping_info si on rm.shipping_id = si.id
@@ -83,7 +88,8 @@
                rm.refund_amount,
                rm.return_reason,
                rm.make_time,
                sl.sales_contract_no
                sl.sales_contract_no,
                sl.master_contract_no
        from return_management rm
                 left join shipping_info si on rm.shipping_id = si.id
                 left join customer c on rm.customer_id = c.id
src/main/resources/mapper/production/ProductionOrderMapper.xml
@@ -23,6 +23,7 @@
    <resultMap id="ProductionOrderVoResultMap" type="com.ruoyi.production.bean.vo.ProductionOrderVo" extends="BaseResultMap">
        <result column="salesContractNo" property="salesContractNo" />
        <result column="masterContractNo" property="masterContractNo" />
        <result column="customerName" property="customerName" />
        <result column="productName" property="productName" />
        <result column="model" property="model" />
@@ -47,6 +48,7 @@
        po.plan_complete_time,
        po.status,
        po_sales.salesContractNo,
        po_sales.masterContractNo,
        po_sales.customerName,
        p.product_name as productName,
        pm.model as model,
@@ -62,6 +64,7 @@
                 left join (
            select po2.id as orderId,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as salesContractNo,
                   group_concat(distinct sl2.master_contract_no order by sl2.master_contract_no separator ',') as masterContractNo,
                   group_concat(distinct sl2.customer_name order by sl2.customer_name separator ',') as customerName,
                   group_concat(distinct sl2.project_name order by sl2.project_name separator ',') as projectName,
                   min(sl2.delivery_date) as deliveryDate
src/main/resources/mapper/production/ProductionPlanMapper.xml
@@ -27,6 +27,7 @@
        p.product_name AS productName,
        pm.unit,
        sl.sales_contract_no,
        sl.master_contract_no,
        sl.customer_name,
        sl.project_name
        FROM production_plan pp
@@ -55,6 +56,9 @@
                </if>
                <if test="c.salesContractNo != null and c.salesContractNo != ''">
                    and sl.sales_contract_no like concat('%', #{c.salesContractNo}, '%')
                </if>
                <if test="c.masterContractNo != null and c.masterContractNo != ''">
                    and sl.master_contract_no like concat('%', #{c.masterContractNo}, '%')
                </if>
            </if>
        </where>
@@ -94,6 +98,7 @@
        p.product_name AS productName,
        pm.unit,
        sl.sales_contract_no,
        sl.master_contract_no,
        sl.customer_name,
        sl.project_name
        FROM production_plan pp
src/main/resources/mapper/production/ProductionProductMainMapper.xml
@@ -31,6 +31,7 @@
               pm.model as productModelName,
               pm.unit,
               po_sales.salesContractNo,
               po_sales.masterContractNo,
               date(ppm.create_time) as schedulingDate,
               su.nick_name as schedulingUserName,
               po_sales.customerName,
@@ -42,6 +43,7 @@
                 left join (
            select po2.id as orderId,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as salesContractNo,
                   group_concat(distinct sl2.master_contract_no order by sl2.master_contract_no separator ',') as masterContractNo,
                   group_concat(distinct sl2.customer_name order by sl2.customer_name separator ',') as customerName
            from production_order po2
                     left join production_plan pp2
@@ -63,6 +65,9 @@
            <if test="c.salesContractNo != null and c.salesContractNo != ''">
                and po_sales.salesContractNo like concat('%', #{c.salesContractNo}, '%')
            </if>
            <if test="c.masterContractNo != null and c.masterContractNo != ''">
                and po_sales.masterContractNo like concat('%', #{c.masterContractNo}, '%')
            </if>
            <if test="c.customerName != null and c.customerName != ''">
                and po_sales.customerName like concat('%', #{c.customerName}, '%')
            </if>
src/main/resources/mapper/purchase/PurchaseReturnOrdersMapper.xml
@@ -22,7 +22,8 @@
        SELECT
            pro.*,
            sm.supplier_name as supplier_name,
            pl.purchase_contract_number as purchase_contract_number
            pl.purchase_contract_number as purchase_contract_number,
            pl.master_contract_no as master_contract_no
        FROM purchase_return_orders pro
                 LEFT JOIN supplier_manage sm ON pro.supplier_id = sm.id
                 LEFT JOIN purchase_ledger pl ON pl.id = pro.purchase_ledger_id
@@ -62,7 +63,8 @@
                pro.prepared_at,
                pro.total_amount,
                CASE pro.return_type WHEN 0 THEN '退货退款' WHEN 1 THEN '拒收' END AS returnType,
                pl.purchase_contract_number
                pl.purchase_contract_number,
                pl.master_contract_no
        from purchase_return_orders pro
        left join
            (select prop.purchase_return_order_id,
src/main/resources/mapper/sales/ShippingInfoMapper.xml
@@ -19,6 +19,7 @@
        s.update_user,
        s.tenant_id,
        sl.sales_contract_no,
        sl.master_contract_no,
        s.outbound_batches,
        pm.model as specification_model,
        pm.unit,
@@ -57,6 +58,9 @@
        WHERE 1=1
        <if test="req.salesContractNo != null and req.salesContractNo != ''">
            AND sl.sales_contract_no LIKE CONCAT('%',#{req.salesContractNo},'%')
        </if>
        <if test="req.masterContractNo != null and req.masterContractNo != ''">
            AND sl.master_contract_no LIKE CONCAT('%',#{req.masterContractNo},'%')
        </if>
        <if test="req.shippingCarNumber != null and req.shippingCarNumber != ''">
            AND s.shipping_car_number LIKE CONCAT('%',#{req.shippingCarNumber},'%')
@@ -134,6 +138,7 @@
            si.id AS shippingId,
            si.shipping_no AS shippingNo,
            sl.sales_contract_no AS salesContractNo,
            sl.master_contract_no AS masterContractNo,
            sl.customer_name AS customerName,
            IFNULL(p.product_name, slp.product_category) AS productName,
            IFNULL(pm.model, slp.specification_model) AS model,
src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -170,7 +170,8 @@
            p.product_name,
            pm.model as specification_model,
            sir.stock_in_num * slp.tax_inclusive_unit_price AS InboundAmount,
            pl.purchase_contract_number
            pl.purchase_contract_number,
            pl.master_contract_no
            FROM stock_in_record sir
            -- 10 ç±»åž‹æ‰å…³è”质检表
            LEFT JOIN quality_inspect qi ON sir.record_type = 10 AND sir.record_id = qi.id
src/main/resources/mapper/stock/StockOutRecordMapper.xml
@@ -103,7 +103,8 @@
        slp.tax_rate,
        sor.stock_out_num * slp.tax_inclusive_unit_price as outboundAmount,
        s.shipping_no,
        sl.sales_contract_no
        sl.sales_contract_no,
        sl.master_contract_no
        FROM stock_out_record sor
        left join shipping_info s on sor.record_id = s.id
        LEFT JOIN sales_ledger sl ON s.sales_ledger_id = sl.id