Преглед изворни кода

Merge branch 'hurx'

# Conflicts:
#	ruoyi-modules/pom.xml
hurx пре 2 месеци
родитељ
комит
4fca857125
84 измењених фајлова са 5813 додато и 28 уклоњено
  1. 2 0
      ruoyi-modules/pom.xml
  2. 33 0
      ruoyi-modules/ruoyi-bill/.gitignore
  3. 147 0
      ruoyi-modules/ruoyi-bill/pom.xml
  4. 17 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/RuoyiBillApplication.java
  5. 106 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/InvoiceInfoController.java
  6. 106 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementDetailController.java
  7. 123 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceController.java
  8. 106 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceDetailController.java
  9. 106 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceProductController.java
  10. 145 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementOrderController.java
  11. 106 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementProductController.java
  12. 85 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/InvoiceInfo.java
  13. 104 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementDetail.java
  14. 84 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoice.java
  15. 122 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoiceDetail.java
  16. 113 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoiceProduct.java
  17. 115 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementOrder.java
  18. 113 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementProduct.java
  19. 77 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/InvoiceInfoBo.java
  20. 97 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementDetailBo.java
  21. 93 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceBo.java
  22. 114 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceDetailBo.java
  23. 105 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceProductBo.java
  24. 118 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementOrderBo.java
  25. 103 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementProductBo.java
  26. 11 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/dto/StatementOrderItem.java
  27. 96 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/InvoiceInfoVo.java
  28. 126 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementDetailVo.java
  29. 140 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceDetailVo.java
  30. 131 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceProductVo.java
  31. 112 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceVo.java
  32. 140 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementOrderVo.java
  33. 129 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementProductVo.java
  34. 16 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/InvoiceInfoMapper.java
  35. 16 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementDetailMapper.java
  36. 18 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceDetailMapper.java
  37. 16 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceMapper.java
  38. 18 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceProductMapper.java
  39. 17 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementOrderMapper.java
  40. 23 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementProductMapper.java
  41. 70 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IInvoiceInfoService.java
  42. 70 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementDetailService.java
  43. 70 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceDetailService.java
  44. 70 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceProductService.java
  45. 79 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceService.java
  46. 100 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementOrderService.java
  47. 70 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementProductService.java
  48. 141 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/InvoiceInfoServiceImpl.java
  49. 143 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementDetailServiceImpl.java
  50. 148 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceDetailServiceImpl.java
  51. 147 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceProductServiceImpl.java
  52. 270 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceServiceImpl.java
  53. 368 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementOrderServiceImpl.java
  54. 147 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementProductServiceImpl.java
  55. 34 0
      ruoyi-modules/ruoyi-bill/src/main/resources/application.yml
  56. 28 0
      ruoyi-modules/ruoyi-bill/src/main/resources/logback-plus.xml
  57. 13 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/InvoiceInfoMapper.xml
  58. 13 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementDetailMapper.xml
  59. 13 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceDetailMapper.xml
  60. 7 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceMapper.xml
  61. 13 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceProductMapper.xml
  62. 7 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementOrderMapper.xml
  63. 24 0
      ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementProductMapper.xml
  64. 23 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerBusinessInfoController.java
  65. 24 4
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java
  66. 2 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerBusinessInfoVo.java
  67. 9 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerBusinessInfoService.java
  68. 9 4
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java
  69. 70 4
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerBusinessInfoServiceImpl.java
  70. 12 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  71. 10 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderDeliverController.java
  72. 23 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainController.java
  73. 5 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderDeliver.java
  74. 5 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderDeliverBo.java
  75. 5 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderDeliverVo.java
  76. 8 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainVo.java
  77. 11 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderDeliverService.java
  78. 5 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainService.java
  79. 33 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java
  80. 47 3
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java
  81. 5 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComLogisticsCompany.java
  82. 6 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComLogisticsCompanyBo.java
  83. 5 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComLogisticsCompanyVo.java
  84. 2 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComLogisticsCompanyServiceImpl.java

+ 2 - 0
ruoyi-modules/pom.xml

@@ -19,6 +19,8 @@
         <module>ruoyi-customer</module>
 	    <module>ruoyi-external</module>
 	    <module>ruoyi-mall</module>
+        <module>ruoyi-external</module>
+        <module>ruoyi-bill</module>
     </modules>
 
     <artifactId>ruoyi-modules</artifactId>

+ 33 - 0
ruoyi-modules/ruoyi-bill/.gitignore

@@ -0,0 +1,33 @@
+HELP.md
+target/
+.mvn/wrapper/maven-wrapper.jar
+!**/src/main/**/target/
+!**/src/test/**/target/
+
+### STS ###
+.apt_generated
+.classpath
+.factorypath
+.project
+.settings
+.springBeans
+.sts4-cache
+
+### IntelliJ IDEA ###
+.idea
+*.iws
+*.iml
+*.ipr
+
+### NetBeans ###
+/nbproject/private/
+/nbbuild/
+/dist/
+/nbdist/
+/.nb-gradle/
+build/
+!**/src/main/**/build/
+!**/src/test/**/build/
+
+### VS Code ###
+.vscode/

+ 147 - 0
ruoyi-modules/ruoyi-bill/pom.xml

@@ -0,0 +1,147 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-modules</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>ruoyi-bill</artifactId>
+
+    <description>
+        ruoyi-bill账单模块
+    </description>
+
+    <dependencies>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-nacos</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-sentinel</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Log -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-log</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-service-impl</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-doc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-mybatis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-seata</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-idempotent</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-tenant</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-translation</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-sensitive</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-encrypt</artifactId>
+        </dependency>
+
+        <!-- RuoYi Api System -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-system</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-resource</artifactId>
+        </dependency>
+
+        <!-- RuoYi Api System -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-workflow</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+
+        <!-- RuoYi Api Product -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-product</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 17 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/RuoyiBillApplication.java

@@ -0,0 +1,17 @@
+package org.dromara.bill;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
+
+@SpringBootApplication
+public class RuoyiBillApplication {
+
+    public static void main(String[] args) {
+        SpringApplication application = new SpringApplication(RuoyiBillApplication.class);
+        application.setApplicationStartup(new BufferingApplicationStartup(2048));
+        application.run(args);
+        System.out.println("(♥◠‿◠)ノ゙  账单模块启动成功   ლ(´ڡ`ლ)゙  ");
+    }
+
+}

+ 106 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/InvoiceInfoController.java

@@ -0,0 +1,106 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.InvoiceInfoVo;
+import org.dromara.bill.domain.bo.InvoiceInfoBo;
+import org.dromara.bill.service.IInvoiceInfoService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 发票信息
+ * 前端访问路由地址为:/bill/invoiceInfo
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/invoiceInfo")
+public class InvoiceInfoController extends BaseController {
+
+    private final IInvoiceInfoService invoiceInfoService;
+
+    /**
+     * 查询发票信息列表
+     */
+    @SaCheckPermission("bill:invoiceInfo:list")
+    @GetMapping("/list")
+    public TableDataInfo<InvoiceInfoVo> list(InvoiceInfoBo bo, PageQuery pageQuery) {
+        return invoiceInfoService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出发票信息列表
+     */
+    @SaCheckPermission("bill:invoiceInfo:export")
+    @Log(title = "发票信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(InvoiceInfoBo bo, HttpServletResponse response) {
+        List<InvoiceInfoVo> list = invoiceInfoService.queryList(bo);
+        ExcelUtil.exportExcel(list, "发票信息", InvoiceInfoVo.class, response);
+    }
+
+    /**
+     * 获取发票信息详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("bill:invoiceInfo:query")
+    @GetMapping("/{id}")
+    public R<InvoiceInfoVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(invoiceInfoService.queryById(id));
+    }
+
+    /**
+     * 新增发票信息
+     */
+    @SaCheckPermission("bill:invoiceInfo:add")
+    @Log(title = "发票信息", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody InvoiceInfoBo bo) {
+        return toAjax(invoiceInfoService.insertByBo(bo));
+    }
+
+    /**
+     * 修改发票信息
+     */
+    @SaCheckPermission("bill:invoiceInfo:edit")
+    @Log(title = "发票信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody InvoiceInfoBo bo) {
+        return toAjax(invoiceInfoService.updateByBo(bo));
+    }
+
+    /**
+     * 删除发票信息
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("bill:invoiceInfo:remove")
+    @Log(title = "发票信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(invoiceInfoService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementDetailController.java

@@ -0,0 +1,106 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.bo.StatementDetailBo;
+import org.dromara.bill.service.IStatementDetailService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 对账单交易明细
+ * 前端访问路由地址为:/bill/statementDetail
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementDetail")
+public class StatementDetailController extends BaseController {
+
+    private final IStatementDetailService statementDetailService;
+
+    /**
+     * 查询对账单交易明细列表
+     */
+//    @SaCheckPermission("bill:statementDetail:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementDetailVo> list(StatementDetailBo bo, PageQuery pageQuery) {
+        return statementDetailService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出对账单交易明细列表
+     */
+//    @SaCheckPermission("bill:statementDetail:export")
+    @Log(title = "对账单交易明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementDetailBo bo, HttpServletResponse response) {
+        List<StatementDetailVo> list = statementDetailService.queryList(bo);
+        ExcelUtil.exportExcel(list, "对账单交易明细", StatementDetailVo.class, response);
+    }
+
+    /**
+     * 获取对账单交易明细详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("bill:statementDetail:query")
+    @GetMapping("/{id}")
+    public R<StatementDetailVo> getInfo(@NotNull(message = "主键不能为空")
+                                        @PathVariable("id") Long id) {
+        return R.ok(statementDetailService.queryById(id));
+    }
+
+    /**
+     * 新增对账单交易明细
+     */
+//    @SaCheckPermission("bill:statementDetail:add")
+    @Log(title = "对账单交易明细", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementDetailBo bo) {
+        return toAjax(statementDetailService.insertByBo(bo));
+    }
+
+    /**
+     * 修改对账单交易明细
+     */
+//    @SaCheckPermission("bill:statementDetail:edit")
+    @Log(title = "对账单交易明细", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementDetailBo bo) {
+        return toAjax(statementDetailService.updateByBo(bo));
+    }
+
+    /**
+     * 删除对账单交易明细
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("bill:statementDetail:remove")
+    @Log(title = "对账单交易明细", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementDetailService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 123 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceController.java

@@ -0,0 +1,123 @@
+package org.dromara.bill.controller;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import org.dromara.bill.domain.bo.StatementOrderBo;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementInvoiceVo;
+import org.dromara.bill.domain.bo.StatementInvoiceBo;
+import org.dromara.bill.service.IStatementInvoiceService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 销售发票主
+ * 前端访问路由地址为:/bill/statementInvoice
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementInvoice")
+public class StatementInvoiceController extends BaseController {
+
+    private final IStatementInvoiceService statementInvoiceService;
+
+    /**
+     * 查询销售发票主列表
+     */
+    @SaCheckPermission("bill:statementInvoice:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementInvoiceVo> list(StatementInvoiceBo bo, PageQuery pageQuery) {
+        return statementInvoiceService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出销售发票主列表
+     */
+    @SaCheckPermission("bill:statementInvoice:export")
+    @Log(title = "销售发票主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementInvoiceBo bo, HttpServletResponse response) {
+        List<StatementInvoiceVo> list = statementInvoiceService.queryList(bo);
+        ExcelUtil.exportExcel(list, "销售发票主", StatementInvoiceVo.class, response);
+    }
+
+    /**
+     * 获取销售发票主详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("bill:statementInvoice:query")
+    @GetMapping("/{id}")
+    public R<StatementInvoiceVo> getInfo(@NotNull(message = "主键不能为空")
+                                         @PathVariable("id") Long id) {
+        return R.ok(statementInvoiceService.queryById(id));
+    }
+
+    /**
+     * 新增销售发票主
+     */
+    @SaCheckPermission("bill:statementInvoice:add")
+    @Log(title = "销售发票主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementInvoiceBo bo) {
+        return toAjax(statementInvoiceService.insertByBo(bo));
+    }
+
+    /**
+     * 修改销售发票主
+     */
+    @SaCheckPermission("bill:statementInvoice:edit")
+    @Log(title = "销售发票主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementInvoiceBo bo) {
+        return toAjax(statementInvoiceService.updateByBo(bo));
+    }
+
+    /**
+     * 删除销售发票主
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("bill:statementInvoice:remove")
+    @Log(title = "销售发票主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementInvoiceService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @Log(title = "销售发票主", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody StatementInvoiceBo bo) {
+        return toAjax(statementInvoiceService.updateStatus(bo));
+    }
+
+
+}

+ 106 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceDetailController.java

@@ -0,0 +1,106 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementInvoiceDetailVo;
+import org.dromara.bill.domain.bo.StatementInvoiceDetailBo;
+import org.dromara.bill.service.IStatementInvoiceDetailService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 销售发票明细
+ * 前端访问路由地址为:/bill/statementInvoiceDetail
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementInvoiceDetail")
+public class StatementInvoiceDetailController extends BaseController {
+
+    private final IStatementInvoiceDetailService statementInvoiceDetailService;
+
+    /**
+     * 查询销售发票明细列表
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementInvoiceDetailVo> list(StatementInvoiceDetailBo bo, PageQuery pageQuery) {
+        return statementInvoiceDetailService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出销售发票明细列表
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:export")
+    @Log(title = "销售发票明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementInvoiceDetailBo bo, HttpServletResponse response) {
+        List<StatementInvoiceDetailVo> list = statementInvoiceDetailService.queryList(bo);
+        ExcelUtil.exportExcel(list, "销售发票明细", StatementInvoiceDetailVo.class, response);
+    }
+
+    /**
+     * 获取销售发票明细详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:query")
+    @GetMapping("/{id}")
+    public R<StatementInvoiceDetailVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(statementInvoiceDetailService.queryById(id));
+    }
+
+    /**
+     * 新增销售发票明细
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:add")
+    @Log(title = "销售发票明细", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementInvoiceDetailBo bo) {
+        return toAjax(statementInvoiceDetailService.insertByBo(bo));
+    }
+
+    /**
+     * 修改销售发票明细
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:edit")
+    @Log(title = "销售发票明细", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementInvoiceDetailBo bo) {
+        return toAjax(statementInvoiceDetailService.updateByBo(bo));
+    }
+
+    /**
+     * 删除销售发票明细
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("bill:statementInvoiceDetail:remove")
+    @Log(title = "销售发票明细", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementInvoiceDetailService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceProductController.java

@@ -0,0 +1,106 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.dromara.bill.domain.bo.StatementInvoiceProductBo;
+import org.dromara.bill.service.IStatementInvoiceProductService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 销售发票商品
+ * 前端访问路由地址为:/bill/statementInvoiceProduct
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementInvoiceProduct")
+public class StatementInvoiceProductController extends BaseController {
+
+    private final IStatementInvoiceProductService statementInvoiceProductService;
+
+    /**
+     * 查询销售发票商品列表
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementInvoiceProductVo> list(StatementInvoiceProductBo bo, PageQuery pageQuery) {
+        return statementInvoiceProductService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出销售发票商品列表
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:export")
+    @Log(title = "销售发票商品", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementInvoiceProductBo bo, HttpServletResponse response) {
+        List<StatementInvoiceProductVo> list = statementInvoiceProductService.queryList(bo);
+        ExcelUtil.exportExcel(list, "销售发票商品", StatementInvoiceProductVo.class, response);
+    }
+
+    /**
+     * 获取销售发票商品详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:query")
+    @GetMapping("/{id}")
+    public R<StatementInvoiceProductVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(statementInvoiceProductService.queryById(id));
+    }
+
+    /**
+     * 新增销售发票商品
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:add")
+    @Log(title = "销售发票商品", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementInvoiceProductBo bo) {
+        return toAjax(statementInvoiceProductService.insertByBo(bo));
+    }
+
+    /**
+     * 修改销售发票商品
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:edit")
+    @Log(title = "销售发票商品", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementInvoiceProductBo bo) {
+        return toAjax(statementInvoiceProductService.updateByBo(bo));
+    }
+
+    /**
+     * 删除销售发票商品
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("bill:statementInvoiceProduct:remove")
+    @Log(title = "销售发票商品", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementInvoiceProductService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 145 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementOrderController.java

@@ -0,0 +1,145 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import org.dromara.bill.domain.dto.StatementOrderItem;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementOrderVo;
+import org.dromara.bill.domain.bo.StatementOrderBo;
+import org.dromara.bill.service.IStatementOrderService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 对账单主
+ * 前端访问路由地址为:/bill/statementOrder
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementOrder")
+public class StatementOrderController extends BaseController {
+
+    private final IStatementOrderService statementOrderService;
+
+    /**
+     * 查询对账单主列表
+     */
+//    @SaCheckPermission("bill:statementOrder:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementOrderVo> list(StatementOrderBo bo, PageQuery pageQuery) {
+        return statementOrderService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 根据订单id查询订单商品
+     */
+    @PostMapping("/getStatementProductList")
+    public TableDataInfo<StatementProductVo> getStatementProductList(
+        @RequestBody List<StatementOrderItem> items) {
+
+        if (CollectionUtils.isEmpty(items)) {
+            throw new IllegalArgumentException("至少选择一个订单");
+        }
+
+        // 校验参数
+        if (items.stream().anyMatch(item -> item.getStatementOrderId() == null || item.getOrderId() == null)) {
+            throw new IllegalArgumentException("statementOrderId 和 orderId 不能为空");
+        }
+
+        return statementOrderService.getStatementProductList(items);
+    }
+
+    /**
+     * 导出对账单主列表
+     */
+//    @SaCheckPermission("bill:statementOrder:export")
+    @Log(title = "对账单主", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementOrderBo bo, HttpServletResponse response) {
+        List<StatementOrderVo> list = statementOrderService.queryList(bo);
+        ExcelUtil.exportExcel(list, "对账单主", StatementOrderVo.class, response);
+    }
+
+    /**
+     * 获取对账单主详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("bill:statementOrder:query")
+    @GetMapping("/{id}")
+    public R<StatementOrderVo> getInfo(@NotNull(message = "主键不能为空")
+                                       @PathVariable("id") Long id) {
+        return R.ok(statementOrderService.queryById(id));
+    }
+
+    /**
+     * 新增对账单主
+     */
+//    @SaCheckPermission("bill:statementOrder:add")
+    @Log(title = "对账单主", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementOrderBo bo) {
+        return toAjax(statementOrderService.insertByBo(bo));
+    }
+
+    /**
+     * 修改对账单主
+     */
+//    @SaCheckPermission("bill:statementOrder:edit")
+    @Log(title = "对账单主", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementOrderBo bo) {
+        return toAjax(statementOrderService.updateByBo(bo));
+    }
+
+    /**
+     * 删除对账单主
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("bill:statementOrder:remove")
+    @Log(title = "对账单主", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementOrderService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @Log(title = "对账单主", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody StatementOrderBo bo) {
+        return toAjax(statementOrderService.updateStatus(bo));
+    }
+
+
+    /*根据客户id查询客户对账单对应的订单*/
+    @GetMapping("/getCustomerOrderDetails/{customerId}")
+    public TableDataInfo<StatementDetailVo> getCustomerDetails(@PathVariable Long customerId,
+                                                               PageQuery pageQuery) {
+        return statementOrderService.listDetailsByCustomerIdPage(customerId, pageQuery);
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementProductController.java

@@ -0,0 +1,106 @@
+package org.dromara.bill.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.bill.domain.bo.StatementProductBo;
+import org.dromara.bill.service.IStatementProductService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 对账单商品明细
+ * 前端访问路由地址为:/bill/statementProduct
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/statementProduct")
+public class StatementProductController extends BaseController {
+
+    private final IStatementProductService statementProductService;
+
+    /**
+     * 查询对账单商品明细列表
+     */
+//    @SaCheckPermission("bill:statementProduct:list")
+    @GetMapping("/list")
+    public TableDataInfo<StatementProductVo> list(StatementProductBo bo, PageQuery pageQuery) {
+        return statementProductService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出对账单商品明细列表
+     */
+//    @SaCheckPermission("bill:statementProduct:export")
+    @Log(title = "对账单商品明细", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(StatementProductBo bo, HttpServletResponse response) {
+        List<StatementProductVo> list = statementProductService.queryList(bo);
+        ExcelUtil.exportExcel(list, "对账单商品明细", StatementProductVo.class, response);
+    }
+
+    /**
+     * 获取对账单商品明细详细信息
+     *
+     * @param id 主键
+     */
+//    @SaCheckPermission("bill:statementProduct:query")
+    @GetMapping("/{id}")
+    public R<StatementProductVo> getInfo(@NotNull(message = "主键不能为空")
+                                         @PathVariable("id") Long id) {
+        return R.ok(statementProductService.queryById(id));
+    }
+
+    /**
+     * 新增对账单商品明细
+     */
+//    @SaCheckPermission("bill:statementProduct:add")
+    @Log(title = "对账单商品明细", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody StatementProductBo bo) {
+        return toAjax(statementProductService.insertByBo(bo));
+    }
+
+    /**
+     * 修改对账单商品明细
+     */
+//    @SaCheckPermission("bill:statementProduct:edit")
+    @Log(title = "对账单商品明细", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody StatementProductBo bo) {
+        return toAjax(statementProductService.updateByBo(bo));
+    }
+
+    /**
+     * 删除对账单商品明细
+     *
+     * @param ids 主键串
+     */
+//    @SaCheckPermission("bill:statementProduct:remove")
+    @Log(title = "对账单商品明细", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(statementProductService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 85 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/InvoiceInfo.java

@@ -0,0 +1,85 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 发票信息对象 invoice_info
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("invoice_info")
+public class InvoiceInfo extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 对账单发票id
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 对账单发票编号
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 发票类型
+     */
+    private String invoiceType;
+
+    /**
+     * 发票代码
+     */
+    private String invoiceCode;
+
+    /**
+     * 发票金额
+     */
+    private BigDecimal invoiceAmount;
+
+    /**
+     * 发票附件路径或URL
+     */
+    private String invoiceAnnex;
+
+    /**
+     * 开票公司名称
+     */
+    private String companyName;
+
+    /**
+     * 发票开具日期
+     */
+    private Date invoiceDate;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 104 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementDetail.java

@@ -0,0 +1,104 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 对账单交易明细对象 statement_detail
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_detail")
+public class StatementDetail extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 明细类型(如:1-销售订单, 2-退款等)
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 该明细金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 订单时间
+     */
+    private Date orderTime;
+
+    /**
+     * 签收日期
+     */
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    private Long userId;
+
+    /**
+     * 操作用户
+     */
+    private String userName;
+
+    private Long userDeptId;
+
+    /**
+     * 用户所属部门
+     */
+    private String userDept;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 84 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoice.java

@@ -0,0 +1,84 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 销售发票主对象 statement_invoice
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_invoice")
+public class StatementInvoice extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 发票编号
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 发票金额
+     */
+    private Long invoiceAmount;
+
+    /**
+     * 发票状态
+     */
+    private String invoiceStatus;
+
+    /**
+     * 开票时间
+     */
+    private Date invoiceTime;
+
+    /**
+     * 驳回备注
+     */
+    private String rejectRemark;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 122 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoiceDetail.java

@@ -0,0 +1,122 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 销售发票明细对象 statement_invoice_detail
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_invoice_detail")
+public class StatementInvoiceDetail extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 对账金额
+     */
+    private BigDecimal statementAmount;
+
+    /**
+     * 订单类型
+     */
+    private String orderType;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 订单金额
+     */
+    private BigDecimal orderAmount;
+
+    /**
+     * 订单时间
+     */
+    private Date orderTime;
+
+    /**
+     * 签约/对账日期
+     */
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    private Long userId;
+
+    /**
+     * 操作人
+     */
+    private String userName;
+
+    /**
+     * 操作人部门
+     */
+    private Long userDeptId;
+
+    /**
+     * 操作人部门
+     */
+    private String userDept;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 113 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoiceProduct.java

@@ -0,0 +1,113 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+
+import java.io.Serial;
+
+/**
+ * 销售发票商品对象 statement_invoice_product
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_invoice_product")
+public class StatementInvoiceProduct extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 商品类型
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 所属订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    private Long unitId;
+
+    /**
+     * 单位名称
+     */
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 115 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementOrder.java

@@ -0,0 +1,115 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 对账单主对象 statement_order
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_order")
+public class StatementOrder extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 对账总金额
+     */
+    private BigDecimal amount;
+
+    /*对账人id*/
+    private Long statementSelfId;
+
+    /**
+     * 对账人姓名
+     */
+    private String statementSelf;
+
+    /**
+     * 对账人电话
+     */
+    private String statementSelfPhone;
+
+    /**
+     * 对账状态(如:0-待确认, 1-已确认, 2-已驳回)
+     */
+    private String statementStatus;
+
+    /**
+     * 是否已付款
+     */
+    private String isPaymentStatus;
+
+    /**
+     * 是否已开票
+     */
+    private String isInvoiceStatus;
+
+    /**
+     * 对账日期
+     */
+    private Date statementDate;
+
+    /**
+     * 附件存储路径
+     */
+    private String annexAddress;
+
+    /**
+     * 驳回原因
+     */
+    private String rejectRemark;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 113 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementProduct.java

@@ -0,0 +1,113 @@
+package org.dromara.bill.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import java.math.BigDecimal;
+
+import java.io.Serial;
+
+/**
+ * 对账单商品明细对象 statement_product
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("statement_product")
+public class StatementProduct extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 商品类型(如:1-实物, 2-服务等)
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    private Long unitId;
+
+    /**
+     * 单位
+     */
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 77 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/InvoiceInfoBo.java

@@ -0,0 +1,77 @@
+package org.dromara.bill.domain.bo;
+
+import org.dromara.bill.domain.InvoiceInfo;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 发票信息业务对象 invoice_info
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = InvoiceInfo.class, reverseConvertGenerate = false)
+public class InvoiceInfoBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 对账单发票id
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 对账单发票编号
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 发票类型
+     */
+    private String invoiceType;
+
+    /**
+     * 发票代码
+     */
+    private String invoiceCode;
+
+    /**
+     * 发票金额
+     */
+    private BigDecimal invoiceAmount;
+
+    /**
+     * 发票附件路径或URL
+     */
+    private String invoiceAnnex;
+
+    /**
+     * 开票公司名称
+     */
+    private String companyName;
+
+    /**
+     * 发票开具日期
+     */
+    private Date invoiceDate;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 97 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementDetailBo.java

@@ -0,0 +1,97 @@
+package org.dromara.bill.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.bill.domain.StatementDetail;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * 对账单交易明细业务对象 statement_detail
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementDetail.class, reverseConvertGenerate = false)
+public class StatementDetailBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 明细类型(如:1-销售订单, 2-退款等)
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 该明细金额
+     */
+    private BigDecimal amount;
+
+    /**
+     * 订单时间
+     */
+    private Date orderTime;
+
+    /**
+     * 签收日期
+     */
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    private Long userId;
+
+    /**
+     * 操作用户
+     */
+    private String userName;
+
+    private Long userDeptId;
+
+    /**
+     * 用户所属部门
+     */
+    private String userDept;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 该订单下的商品明细列表
+     */
+    private List<StatementProductBo> productList;
+
+
+}

+ 93 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceBo.java

@@ -0,0 +1,93 @@
+package org.dromara.bill.domain.bo;
+
+import org.dromara.bill.domain.StatementInvoice;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 销售发票主业务对象 statement_invoice
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementInvoice.class, reverseConvertGenerate = false)
+public class StatementInvoiceBo extends BaseEntity {
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 发票编号
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 发票金额
+     */
+    private Long invoiceAmount;
+
+    /**
+     * 发票状态
+     */
+    private String invoiceStatus;
+
+    /**
+     * 开票时间
+     */
+    private Date invoiceTime;
+
+    /**
+     * 驳回备注
+     */
+    private String rejectRemark;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+    /**
+     * 对账单明细列表(关联的订单)
+     */
+    @NotNull(message = "订单明细不能为空")
+    @Size(min = 1, message = "至少需要一个订单")
+    private List<StatementInvoiceDetailBo> detailList;
+
+    /**
+     * 商品明细列表
+     */
+    private List<StatementInvoiceProductBo> productList;
+
+    private List<InvoiceInfoBo> invoiceList;
+
+}

+ 114 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceDetailBo.java

@@ -0,0 +1,114 @@
+package org.dromara.bill.domain.bo;
+
+import org.dromara.bill.domain.StatementInvoiceDetail;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 销售发票明细业务对象 statement_invoice_detail
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementInvoiceDetail.class, reverseConvertGenerate = false)
+public class StatementInvoiceDetailBo extends BaseEntity {
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 对账金额
+     */
+    private BigDecimal statementAmount;
+
+    /**
+     * 订单类型
+     */
+    private String orderType;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 订单金额
+     */
+    private BigDecimal orderAmount;
+
+    /**
+     * 订单时间
+     */
+    private Date orderTime;
+
+    /**
+     * 签约/对账日期
+     */
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    private Long userId;
+
+    /**
+     * 操作人
+     */
+    private String userName;
+
+    /**
+     * 操作人部门
+     */
+    private Long userDeptId;
+
+    /**
+     * 操作人部门
+     */
+    private String userDept;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 105 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceProductBo.java

@@ -0,0 +1,105 @@
+package org.dromara.bill.domain.bo;
+
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import java.math.BigDecimal;
+
+/**
+ * 销售发票商品业务对象 statement_invoice_product
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementInvoiceProduct.class, reverseConvertGenerate = false)
+public class StatementInvoiceProductBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    private String statementInvoiceNo;
+
+    /**
+     * 商品类型
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 所属订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    private Long unitId;
+
+    /**
+     * 单位名称
+     */
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 118 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementOrderBo.java

@@ -0,0 +1,118 @@
+package org.dromara.bill.domain.bo;
+
+import org.dromara.bill.domain.StatementOrder;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import java.util.List;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 对账单主业务对象 statement_order
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementOrder.class, reverseConvertGenerate = false)
+public class StatementOrderBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 客户编号
+     */
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    private String customerName;
+
+    /**
+     * 对账总金额
+     */
+    private BigDecimal amount;
+
+    /*对账人id*/
+    private Long statementSelfId;
+
+    /**
+     * 对账人姓名
+     */
+    private String statementSelf;
+
+    /**
+     * 对账人电话
+     */
+    private String statementSelfPhone;
+
+    /**
+     * 对账状态(如:0-待确认, 1-已确认, 2-已驳回)
+     */
+    private String statementStatus;
+
+    /**
+     * 是否已付款
+     */
+    private String isPaymentStatus;
+
+    /**
+     * 是否已开票
+     */
+    private String isInvoiceStatus;
+
+    /**
+     * 对账日期
+     */
+    private Date statementDate;
+
+    /**
+     * 附件存储路径
+     */
+    private String annexAddress;
+
+    /**
+     * 驳回原因
+     */
+    private String rejectRemark;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     * 对账单明细列表(关联的订单)
+     */
+    @NotNull(message = "订单明细不能为空")
+    @Size(min = 1, message = "至少需要一个订单")
+    private List<StatementDetailBo> detailList;
+
+    /**
+     * 商品明细列表
+     */
+    private List<StatementProductBo> productList;
+}

+ 103 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementProductBo.java

@@ -0,0 +1,103 @@
+package org.dromara.bill.domain.bo;
+
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.bill.domain.StatementProduct;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+
+import java.math.BigDecimal;
+
+/**
+ * 对账单商品明细业务对象 statement_product
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = StatementProduct.class, reverseConvertGenerate = false)
+public class StatementProductBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    private String statementOrderNo;
+
+    /**
+     * 商品类型(如:1-实物, 2-服务等)
+     */
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    private Long unitId;
+
+    /**
+     * 单位
+     */
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    private BigDecimal unitPrice;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 11 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/dto/StatementOrderItem.java

@@ -0,0 +1,11 @@
+package org.dromara.bill.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class StatementOrderItem {
+
+    private String statementOrderId;
+
+    private Long orderId;
+}

+ 96 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/InvoiceInfoVo.java

@@ -0,0 +1,96 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.bill.domain.InvoiceInfo;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 发票信息视图对象 invoice_info
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = InvoiceInfo.class)
+public class InvoiceInfoVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 对账单发票id
+     */
+    @ExcelProperty(value = "对账单发票id")
+    private Long statementInvoiceId;
+
+    /**
+     * 对账单发票编号
+     */
+    @ExcelProperty(value = "对账单发票编号")
+    private String statementInvoiceNo;
+
+    /**
+     * 发票类型
+     */
+    @ExcelProperty(value = "发票类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "invoice_type")
+    private String invoiceType;
+
+    /**
+     * 发票代码
+     */
+    @ExcelProperty(value = "发票代码")
+    private String invoiceCode;
+
+    /**
+     * 发票金额
+     */
+    @ExcelProperty(value = "发票金额")
+    private BigDecimal invoiceAmount;
+
+    /**
+     * 发票附件路径或URL
+     */
+    @ExcelProperty(value = "发票附件路径或URL")
+    private String invoiceAnnex;
+
+    /**
+     * 开票公司名称
+     */
+    @ExcelProperty(value = "开票公司名称")
+    private String companyName;
+
+    /**
+     * 发票开具日期
+     */
+    @ExcelProperty(value = "发票开具日期")
+    private Date invoiceDate;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 126 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementDetailVo.java

@@ -0,0 +1,126 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.bill.domain.StatementDetail;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.bill.domain.bo.StatementProductBo;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 对账单交易明细视图对象 statement_detail
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementDetail.class)
+public class StatementDetailVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    @ExcelProperty(value = "对账单id")
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    @ExcelProperty(value = "对账单编号")
+    private String statementOrderNo;
+
+    /**
+     * 明细类型(如:1-销售订单, 2-退款等)
+     */
+    @ExcelProperty(value = "明细类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "statement_order_type")
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    @ExcelProperty(value = "关联的订单id")
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    @ExcelProperty(value = "关联的订单编号")
+    private String orderNo;
+
+    /**
+     * 该明细金额
+     */
+    @ExcelProperty(value = "该明细金额")
+    private BigDecimal amount;
+
+    /**
+     * 对账总金额
+     */
+    private BigDecimal statementAmount;
+
+    /**
+     * 订单时间
+     */
+    @ExcelProperty(value = "订单时间")
+    private Date orderTime;
+
+    /**
+     * 签收日期
+     */
+    @ExcelProperty(value = "签收日期")
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    @ExcelProperty(value = "操作用户id")
+    private Long userId;
+
+    /**
+     * 用户所属部门
+     */
+    @ExcelProperty(value = "用户所属部门")
+    private String userDept;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /**
+     * 操作用户
+     */
+    private String userName;
+
+    private Long userDeptId;
+
+    /**
+     * 该订单下的商品明细列表
+     */
+    private List<StatementProductVo> productList;
+
+}

+ 140 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceDetailVo.java

@@ -0,0 +1,140 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.bill.domain.StatementInvoiceDetail;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 销售发票明细视图对象 statement_invoice_detail
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementInvoiceDetail.class)
+public class StatementInvoiceDetailVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    @ExcelProperty(value = "发票主表id", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联主表")
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    @ExcelProperty(value = "发票编号", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联主表")
+    private String statementInvoiceNo;
+
+    /**
+     * 对账金额
+     */
+    @ExcelProperty(value = "对账金额")
+    private BigDecimal statementAmount;
+
+    /**
+     * 订单类型
+     */
+    @ExcelProperty(value = "订单类型")
+    private String orderType;
+
+    /**
+     * 关联的订单id
+     */
+    @ExcelProperty(value = "关联的订单id")
+    private Long orderId;
+
+    /**
+     * 订单编号
+     */
+    @ExcelProperty(value = "订单编号")
+    private String orderNo;
+
+    /**
+     * 订单金额
+     */
+    @ExcelProperty(value = "订单金额")
+    private BigDecimal orderAmount;
+
+    /**
+     * 订单时间
+     */
+    @ExcelProperty(value = "订单时间")
+    private Date orderTime;
+
+    /**
+     * 签约/对账日期
+     */
+    @ExcelProperty(value = "签约/对账日期")
+    private Date signingDate;
+
+    /**
+     * 操作用户id
+     */
+    @ExcelProperty(value = "操作用户id")
+    private Long userId;
+
+    /**
+     * 操作人
+     */
+    @ExcelProperty(value = "操作人")
+    private String userName;
+
+    /**
+     * 操作人部门
+     */
+    @ExcelProperty(value = "操作人部门")
+    private Long userDeptId;
+
+    /**
+     * 操作人部门
+     */
+    @ExcelProperty(value = "操作人部门")
+    private String userDept;
+
+    /**
+     * 对账单id
+     */
+    @ExcelProperty(value = "对账单id")
+    private Long statementOrderId;
+
+    /**
+     * 对账单号(可选)
+     */
+    @ExcelProperty(value = "对账单号", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "可=选")
+    private String statementOrderNo;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 131 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceProductVo.java

@@ -0,0 +1,131 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 销售发票商品视图对象 statement_invoice_product
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementInvoiceProduct.class)
+public class StatementInvoiceProductVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 发票主表id(关联主表)
+     */
+    @ExcelProperty(value = "发票主表id", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联主表")
+    private Long statementInvoiceId;
+
+    /**
+     * 发票编号(关联主表)
+     */
+    @ExcelProperty(value = "发票编号", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联主表")
+    private String statementInvoiceNo;
+
+    /**
+     * 商品类型
+     */
+    @ExcelProperty(value = "商品类型")
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    @ExcelProperty(value = "关联的订单id")
+    private Long orderId;
+
+    /**
+     * 所属订单编号
+     */
+    @ExcelProperty(value = "所属订单编号")
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    @ExcelProperty(value = "品类id")
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    @ExcelProperty(value = "品类编号")
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    @ExcelProperty(value = "商品id")
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    @ExcelProperty(value = "商品名称")
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    @ExcelProperty(value = "单位")
+    private Long unitId;
+
+    /**
+     * 单位名称
+     */
+    @ExcelProperty(value = "单位名称")
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    @ExcelProperty(value = "数量")
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    @ExcelProperty(value = "单价")
+    private BigDecimal unitPrice;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 112 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceVo.java

@@ -0,0 +1,112 @@
+package org.dromara.bill.domain.vo;
+
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.bill.domain.InvoiceInfo;
+import org.dromara.bill.domain.StatementInvoice;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 销售发票主视图对象 statement_invoice
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementInvoice.class)
+public class StatementInvoiceVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 发票编号
+     */
+    @ExcelProperty(value = "发票编号")
+    private String statementInvoiceNo;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    @ExcelProperty(value = "客户名称")
+    private String customerName;
+
+    /**
+     * 发票金额
+     */
+    @ExcelProperty(value = "发票金额")
+    private Long invoiceAmount;
+
+    /**
+     * 发票状态
+     */
+    @ExcelProperty(value = "发票状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "invoice_status")
+    private String invoiceStatus;
+
+    /**
+     * 开票时间
+     */
+    @ExcelProperty(value = "开票时间")
+    private Date invoiceTime;
+
+    /**
+     * 驳回备注
+     */
+    @ExcelProperty(value = "驳回备注")
+    private String rejectRemark;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /**
+     * 销售发票明细列表(订单级)
+     */
+    private List<StatementInvoiceDetailVo> detailList;
+
+    /**
+     * 商品清单列表(商品级)
+     */
+    private List<StatementInvoiceProductVo> productList;
+
+    /**
+     * 发票信息列表
+     */
+    private List<InvoiceInfoVo> invoiceList;
+
+
+}

+ 140 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementOrderVo.java

@@ -0,0 +1,140 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.bill.domain.StatementOrder;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 对账单主视图对象 statement_order
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementOrder.class)
+public class StatementOrderVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 对账单编号
+     */
+    @ExcelProperty(value = "对账单编号")
+    private String statementOrderNo;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private Long customerId;
+
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    @ExcelProperty(value = "客户名称")
+    private String customerName;
+
+    /**
+     * 对账总金额
+     */
+    @ExcelProperty(value = "对账总金额")
+    private BigDecimal amount;
+
+    /*对账人id*/
+    private Long statementSelfId;
+
+    /**
+     * 对账人姓名
+     */
+    @ExcelProperty(value = "对账人姓名")
+    private String statementSelf;
+
+    /**
+     * 对账人电话
+     */
+    @ExcelProperty(value = "对账人电话")
+    private String statementSelfPhone;
+
+    /**
+     * 对账状态(如:0-待确认, 1-已确认, 2-已驳回)
+     */
+    @ExcelProperty(value = "对账状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "statement_status")
+    private String statementStatus;
+
+    /**
+     * 是否已付款
+     */
+    @ExcelProperty(value = "是否已付款", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "payment_status")
+    private String isPaymentStatus;
+
+    /**
+     * 是否已开票
+     */
+    @ExcelProperty(value = "是否已开票", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(dictType = "invoice_issuance_status")
+    private String isInvoiceStatus;
+
+    /**
+     * 对账日期
+     */
+    @ExcelProperty(value = "对账日期")
+    private Date statementDate;
+
+    /**
+     * 附件存储路径
+     */
+    @ExcelProperty(value = "附件存储路径")
+    private String annexAddress;
+
+    /**
+     * 驳回原因
+     */
+    @ExcelProperty(value = "驳回原因")
+    private String rejectRemark;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /**
+     * 对账明细列表(订单级)
+     */
+    private List<StatementDetailVo> detailList;
+
+    /**
+     * 商品清单列表(商品级)
+     */
+    private List<StatementProductVo> productList;
+}

+ 129 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementProductVo.java

@@ -0,0 +1,129 @@
+package org.dromara.bill.domain.vo;
+
+import java.math.BigDecimal;
+
+import org.dromara.bill.domain.StatementProduct;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+/**
+ * 对账单商品明细视图对象 statement_product
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = StatementProduct.class)
+public class StatementProductVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 对账单id
+     */
+    @ExcelProperty(value = "对账单id")
+    private Long statementOrderId;
+
+    /**
+     * 对账单编号
+     */
+    @ExcelProperty(value = "对账单编号")
+    private String statementOrderNo;
+
+    /**
+     * 商品类型(如:1-实物, 2-服务等)
+     */
+    @ExcelProperty(value = "商品类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:1-实物,,2=-服务等")
+    private String type;
+
+    /**
+     * 关联的订单id
+     */
+    @ExcelProperty(value = "关联的订单id")
+    private Long orderId;
+
+    /**
+     * 关联的订单编号
+     */
+    @ExcelProperty(value = "关联的订单编号")
+    private String orderNo;
+
+    /**
+     * 品类id
+     */
+    @ExcelProperty(value = "品类id")
+    private Long categoryId;
+
+    /**
+     * 品类编号
+     */
+    @ExcelProperty(value = "品类编号")
+    private String categoryNo;
+
+    /**
+     * 商品id
+     */
+    @ExcelProperty(value = "商品id")
+    private Long productId;
+
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    @ExcelProperty(value = "商品名称")
+    private String itemName;
+
+    /**
+     * 单位
+     */
+    @ExcelProperty(value = "单位")
+    private Long unitId;
+
+    /**
+     * 单位
+     */
+    @ExcelProperty(value = "单位")
+    private String unitName;
+
+    /**
+     * 数量
+     */
+    @ExcelProperty(value = "数量")
+    private Long quantity;
+
+    /**
+     * 单价
+     */
+    @ExcelProperty(value = "单价")
+    private BigDecimal unitPrice;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+}

+ 16 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/InvoiceInfoMapper.java

@@ -0,0 +1,16 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.InvoiceInfo;
+import org.dromara.bill.domain.vo.InvoiceInfoVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 发票信息Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface InvoiceInfoMapper extends BaseMapperPlus<InvoiceInfo, InvoiceInfoVo> {
+    void deleteByStatementInvoiceId(@Param("id") Long id);
+}

+ 16 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementDetailMapper.java

@@ -0,0 +1,16 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementDetail;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 对账单交易明细Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface StatementDetailMapper extends BaseMapperPlus<StatementDetail, StatementDetailVo> {
+    void deleteByStatementOrderId(@Param("id") Long id);
+}

+ 18 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceDetailMapper.java

@@ -0,0 +1,18 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementInvoiceDetail;
+import org.dromara.bill.domain.vo.StatementInvoiceDetailVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 销售发票明细Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface StatementInvoiceDetailMapper extends BaseMapperPlus<StatementInvoiceDetail, StatementInvoiceDetailVo> {
+
+    void deleteByStatementInvoiceId(@Param("id") Long id);
+
+}

+ 16 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceMapper.java

@@ -0,0 +1,16 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementInvoice;
+import org.dromara.bill.domain.vo.StatementInvoiceVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 销售发票主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface StatementInvoiceMapper extends BaseMapperPlus<StatementInvoice, StatementInvoiceVo> {
+
+}

+ 18 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementInvoiceProductMapper.java

@@ -0,0 +1,18 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 销售发票商品Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface StatementInvoiceProductMapper extends BaseMapperPlus<StatementInvoiceProduct, StatementInvoiceProductVo> {
+
+    void deleteByStatementInvoiceId(@Param("id") Long id);
+
+}

+ 17 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementOrderMapper.java

@@ -0,0 +1,17 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementOrder;
+import org.dromara.bill.domain.vo.StatementOrderVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 对账单主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface StatementOrderMapper extends BaseMapperPlus<StatementOrder, StatementOrderVo> {
+
+
+}

+ 23 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/mapper/StatementProductMapper.java

@@ -0,0 +1,23 @@
+package org.dromara.bill.mapper;
+
+import org.apache.dubbo.remoting.http12.rest.Param;
+import org.dromara.bill.domain.StatementProduct;
+import org.dromara.bill.domain.dto.StatementOrderItem;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+import java.util.List;
+
+/**
+ * 对账单商品明细Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface StatementProductMapper extends BaseMapperPlus<StatementProduct, StatementProductVo> {
+
+    void deleteByStatementOrderId(@Param("id") Long id);
+
+    List<StatementProductVo> selectByStatementAndOrderIds(@Param("items") List<StatementOrderItem> items);
+
+}

+ 70 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IInvoiceInfoService.java

@@ -0,0 +1,70 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.InvoiceInfo;
+import org.dromara.bill.domain.vo.InvoiceInfoVo;
+import org.dromara.bill.domain.bo.InvoiceInfoBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 发票信息Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface IInvoiceInfoService extends IService<InvoiceInfo>{
+
+    /**
+     * 查询发票信息
+     *
+     * @param id 主键
+     * @return 发票信息
+     */
+    InvoiceInfoVo queryById(Long id);
+
+    /**
+     * 分页查询发票信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 发票信息分页列表
+     */
+    TableDataInfo<InvoiceInfoVo> queryPageList(InvoiceInfoBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的发票信息列表
+     *
+     * @param bo 查询条件
+     * @return 发票信息列表
+     */
+    List<InvoiceInfoVo> queryList(InvoiceInfoBo bo);
+
+    /**
+     * 新增发票信息
+     *
+     * @param bo 发票信息
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(InvoiceInfoBo bo);
+
+    /**
+     * 修改发票信息
+     *
+     * @param bo 发票信息
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(InvoiceInfoBo bo);
+
+    /**
+     * 校验并批量删除发票信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementDetailService.java

@@ -0,0 +1,70 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementDetail;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.bo.StatementDetailBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 对账单交易明细Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface IStatementDetailService extends IService<StatementDetail>{
+
+    /**
+     * 查询对账单交易明细
+     *
+     * @param id 主键
+     * @return 对账单交易明细
+     */
+    StatementDetailVo queryById(Long id);
+
+    /**
+     * 分页查询对账单交易明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单交易明细分页列表
+     */
+    TableDataInfo<StatementDetailVo> queryPageList(StatementDetailBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的对账单交易明细列表
+     *
+     * @param bo 查询条件
+     * @return 对账单交易明细列表
+     */
+    List<StatementDetailVo> queryList(StatementDetailBo bo);
+
+    /**
+     * 新增对账单交易明细
+     *
+     * @param bo 对账单交易明细
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementDetailBo bo);
+
+    /**
+     * 修改对账单交易明细
+     *
+     * @param bo 对账单交易明细
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementDetailBo bo);
+
+    /**
+     * 校验并批量删除对账单交易明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceDetailService.java

@@ -0,0 +1,70 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementInvoiceDetail;
+import org.dromara.bill.domain.vo.StatementInvoiceDetailVo;
+import org.dromara.bill.domain.bo.StatementInvoiceDetailBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 销售发票明细Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface IStatementInvoiceDetailService extends IService<StatementInvoiceDetail>{
+
+    /**
+     * 查询销售发票明细
+     *
+     * @param id 主键
+     * @return 销售发票明细
+     */
+    StatementInvoiceDetailVo queryById(Long id);
+
+    /**
+     * 分页查询销售发票明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票明细分页列表
+     */
+    TableDataInfo<StatementInvoiceDetailVo> queryPageList(StatementInvoiceDetailBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的销售发票明细列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票明细列表
+     */
+    List<StatementInvoiceDetailVo> queryList(StatementInvoiceDetailBo bo);
+
+    /**
+     * 新增销售发票明细
+     *
+     * @param bo 销售发票明细
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementInvoiceDetailBo bo);
+
+    /**
+     * 修改销售发票明细
+     *
+     * @param bo 销售发票明细
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementInvoiceDetailBo bo);
+
+    /**
+     * 校验并批量删除销售发票明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceProductService.java

@@ -0,0 +1,70 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.dromara.bill.domain.bo.StatementInvoiceProductBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 销售发票商品Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface IStatementInvoiceProductService extends IService<StatementInvoiceProduct>{
+
+    /**
+     * 查询销售发票商品
+     *
+     * @param id 主键
+     * @return 销售发票商品
+     */
+    StatementInvoiceProductVo queryById(Long id);
+
+    /**
+     * 分页查询销售发票商品列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票商品分页列表
+     */
+    TableDataInfo<StatementInvoiceProductVo> queryPageList(StatementInvoiceProductBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的销售发票商品列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票商品列表
+     */
+    List<StatementInvoiceProductVo> queryList(StatementInvoiceProductBo bo);
+
+    /**
+     * 新增销售发票商品
+     *
+     * @param bo 销售发票商品
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementInvoiceProductBo bo);
+
+    /**
+     * 修改销售发票商品
+     *
+     * @param bo 销售发票商品
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementInvoiceProductBo bo);
+
+    /**
+     * 校验并批量删除销售发票商品信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 79 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementInvoiceService.java

@@ -0,0 +1,79 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementInvoice;
+import org.dromara.bill.domain.bo.StatementOrderBo;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.dromara.bill.domain.vo.StatementInvoiceVo;
+import org.dromara.bill.domain.bo.StatementInvoiceBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 销售发票主Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface IStatementInvoiceService extends IService<StatementInvoice> {
+
+    /**
+     * 查询销售发票主
+     *
+     * @param id 主键
+     * @return 销售发票主
+     */
+    StatementInvoiceVo queryById(Long id);
+
+    /**
+     * 分页查询销售发票主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票主分页列表
+     */
+    TableDataInfo<StatementInvoiceVo> queryPageList(StatementInvoiceBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的销售发票主列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票主列表
+     */
+    List<StatementInvoiceVo> queryList(StatementInvoiceBo bo);
+
+    /**
+     * 新增销售发票主
+     *
+     * @param bo 销售发票主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementInvoiceBo bo);
+
+    /**
+     * 修改销售发票主
+     *
+     * @param bo 销售发票主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementInvoiceBo bo);
+
+    /**
+     * 修改状态
+     */
+    int updateStatus(StatementInvoiceBo bo);
+
+
+    /**
+     * 校验并批量删除销售发票主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 100 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementOrderService.java

@@ -0,0 +1,100 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementOrder;
+import org.dromara.bill.domain.dto.StatementOrderItem;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.vo.StatementOrderVo;
+import org.dromara.bill.domain.bo.StatementOrderBo;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 对账单主Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface IStatementOrderService extends IService<StatementOrder> {
+
+    /**
+     * 查询对账单主
+     *
+     * @param id 主键
+     * @return 对账单主
+     */
+    StatementOrderVo queryById(Long id);
+
+    /**
+     * 根据客户ID查询该客户所有的对账单订单明细
+     *
+     * @param customerId 客户ID
+     * @return 订单明细列表
+     */
+    List<StatementDetailVo> listDetailsByCustomerId(Long customerId);
+
+    /**
+     * 分页查询客户订单明细
+     *
+     * @param customerId 客户ID
+     * @param pageQuery  分页参数
+     * @return 分页结果
+     */
+    TableDataInfo<StatementDetailVo> listDetailsByCustomerIdPage(Long customerId, PageQuery pageQuery);
+
+
+    /**
+     * 分页查询对账单主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单主分页列表
+     */
+    TableDataInfo<StatementOrderVo> queryPageList(StatementOrderBo bo, PageQuery pageQuery);
+
+
+    TableDataInfo<StatementProductVo> getStatementProductList(List<StatementOrderItem> items);
+
+
+    /**
+     * 查询符合条件的对账单主列表
+     *
+     * @param bo 查询条件
+     * @return 对账单主列表
+     */
+    List<StatementOrderVo> queryList(StatementOrderBo bo);
+
+    /**
+     * 新增对账单主
+     *
+     * @param bo 对账单主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementOrderBo bo);
+
+    /**
+     * 修改对账单主
+     *
+     * @param bo 对账单主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementOrderBo bo);
+
+    /**
+     * 修改状态
+     */
+    int updateStatus(StatementOrderBo bo);
+
+    /**
+     * 校验并批量删除对账单主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/IStatementProductService.java

@@ -0,0 +1,70 @@
+package org.dromara.bill.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.bill.domain.StatementProduct;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.bill.domain.bo.StatementProductBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 对账单商品明细Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface IStatementProductService extends IService<StatementProduct>{
+
+    /**
+     * 查询对账单商品明细
+     *
+     * @param id 主键
+     * @return 对账单商品明细
+     */
+    StatementProductVo queryById(Long id);
+
+    /**
+     * 分页查询对账单商品明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单商品明细分页列表
+     */
+    TableDataInfo<StatementProductVo> queryPageList(StatementProductBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的对账单商品明细列表
+     *
+     * @param bo 查询条件
+     * @return 对账单商品明细列表
+     */
+    List<StatementProductVo> queryList(StatementProductBo bo);
+
+    /**
+     * 新增对账单商品明细
+     *
+     * @param bo 对账单商品明细
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(StatementProductBo bo);
+
+    /**
+     * 修改对账单商品明细
+     *
+     * @param bo 对账单商品明细
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(StatementProductBo bo);
+
+    /**
+     * 校验并批量删除对账单商品明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 141 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/InvoiceInfoServiceImpl.java

@@ -0,0 +1,141 @@
+package org.dromara.bill.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.domain.bo.InvoiceInfoBo;
+import org.dromara.bill.domain.vo.InvoiceInfoVo;
+import org.dromara.bill.domain.InvoiceInfo;
+import org.dromara.bill.mapper.InvoiceInfoMapper;
+import org.dromara.bill.service.IInvoiceInfoService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 发票信息Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class InvoiceInfoServiceImpl  extends ServiceImpl<InvoiceInfoMapper, InvoiceInfo> implements IInvoiceInfoService {
+
+    private final InvoiceInfoMapper baseMapper;
+
+    /**
+     * 查询发票信息
+     *
+     * @param id 主键
+     * @return 发票信息
+     */
+    @Override
+    public InvoiceInfoVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询发票信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 发票信息分页列表
+     */
+    @Override
+    public TableDataInfo<InvoiceInfoVo> queryPageList(InvoiceInfoBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<InvoiceInfo> lqw = buildQueryWrapper(bo);
+        Page<InvoiceInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的发票信息列表
+     *
+     * @param bo 查询条件
+     * @return 发票信息列表
+     */
+    @Override
+    public List<InvoiceInfoVo> queryList(InvoiceInfoBo bo) {
+        LambdaQueryWrapper<InvoiceInfo> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<InvoiceInfo> buildQueryWrapper(InvoiceInfoBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<InvoiceInfo> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(InvoiceInfo::getId);
+        lqw.eq(bo.getStatementInvoiceId() != null, InvoiceInfo::getStatementInvoiceId, bo.getStatementInvoiceId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementInvoiceNo()), InvoiceInfo::getStatementInvoiceNo, bo.getStatementInvoiceNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceType()), InvoiceInfo::getInvoiceType, bo.getInvoiceType());
+        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceCode()), InvoiceInfo::getInvoiceCode, bo.getInvoiceCode());
+        lqw.eq(bo.getInvoiceAmount() != null, InvoiceInfo::getInvoiceAmount, bo.getInvoiceAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceAnnex()), InvoiceInfo::getInvoiceAnnex, bo.getInvoiceAnnex());
+        lqw.like(StringUtils.isNotBlank(bo.getCompanyName()), InvoiceInfo::getCompanyName, bo.getCompanyName());
+        lqw.eq(bo.getInvoiceDate() != null, InvoiceInfo::getInvoiceDate, bo.getInvoiceDate());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), InvoiceInfo::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增发票信息
+     *
+     * @param bo 发票信息
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(InvoiceInfoBo bo) {
+        InvoiceInfo add = MapstructUtils.convert(bo, InvoiceInfo.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改发票信息
+     *
+     * @param bo 发票信息
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(InvoiceInfoBo bo) {
+        InvoiceInfo update = MapstructUtils.convert(bo, InvoiceInfo.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(InvoiceInfo entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除发票信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 143 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementDetailServiceImpl.java

@@ -0,0 +1,143 @@
+package org.dromara.bill.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.domain.bo.StatementDetailBo;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.StatementDetail;
+import org.dromara.bill.mapper.StatementDetailMapper;
+import org.dromara.bill.service.IStatementDetailService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 对账单交易明细Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementDetailServiceImpl extends ServiceImpl<StatementDetailMapper, StatementDetail> implements IStatementDetailService {
+
+    private final StatementDetailMapper baseMapper;
+
+    /**
+     * 查询对账单交易明细
+     *
+     * @param id 主键
+     * @return 对账单交易明细
+     */
+    @Override
+    public StatementDetailVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询对账单交易明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单交易明细分页列表
+     */
+    @Override
+    public TableDataInfo<StatementDetailVo> queryPageList(StatementDetailBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementDetail> lqw = buildQueryWrapper(bo);
+        Page<StatementDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的对账单交易明细列表
+     *
+     * @param bo 查询条件
+     * @return 对账单交易明细列表
+     */
+    @Override
+    public List<StatementDetailVo> queryList(StatementDetailBo bo) {
+        LambdaQueryWrapper<StatementDetail> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementDetail> buildQueryWrapper(StatementDetailBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementDetail> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementDetail::getId);
+        lqw.eq(bo.getStatementOrderId() != null, StatementDetail::getStatementOrderId, bo.getStatementOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementOrderNo()), StatementDetail::getStatementOrderNo, bo.getStatementOrderNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), StatementDetail::getType, bo.getType());
+        lqw.eq(bo.getOrderId() != null, StatementDetail::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), StatementDetail::getOrderNo, bo.getOrderNo());
+        lqw.eq(bo.getAmount() != null, StatementDetail::getAmount, bo.getAmount());
+        lqw.eq(bo.getOrderTime() != null, StatementDetail::getOrderTime, bo.getOrderTime());
+        lqw.eq(bo.getSigningDate() != null, StatementDetail::getSigningDate, bo.getSigningDate());
+        lqw.eq(bo.getUserId() != null, StatementDetail::getUserId, bo.getUserId());
+        lqw.eq(StringUtils.isNotBlank(bo.getUserDept()), StatementDetail::getUserDept, bo.getUserDept());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementDetail::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增对账单交易明细
+     *
+     * @param bo 对账单交易明细
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(StatementDetailBo bo) {
+        StatementDetail add = MapstructUtils.convert(bo, StatementDetail.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改对账单交易明细
+     *
+     * @param bo 对账单交易明细
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(StatementDetailBo bo) {
+        StatementDetail update = MapstructUtils.convert(bo, StatementDetail.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementDetail entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除对账单交易明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 148 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceDetailServiceImpl.java

@@ -0,0 +1,148 @@
+package org.dromara.bill.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.domain.bo.StatementInvoiceDetailBo;
+import org.dromara.bill.domain.vo.StatementInvoiceDetailVo;
+import org.dromara.bill.domain.StatementInvoiceDetail;
+import org.dromara.bill.mapper.StatementInvoiceDetailMapper;
+import org.dromara.bill.service.IStatementInvoiceDetailService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 销售发票明细Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementInvoiceDetailServiceImpl  extends ServiceImpl<StatementInvoiceDetailMapper, StatementInvoiceDetail> implements IStatementInvoiceDetailService {
+
+    private final StatementInvoiceDetailMapper baseMapper;
+
+    /**
+     * 查询销售发票明细
+     *
+     * @param id 主键
+     * @return 销售发票明细
+     */
+    @Override
+    public StatementInvoiceDetailVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询销售发票明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票明细分页列表
+     */
+    @Override
+    public TableDataInfo<StatementInvoiceDetailVo> queryPageList(StatementInvoiceDetailBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementInvoiceDetail> lqw = buildQueryWrapper(bo);
+        Page<StatementInvoiceDetailVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的销售发票明细列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票明细列表
+     */
+    @Override
+    public List<StatementInvoiceDetailVo> queryList(StatementInvoiceDetailBo bo) {
+        LambdaQueryWrapper<StatementInvoiceDetail> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementInvoiceDetail> buildQueryWrapper(StatementInvoiceDetailBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementInvoiceDetail> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementInvoiceDetail::getId);
+        lqw.eq(bo.getStatementInvoiceId() != null, StatementInvoiceDetail::getStatementInvoiceId, bo.getStatementInvoiceId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementInvoiceNo()), StatementInvoiceDetail::getStatementInvoiceNo, bo.getStatementInvoiceNo());
+        lqw.eq(bo.getStatementAmount() != null, StatementInvoiceDetail::getStatementAmount, bo.getStatementAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderType()), StatementInvoiceDetail::getOrderType, bo.getOrderType());
+        lqw.eq(bo.getOrderId() != null, StatementInvoiceDetail::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), StatementInvoiceDetail::getOrderNo, bo.getOrderNo());
+        lqw.eq(bo.getOrderAmount() != null, StatementInvoiceDetail::getOrderAmount, bo.getOrderAmount());
+        lqw.eq(bo.getOrderTime() != null, StatementInvoiceDetail::getOrderTime, bo.getOrderTime());
+        lqw.eq(bo.getSigningDate() != null, StatementInvoiceDetail::getSigningDate, bo.getSigningDate());
+        lqw.eq(bo.getUserId() != null, StatementInvoiceDetail::getUserId, bo.getUserId());
+        lqw.like(StringUtils.isNotBlank(bo.getUserName()), StatementInvoiceDetail::getUserName, bo.getUserName());
+        lqw.eq(bo.getUserDeptId() != null, StatementInvoiceDetail::getUserDeptId, bo.getUserDeptId());
+        lqw.eq(StringUtils.isNotBlank(bo.getUserDept()), StatementInvoiceDetail::getUserDept, bo.getUserDept());
+        lqw.eq(bo.getStatementOrderId() != null, StatementInvoiceDetail::getStatementOrderId, bo.getStatementOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementOrderNo()), StatementInvoiceDetail::getStatementOrderNo, bo.getStatementOrderNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementInvoiceDetail::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增销售发票明细
+     *
+     * @param bo 销售发票明细
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(StatementInvoiceDetailBo bo) {
+        StatementInvoiceDetail add = MapstructUtils.convert(bo, StatementInvoiceDetail.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改销售发票明细
+     *
+     * @param bo 销售发票明细
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(StatementInvoiceDetailBo bo) {
+        StatementInvoiceDetail update = MapstructUtils.convert(bo, StatementInvoiceDetail.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementInvoiceDetail entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除销售发票明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 147 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceProductServiceImpl.java

@@ -0,0 +1,147 @@
+package org.dromara.bill.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.domain.bo.StatementInvoiceProductBo;
+import org.dromara.bill.domain.vo.StatementInvoiceProductVo;
+import org.dromara.bill.domain.StatementInvoiceProduct;
+import org.dromara.bill.mapper.StatementInvoiceProductMapper;
+import org.dromara.bill.service.IStatementInvoiceProductService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 销售发票商品Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementInvoiceProductServiceImpl  extends ServiceImpl<StatementInvoiceProductMapper, StatementInvoiceProduct> implements IStatementInvoiceProductService {
+
+    private final StatementInvoiceProductMapper baseMapper;
+
+    /**
+     * 查询销售发票商品
+     *
+     * @param id 主键
+     * @return 销售发票商品
+     */
+    @Override
+    public StatementInvoiceProductVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询销售发票商品列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票商品分页列表
+     */
+    @Override
+    public TableDataInfo<StatementInvoiceProductVo> queryPageList(StatementInvoiceProductBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementInvoiceProduct> lqw = buildQueryWrapper(bo);
+        Page<StatementInvoiceProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的销售发票商品列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票商品列表
+     */
+    @Override
+    public List<StatementInvoiceProductVo> queryList(StatementInvoiceProductBo bo) {
+        LambdaQueryWrapper<StatementInvoiceProduct> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementInvoiceProduct> buildQueryWrapper(StatementInvoiceProductBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementInvoiceProduct> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementInvoiceProduct::getId);
+        lqw.eq(bo.getStatementInvoiceId() != null, StatementInvoiceProduct::getStatementInvoiceId, bo.getStatementInvoiceId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementInvoiceNo()), StatementInvoiceProduct::getStatementInvoiceNo, bo.getStatementInvoiceNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), StatementInvoiceProduct::getType, bo.getType());
+        lqw.eq(bo.getOrderId() != null, StatementInvoiceProduct::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), StatementInvoiceProduct::getOrderNo, bo.getOrderNo());
+        lqw.eq(bo.getCategoryId() != null, StatementInvoiceProduct::getCategoryId, bo.getCategoryId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCategoryNo()), StatementInvoiceProduct::getCategoryNo, bo.getCategoryNo());
+        lqw.eq(bo.getProductId() != null, StatementInvoiceProduct::getProductId, bo.getProductId());
+        lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), StatementInvoiceProduct::getProductNo, bo.getProductNo());
+        lqw.like(StringUtils.isNotBlank(bo.getItemName()), StatementInvoiceProduct::getItemName, bo.getItemName());
+        lqw.eq(bo.getUnitId() != null, StatementInvoiceProduct::getUnitId, bo.getUnitId());
+        lqw.like(StringUtils.isNotBlank(bo.getUnitName()), StatementInvoiceProduct::getUnitName, bo.getUnitName());
+        lqw.eq(bo.getQuantity() != null, StatementInvoiceProduct::getQuantity, bo.getQuantity());
+        lqw.eq(bo.getUnitPrice() != null, StatementInvoiceProduct::getUnitPrice, bo.getUnitPrice());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementInvoiceProduct::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增销售发票商品
+     *
+     * @param bo 销售发票商品
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(StatementInvoiceProductBo bo) {
+        StatementInvoiceProduct add = MapstructUtils.convert(bo, StatementInvoiceProduct.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改销售发票商品
+     *
+     * @param bo 销售发票商品
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(StatementInvoiceProductBo bo) {
+        StatementInvoiceProduct update = MapstructUtils.convert(bo, StatementInvoiceProduct.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementInvoiceProduct entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除销售发票商品信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 270 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementInvoiceServiceImpl.java

@@ -0,0 +1,270 @@
+package org.dromara.bill.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.bill.domain.*;
+import org.dromara.bill.domain.bo.*;
+import org.dromara.bill.domain.vo.*;
+import org.dromara.bill.mapper.InvoiceInfoMapper;
+import org.dromara.bill.mapper.StatementInvoiceDetailMapper;
+import org.dromara.bill.mapper.StatementInvoiceProductMapper;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.mapper.StatementInvoiceMapper;
+import org.dromara.bill.service.IStatementInvoiceService;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 销售发票主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementInvoiceServiceImpl extends ServiceImpl<StatementInvoiceMapper, StatementInvoice> implements IStatementInvoiceService {
+
+    private final InvoiceInfoMapper invoiceInfoMapper;
+
+    private final StatementInvoiceMapper baseMapper;
+
+    private final StatementInvoiceDetailMapper statementInvoiceDetailMapper;
+
+    private final StatementInvoiceProductMapper statementInvoiceProductMapper;
+
+
+    /**
+     * 查询销售发票主
+     *
+     * @param id 主键
+     * @return 销售发票主
+     */
+    @Override
+    public StatementInvoiceVo queryById(Long id) {
+
+        // 1. 查询主表
+        StatementInvoiceVo invoiceVo = baseMapper.selectVoById(id);
+        if (invoiceVo == null) {
+            return null;
+        }
+
+        // 2. 查询所有明细(按 statement_invoice_id)
+        LambdaQueryWrapper<StatementInvoiceDetail> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.eq(StatementInvoiceDetail::getStatementInvoiceId, id);
+        List<StatementInvoiceDetailVo> detailVos = statementInvoiceDetailMapper.selectList(detailWrapper).stream()
+            .map(d -> MapstructUtils.convert(d, StatementInvoiceDetailVo.class))
+            .collect(Collectors.toList());
+
+        // 3. 查询所有商品(按 statement_invoice_id)
+        LambdaQueryWrapper<StatementInvoiceProduct> productWrapper = new LambdaQueryWrapper<>();
+        productWrapper.eq(StatementInvoiceProduct::getStatementInvoiceId, id);
+        List<StatementInvoiceProductVo> productVos = statementInvoiceProductMapper.selectList(productWrapper).stream()
+            .map(p -> MapstructUtils.convert(p, StatementInvoiceProductVo.class))
+            .collect(Collectors.toList());
+
+        // 4. 查询所有发票(按 statement_invoice_id)
+        LambdaQueryWrapper<InvoiceInfo> invoiceInfoWrapper = new LambdaQueryWrapper<>();
+        invoiceInfoWrapper.eq(InvoiceInfo::getStatementInvoiceId, id);
+        List<InvoiceInfoVo> invoiceInfoVos = invoiceInfoMapper.selectList(invoiceInfoWrapper).stream()
+            .map(p -> MapstructUtils.convert(p, InvoiceInfoVo.class))
+            .collect(Collectors.toList());
+
+        // 5. 装填到 VO
+        invoiceVo.setDetailList(detailVos);
+        invoiceVo.setProductList(productVos);
+        invoiceVo.setInvoiceList(invoiceInfoVos);
+
+
+        return invoiceVo;
+    }
+
+    /**
+     * 分页查询销售发票主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 销售发票主分页列表
+     */
+    @Override
+    public TableDataInfo<StatementInvoiceVo> queryPageList(StatementInvoiceBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementInvoice> lqw = buildQueryWrapper(bo);
+        Page<StatementInvoiceVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的销售发票主列表
+     *
+     * @param bo 查询条件
+     * @return 销售发票主列表
+     */
+    @Override
+    public List<StatementInvoiceVo> queryList(StatementInvoiceBo bo) {
+        LambdaQueryWrapper<StatementInvoice> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementInvoice> buildQueryWrapper(StatementInvoiceBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementInvoice> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementInvoice::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementInvoiceNo()), StatementInvoice::getStatementInvoiceNo, bo.getStatementInvoiceNo());
+        lqw.eq(bo.getCustomerId() != null, StatementInvoice::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCustomerNo()), StatementInvoice::getCustomerNo, bo.getCustomerNo());
+        lqw.like(StringUtils.isNotBlank(bo.getCustomerName()), StatementInvoice::getCustomerName, bo.getCustomerName());
+        lqw.eq(bo.getInvoiceAmount() != null, StatementInvoice::getInvoiceAmount, bo.getInvoiceAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getInvoiceStatus()), StatementInvoice::getInvoiceStatus, bo.getInvoiceStatus());
+        lqw.eq(bo.getInvoiceTime() != null, StatementInvoice::getInvoiceTime, bo.getInvoiceTime());
+        lqw.eq(StringUtils.isNotBlank(bo.getRejectRemark()), StatementInvoice::getRejectRemark, bo.getRejectRemark());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementInvoice::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增销售发票主
+     *
+     * @param bo 销售发票主
+     * @return 是否新增成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(StatementInvoiceBo bo) {
+        String statementInvoiceNo = SequenceUtils.generateOrderCode("BL");
+        bo.setStatementInvoiceNo(statementInvoiceNo);
+        StatementInvoice entity = MapstructUtils.convert(bo, StatementInvoice.class);
+        validEntityBeforeSave(entity);
+        boolean success = this.save(entity);
+        if (success) {
+            bo.setId(entity.getId());
+            saveDetailsAndProductsAndInvoiceInfos(bo);
+        }
+        return success;
+    }
+
+    /**
+     * 修改销售发票主
+     *
+     * @param bo 销售发票主
+     * @return 是否修改成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateByBo(StatementInvoiceBo bo) {
+        StatementInvoice entity = MapstructUtils.convert(bo, StatementInvoice.class);
+        validEntityBeforeSave(entity);
+
+        // 先删除旧数据
+        deleteDetailsAndProductsAndInvoiceInfos(entity.getId());
+
+        // 再保存新数据
+        boolean success = this.updateById(entity);
+        if (success && CollectionUtil.isNotEmpty(bo.getDetailList())) {
+            saveDetailsAndProductsAndInvoiceInfos(bo);
+        }
+        return success;
+    }
+
+    /**
+     * 公共方法:保存明细和商品 发票
+     */
+    private void saveDetailsAndProductsAndInvoiceInfos(StatementInvoiceBo bo) {
+        List<StatementInvoiceDetail> details = new ArrayList<>();
+        List<StatementInvoiceProduct> products = new ArrayList<>();
+        List<InvoiceInfo> invoiceInfoList = new ArrayList<>();
+
+        // 1. 先保存所有明细
+        if (CollectionUtil.isNotEmpty(bo.getDetailList())) {
+            for (StatementInvoiceDetailBo detailBo : bo.getDetailList()) {
+                StatementInvoiceDetail detail = MapstructUtils.convert(detailBo, StatementInvoiceDetail.class);
+                detail.setStatementInvoiceId(bo.getId());
+                detail.setStatementInvoiceNo(bo.getStatementInvoiceNo());
+                details.add(detail);
+            }
+        }
+
+        if (CollectionUtil.isNotEmpty(bo.getProductList())) {
+            for (StatementInvoiceProductBo productBo : bo.getProductList()) {
+                StatementInvoiceProduct product = MapstructUtils.convert(productBo, StatementInvoiceProduct.class);
+                product.setStatementInvoiceId(bo.getId());
+                product.setStatementInvoiceNo(bo.getStatementInvoiceNo());
+                products.add(product);
+            }
+        }
+        if (CollectionUtil.isNotEmpty(bo.getInvoiceList())) {
+            for (InvoiceInfoBo invoiceInfoBo : bo.getInvoiceList()) {
+                InvoiceInfo invoiceInfo = MapstructUtils.convert(invoiceInfoBo, InvoiceInfo.class);
+                invoiceInfo.setStatementInvoiceId(bo.getId());
+                invoiceInfo.setStatementInvoiceNo(bo.getStatementInvoiceNo());
+                invoiceInfoList.add(invoiceInfo);
+            }
+        }
+        if (!invoiceInfoList.isEmpty()) {
+            invoiceInfoMapper.insertBatch(invoiceInfoList);
+        }
+        if (!details.isEmpty()) {
+            statementInvoiceDetailMapper.insertBatch(details);
+        }
+        if (!products.isEmpty()) {
+            statementInvoiceProductMapper.insertBatch(products);
+        }
+    }
+
+    /**
+     * 公共方法:删除明细和商品
+     */
+    private void deleteDetailsAndProductsAndInvoiceInfos(Long statementInvoiceId) {
+        statementInvoiceDetailMapper.deleteByStatementInvoiceId(statementInvoiceId);
+        statementInvoiceProductMapper.deleteByStatementInvoiceId(statementInvoiceId);
+        invoiceInfoMapper.deleteByStatementInvoiceId(statementInvoiceId);
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateStatus(StatementInvoiceBo bo) {
+        StatementInvoice invoice = new StatementInvoice();
+        invoice.setId(bo.getId());
+        invoice.setInvoiceStatus(bo.getInvoiceStatus());
+        return baseMapper.updateById(invoice);
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementInvoice entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除销售发票主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 368 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementOrderServiceImpl.java

@@ -0,0 +1,368 @@
+package org.dromara.bill.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.bill.domain.StatementDetail;
+import org.dromara.bill.domain.StatementOrder;
+import org.dromara.bill.domain.StatementProduct;
+import org.dromara.bill.domain.bo.StatementDetailBo;
+import org.dromara.bill.domain.bo.StatementOrderBo;
+import org.dromara.bill.domain.bo.StatementProductBo;
+import org.dromara.bill.domain.dto.StatementOrderItem;
+import org.dromara.bill.domain.vo.StatementDetailVo;
+import org.dromara.bill.domain.vo.StatementOrderVo;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.bill.mapper.StatementDetailMapper;
+import org.dromara.bill.mapper.StatementOrderMapper;
+import org.dromara.bill.mapper.StatementProductMapper;
+import org.dromara.bill.service.IStatementOrderService;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.redis.utils.SequenceUtils;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 对账单主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementOrderServiceImpl extends ServiceImpl<StatementOrderMapper, StatementOrder> implements IStatementOrderService {
+
+    private final StatementOrderMapper baseMapper;
+
+    private final StatementOrderMapper statementOrderMapper;
+
+    private final StatementDetailMapper statementDetailMapper;
+
+    private final StatementProductMapper statementProductMapper;
+
+    /**
+     * 查询对账单主
+     *
+     * @param id 主键
+     * @return 对账单主
+     */
+    @Override
+    public StatementOrderVo queryById(Long id) {
+        // 1. 查询主表
+        StatementOrderVo orderVo = baseMapper.selectVoById(id);
+        if (orderVo == null) {
+            return null;
+        }
+
+        // 2. 查询所有明细(按 statement_order_id)
+        LambdaQueryWrapper<StatementDetail> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.eq(StatementDetail::getStatementOrderId, id);
+        List<StatementDetailVo> detailVos = statementDetailMapper.selectList(detailWrapper).stream()
+            .map(d -> MapstructUtils.convert(d, StatementDetailVo.class))
+            .collect(Collectors.toList());
+
+        // 3. 查询所有商品(按 statement_order_id)
+        LambdaQueryWrapper<StatementProduct> productWrapper = new LambdaQueryWrapper<>();
+        productWrapper.eq(StatementProduct::getStatementOrderId, id);
+        List<StatementProductVo> productVos = statementProductMapper.selectList(productWrapper).stream()
+            .map(p -> MapstructUtils.convert(p, StatementProductVo.class))
+            .collect(Collectors.toList());
+
+        // 4. 装填到 VO
+        orderVo.setDetailList(detailVos);
+        orderVo.setProductList(productVos);
+
+        return orderVo;
+    }
+
+    @Override
+    public List<StatementDetailVo> listDetailsByCustomerId(Long customerId) {
+        if (customerId == null) {
+            return Collections.emptyList();
+        }
+
+        // 第一步:先查出该客户的所有对账单 ID
+        LambdaQueryWrapper<StatementOrder> orderWrapper = new LambdaQueryWrapper<>();
+        orderWrapper.eq(StatementOrder::getCustomerId, customerId)
+            .eq(StatementOrder::getDelFlag, "0"); // 未删除的对账单
+
+        List<Long> statementOrderIds = baseMapper.selectList(orderWrapper).stream()
+            .map(StatementOrder::getId)
+            .collect(Collectors.toList());
+
+        if (statementOrderIds.isEmpty()) {
+            return Collections.emptyList();
+        }
+
+        // 第二步:根据这些对账单ID,查询所有明细
+        LambdaQueryWrapper<StatementDetail> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.in(StatementDetail::getStatementOrderId, statementOrderIds)
+            .eq(StatementDetail::getDelFlag, "0"); // 未删除的明细
+
+        List<StatementDetail> details = statementDetailMapper.selectList(detailWrapper);
+
+        return details.stream()
+            .map(d -> MapstructUtils.convert(d, StatementDetailVo.class))
+            .collect(Collectors.toList());
+    }
+
+    @Override
+    public TableDataInfo<StatementDetailVo> listDetailsByCustomerIdPage(Long customerId, PageQuery pageQuery) {
+        if (customerId == null) {
+            return TableDataInfo.build(new Page<>(0, 0));
+        }
+
+        // 查询客户的所有有效对账单
+        LambdaQueryWrapper<StatementOrder> orderWrapper = new LambdaQueryWrapper<>();
+        orderWrapper.eq(StatementOrder::getCustomerId, customerId)
+            .eq(StatementOrder::getDelFlag, "0");
+
+        List<StatementOrder> statementOrders = baseMapper.selectList(orderWrapper);
+        if (statementOrders.isEmpty()) {
+            return TableDataInfo.build(new Page<>(0, 0));
+        }
+
+        List<Long> statementOrderIds = statementOrders.stream()
+            .map(StatementOrder::getId)
+            .collect(Collectors.toList());
+
+        // 构建 orderId -> amount 映射
+        Map<Long, BigDecimal> orderIdToAmountMap = statementOrders.stream()
+            .collect(Collectors.toMap(
+                StatementOrder::getId,
+                StatementOrder::getAmount,
+                (v1, v2) -> v1
+            ));
+
+        // 查询明细(分页)
+        LambdaQueryWrapper<StatementDetail> detailWrapper = new LambdaQueryWrapper<>();
+        detailWrapper.in(StatementDetail::getStatementOrderId, statementOrderIds)
+            .eq(StatementDetail::getDelFlag, "0");
+
+        Page<StatementDetailVo> pageResult = statementDetailMapper.selectVoPage(pageQuery.build(), detailWrapper);
+
+        // 填充 statementAmount
+        pageResult.getRecords().forEach(vo -> {
+            Long orderId = vo.getStatementOrderId();
+            if (orderId != null) {
+                vo.setStatementAmount(orderIdToAmountMap.get(orderId));
+            }
+        });
+
+        return TableDataInfo.build(pageResult);
+    }
+
+    @Override
+    public TableDataInfo<StatementProductVo> getStatementProductList(List<StatementOrderItem> items) {
+        if (CollectionUtils.isEmpty(items)) {
+            return TableDataInfo.build(Collections.emptyList());
+        }
+        //:使用自定义 SQL 实现 WHERE (a,b) IN ((1,100),(2,200))
+        List<StatementProductVo> productVos = statementProductMapper.selectByStatementAndOrderIds(items);
+
+        return TableDataInfo.build(productVos);
+    }
+
+    /**
+     * 分页查询对账单主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单主分页列表
+     */
+    @Override
+    public TableDataInfo<StatementOrderVo> queryPageList(StatementOrderBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementOrder> lqw = buildQueryWrapper(bo);
+        Page<StatementOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的对账单主列表
+     *
+     * @param bo 查询条件
+     * @return 对账单主列表
+     */
+    @Override
+    public List<StatementOrderVo> queryList(StatementOrderBo bo) {
+        LambdaQueryWrapper<StatementOrder> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementOrder> buildQueryWrapper(StatementOrderBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementOrder> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementOrder::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementOrderNo()), StatementOrder::getStatementOrderNo, bo.getStatementOrderNo());
+        lqw.eq(bo.getCustomerId() != null, StatementOrder::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCustomerNo()), StatementOrder::getCustomerNo, bo.getCustomerNo());
+        lqw.like(StringUtils.isNotBlank(bo.getCustomerName()), StatementOrder::getCustomerName, bo.getCustomerName());
+        lqw.eq(bo.getAmount() != null, StatementOrder::getAmount, bo.getAmount());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementSelf()), StatementOrder::getStatementSelf, bo.getStatementSelf());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementSelfPhone()), StatementOrder::getStatementSelfPhone, bo.getStatementSelfPhone());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementStatus()), StatementOrder::getStatementStatus, bo.getStatementStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsPaymentStatus()), StatementOrder::getIsPaymentStatus, bo.getIsPaymentStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsInvoiceStatus()), StatementOrder::getIsInvoiceStatus, bo.getIsInvoiceStatus());
+        lqw.eq(bo.getStatementDate() != null, StatementOrder::getStatementDate, bo.getStatementDate());
+        lqw.eq(StringUtils.isNotBlank(bo.getAnnexAddress()), StatementOrder::getAnnexAddress, bo.getAnnexAddress());
+        lqw.eq(StringUtils.isNotBlank(bo.getRejectRemark()), StatementOrder::getRejectRemark, bo.getRejectRemark());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementOrder::getPlatformCode, bo.getPlatformCode());
+        if (params != null) {
+            lqw.between(params.get("beginTime") != null && params.get("endTime") != null,
+                StatementOrder::getStatementDate, params.get("beginTime"), params.get("endTime"));
+        }
+        return lqw;
+    }
+
+    /**
+     * 新增对账单主
+     *
+     * @param bo 对账单主
+     * @return 是否新增成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean insertByBo(StatementOrderBo bo) {
+        String statementOrderNo = SequenceUtils.generateOrderCode("RC");
+        bo.setStatementOrderNo(statementOrderNo);
+        StatementOrder entity = MapstructUtils.convert(bo, StatementOrder.class);
+        validEntityBeforeSave(entity);
+        boolean success = this.save(entity);
+        if (success) {
+            bo.setId(entity.getId());
+            saveDetailsAndProducts(bo);
+        }
+        return success;
+    }
+
+
+    /**
+     * 修改对账单主
+     *
+     * @param bo 对账单主
+     * @return 是否修改成功
+     */
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Boolean updateByBo(StatementOrderBo bo) {
+        StatementOrder entity = MapstructUtils.convert(bo, StatementOrder.class);
+        validEntityBeforeSave(entity);
+
+        // 先删除旧数据
+        deleteDetailsAndProducts(entity.getId());
+
+        // 再保存新数据
+        boolean success = this.updateById(entity);
+        if (success && CollectionUtil.isNotEmpty(bo.getDetailList())) {
+            saveDetailsAndProducts(bo);
+        }
+        return success;
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 信息
+     * @return 结果
+     */
+    @Override
+    public int updateStatus(StatementOrderBo bo) {
+        StatementOrder order = new StatementOrder();
+        order.setId(bo.getId());
+        order.setStatementStatus(bo.getStatementStatus());
+        return baseMapper.updateById(order);
+    }
+
+    /**
+     * 公共方法:保存明细和商品
+     */
+    private void saveDetailsAndProducts(StatementOrderBo bo) {
+        List<StatementDetail> details = new ArrayList<>();
+        List<StatementProduct> products = new ArrayList<>();
+
+        // 1. 先保存所有明细
+        if (CollectionUtil.isNotEmpty(bo.getDetailList())) {
+            for (StatementDetailBo detailBo : bo.getDetailList()) {
+                StatementDetail detail = MapstructUtils.convert(detailBo, StatementDetail.class);
+                detail.setStatementOrderId(bo.getId());
+                detail.setStatementOrderNo(bo.getStatementOrderNo());
+                details.add(detail);
+            }
+        }
+
+        // 2. 按 orderId 分组商品
+        Map<Long, List<StatementProductBo>> productGroupByOrderId =
+            CollectionUtil.isNotEmpty(bo.getProductList())
+                ? bo.getProductList().stream()
+                .collect(Collectors.groupingBy(StatementProductBo::getOrderId))
+                : Collections.emptyMap();
+
+        // 3. 为每个明细,找到对应的商品
+        for (StatementDetailBo detailBo : bo.getDetailList()) {
+            Long originalOrderId = detailBo.getOrderId();
+            List<StatementProductBo> productListForThisOrder = productGroupByOrderId.get(originalOrderId);
+
+            if (CollectionUtil.isNotEmpty(productListForThisOrder)) {
+                for (StatementProductBo productBo : productListForThisOrder) {
+                    StatementProduct product = MapstructUtils.convert(productBo, StatementProduct.class);
+                    product.setStatementOrderId(bo.getId());
+                    product.setStatementOrderNo(bo.getStatementOrderNo());
+                    product.setOrderId(originalOrderId);
+                    product.setOrderNo(detailBo.getOrderNo());
+                    products.add(product);
+                }
+            }
+        }
+
+        if (!details.isEmpty()) {
+            statementDetailMapper.insertBatch(details);
+        }
+        if (!products.isEmpty()) {
+            statementProductMapper.insertBatch(products);
+        }
+    }
+
+    /**
+     * 公共方法:删除明细和商品
+     */
+    private void deleteDetailsAndProducts(Long statementOrderId) {
+        statementDetailMapper.deleteByStatementOrderId(statementOrderId);
+        statementProductMapper.deleteByStatementOrderId(statementOrderId);
+    }
+
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementOrder entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除对账单主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 147 - 0
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/service/impl/StatementProductServiceImpl.java

@@ -0,0 +1,147 @@
+package org.dromara.bill.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.bill.domain.bo.StatementProductBo;
+import org.dromara.bill.domain.vo.StatementProductVo;
+import org.dromara.bill.domain.StatementProduct;
+import org.dromara.bill.mapper.StatementProductMapper;
+import org.dromara.bill.service.IStatementProductService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 对账单商品明细Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class StatementProductServiceImpl  extends ServiceImpl<StatementProductMapper, StatementProduct> implements IStatementProductService {
+
+    private final StatementProductMapper baseMapper;
+
+    /**
+     * 查询对账单商品明细
+     *
+     * @param id 主键
+     * @return 对账单商品明细
+     */
+    @Override
+    public StatementProductVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询对账单商品明细列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 对账单商品明细分页列表
+     */
+    @Override
+    public TableDataInfo<StatementProductVo> queryPageList(StatementProductBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<StatementProduct> lqw = buildQueryWrapper(bo);
+        Page<StatementProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的对账单商品明细列表
+     *
+     * @param bo 查询条件
+     * @return 对账单商品明细列表
+     */
+    @Override
+    public List<StatementProductVo> queryList(StatementProductBo bo) {
+        LambdaQueryWrapper<StatementProduct> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<StatementProduct> buildQueryWrapper(StatementProductBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<StatementProduct> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(StatementProduct::getId);
+        lqw.eq(bo.getStatementOrderId() != null, StatementProduct::getStatementOrderId, bo.getStatementOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatementOrderNo()), StatementProduct::getStatementOrderNo, bo.getStatementOrderNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), StatementProduct::getType, bo.getType());
+        lqw.eq(bo.getOrderId() != null, StatementProduct::getOrderId, bo.getOrderId());
+        lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), StatementProduct::getOrderNo, bo.getOrderNo());
+        lqw.eq(bo.getCategoryId() != null, StatementProduct::getCategoryId, bo.getCategoryId());
+        lqw.eq(StringUtils.isNotBlank(bo.getCategoryNo()), StatementProduct::getCategoryNo, bo.getCategoryNo());
+        lqw.eq(bo.getProductId() != null, StatementProduct::getProductId, bo.getProductId());
+        lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), StatementProduct::getProductNo, bo.getProductNo());
+        lqw.like(StringUtils.isNotBlank(bo.getItemName()), StatementProduct::getItemName, bo.getItemName());
+        lqw.eq(bo.getUnitId() != null, StatementProduct::getUnitId, bo.getUnitId());
+        lqw.like(StringUtils.isNotBlank(bo.getUnitName()), StatementProduct::getUnitName, bo.getUnitName());
+        lqw.eq(bo.getQuantity() != null, StatementProduct::getQuantity, bo.getQuantity());
+        lqw.eq(bo.getUnitPrice() != null, StatementProduct::getUnitPrice, bo.getUnitPrice());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), StatementProduct::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增对账单商品明细
+     *
+     * @param bo 对账单商品明细
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(StatementProductBo bo) {
+        StatementProduct add = MapstructUtils.convert(bo, StatementProduct.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改对账单商品明细
+     *
+     * @param bo 对账单商品明细
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(StatementProductBo bo) {
+        StatementProduct update = MapstructUtils.convert(bo, StatementProduct.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(StatementProduct entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除对账单商品明细信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 34 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/application.yml

@@ -0,0 +1,34 @@
+# Tomcat
+server:
+  port: 9318
+
+# Spring
+spring:
+  application:
+    # ????
+    name: ruoyi-bill
+  profiles:
+    # ????
+    active: @profiles.active@
+
+--- # nacos ??
+spring:
+  cloud:
+    nacos:
+      # nacos ????
+      server-addr: @nacos.server@
+      username: @nacos.username@
+      password: @nacos.password@
+      discovery:
+        # ???
+        group: @nacos.discovery.group@
+        namespace: ${spring.profiles.active}
+      config:
+        # ???
+        group: @nacos.config.group@
+        namespace: ${spring.profiles.active}
+  config:
+    import:
+      - optional:nacos:application-common.yml
+      - optional:nacos:datasource.yml
+      - optional:nacos:${spring.application.name}.yml

+ 28 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/logback-plus.xml

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="logs/${project.artifactId}" />
+   <!-- 日志输出格式 -->
+    <property name="console.log.pattern"
+              value="%cyan(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{36}%n) - %msg%n"/>
+
+    <!-- 控制台输出 -->
+    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+        <encoder>
+            <pattern>${console.log.pattern}</pattern>
+            <charset>utf-8</charset>
+        </encoder>
+    </appender>
+
+    <include resource="logback-common.xml" />
+
+    <include resource="logback-logstash.xml" />
+
+    <!-- 开启 skywalking 日志收集 -->
+    <include resource="logback-skylog.xml" />
+
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="console" />
+    </root>
+</configuration>

+ 13 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/InvoiceInfoMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.InvoiceInfoMapper">
+
+    <delete id="deleteByStatementInvoiceId">
+        DELETE
+        FROM invoice_info
+        WHERE statement_invoice_id = #{id}
+    </delete>
+
+</mapper>

+ 13 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementDetailMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementDetailMapper">
+
+    <delete id="deleteByStatementOrderId">
+        DELETE
+        FROM statement_detail
+        WHERE statement_order_id = #{id}
+    </delete>
+
+</mapper>

+ 13 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceDetailMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementInvoiceDetailMapper">
+
+    <delete id="deleteByStatementInvoiceId">
+        DELETE
+        FROM statement_invoice_detail
+        WHERE statement_invoice_id = #{id}
+    </delete>
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementInvoiceMapper">
+
+</mapper>

+ 13 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementInvoiceProductMapper.xml

@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementInvoiceProductMapper">
+
+    <delete id="deleteByStatementInvoiceId">
+        DELETE
+        FROM statement_invoice_product
+        WHERE statement_invoice_id = #{id}
+    </delete>
+
+</mapper>

+ 7 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementOrderMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementOrderMapper">
+
+</mapper>

+ 24 - 0
ruoyi-modules/ruoyi-bill/src/main/resources/mapper/bill/StatementProductMapper.xml

@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.bill.mapper.StatementProductMapper">
+
+    <delete id="deleteByStatementOrderId">
+        DELETE
+        FROM statement_product
+        WHERE statement_order_id = #{id}
+    </delete>
+
+    <select id="selectByStatementAndOrderIds" resultType="org.dromara.bill.domain.vo.StatementProductVo">
+        SELECT *
+        FROM statement_product
+        WHERE del_flag = '0'
+        AND (
+        <foreach collection="items" item="item" separator=" OR ">
+            (statement_order_id = #{item.statementOrderId} AND order_id = #{item.orderId})
+        </foreach>
+        )
+    </select>
+
+</mapper>

+ 23 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerBusinessInfoController.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.utils.StringUtils;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -62,10 +63,31 @@ public class CustomerBusinessInfoController extends BaseController {
      */
     @GetMapping("/{customerId}")
     public R<CustomerBusinessInfoVo> getInfo(@NotNull(message = "主键不能为空")
-                                     @PathVariable("customerId") Long customerId) {
+                                             @PathVariable("customerId") Long customerId) {
         return R.ok(customerBusinessInfoService.queryById(customerId));
     }
 
+    /**
+     * 获取客户名称查询工商注册信息详细信息
+     *
+     * @param customerName 主键
+     */
+    @GetMapping("/selectBusinessByCustomerName/{customerName}")
+    public R<CustomerBusinessInfoVo> getBusinessInfo(
+        @PathVariable("customerName") String customerName) {
+
+        if (StringUtils.isBlank(customerName)) {
+            return R.fail("客户名称不能为空");
+        }
+
+        CustomerBusinessInfoVo vo = customerBusinessInfoService.selectBusinessByCustomerName(customerName);
+        if (vo == null) {
+            return R.fail("未查询到该企业的工商信息");
+        }
+
+        return R.ok(vo);
+    }
+
     /**
      * 新增客户工商注册信息
      */

+ 24 - 4
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java

@@ -1,19 +1,19 @@
 package org.dromara.customer.controller;
 
+import java.util.Collection;
 import java.util.List;
 
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.customer.domain.CustomerSalesInfo;
 import org.dromara.customer.domain.bo.CustomerSalesInfoBo;
 import org.dromara.customer.domain.bo.CustomerListBo;
 import org.dromara.customer.domain.bo.MessagePublishCustomerBo;
 import org.dromara.customer.domain.dto.SetCustomerInfoTagDto;
-import org.dromara.customer.domain.vo.ContractVo;
-import org.dromara.customer.domain.vo.CustomerListVo;
-import org.dromara.customer.domain.vo.MessagePublishCustomerVo;
+import org.dromara.customer.domain.vo.*;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -25,7 +25,6 @@ import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.excel.utils.ExcelUtil;
-import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.dromara.customer.domain.bo.CustomerInfoBo;
 import org.dromara.customer.service.ICustomerInfoService;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -135,6 +134,27 @@ public class CustomerInfoController extends BaseController {
         return toAjax(customerInfoService.deleteWithValidByIds(List.of(ids), true));
     }
 
+    /**
+     * 获取客户名称查询工商注册信息详细信息
+     *
+     * @param customerName 主键
+     */
+    @GetMapping("/selectByCustomerName/{customerName}")
+    public R<List<CustomerInfoVo>> selectByCustomerName(
+        @PathVariable("customerName") String customerName) {
+
+        if (StringUtils.isBlank(customerName)) {
+            return R.fail("客户名称不能为空");
+        }
+
+        List<CustomerInfoVo> customerInfoVoList = customerInfoService.selectByCustomerName(customerName);
+        if (null == customerInfoVoList || customerInfoVoList.size() == 0) {
+            return R.fail("未查询到客户信息");
+        }
+
+        return R.ok(customerInfoVoList);
+    }
+
     /**
      * 状态修改
      */

+ 2 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerBusinessInfoVo.java

@@ -1,6 +1,7 @@
 package org.dromara.customer.domain.vo;
 
 import java.util.Date;
+
 import com.fasterxml.jackson.annotation.JsonFormat;
 import org.dromara.customer.domain.CustomerBusinessInfo;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
@@ -15,7 +16,6 @@ import java.io.Serializable;
 import java.util.Date;
 
 
-
 /**
  * 客户工商注册信息视图对象 customer_business_info
  *
@@ -69,6 +69,7 @@ public class CustomerBusinessInfoVo implements Serializable {
     /**
      * 成立日期
      */
+    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
     @ExcelProperty(value = "成立日期")
     private Date establishmentDate;
 

+ 9 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerBusinessInfoService.java

@@ -16,7 +16,7 @@ import java.util.List;
  * @author LionLi
  * @date 2025-12-11
  */
-public interface ICustomerBusinessInfoService extends IService<CustomerBusinessInfo>{
+public interface ICustomerBusinessInfoService extends IService<CustomerBusinessInfo> {
 
     /**
      * 查询客户工商注册信息
@@ -26,6 +26,14 @@ public interface ICustomerBusinessInfoService extends IService<CustomerBusinessI
      */
     CustomerBusinessInfoVo queryById(Long customerId);
 
+    /**
+     * 查询客户名称查询工商注册信息详细信息
+     *
+     * @param customerName 主键
+     * @return 客户工商注册信息
+     */
+    CustomerBusinessInfoVo selectBusinessByCustomerName(String customerName);
+
     /**
      * 分页查询客户工商注册信息列表
      *

+ 9 - 4
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java

@@ -4,13 +4,10 @@ import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.customer.domain.CustomerInfo;
 import org.dromara.customer.domain.bo.CustomerListBo;
 import org.dromara.customer.domain.bo.MessagePublishCustomerBo;
-import org.dromara.customer.domain.vo.ContractVo;
-import org.dromara.customer.domain.vo.CustomerInfoVo;
+import org.dromara.customer.domain.vo.*;
 import org.dromara.customer.domain.bo.CustomerInfoBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.customer.domain.vo.CustomerListVo;
-import org.dromara.customer.domain.vo.MessagePublishCustomerVo;
 
 import java.math.BigDecimal;
 import java.util.Collection;
@@ -108,6 +105,14 @@ public interface ICustomerInfoService extends IService<CustomerInfo> {
 
     Map<Long, String> selectCustomerNameByIds(Set<Long> ids);
 
+    /**
+     * 查询客户名称查询客户信息
+     *
+     * @param customerName 主键
+     * @return 客户信息
+     */
+    List<CustomerInfoVo> selectByCustomerName(String customerName);
+
     /**
      * 校验并批量删除客户信息信息
      *

+ 70 - 4
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerBusinessInfoServiceImpl.java

@@ -1,6 +1,7 @@
 package org.dromara.customer.service.impl;
 
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.DateUtils;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -10,6 +11,9 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.utils.qcc.QccUtils;
+import org.dromara.customer.utils.qcc.domain.CompanyInfoResponse;
+import org.dromara.customer.utils.qcc.domain.Result;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.CustomerBusinessInfoBo;
 import org.dromara.customer.domain.vo.CustomerBusinessInfoVo;
@@ -30,7 +34,7 @@ import java.util.Collection;
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class CustomerBusinessInfoServiceImpl  extends ServiceImpl<CustomerBusinessInfoMapper, CustomerBusinessInfo> implements ICustomerBusinessInfoService {
+public class CustomerBusinessInfoServiceImpl extends ServiceImpl<CustomerBusinessInfoMapper, CustomerBusinessInfo> implements ICustomerBusinessInfoService {
 
     private final CustomerBusinessInfoMapper baseMapper;
 
@@ -41,10 +45,72 @@ public class CustomerBusinessInfoServiceImpl  extends ServiceImpl<CustomerBusine
      * @return 客户工商注册信息
      */
     @Override
-    public CustomerBusinessInfoVo queryById(Long customerId){
+    public CustomerBusinessInfoVo queryById(Long customerId) {
         return baseMapper.selectVoById(customerId);
     }
 
+    @Override
+    public CustomerBusinessInfoVo selectBusinessByCustomerName(String customerName) {
+        // 1. 先查本地数据库
+        LambdaQueryWrapper<CustomerBusinessInfo> query = new LambdaQueryWrapper<CustomerBusinessInfo>()
+            .eq(CustomerBusinessInfo::getBusinessCustomerName, customerName)
+            .last("LIMIT 1");
+
+        List<CustomerBusinessInfoVo> list = baseMapper.selectVoList(query);
+        if (!list.isEmpty()) {
+            return list.get(0);
+        }
+
+        // 2. 调用企查查接口
+        CompanyInfoResponse response = QccUtils.getCompanyInfo(customerName);
+        if (response == null || response.getResult() == null) {
+            return null; // 或抛异常,根据业务需求
+        }
+
+        // 3. 映射 QCC 数据到实体(注意:不设置 businessLicense)
+        Result result = response.getResult();
+        CustomerBusinessInfo entity = new CustomerBusinessInfo();
+
+        entity.setBusinessCustomerName(result.getName());
+        entity.setSocialCreditCode(result.getCreditCode());
+        entity.setLegalPersonName(result.getOperName());
+
+        // 注册资本:拼接数值 + 单位(如 "101万元")
+        String regCap = result.getRegisteredCapital();
+        String regUnit = result.getRegisteredCapitalUnit();
+        entity.setRegisteredCapital(
+            StringUtils.isNotBlank(regCap) && StringUtils.isNotBlank(regUnit)
+                ? regCap + regUnit
+                : regCap
+        );
+
+        // 实缴资本(类似处理)
+        String paidCap = result.getPaidUpCapital();
+        String paidUnit = result.getPaidUpCapitalUnit();
+        entity.setPaidInCapital(
+            StringUtils.isNotBlank(paidCap) && StringUtils.isNotBlank(paidUnit)
+                ? paidCap + paidUnit
+                : paidCap
+        );
+
+        // 日期转换(注意时区和格式)
+        entity.setEstablishmentDate(DateUtils.parseDate(result.getStartDate()));
+        // revocationDate 暂不处理,留 null
+        entity.setRevocationDate(null);
+
+        entity.setRegistrationStatus(result.getStatus());
+        entity.setRegistrationAuthority(result.getBelongOrg());
+        entity.setBussinessRange(result.getScope());
+        entity.setBusinessAddress(result.getAddress());
+
+        // 关键:不设置 businessLicense!保留为 null(由用户后续上传)
+        entity.setBusinessLicense(null);
+
+
+        // 5. 转 VO 返回
+        return MapstructUtils.convert(entity, CustomerBusinessInfoVo.class);
+    }
+
     /**
      * 分页查询客户工商注册信息列表
      *
@@ -125,7 +191,7 @@ public class CustomerBusinessInfoServiceImpl  extends ServiceImpl<CustomerBusine
     /**
      * 保存前的数据校验
      */
-    private void validEntityBeforeSave(CustomerBusinessInfo entity){
+    private void validEntityBeforeSave(CustomerBusinessInfo entity) {
         //TODO 做一些数据校验,如唯一约束
     }
 
@@ -138,7 +204,7 @@ public class CustomerBusinessInfoServiceImpl  extends ServiceImpl<CustomerBusine
      */
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        if(isValid){
+        if (isValid) {
             //TODO 做一些业务上的校验,判断是否需要校验
         }
         return baseMapper.deleteByIds(ids) > 0;

+ 12 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -11,7 +11,6 @@ import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.context.PlatformContext;
 import org.dromara.common.core.enums.IsDefault;
-import org.dromara.common.core.enums.SysPlatformCode;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -388,6 +387,18 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         return vo;
     }
 
+    @Override
+    public List<CustomerInfoVo> selectByCustomerName(String customerName) {
+        if (StringUtils.isBlank(customerName)) {
+            return Collections.emptyList();
+        }
+
+        LambdaQueryWrapper<CustomerInfo> wrapper = new LambdaQueryWrapper<CustomerInfo>()
+            .like(CustomerInfo::getCustomerName, customerName);
+
+        return baseMapper.selectVoList(wrapper);
+    }
+
     /**
      * 消息发布-分页查询客户列表
      *

+ 10 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderDeliverController.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.order.utils.kd100.domain.TrackVO;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -46,6 +47,15 @@ public class OrderDeliverController extends BaseController {
         return orderDeliverService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 查询订单物流信息列表
+     */
+//    @SaCheckPermission("system:orderDeliver:list")
+    @GetMapping("/queryTrack")
+    public TrackVO queryTrack(OrderDeliverBo bo) {
+        return orderDeliverService.queryTrack(bo);
+    }
+
     /**
      * 导出订单发货主列表
      */

+ 23 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainController.java

@@ -1,5 +1,6 @@
 package org.dromara.order.controller;
 
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
@@ -15,14 +16,18 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.tenant.helper.PlatformHelper;
 import org.dromara.common.web.core.BaseController;
+import org.dromara.order.domain.OrderProduct;
 import org.dromara.order.domain.bo.OrderMainBo;
 import org.dromara.order.domain.vo.OrderMainVo;
+import org.dromara.order.domain.vo.OrderProductVo;
 import org.dromara.order.domain.vo.OrderStatusStats;
 import org.dromara.order.service.IOrderMainService;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 /**
  * 订单主信息
@@ -47,6 +52,24 @@ public class OrderMainController extends BaseController {
         return orderMainService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 根据订单id查询订单商品
+     */
+    @GetMapping("/getCustomerOrderProductList")
+    public TableDataInfo<OrderProductVo> getCustomerOrderProductList(
+        @RequestParam(value = "orderId", required = false) List<Long> orderIdList) {
+
+        if (CollectionUtils.isEmpty(orderIdList)) {
+            throw new IllegalArgumentException("订单ID列表不能为空");
+        }
+        if (orderIdList.size() > 1000) {
+            throw new IllegalArgumentException("订单ID数量不能超过1000个");
+        }
+
+        Set<Long> uniqueOrderIds = new HashSet<>(orderIdList);
+        return orderMainService.getCustomerOrderProductList(uniqueOrderIds);
+    }
+
     /**
      * 查询分配订单列表
      */

+ 5 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderDeliver.java

@@ -1,5 +1,6 @@
 package org.dromara.order.domain;
 
+import cn.idev.excel.annotation.ExcelProperty;
 import org.dromara.common.tenant.core.TenantEntity;
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
@@ -83,7 +84,10 @@ public class OrderDeliver extends TenantEntity {
     /**
      * 承运物流公司
      */
-    private Long logisticsCompany;
+    @ExcelProperty(value = "承运物流公司")
+    private Long logisticsCompanyId;
+
+    private String logisticsCompanyCode;
 
     /**
      * 物流单号

+ 5 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderDeliverBo.java

@@ -1,5 +1,6 @@
 package org.dromara.order.domain.bo;
 
+import cn.idev.excel.annotation.ExcelProperty;
 import org.dromara.order.domain.OrderDeliver;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -80,7 +81,10 @@ public class OrderDeliverBo extends BaseEntity {
     /**
      * 承运物流公司
      */
-    private Long logisticsCompany;
+    @ExcelProperty(value = "承运物流公司")
+    private Long logisticsCompanyId;
+
+    private String logisticsCompanyCode;
 
     /**
      * 物流单号

+ 5 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderDeliverVo.java

@@ -99,7 +99,9 @@ public class OrderDeliverVo implements Serializable {
      * 承运物流公司
      */
     @ExcelProperty(value = "承运物流公司")
-    private Long logisticsCompany;
+    private Long logisticsCompanyId;
+
+    private String logisticsCompanyCode;
 
     /**
      * 物流单号
@@ -127,5 +129,7 @@ public class OrderDeliverVo implements Serializable {
 
     private String dataSource;
 
+    private Date createTime;
+
     private List<OrderDeliverProductVo> deliverProductList;
 }

+ 8 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainVo.java

@@ -362,6 +362,14 @@ public class OrderMainVo implements Serializable {
 
     private String customerName;
 
+    private Long createBy;
+
+    private String createName;
+
+    private Long createDept;
+
+    private String createDeptName;
+
     /*订单商品种数*/
     private Long productTotal;
 

+ 11 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderDeliverService.java

@@ -6,6 +6,7 @@ import org.dromara.order.domain.vo.OrderDeliverVo;
 import org.dromara.order.domain.bo.OrderDeliverBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.order.utils.kd100.domain.TrackVO;
 
 import java.util.Collection;
 import java.util.List;
@@ -16,7 +17,7 @@ import java.util.List;
  * @author LionLi
  * @date 2025-12-30
  */
-public interface IOrderDeliverService extends IService<OrderDeliver>{
+public interface IOrderDeliverService extends IService<OrderDeliver> {
 
     /**
      * 查询订单发货主
@@ -35,6 +36,15 @@ public interface IOrderDeliverService extends IService<OrderDeliver>{
      */
     TableDataInfo<OrderDeliverVo> queryPageList(OrderDeliverBo bo, PageQuery pageQuery);
 
+
+    /**
+     * 查询订单发货物流信息
+     *
+     * @param bo 订单发货信息
+     * @return 订单发货信息
+     */
+    TrackVO queryTrack(OrderDeliverBo bo);
+
     /**
      * 查询符合条件的订单发货主列表
      *

+ 5 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainService.java

@@ -2,14 +2,17 @@ package org.dromara.order.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.order.domain.OrderMain;
+import org.dromara.order.domain.OrderProduct;
 import org.dromara.order.domain.vo.OrderMainVo;
 import org.dromara.order.domain.bo.OrderMainBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.order.domain.vo.OrderProductVo;
 import org.dromara.order.domain.vo.OrderStatusStats;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Set;
 
 /**
  * 订单主信息Service接口
@@ -44,6 +47,8 @@ public interface IOrderMainService extends IService<OrderMain> {
      */
     List<OrderMainVo> queryList(OrderMainBo bo);
 
+    TableDataInfo<OrderProductVo> getCustomerOrderProductList(Set<Long> orderIdList);
+
     OrderStatusStats queryOrderStatusStats();
 
     /**

+ 33 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderDeliverServiceImpl.java

@@ -8,6 +8,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.core.enums.OrderStatus;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -25,6 +26,9 @@ import org.dromara.order.mapper.OrderDeliverProductMapper;
 import org.dromara.order.mapper.OrderMainMapper;
 import org.dromara.order.mapper.OrderProductMapper;
 import org.dromara.order.service.IOrderDeliverService;
+import org.dromara.order.utils.kd100.Kd100Util;
+import org.dromara.order.utils.kd100.domain.QueryTrackDTO;
+import org.dromara.order.utils.kd100.domain.TrackVO;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
@@ -81,6 +85,34 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
         return TableDataInfo.build(result);
     }
 
+    @Override
+    public TrackVO queryTrack(OrderDeliverBo bo) {
+
+        // 1. 参数校验
+        if (!StringUtils.isNotBlank(bo.getLogisticNo())) {
+            log.warn("物流单号不能为空,bo={}", bo);
+            throw new IllegalArgumentException("物流单号不能为空");
+        }
+
+        // 2. 构建查询 DTO
+        QueryTrackDTO dto = QueryTrackDTO.builder()
+            .com(bo.getLogisticsCompanyCode())
+            .num(bo.getLogisticNo())
+            .phone(bo.getPhone())
+            .build();
+
+        // 3. 调用物流查询
+        try {
+            log.info("开始查询物流信息,单号: {}, 公司代码: {}", dto.getNum(), dto.getCom());
+            TrackVO trackVO = Kd100Util.queryTrack(dto);
+            return trackVO;
+
+        } catch (Exception e) {
+            log.error("查询物流信息失败,dto={}", dto, e);
+            throw new ServiceException("物流信息查询失败,请稍后重试");
+        }
+    }
+
     /**
      * 查询符合条件的订单发货主列表
      *
@@ -106,7 +138,7 @@ public class OrderDeliverServiceImpl extends ServiceImpl<OrderDeliverMapper, Ord
         lqw.eq(StringUtils.isNotBlank(bo.getLogisticsStatus()), OrderDeliver::getLogisticsStatus, bo.getLogisticsStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getDeliverRemark()), OrderDeliver::getDeliverRemark, bo.getDeliverRemark());
         lqw.eq(StringUtils.isNotBlank(bo.getChecklistRemark()), OrderDeliver::getChecklistRemark, bo.getChecklistRemark());
-        lqw.eq(bo.getLogisticsCompany() != null, OrderDeliver::getLogisticsCompany, bo.getLogisticsCompany());
+        lqw.eq(bo.getLogisticsCompanyId() != null, OrderDeliver::getLogisticsCompanyId, bo.getLogisticsCompanyId());
         lqw.eq(StringUtils.isNotBlank(bo.getLogisticNo()), OrderDeliver::getLogisticNo, bo.getLogisticNo());
         lqw.eq(StringUtils.isNotBlank(bo.getLogisticPackStatus()), OrderDeliver::getLogisticPackStatus, bo.getLogisticPackStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getConsigneePhone()), OrderDeliver::getConsigneePhone, bo.getConsigneePhone());

+ 47 - 3
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -2,6 +2,7 @@ package org.dromara.order.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@@ -26,9 +27,12 @@ import org.dromara.order.mapper.OrderDeliverProductMapper;
 import org.dromara.order.mapper.OrderMainMapper;
 import org.dromara.order.mapper.OrderProductMapper;
 import org.dromara.order.service.IOrderMainService;
+import org.dromara.system.api.RemoteDeptService;
+import org.dromara.system.api.RemoteUserService;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import java.math.BigDecimal;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -43,6 +47,12 @@ import java.util.stream.Collectors;
 @Service
 public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain> implements IOrderMainService {
 
+    @DubboReference
+    private RemoteUserService remoteUserService;
+
+    @DubboReference
+    private RemoteDeptService remoteDeptService;
+
     @DubboReference
     private RemoteCustomerService remoteCustomerService;
 
@@ -84,8 +94,19 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         );
 
         Map<String, Object> stats = orderProductMapper.getAssignmentStats(orderMainVo.getId());
-        Long total = (Long) stats.getOrDefault("total", 0L);
-        Long assigned = (Long) stats.getOrDefault("assigned", 0L);
+        Object totalObj = stats.get("total");
+        Long total = (totalObj instanceof BigDecimal)
+            ? ((BigDecimal) totalObj).longValue()
+            : (totalObj instanceof Long)
+            ? (Long) totalObj
+            : 0L;
+
+        Object assignedObj = stats.get("assigned");
+        Long assigned = (assignedObj instanceof BigDecimal)
+            ? ((BigDecimal) assignedObj).longValue()
+            : (assignedObj instanceof Long)
+            ? (Long) assignedObj
+            : 0L;
         orderMainVo.setProductTotal(total);
         orderMainVo.setUnassigned(total - assigned);
         orderMainVo.setAssigned(assigned);
@@ -108,12 +129,35 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
 
         if (CollUtil.isNotEmpty(records)) {
             Set<Long> customerIds = records.stream().map(OrderMainVo::getCustomerId).collect(Collectors.toSet());
+            Set<Long> createUserIds = records.stream().map(OrderMainVo::getCreateBy).collect(Collectors.toSet());
+            Set<Long> createDeptIds = records.stream().map(OrderMainVo::getCreateDept).collect(Collectors.toSet());
+
+            Map<Long, String> UserMap = remoteUserService.selectUserNamesByIds(createUserIds.stream().toList());
+            Map<Long, String> deptMap = remoteDeptService.selectDeptNameByIds(createDeptIds);
             Map<Long, String> customerMap = remoteCustomerService.selectCustomerNameByIds(customerIds);
-            records.forEach(orderMainVo -> orderMainVo.setCustomerName(customerMap.get(orderMainVo.getCustomerId())));
+            records.forEach(orderMainVo -> {
+                orderMainVo.setCreateName(UserMap.get(orderMainVo.getCreateBy()));
+                orderMainVo.setCreateDeptName(deptMap.get(orderMainVo.getCreateDept()));
+                orderMainVo.setCustomerName(customerMap.get(orderMainVo.getCustomerId()));
+            });
         }
         return TableDataInfo.build(result);
     }
 
+    @Override
+    public TableDataInfo<OrderProductVo> getCustomerOrderProductList(Set<Long> orderIdList) {
+        // 1. 空值与空集合校验
+        if (CollectionUtils.isEmpty(orderIdList)) {
+            return TableDataInfo.build(Collections.emptyList());
+        }
+
+        List<OrderProductVo> orderProductVoList = orderProductMapper.selectVoList(
+            new LambdaQueryWrapper<OrderProduct>()
+                .in(OrderProduct::getOrderId, orderIdList)
+        );
+        return TableDataInfo.build(orderProductVoList);
+    }
+
     @Override
     public OrderStatusStats queryOrderStatusStats() {
         return baseMapper.selectOrderStatusCounts();

+ 5 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ComLogisticsCompany.java

@@ -27,6 +27,11 @@ public class ComLogisticsCompany extends TenantEntity {
     @TableId(value = "id")
     private Long id;
 
+    /**
+     * 物流公司编号
+     */
+    private String logisticsNo;
+
     /**
      * 物流公司编码
      */

+ 6 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ComLogisticsCompanyBo.java

@@ -25,6 +25,11 @@ public class ComLogisticsCompanyBo extends BaseEntity {
      */
     private Long id;
 
+    /**
+     * 物流公司编号
+     */
+    private String logisticsNo;
+
     /**
      * 物流公司编码
      */
@@ -33,7 +38,7 @@ public class ComLogisticsCompanyBo extends BaseEntity {
     /**
      * 物流公司名称
      */
-    @NotBlank(message = "物流公司名称不能为空", groups = { AddGroup.class, EditGroup.class })
+    @NotBlank(message = "物流公司名称不能为空", groups = {AddGroup.class, EditGroup.class})
     private String logisticsName;
 
     /**

+ 5 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ComLogisticsCompanyVo.java

@@ -13,7 +13,6 @@ import java.io.Serializable;
 import java.util.Date;
 
 
-
 /**
  * 物流公司视图对象 com_logistics_company
  *
@@ -34,6 +33,11 @@ public class ComLogisticsCompanyVo implements Serializable {
     @ExcelProperty(value = "主键ID")
     private Long id;
 
+    /**
+     * 物流公司编号
+     */
+    private String logisticsNo;
+
     /**
      * 物流公司编码
      */

+ 2 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ComLogisticsCompanyServiceImpl.java

@@ -36,7 +36,7 @@ import java.util.Collection;
 @Service
 public class ComLogisticsCompanyServiceImpl extends ServiceImpl<ComLogisticsCompanyMapper, ComLogisticsCompany> implements IComLogisticsCompanyService {
 
-    private static final String LOGISTICS_CODE_KEY = "com_logistics_company:logistics_code";
+    private static final String LOGISTICS_NO_KEY = "com_logistics_company:logistics_no";
 
     private final ComLogisticsCompanyMapper baseMapper;
 
@@ -98,7 +98,7 @@ public class ComLogisticsCompanyServiceImpl extends ServiceImpl<ComLogisticsComp
      */
     @Override
     public Boolean insertByBo(ComLogisticsCompanyBo bo) {
-        bo.setLogisticsCode(SequenceUtils.nextPaddedIdStr(LOGISTICS_CODE_KEY, Duration.ofDays(3650), 4));
+        bo.setLogisticsNo(SequenceUtils.nextPaddedIdStr(LOGISTICS_NO_KEY, Duration.ofDays(3650), 4));
         ComLogisticsCompany add = MapstructUtils.convert(bo, ComLogisticsCompany.class);
         validEntityBeforeSave(add);
         boolean flag = baseMapper.insert(add) > 0;