Bladeren bron

feat(bill): 扩展对账单功能支持伙伴商业务

- 新增对账单目标类型字段,支持客户和伙伴商区分
- 实现伙伴商登录权限控制和数据隔离
- 添加伙伴商专用对账单查询接口和权限限制
- 增加对账单确认和驳回操作功能
- 更新数据范围拦截器,添加新的业务表前缀配置
- 优化订单服务中的查询条件过滤逻辑
hurx 3 weken geleden
bovenliggende
commit
6dacab9bbf

+ 0 - 1
ruoyi-auth/src/main/java/org/dromara/auth/controller/MiniTokenController.java

@@ -192,7 +192,6 @@ public class MiniTokenController {
         return R.ok(getPhoneNumberByCode(data.get("code")));
     }
 
-
     private String getPhoneNumberByCode(String code) {
         try {
             // 1. 获取 access_token

+ 7 - 1
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -114,7 +114,13 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "partner_prepared",
         "partner_prepared_product",
         "protocol_",
-        "ns_diy_"
+        "ns_diy_",
+        "m_navigation_config",
+        "m_bottom_nav_items",
+        "statement_order",
+        "statement_detail",
+        "statement_product",
+        "invoice_info"
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 

+ 14 - 1
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceController.java

@@ -1,6 +1,7 @@
 package org.dromara.bill.controller;
 
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import cn.hutool.core.util.ObjectUtil;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
@@ -17,6 +18,7 @@ import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.web.core.BaseController;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -44,6 +46,10 @@ public class StatementInvoiceController extends BaseController {
     @SaCheckPermission("bill:statementInvoice:list")
     @GetMapping("/list")
     public TableDataInfo<StatementInvoiceVo> list(StatementInvoiceBo bo, PageQuery pageQuery) {
+        Long partnerId = LoginHelper.getLoginUser().getPartnerId();
+        if (ObjectUtil.isNotEmpty(partnerId)) {
+            bo.setCustomerId(partnerId);
+        }
         return statementInvoiceService.queryPageList(bo, pageQuery);
     }
 
@@ -114,5 +120,12 @@ public class StatementInvoiceController extends BaseController {
         return toAjax(statementInvoiceService.updateStatus(bo));
     }
 
-
+    /*伙伴商申请开票*/
+    @PostMapping("/insertByBo")
+    public R<Long> insertByBo(@Validated(AddGroup.class) @RequestBody StatementInvoiceBo bo) {
+        Long partnerId = LoginHelper.getLoginUser().getPartnerId();
+        bo.setCustomerId(partnerId);
+        Long insert = statementInvoiceService.pcInsertByBo(bo);
+        return R.ok(insert);
+    }
 }

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

@@ -1,10 +1,13 @@
 package org.dromara.bill.controller;
 
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
+import org.dromara.bill.domain.StatementOrder;
 import org.dromara.bill.domain.bo.StatementOrderBo;
 import org.dromara.bill.domain.dto.StatementOrderItem;
 import org.dromara.bill.domain.vo.StatementDetailVo;
@@ -20,10 +23,12 @@ import org.dromara.common.log.annotation.Log;
 import org.dromara.common.log.enums.BusinessType;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.web.core.BaseController;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Arrays;
 import java.util.List;
 
 /**
@@ -47,9 +52,48 @@ public class StatementOrderController extends BaseController {
 //    @SaCheckPermission("bill:statementOrder:list")
     @GetMapping("/list")
     public TableDataInfo<StatementOrderVo> list(StatementOrderBo bo, PageQuery pageQuery) {
+        Long partnerId = LoginHelper.getLoginUser().getPartnerId();
+        if (ObjectUtil.isNotEmpty(partnerId)) {
+            bo.setCustomerId(partnerId);
+        }
         return statementOrderService.queryPageList(bo, pageQuery);
     }
 
+    @GetMapping("/bpStatementOrderList")
+    public TableDataInfo<StatementOrderVo> bpStatementOrderList(StatementOrderBo bo, PageQuery pageQuery) {
+        Long partnerId = LoginHelper.getLoginUser().getPartnerId();
+
+        // PC端权限控制:强制只查询状态为 1、2、3 的对账单
+        LambdaQueryWrapper<StatementOrder> wrapper = new LambdaQueryWrapper<>();
+        wrapper.eq(StatementOrder::getCustomerId, partnerId);
+        wrapper.in(StatementOrder::getStatementStatus, Arrays.asList("1", "2", "3"));
+
+        // 如果用户指定了状态,且状态在允许范围内,则使用用户指定的状态
+        String statementStatus = bo.getStatementStatus();
+        if (statementStatus != null && !statementStatus.isEmpty()) {
+            if ("1".equals(statementStatus) || "2".equals(statementStatus) || "3".equals(statementStatus)) {
+                // 用户指定的状态在允许范围内,覆盖 IN 条件
+                wrapper.clear();
+                wrapper.eq(StatementOrder::getStatementStatus, statementStatus);
+            }
+            // 如果用户指定了不允许的状态(0或4),保持 IN 条件,会返回空结果
+        }
+
+        // 添加其他查询条件
+        if (bo.getStatementOrderNo() != null && !bo.getStatementOrderNo().isEmpty()) {
+            wrapper.like(StatementOrder::getStatementOrderNo, bo.getStatementOrderNo());
+        }
+        if (bo.getIsInvoiceStatus() != null && !bo.getIsInvoiceStatus().isEmpty()) {
+            wrapper.eq(StatementOrder::getIsInvoiceStatus, bo.getIsInvoiceStatus());
+        }
+        if (bo.getIsPaymentStatus() != null && !bo.getIsPaymentStatus().isEmpty()) {
+            wrapper.eq(StatementOrder::getIsPaymentStatus, bo.getIsPaymentStatus());
+        }
+
+        // 使用新添加的 PC 端专用方法
+        return statementOrderService.queryPageListByWrapper(wrapper, pageQuery);
+    }
+
     /**
      * 根据订单id查询订单商品
      */
@@ -143,4 +187,21 @@ public class StatementOrderController extends BaseController {
                                                                PageQuery pageQuery) {
         return statementOrderService.listDetailsByCustomerIdPage(customerId, pageQuery);
     }
+
+    @Log(title = "对账单确认", businessType = BusinessType.UPDATE)
+    @PutMapping("/confirm")
+    public R<Void> confirm(@RequestBody StatementOrderBo bo) {
+        bo.setStatementStatus("2");
+        return toAjax(statementOrderService.updateStatus(bo));
+    }
+
+    /**
+     * 驳回对账单
+     */
+    @Log(title = "对账单驳回", businessType = BusinessType.UPDATE)
+    @PutMapping("/reject")
+    public R<Void> reject(@RequestBody StatementOrderBo bo) {
+        bo.setStatementStatus("3");
+        return toAjax(statementOrderService.updateStatus(bo));
+    }
 }

+ 8 - 3
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoice.java

@@ -37,17 +37,22 @@ public class StatementInvoice extends TenantEntity {
     private String statementInvoiceNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     private String customerName;
 

+ 13 - 9
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementOrder.java

@@ -1,17 +1,16 @@
 package org.dromara.bill.domain;
 
-import org.dromara.common.tenant.core.TenantEntity;
-import com.baomidou.mybatisplus.annotation.*;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+import org.dromara.common.tenant.core.TenantEntity;
 
+import java.io.Serial;
 import java.math.BigDecimal;
 import java.util.Date;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
-
-import java.io.Serial;
-
 /**
  * 对账单主对象 statement_order
  *
@@ -38,17 +37,22 @@ public class StatementOrder extends TenantEntity {
     private String statementOrderNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     private String customerName;
 

+ 8 - 3
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceBo.java

@@ -35,17 +35,22 @@ public class StatementInvoiceBo extends BaseEntity {
     private String statementInvoiceNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     private String customerName;
 

+ 12 - 10
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementOrderBo.java

@@ -1,20 +1,17 @@
 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 jakarta.validation.constraints.NotNull;
+import jakarta.validation.constraints.Size;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
-import jakarta.validation.constraints.*;
+import org.dromara.bill.domain.StatementOrder;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
 
 import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
-import com.fasterxml.jackson.annotation.JsonFormat;
-
 /**
  * 对账单主业务对象 statement_order
  *
@@ -37,17 +34,22 @@ public class StatementOrderBo extends BaseEntity {
     private String statementOrderNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     private String customerName;
 

+ 8 - 3
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceVo.java

@@ -46,19 +46,24 @@ public class StatementInvoiceVo implements Serializable {
     private String statementInvoiceNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     @ExcelProperty(value = "客户编号")
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     @ExcelProperty(value = "客户编号")
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     @ExcelProperty(value = "客户名称")
     private String customerName;

+ 12 - 10
ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementOrderVo.java

@@ -1,19 +1,16 @@
 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 org.dromara.bill.domain.StatementOrder;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 import java.util.List;
 
@@ -45,19 +42,24 @@ public class StatementOrderVo implements Serializable {
     private String statementOrderNo;
 
     /**
-     * 客户编号
+     * 对账单目标类型( 1-客户, 2-伙伴商)
+     */
+    private String statementType;
+
+    /**
+     * 对账目标人id statementType=1时 为客户id statementType=2时 为伙伴商id
      */
     @ExcelProperty(value = "客户编号")
     private Long customerId;
 
     /**
-     * 客户编号
+     * 对账目标人编号 statementType=1时 为客户编号 statementType=2时 为伙伴商编号
      */
     @ExcelProperty(value = "客户编号")
     private String customerNo;
 
     /**
-     * 客户名称
+     * 对账目标人名称 statementType=1时 为客户名称 statementType=2时 为伙伴商名称
      */
     @ExcelProperty(value = "客户名称")
     private String customerName;

+ 2 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -368,13 +368,14 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         lqw.eq(bo.getAfterSaleCompleted() != null, OrderMain::getAfterSaleCompleted, bo.getAfterSaleCompleted());
         lqw.eq(bo.getAfterSalePending() != null, OrderMain::getAfterSalePending, bo.getAfterSalePending());
         lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), OrderMain::getPushStatus, bo.getPushStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getAssigneeType()), OrderMain::getAssigneeType, bo.getAssigneeType());
         lqw.eq(StringUtils.isNotBlank(bo.getCheckStatus()), OrderMain::getCheckStatus, bo.getCheckStatus());
-        lqw.eq(StringUtils.isNotBlank(bo.getAttachmentPath()), OrderMain::getAttachmentPath, bo.getAttachmentPath());
         lqw.eq(StringUtils.isNotBlank(bo.getDeliveryType()), OrderMain::getDeliveryType, bo.getDeliveryType());
         lqw.eq(StringUtils.isNotBlank(bo.getOrderCategory()), OrderMain::getOrderCategory, bo.getOrderCategory());
         lqw.eq(StringUtils.isNotBlank(bo.getExpenseType()), OrderMain::getExpenseType, bo.getExpenseType());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), OrderMain::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getIsNeedCheck()), OrderMain::getIsNeedCheck, bo.getIsNeedCheck());
+        lqw.eq(StringUtils.isNotBlank(bo.getReturnedStatus()), OrderMain::getReturnedStatus, bo.getReturnedStatus());
         // 关键词搜索:精确匹配订单号
         if (StringUtils.isNotBlank(bo.getSearchValue())) {
             lqw.eq(OrderMain::getOrderNo, bo.getSearchValue().trim());