5 天以前 368c5735a66262a8f12045679c8925ad6d11d126
feat(purchase): 添加采购台账入库状态和销售产品入库审核状态功能

- 在application.yml中将激活配置从dev-pro改为dev
- 在PurchaseLedgerDto中新增stockInStatus字段用于入库状态筛选
- 修改PurchaseLedgerMapper.xml中的查询逻辑,添加入库状态计算和筛选功能
- 移除PurchaseLedgerServiceImpl中不必要的文件查询逻辑
- 在SalesLedgerProduct中新增stockInApprovalStatus字段用于产品入库审核状态
- 更新SalesLedgerProductMapper.xml中的查询逻辑,添加入库审核状态计算
- 在StockInRecordDto中新增sourceOrderNo字段用于源单号显示
- 修改StockInRecordMapper.xml中的查询逻辑,添加多场景源单号追溯功能
- 新增相关技术文档说明入库状态和源单号的业务规则及前端联调方案
已添加3个文件
已修改8个文件
575 ■■■■ 文件已修改
doc/20260522_StockInRecord列表源单号前端联调文档.md 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260522_StockInRecord列表源单号前端联调文档_276补充.md 65 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260522_采购台账入库状态_销售产品入库审核状态前端联调文档.md 127 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/application.yml 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml 162 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/stock/StockInRecordMapper.xml 87 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
doc/20260522_StockInRecordÁбíÔ´µ¥ºÅǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,75 @@
# StockInRecord åˆ—表源单号前端联调文档
更新时间:2026-05-22
适用接口:`GET /stockInRecord/listPage`
## 1. å˜æ›´è¯´æ˜Ž
本次对入库管理列表接口增加返回字段 `sourceOrderNo`(源单号),用于原材料场景展示采购来源单号。
生效条件:
- å½“请求参数 `topParentProductId = 278` æ—¶ï¼ŒåŽç«¯è¿”回 `sourceOrderNo`。
- å…¶ä»– `topParentProductId` åœºæ™¯ä¸‹ï¼Œè¯¥å­—段返回 `null`(或不展示)。
## 2. å­—段定义
新增字段:
- `sourceOrderNo`:`string`,源单号(采购合同号)。
## 3. å–值规则
仅在 `topParentProductId = 278` æ—¶æŒ‰â€œæ¥æºâ€è®¡ç®—:
1. æ¥æº = `采购-入库`(`recordType = 7`)
   - å…ˆæŒ‰ `recordId` æŸ¥é‡‡è´­äº§å“è¡¨ `sales_ledger_product`(`type=2`);
   - å†é€šè¿‡ `sales_ledger_product.sales_ledger_id` æŸ¥é‡‡è´­å°è´¦è¡¨ `purchase_ledger`;
   - è¿”回 `purchase_ledger.purchase_contract_number` ä½œä¸º `sourceOrderNo`。
   - å…¼å®¹å…œåº•:若未命中采购产品链路,则按 `recordId` ç›´æŽ¥æŸ¥ `purchase_ledger.id` å–单号。
2. æ¥æº = `采购-质检-合格入库`(`recordType = 10`)
   - å…ˆæŒ‰ `recordId` æŸ¥è´¨æ£€è¡¨ `quality_inspect`;
   - å†é€šè¿‡ `quality_inspect.purchase_ledger_id` æŸ¥é‡‡è´­å°è´¦è¡¨ `purchase_ledger`;
   - è¿”回 `purchase_ledger.purchase_contract_number` ä½œä¸º `sourceOrderNo`。
## 4. è¿”回示例
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "records": [
      {
        "id": 1024,
        "recordType": "7",
        "productName": "铜排",
        "model": "T2-30x3",
        "sourceOrderNo": "CG-2026-00128"
      },
      {
        "id": 1025,
        "recordType": "10",
        "productName": "铜排",
        "model": "T2-30x3",
        "sourceOrderNo": "CG-2026-00131"
      }
    ],
    "total": 2
  }
}
```
## 5. å‰ç«¯è”调建议
1. åˆ—表列新增“源单号”,读取字段 `sourceOrderNo`。
2. å»ºè®®ä»…在 `topParentProductId = 278` çš„页面/筛选条件下展示该列。
3. å½“ `sourceOrderNo` ä¸ºç©ºæ—¶å±•示 `--`,避免空白。
## 6. å›žå½’清单
1. `topParentProductId=278` + `recordType=7`:应返回采购合同号。
2. `topParentProductId=278` + `recordType=10`:应返回采购合同号(经质检链路)。
3. `topParentProductId!=278`:`sourceOrderNo` åº”为 `null` æˆ–前端不展示。
4. åŽŸæœ‰å­—æ®µï¼ˆ`productName/model/unit/createBy` ç­‰ï¼‰ä¸å—影响。
doc/20260522_StockInRecordÁбíÔ´µ¥ºÅǰ¶ËÁªµ÷Îĵµ_276²¹³ä.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,65 @@
# StockInRecord åˆ—表源单号前端联调文档(`topParentProductId=276`补充)
更新时间:2026-05-22
适用接口:`GET /stockInRecord/listPage`
## 1. å˜æ›´è¯´æ˜Ž
在已有 `sourceOrderNo` åŸºç¡€ä¸Šï¼Œæ–°å¢ž `topParentProductId = 276` çš„æºå•号溯源逻辑:
- æ ¹æ®â€œæ¥æºï¼ˆrecordType)+ recordId”溯源;
- ä¼˜å…ˆè¿”回销售单号(销售合同号);
- è‹¥é”€å”®å•号为空,则回退返回生产订单号;
- ä¸è€ƒè™‘自定义入库(`recordType=0/9`)。
## 2. è¿”回字段
字段无新增,继续使用:
- `sourceOrderNo`:`string`,源单号。
## 3. 276 åœºæ™¯å–值规则
请求参数满足 `topParentProductId = 276` æ—¶ï¼š
1. `recordType = 14/15`(销售退货-合格/不合格入库)
   - `stock_in_record.record_id -> return_sale_product.id -> return_management.shipping_id -> shipping_info.sales_ledger_id -> sales_ledger.sales_contract_no`
   - è¿”回销售合同号。
2. `recordType = 2/5`(生产报工-入库/报废)
   - `stock_in_record.record_id -> production_product_main.id -> production_operation_task.production_order_id -> production_order`
   - å…ˆå–该生产订单关联销售合同号(由生产计划关联销售台账聚合);
   - é”€å”®åˆåŒå·ä¸ºç©ºæ—¶ï¼Œè¿”回 `production_order.nps_no`。
3. `recordType = 6`(质检-合格入库)
   - `stock_in_record.record_id -> quality_inspect.id -> quality_inspect.product_main_id -> production_product_main -> production_operation_task -> production_order`
   - å…ˆå–销售合同号,空则回退 `production_order.nps_no`。
4. `recordType = 4/11`(不合格处理-报废/让步放行)
   - `stock_in_record.record_id -> quality_unqualified.id -> quality_unqualified.inspect_id -> quality_inspect -> production_product_main -> production_operation_task -> production_order`
   - å…ˆå–销售合同号,空则回退 `production_order.nps_no`。
5. `recordType = 20/22`(领料退料/生产退料-合格入库)
   - `stock_in_record.record_id -> production_order_pick.id -> production_order`
   - å…ˆå–销售合同号,空则回退 `production_order.nps_no`。
6. `recordType = 0/9`(自定义入库)
   - ä¸å‚与溯源,`sourceOrderNo = null`。
## 4. å…¶ä»–场景说明
- `topParentProductId = 278` çš„采购链路源单号逻辑保持不变。
- å…¶ä»– `topParentProductId` ä¸è§¦å‘本次 276 è§„则,`sourceOrderNo` ä¸ºç©ºã€‚
## 5. å‰ç«¯è”调建议
1. åœ¨ `topParentProductId=276` çš„列表场景展示“源单号”列,读取 `sourceOrderNo`。
2. å»ºè®®ç©ºå€¼ç»Ÿä¸€å±•示 `--`。
3. ä¸éœ€è¦æ–°å¢žè¯·æ±‚参数,沿用现有 `/stockInRecord/listPage`。
## 6. å›žå½’清单
1. `topParentProductId=276` + `recordType=14/15`:应返回销售合同号。
2. `topParentProductId=276` + `recordType=2/5/6/4/11/20/22`:优先销售合同号,缺失时返回生产订单号。
3. `topParentProductId=276` + `recordType=0/9`:`sourceOrderNo` ä¸ºç©ºã€‚
4. `topParentProductId=278`:仍按采购链路返回采购合同号。
doc/20260522_²É¹ºÌ¨ÕËÈë¿â״̬_ÏúÊÛ²úÆ·Èë¿âÉóºË״̬ǰ¶ËÁªµ÷Îĵµ.md
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,127 @@
# é‡‡è´­å…¥åº“状态前端联调文档
更新时间:2026-05-22
适用版本:本次后端变更后
## 1. å˜æ›´èŒƒå›´
1. `GET /purchaseLedger/listPage`
   - æ–°å¢žæŸ¥è¯¢æ¡ä»¶ï¼š`stockInStatus`(入库状态)
   - æ–°å¢žè¿”回字段:`stockInStatus`(入库状态)
2. `GET /salesLedgerProduct/list`
   - æ–°å¢žè¿”回字段:`stockInApprovalStatus`(每个产品的入库审核状态)
---
## 2. å…¥åº“状态枚举(两接口一致)
- `待入库`
- `入库中`
- `完全入库`
说明:前端筛选值请直接使用以上中文枚举值。
---
## 3. æŽ¥å£ä¸€ï¼š`GET /purchaseLedger/listPage`
### 3.1 æ–°å¢žè¯·æ±‚参数
- `stockInStatus`:`string`,可选
  å¯ä¼ å€¼ï¼š`待入库` / `入库中` / `完全入库`
### 3.2 æ–°å¢žè¿”回字段
- `stockInStatus`:`string`,采购台账维度入库状态
### 3.3 çŠ¶æ€è®¡ç®—è§„åˆ™ï¼ˆé‡‡è´­å°è´¦ç»´åº¦ï¼‰
以该采购台账下 `sales_ledger_product.type = 2` çš„采购产品为计算范围:
1. å…¨éƒ¨äº§å“éƒ½è¾¾åˆ°â€œå®Œå…¨å…¥åº“” => å°è´¦çŠ¶æ€ `完全入库`
2. è‡³å°‘有一个产品存在“审核通过入库”,但未全部完全入库 => å°è´¦çŠ¶æ€ `入库中`
3. æ²¡æœ‰ä»»ä½•产品存在“审核通过入库” => å°è´¦çŠ¶æ€ `待入库`
“审核通过入库”统计口径:`stock_in_record.approval_status = 1`,并按以下来源溯源:
- `record_type = 7`(采购-入库):按采购台账+产品关联统计
- `record_type = 10`(采购-质检-合格入库):通过 `quality_inspect` å›žæº¯åˆ°é‡‡è´­å°è´¦+产品统计
### 3.4 è¿”回示例(节选)
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": {
    "records": [
      {
        "id": 1201,
        "purchaseContractNumber": "CG20260522001",
        "supplierName": "XX供应商",
        "stockInStatus": "入库中"
      }
    ],
    "total": 1
  }
}
```
---
## 4. æŽ¥å£äºŒï¼š`GET /salesLedgerProduct/list`
### 4.1 æ–°å¢žè¿”回字段
- `stockInApprovalStatus`:`string`,当前产品行的入库审核状态
### 4.2 çŠ¶æ€è®¡ç®—è§„åˆ™ï¼ˆäº§å“ç»´åº¦ï¼‰
仅当产品 `type = 2`(采购产品)时计算并返回:
1. å®¡æ ¸é€šè¿‡å…¥åº“数量 `<= 0` => `待入库`
2. å®¡æ ¸é€šè¿‡å…¥åº“数量 `>= äº§å“é‡‡è´­æ•°é‡` => `完全入库`
3. å…¶ä»–情况 => `入库中`
其中“审核通过入库数量”统计同样基于:
- `stock_in_record.approval_status = 1`
- æ¥æº `record_type = 7 / 10` çš„æº¯æºå…³è”逻辑
`type != 2` çš„产品,该字段返回 `null`。
### 4.3 è¿”回示例(节选)
```json
{
  "code": 200,
  "msg": "操作成功",
  "data": [
    {
      "id": 5566,
      "type": 2,
      "productCategory": "铜材",
      "specificationModel": "T2-30x3",
      "quantity": 100,
      "stockInApprovalStatus": "待入库"
    }
  ]
}
```
---
## 5. å‰ç«¯æ”¹é€ å»ºè®®
1. é‡‡è´­å°è´¦åˆ—表新增“入库状态”筛选项,值固定:`待入库/入库中/完全入库`。
2. é‡‡è´­å°è´¦åˆ—表新增“入库状态”列,展示 `stockInStatus`。
3. é‡‡è´­äº§å“åˆ—表新增“入库审核状态”列,展示 `stockInApprovalStatus`。
4. ç©ºå€¼ï¼ˆå¦‚ `type != 2`)建议展示为 `--`。
---
## 6. è”调检查清单
1. `/purchaseLedger/listPage` ä¸ä¼  `stockInStatus`:应正常返回全部数据,并带 `stockInStatus`。
2. `/purchaseLedger/listPage?stockInStatus=待入库`:仅返回待入库台账。
3. `/purchaseLedger/listPage?stockInStatus=入库中`:仅返回入库中台账。
4. `/purchaseLedger/listPage?stockInStatus=完全入库`:仅返回完全入库台账。
5. `/salesLedgerProduct/list` åœ¨é‡‡è´­äº§å“ï¼ˆ`type=2`)下返回 `stockInApprovalStatus`。
6. `/salesLedgerProduct/list` åœ¨éžé‡‡è´­äº§å“ï¼ˆ`type!=2`)下 `stockInApprovalStatus` ä¸º `null`。
src/main/java/com/ruoyi/purchase/dto/PurchaseLedgerDto.java
@@ -27,6 +27,8 @@
    private String entryDateStart;
    private String entryDateEnd;
    @Schema(description = "入库状态")
    private String stockInStatus;
    private Long id;
src/main/java/com/ruoyi/purchase/service/impl/PurchaseLedgerServiceImpl.java
@@ -451,12 +451,7 @@
    @Override
    public IPage<PurchaseLedgerDto> selectPurchaseLedgerListPage(IPage ipage, PurchaseLedgerDto purchaseLedger) {
        IPage<PurchaseLedgerDto> purchaseLedgerDtoIPage = purchaseLedgerMapper.selectPurchaseLedgerListPage(ipage, purchaseLedger);
        purchaseLedgerDtoIPage.getRecords().forEach(purchaseLedgerDto -> {
            List<CommonFile> commonFiles = commonFileMapper.selectList(new LambdaQueryWrapper<CommonFile>().eq(CommonFile::getCommonId, purchaseLedgerDto.getId()).eq(CommonFile::getType, FileNameType.PURCHASE.getValue()));
            purchaseLedgerDto.setSalesLedgerFiles(commonFiles);
        });
        return purchaseLedgerDtoIPage;
        return purchaseLedgerMapper.selectPurchaseLedgerListPage(ipage, purchaseLedger);
    }
    @Override
src/main/java/com/ruoyi/sales/pojo/SalesLedgerProduct.java
@@ -149,6 +149,10 @@
    /**
     * äº§å“çŠ¶æ€
     */
    @TableField(exist = false)
    @Schema(description = "入库审核状态")
    private String stockInApprovalStatus;
//    @TableField(exist = false)
    @Schema(description = "产品状态:1-充足")
    private Integer approveStatus;
src/main/java/com/ruoyi/stock/dto/StockInRecordDto.java
@@ -40,4 +40,7 @@
    @Schema(description = "记录ID列表")
    private List<Long> ids;
    @Schema(description = "源单号")
    private String sourceOrderNo;
}
src/main/resources/application.yml
@@ -3,7 +3,7 @@
  main:
    allow-circular-references: true
  profiles:
    active: dev-pro
    active: dev
langchain4j:
  mcp:
    # MCP æœåŠ¡ç«¯åœ°å€ï¼ˆæ ¹æ®å®žé™…éƒ¨ç½²çš„ MCP æœåŠ¡è°ƒæ•´ï¼‰
src/main/resources/mapper/purchase/PurchaseLedgerMapper.xml
@@ -17,56 +17,118 @@
    </select>
    <select id="selectPurchaseLedgerListPage" resultType="com.ruoyi.purchase.dto.PurchaseLedgerDto">
        SELECT
        pl.id,
        pl.purchase_contract_number,
        pl.sales_contract_no,
        pl.supplier_id,
        pl.supplier_name,
        pl.project_name,
        pl.contract_amount,
        pl.entry_date,
        pl.execution_date,
        pl.recorder_id,
        pl.recorder_name,
        pl.template_name,
        pl.approve_user_ids,
        sm.is_white,
        pl.approval_status,
        pl.payment_method,
        pl.remarks
        FROM purchase_ledger pl
        LEFT JOIN supplier_manage sm ON pl.supplier_id = sm.id
        <where>
            <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
                AND pl.purchase_contract_number LIKE CONCAT('%', #{c.purchaseContractNumber}, '%')
            </if>
            <if test="c.approvalStatus != null and c.approvalStatus != ''">
                AND pl.approval_status = #{c.approvalStatus}
            </if>
            <if test="c.supplierName != null and c.supplierName != ''">
                AND pl.supplier_name LIKE CONCAT('%', #{c.supplierName}, '%')
            </if>
            <if test="c.salesContractNo != null and c.salesContractNo != ''">
                AND pl.sales_contract_no LIKE CONCAT('%', #{c.salesContractNo}, '%')
            </if>
            <if test="c.projectName != null and c.projectName != ''">
                AND pl.project_name LIKE CONCAT('%', #{c.projectName}, '%')
            </if>
            <if test="c.entryDateStart != null and c.entryDateStart != ''">
                AND pl.entry_date &gt;= #{c.entryDateStart}
            </if>
            <if test="c.entryDateEnd != null and c.entryDateEnd != ''">
                AND pl.entry_date &lt;= #{c.entryDateEnd}
            </if>
            <if test="c.supplierId != null">
                AND pl.supplier_id = #{c.supplierId}
            </if>
            <if test="c.approvalStatus != null">
                AND pl.approval_status = #{c.approvalStatus}
            </if>
        </where>
        ORDER BY pl.entry_date DESC
        SELECT result.*
        FROM (
            SELECT
                pl.id,
                pl.purchase_contract_number,
                pl.sales_contract_no,
                pl.supplier_id,
                pl.supplier_name,
                pl.project_name,
                pl.contract_amount,
                pl.entry_date,
                pl.execution_date,
                pl.recorder_id,
                pl.recorder_name,
                pl.template_name,
                pl.approve_user_ids,
                sm.is_white,
                pl.approval_status,
                pl.payment_method,
                pl.remarks,
                CASE
                    WHEN IFNULL(ls.total_product_count, 0) = 0 THEN '待入库'
                    WHEN IFNULL(ls.full_product_count, 0) &gt;= IFNULL(ls.total_product_count, 0) THEN '完全入库'
                    WHEN IFNULL(ls.approved_product_count, 0) &gt; 0 THEN '入库中'
                    ELSE '待入库'
                END AS stock_in_status
            FROM purchase_ledger pl
            LEFT JOIN supplier_manage sm ON pl.supplier_id = sm.id
            LEFT JOIN (
                SELECT
                    product_status.sales_ledger_id,
                    COUNT(1) AS total_product_count,
                    SUM(CASE WHEN product_status.approved_stock_in_num &gt; 0 THEN 1 ELSE 0 END) AS approved_product_count,
                    SUM(CASE WHEN product_status.approved_stock_in_num &gt;= product_status.product_quantity THEN 1 ELSE 0 END) AS full_product_count
                FROM (
                    SELECT
                        slp.id AS sales_ledger_product_id,
                        slp.sales_ledger_id,
                        IFNULL(slp.quantity, 0) AS product_quantity,
                        IFNULL(approved_qty.approved_stock_in_num, 0) AS approved_stock_in_num
                    FROM sales_ledger_product slp
                    LEFT JOIN (
                        SELECT rel.sales_ledger_product_id,
                               IFNULL(SUM(rel.stock_in_num), 0) AS approved_stock_in_num
                        FROM (
                            SELECT slp.id AS sales_ledger_product_id,
                                   sir.stock_in_num
                            FROM stock_in_record sir
                            INNER JOIN sales_ledger_product slp
                                ON slp.type = 2
                                AND TRIM(sir.record_type) = '7'
                                AND sir.record_id = slp.sales_ledger_id
                                AND (
                                    (sir.batch_no IS NOT NULL AND sir.batch_no LIKE CONCAT('%-', slp.id))
                                    OR (sir.batch_no IS NULL AND sir.product_model_id = slp.product_model_id)
                                )
                            WHERE sir.approval_status = 1
                            UNION ALL
                            SELECT slp.id AS sales_ledger_product_id,
                                   sir.stock_in_num
                            FROM stock_in_record sir
                            INNER JOIN quality_inspect qi
                                ON TRIM(sir.record_type) = '10'
                                AND sir.record_id = qi.id
                            INNER JOIN sales_ledger_product slp
                                ON slp.type = 2
                                AND slp.sales_ledger_id = qi.purchase_ledger_id
                                AND slp.product_model_id = qi.product_model_id
                            WHERE sir.approval_status = 1
                        ) rel
                        GROUP BY rel.sales_ledger_product_id
                    ) approved_qty ON approved_qty.sales_ledger_product_id = slp.id
                    WHERE slp.type = 2
                ) product_status
                GROUP BY product_status.sales_ledger_id
            ) ls ON ls.sales_ledger_id = pl.id
            <where>
                <if test="c.purchaseContractNumber != null and c.purchaseContractNumber != ''">
                    AND pl.purchase_contract_number LIKE CONCAT('%', #{c.purchaseContractNumber}, '%')
                </if>
                <if test="c.approvalStatus != null and c.approvalStatus != ''">
                    AND pl.approval_status = #{c.approvalStatus}
                </if>
                <if test="c.supplierName != null and c.supplierName != ''">
                    AND pl.supplier_name LIKE CONCAT('%', #{c.supplierName}, '%')
                </if>
                <if test="c.salesContractNo != null and c.salesContractNo != ''">
                    AND pl.sales_contract_no LIKE CONCAT('%', #{c.salesContractNo}, '%')
                </if>
                <if test="c.projectName != null and c.projectName != ''">
                    AND pl.project_name LIKE CONCAT('%', #{c.projectName}, '%')
                </if>
                <if test="c.entryDateStart != null and c.entryDateStart != ''">
                    AND pl.entry_date &gt;= #{c.entryDateStart}
                </if>
                <if test="c.entryDateEnd != null and c.entryDateEnd != ''">
                    AND pl.entry_date &lt;= #{c.entryDateEnd}
                </if>
                <if test="c.supplierId != null">
                    AND pl.supplier_id = #{c.supplierId}
                </if>
                <if test="c.approvalStatus != null">
                    AND pl.approval_status = #{c.approvalStatus}
                </if>
            </where>
        ) result
        <if test="c.stockInStatus != null and c.stockInStatus != ''">
            WHERE result.stock_in_status = #{c.stockInStatus}
        </if>
        ORDER BY result.entry_date DESC
    </select>
    <select id="selectTotalPurchaseAmount" resultType="java.math.BigDecimal">
src/main/resources/mapper/sales/SalesLedgerProductMapper.xml
@@ -38,7 +38,13 @@
         WHEN IFNULL(t3.shipped_quantity, 0) = 0 THEN '待发货'
         WHEN (IFNULL(T1.quantity, 0) - IFNULL(t3.shipped_quantity, 0)) > 0 THEN '部分发货'
        ELSE '已发货'
        END as shippingStatus
        END as shippingStatus,
        CASE
         WHEN T1.type != 2 THEN NULL
         WHEN IFNULL(t4.approved_stock_in_num, 0) &lt;= 0 THEN '待入库'
         WHEN IFNULL(t4.approved_stock_in_num, 0) &gt;= IFNULL(T1.quantity, 0) THEN '完全入库'
        ELSE '入库中'
        END AS stock_in_approval_status
        FROM
        sales_ledger_product T1
        LEFT JOIN (
@@ -53,6 +59,39 @@
        where si.status != '审核拒绝'
        GROUP BY sales_ledger_product_id
        ) t3 ON t3.sales_ledger_product_id = T1.id
        LEFT JOIN (
        SELECT rel.sales_ledger_product_id,
               IFNULL(SUM(rel.stock_in_num), 0) AS approved_stock_in_num
        FROM (
            SELECT slp.id AS sales_ledger_product_id,
                   sir.stock_in_num
            FROM stock_in_record sir
            INNER JOIN sales_ledger_product slp
                ON slp.type = 2
                AND TRIM(sir.record_type) = '7'
                AND sir.record_id = slp.sales_ledger_id
                AND (
                    (sir.batch_no IS NOT NULL AND sir.batch_no LIKE CONCAT('%-', slp.id))
                    OR (sir.batch_no IS NULL AND sir.product_model_id = slp.product_model_id)
                )
            WHERE sir.approval_status = 1
            UNION ALL
            SELECT slp.id AS sales_ledger_product_id,
                   sir.stock_in_num
            FROM stock_in_record sir
            INNER JOIN quality_inspect qi
                ON TRIM(sir.record_type) = '10'
                AND sir.record_id = qi.id
            INNER JOIN sales_ledger_product slp
                ON slp.type = 2
                AND slp.sales_ledger_id = qi.purchase_ledger_id
                AND slp.product_model_id = qi.product_model_id
            WHERE sir.approval_status = 1
        ) rel
        GROUP BY rel.sales_ledger_product_id
        ) t4 ON t4.sales_ledger_product_id = T1.id
        left join product_model pm ON T1.product_model_id = pm.id
        left join product p ON pm.product_id = p.id
        <where>
src/main/resources/mapper/stock/StockInRecordMapper.xml
@@ -19,11 +19,96 @@
        p.product_name as product_name,
        pm.model,
        pm.unit,
        u.nick_name as createBy
        u.nick_name as createBy,
        CASE
            WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '7' THEN
                COALESCE(pl_by_product.purchase_contract_number, pl_direct.purchase_contract_number)
            WHEN #{params.topParentProductId} = 278 AND TRIM(sir.record_type) = '10' THEN
                pl_by_quality.purchase_contract_number
            WHEN #{params.topParentProductId} = 276 THEN
                CASE
                    WHEN TRIM(sir.record_type) IN ('14', '15') THEN
                        sl_return.sales_contract_no
                    WHEN TRIM(sir.record_type) IN ('2', '5') THEN
                        COALESCE(po_sales_main.sales_contract_no, po_main.nps_no)
                    WHEN TRIM(sir.record_type) = '6' THEN
                        COALESCE(po_sales_qi.sales_contract_no, po_qi.nps_no)
                    WHEN TRIM(sir.record_type) IN ('4', '11') THEN
                        COALESCE(po_sales_uq.sales_contract_no, po_uq.nps_no)
                    WHEN TRIM(sir.record_type) IN ('20', '22') THEN
                        COALESCE(po_sales_pick.sales_contract_no, po_pick.nps_no)
                    ELSE NULL
                END
            ELSE NULL
        END AS sourceOrderNo
        FROM stock_in_record as sir
        LEFT JOIN product_model as pm on sir.product_model_id = pm.id
        LEFT JOIN product as p on pm.product_id = p.id
        LEFT JOIN sys_user as u on sir.create_user = u.user_id
        LEFT JOIN quality_inspect as qi_purchase on TRIM(sir.record_type) = '10' and sir.record_id = qi_purchase.id
        LEFT JOIN sales_ledger_product as slp on TRIM(sir.record_type) = '7' and slp.id = sir.record_id and slp.type = 2
        LEFT JOIN purchase_ledger as pl_by_product on TRIM(sir.record_type) = '7' and pl_by_product.id = slp.sales_ledger_id
        LEFT JOIN purchase_ledger as pl_direct on TRIM(sir.record_type) = '7' and pl_direct.id = sir.record_id
        LEFT JOIN purchase_ledger as pl_by_quality on TRIM(sir.record_type) = '10' and pl_by_quality.id = qi_purchase.purchase_ledger_id
        LEFT JOIN production_product_main as ppm_main on TRIM(sir.record_type) IN ('2', '5') and sir.record_id = ppm_main.id
        LEFT JOIN production_operation_task as pot_main on ppm_main.production_operation_task_id = pot_main.id
        LEFT JOIN production_order as po_main on pot_main.production_order_id = po_main.id
        LEFT JOIN (
            select po2.id as production_order_id,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no
            from production_order po2
                     left join production_plan pp2
                               on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0
                     left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id
            group by po2.id
        ) as po_sales_main on po_sales_main.production_order_id = po_main.id
        LEFT JOIN quality_inspect as qi_prod on TRIM(sir.record_type) = '6' and sir.record_id = qi_prod.id
        LEFT JOIN production_product_main as ppm_qi on qi_prod.product_main_id = ppm_qi.id
        LEFT JOIN production_operation_task as pot_qi on ppm_qi.production_operation_task_id = pot_qi.id
        LEFT JOIN production_order as po_qi on pot_qi.production_order_id = po_qi.id
        LEFT JOIN (
            select po2.id as production_order_id,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no
            from production_order po2
                     left join production_plan pp2
                               on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0
                     left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id
            group by po2.id
        ) as po_sales_qi on po_sales_qi.production_order_id = po_qi.id
        LEFT JOIN quality_unqualified as qu on TRIM(sir.record_type) IN ('4', '11') and sir.record_id = qu.id
        LEFT JOIN quality_inspect as qi_uq on qu.inspect_id = qi_uq.id
        LEFT JOIN production_product_main as ppm_uq on qi_uq.product_main_id = ppm_uq.id
        LEFT JOIN production_operation_task as pot_uq on ppm_uq.production_operation_task_id = pot_uq.id
        LEFT JOIN production_order as po_uq on pot_uq.production_order_id = po_uq.id
        LEFT JOIN (
            select po2.id as production_order_id,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no
            from production_order po2
                     left join production_plan pp2
                               on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0
                     left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id
            group by po2.id
        ) as po_sales_uq on po_sales_uq.production_order_id = po_uq.id
        LEFT JOIN production_order_pick as pop on TRIM(sir.record_type) IN ('20', '22') and sir.record_id = pop.id
        LEFT JOIN production_order as po_pick on pop.production_order_id = po_pick.id
        LEFT JOIN (
            select po2.id as production_order_id,
                   group_concat(distinct sl2.sales_contract_no order by sl2.sales_contract_no separator ',') as sales_contract_no
            from production_order po2
                     left join production_plan pp2
                               on find_in_set(pp2.id, replace(replace(replace(po2.production_plan_ids, '[', ''), ']', ''), ' ', '')) > 0
                     left join sales_ledger sl2 on sl2.id = pp2.sales_ledger_id
            group by po2.id
        ) as po_sales_pick on po_sales_pick.production_order_id = po_pick.id
        LEFT JOIN return_sale_product as rsp on TRIM(sir.record_type) IN ('14', '15') and sir.record_id = rsp.id
        LEFT JOIN return_management as rm on rsp.return_management_id = rm.id
        LEFT JOIN shipping_info as si_return on rm.shipping_id = si_return.id
        LEFT JOIN sales_ledger as sl_return on si_return.sales_ledger_id = sl_return.id
        <where>
            <if test="params.timeStr != null and params.timeStr != ''">
                and sir.create_time like concat('%',#{params.timeStr},'%')