ソースを参照

Merge remote-tracking branch 'origin/master' into tys

沐梦. 2 週間 前
コミット
6cac54c147
78 ファイル変更1536 行追加329 行削除
  1. 8 0
      pom.xml
  2. 19 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/CustomerInfoDTO.java
  3. 1 1
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java
  4. 10 1
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java
  5. 0 1
      ruoyi-auth/src/main/java/org/dromara/auth/controller/MiniTokenController.java
  6. 18 12
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java
  7. 65 0
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java
  8. 5 0
      ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java
  9. 7 1
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  10. 14 1
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementInvoiceController.java
  11. 61 0
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/controller/StatementOrderController.java
  12. 8 3
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementInvoice.java
  13. 13 9
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/StatementOrder.java
  14. 8 3
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementInvoiceBo.java
  15. 12 10
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/bo/StatementOrderBo.java
  16. 8 3
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementInvoiceVo.java
  17. 12 10
      ruoyi-modules/ruoyi-bill/src/main/java/org/dromara/bill/domain/vo/StatementOrderVo.java
  18. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java
  19. 23 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/PartnerInfoController.java
  20. 22 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierInfoController.java
  21. 32 4
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java
  22. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcPurchaseHabitController.java
  23. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyProductVo.java
  24. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerContactVo.java
  25. 6 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContactMapper.java
  26. 6 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java
  27. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/IPartnerInfoService.java
  28. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java
  29. 33 10
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerContactServiceImpl.java
  30. 304 105
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  31. 14 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/PartnerInfoServiceImpl.java
  32. 6 6
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAddressServiceImpl.java
  33. 17 17
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContactServiceImpl.java
  34. 18 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java
  35. 4 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerContactMapper.xml
  36. 3 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalItem.java
  37. 1 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java
  38. 35 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/mini/MiniNavigationConfigController.java
  39. 17 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderMainController.java
  40. 0 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderStatusLogController.java
  41. 41 5
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/mini/MiniOrderController.java
  42. 8 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/OrderMain.java
  43. 8 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderMainBo.java
  44. 11 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/dto/ChangeReturnedStatusRequestDto.java
  45. 8 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/vo/OrderMainVo.java
  46. 3 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/IOrderMainService.java
  47. 44 12
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java
  48. 8 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnServiceImpl.java
  49. 44 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderStatusLogServiceImpl.java
  50. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java
  51. 129 9
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/mini/MiniProductController.java
  52. 13 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/IndexProductController.java
  53. 3 7
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/MyProductController.java
  54. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java
  55. 2 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java
  56. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductCategoryService.java
  57. 6 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseAuditServiceImpl.java
  58. 16 9
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  59. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java
  60. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryRecommendedLinkServiceImpl.java
  61. 3 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java
  62. 18 3
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProtocolInfoServiceImpl.java
  63. 0 45
      ruoyi-modules/ruoyi-product/src/main/resources/application.yml
  64. 1 1
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml
  65. 144 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/MenuSqlGenerator.java
  66. 10 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysTaxCodeController.java
  67. 52 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/mini/MiniSystemController.java
  68. 5 3
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSysUserController.java
  69. 53 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSystemController.java
  70. 7 7
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java
  71. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTaxCodeVo.java
  72. 13 5
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java
  73. 10 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTaxCodeService.java
  74. 1 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java
  75. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
  76. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java
  77. 31 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaxCodeServiceImpl.java
  78. 2 2
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysUserServiceImpl.java

+ 8 - 0
pom.xml

@@ -37,6 +37,7 @@
         <lombok.version>1.18.36</lombok.version>
         <logstash.version>7.4</logstash.version>
         <easy-es.version>3.0.0</easy-es.version>
+        <elasticsearch-java.version>8.11.0</elasticsearch-java.version>
         <skywalking-toolkit.version>9.3.0</skywalking-toolkit.version>
         <bouncycastle.version>1.80</bouncycastle.version>
         <mapstruct-plus.version>1.4.8</mapstruct-plus.version>
@@ -367,6 +368,13 @@
                 <version>${easy-es.version}</version>
             </dependency>
 
+            <!-- 强制指定 Elasticsearch Java Client 版本以兼容 Easy-ES 3.0.0 -->
+            <dependency>
+                <groupId>co.elastic.clients</groupId>
+                <artifactId>elasticsearch-java</artifactId>
+                <version>${elasticsearch-java.version}</version>
+            </dependency>
+
             <!-- skywalking 整合 logback -->
             <dependency>
                 <groupId>org.apache.skywalking</groupId>

+ 19 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/CustomerInfoDTO.java

@@ -14,10 +14,29 @@ public class CustomerInfoDTO implements Serializable {
 
     private String customerName;
 
+    private String customerNo;
+
+    /**
+     * 业务负责人
+     */
+    private Long salesPersonId;
+
+    /**
+     * 客服支持
+     */
+    private Long serviceStaffId;
+
+    /**
+     * 所属部门
+     */
+    private Long belongingDepartmentId;
+
     /**
      * 状态(0已审核 待审核)
      */
     private String status;
 
 
+
+
 }

+ 1 - 1
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteUserService.java

@@ -24,7 +24,7 @@ public interface RemoteUserService {
      * @param tenantId 租户id
      * @return 结果
      */
-    LoginUser getUserInfo(String username, String tenantId) throws UserException;
+    LoginUser getUserInfo(String username, String tenantId,String userSonType) throws UserException;
 
     /**
      * 通过用户id查询用户信息

+ 10 - 1
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java

@@ -45,7 +45,7 @@ public class RemoteUserBo implements Serializable {
      * 用户账号
      */
     @Xss(message = "用户账号不能包含脚本字符")
-    @NotBlank(message = "用户账号不能为空")
+//    @NotBlank(message = "用户账号不能为空")
     @Size(min = 0, max = 30, message = "用户账号长度不能超过{max}个字符")
     private String userName;
 
@@ -113,6 +113,13 @@ public class RemoteUserBo implements Serializable {
      */
     private Long roleId;
 
+    /**
+    *
+    * */
+    private Long[] roleIds;
+
+
+
     /**
      * 用户子类型 用户子类型(0=平台用户,1=供应商,2=伙伴商,3=商城用户,4=小程序用户)
      */
@@ -123,6 +130,8 @@ public class RemoteUserBo implements Serializable {
      */
     private String platformCode;
 
+    private String delFlag;
+
     public RemoteUserBo(Long userId) {
         this.userId = userId;
     }

+ 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

+ 18 - 12
ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java

@@ -79,8 +79,11 @@ public class PasswordAuthStrategy implements IAuthStrategy {
         if (captchaProperties.getEnabled()) {
             validateCaptcha(tenantId, username, code, uuid);
         }
+        if(ObjectUtil.isEmpty(loginBody.getUserSonType())){
+            loginBody.setUserSonType("0");
+        }
         LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
-            LoginUser user = remoteUserService.getUserInfo(username, tenantId);
+            LoginUser user = remoteUserService.getUserInfo(username, tenantId, loginBody.getUserSonType());
             loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
             return user;
         });
@@ -131,25 +134,28 @@ public class PasswordAuthStrategy implements IAuthStrategy {
             validateCaptcha(tenantId, username, code, uuid);
         }
         LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
-            LoginUser user = remoteUserService.getUserInfo(username, tenantId);
+            LoginUser user = remoteUserService.getUserInfo(username, tenantId, "3,4");
 //            if(!Objects.equals(user.getUserSonType(), "3")){
 //                throw new ServiceException("不存在该账号");
 //            }
             loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
             return user;
         });
-        //获取客户信息
-        Long customerId = remoteCustomerService.selectCustomerIdByUserId(loginUser.getUserId());
-        if (Objects.isNull(customerId)) {
-            throw new ServiceException("不存在该账号");
-        }
-        CustomerInfoDTO customerInfoDTO = remoteCustomerService.selectCustomerInfoById(customerId);
-        if (null != customerInfoDTO && "0".equals(customerInfoDTO.getStatus())) {
-            throw new ServiceException("该企业当前未审核,请审核后再登录");
+        if(Objects.equals(loginUser.getUserSonType(), "3")){
+            //获取客户信息
+            Long customerId = remoteCustomerService.selectCustomerIdByUserId(loginUser.getUserId());
+            if (Objects.isNull(customerId)) {
+                throw new ServiceException("不存在该账号");
+            }
+            CustomerInfoDTO customerInfoDTO = remoteCustomerService.selectCustomerInfoById(customerId);
+            if (null != customerInfoDTO && "0".equals(customerInfoDTO.getStatus())) {
+                throw new ServiceException("该企业当前未审核,请审核后再登录");
+            }
+            loginUser.setCustomerId(customerId);
         }
+
         loginUser.setClientKey(client.getClientKey());
         loginUser.setDeviceType(client.getDeviceType());
-        loginUser.setCustomerId(customerId);
         SaLoginParameter model = new SaLoginParameter();
         model.setDeviceType(client.getDeviceType());
         // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
@@ -193,7 +199,7 @@ public class PasswordAuthStrategy implements IAuthStrategy {
         String tenantId = "000000";
         LoginVo loginVo = new LoginVo();
         LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
-            LoginUser user = remoteUserService.getUserInfo(username, tenantId);
+            LoginUser user = remoteUserService.getUserInfo(username, tenantId,"0");
             loginService.checkLogin(LoginType.PASSWORD, tenantId, username, () -> !BCrypt.checkpw(password, user.getPassword()));
             return user;
         });

+ 65 - 0
ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java

@@ -2,16 +2,19 @@ package org.dromara.auth.service.impl;
 
 import cn.dev33.satoken.stp.StpUtil;
 import cn.dev33.satoken.stp.parameter.SaLoginParameter;
+import cn.hutool.crypto.digest.BCrypt;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.auth.domain.vo.LoginVo;
+import org.dromara.auth.form.PasswordLoginBody;
 import org.dromara.auth.form.SmsLoginBody;
 import org.dromara.auth.service.IAuthStrategy;
 import org.dromara.auth.service.SysLoginService;
 import org.dromara.common.core.constant.Constants;
 import org.dromara.common.core.constant.GlobalConstants;
 import org.dromara.common.core.enums.LoginType;
+import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.user.CaptchaExpireException;
 import org.dromara.common.core.utils.MessageUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -20,11 +23,17 @@ import org.dromara.common.json.utils.JsonUtils;
 import org.dromara.common.redis.utils.RedisUtils;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.common.tenant.helper.TenantHelper;
+import org.dromara.customer.api.RemoteCustomerService;
+import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.dromara.customer.api.domain.dto.CustomerInfoDTO;
+import org.dromara.system.api.RemoteClientService;
 import org.dromara.system.api.RemoteUserService;
 import org.dromara.system.api.domain.vo.RemoteClientVo;
 import org.dromara.system.api.model.LoginUser;
 import org.springframework.stereotype.Service;
 
+import java.util.Objects;
+
 /**
  * 短信认证策略
  *
@@ -37,9 +46,19 @@ public class SmsAuthStrategy implements IAuthStrategy {
 
     private final SysLoginService loginService;
 
+
     @DubboReference
     private RemoteUserService remoteUserService;
 
+    @DubboReference
+    private RemoteClientService remoteClientService;
+
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
+    @DubboReference
+    private RemoteSupplierInfoService remoteSupplierInfoService;
+
     @Override
     public LoginVo login(String body, RemoteClientVo client) {
         SmsLoginBody loginBody = JsonUtils.parseObject(body, SmsLoginBody.class);
@@ -80,6 +99,52 @@ public class SmsAuthStrategy implements IAuthStrategy {
      */
     @Override
     public LoginVo clientLogin(String body, RemoteClientVo client) {
+        SmsLoginBody loginBody = JsonUtils.parseObject(body, SmsLoginBody.class);
+
+        String tenantId = loginBody.getTenantId();
+        String username = loginBody.getPhonenumber();
+        boolean b = this.validateSmsCode(tenantId, username, loginBody.getSmsCode());
+        if (!b) {
+            throw new ServiceException("验证码错误");
+        }
+
+
+        LoginUser loginUser = TenantHelper.dynamic(tenantId, () -> {
+            LoginUser user = remoteUserService.getUserInfo(username, tenantId, "3,4");
+//            if(!Objects.equals(user.getUserSonType(), "3")){
+//                throw new ServiceException("不存在该账号");
+//            }
+            return user;
+        });
+        if(Objects.equals(loginUser.getUserSonType(), "3")){
+            //获取客户信息
+            Long customerId = remoteCustomerService.selectCustomerIdByUserId(loginUser.getUserId());
+            if (Objects.isNull(customerId)) {
+                throw new ServiceException("不存在该账号");
+            }
+            CustomerInfoDTO customerInfoDTO = remoteCustomerService.selectCustomerInfoById(customerId);
+            if (null != customerInfoDTO && "0".equals(customerInfoDTO.getStatus())) {
+                throw new ServiceException("该企业当前未审核,请审核后再登录");
+            }
+            loginUser.setCustomerId(customerId);
+        }
+
+        loginUser.setClientKey(client.getClientKey());
+        loginUser.setDeviceType(client.getDeviceType());
+        SaLoginParameter model = new SaLoginParameter();
+        model.setDeviceType(client.getDeviceType());
+        // 自定义分配 不同用户体系 不同 token 授权时间 不设置默认走全局 yml 配置
+        // 例如: 后台用户30分钟过期 app用户1天过期
+        model.setTimeout(client.getTimeout());
+        model.setActiveTimeout(client.getActiveTimeout());
+        model.setExtra(LoginHelper.CLIENT_KEY, client.getClientId());
+        // 生成token
+        LoginHelper.login(loginUser, model);
+
+        LoginVo loginVo = new LoginVo();
+        loginVo.setAccessToken(StpUtil.getTokenValue());
+        loginVo.setExpireIn(StpUtil.getTokenTimeout());
+        loginVo.setClientId(client.getClientId());
         return null;
     }
 

+ 5 - 0
ruoyi-common/ruoyi-common-core/src/main/java/org/dromara/common/core/domain/model/LoginBody.java

@@ -38,4 +38,9 @@ public class LoginBody {
      */
     private String uuid;
 
+    /**
+    *   用户子类型(0=平台用户,1=供应商,2=伙伴商,3=企业客户,4=个人用户)
+    * */
+    private String userSonType;
+
 }

+ 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;

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

@@ -163,7 +163,7 @@ public class CustomerInfoController extends BaseController {
     }
 
     /**
-     * 获取客户名称查询工商注册信息详细信息
+     * 获取客户名称模糊查询客户列表信息
      *
      * @param customerName 主键
      */

+ 23 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/PartnerInfoController.java

@@ -6,6 +6,8 @@ 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.vo.CustomerInfoVo;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -112,4 +114,25 @@ public class PartnerInfoController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(partnerInfoService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+     * 获取伙伴商名称模糊查询伙伴商列表信息
+     *
+     * @param partnerName 主键
+     */
+    @GetMapping("/selectByPartnerName/{partnerName}")
+    public R<List<PartnerInfoVo>> selectByPartnerName(
+        @PathVariable("partnerName") String partnerName) {
+
+        if (StringUtils.isBlank(partnerName)) {
+            return R.fail("伙伴商名称不能为空");
+        }
+
+        List<PartnerInfoVo> partnerfoVoList = partnerInfoService.selectByPartnerName(partnerName);
+        if (null == partnerfoVoList || partnerfoVoList.size() == 0) {
+            return R.fail("未查询到伙伴商信息");
+        }
+
+        return R.ok(partnerfoVoList);
+    }
 }

+ 22 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierInfoController.java

@@ -8,6 +8,7 @@ import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.core.validate.AddGroup;
 import org.dromara.common.core.validate.EditGroup;
 import org.dromara.common.excel.core.ExcelResult;
@@ -19,6 +20,7 @@ import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.customer.domain.bo.SupplierInfoBo;
+import org.dromara.customer.domain.vo.PartnerInfoVo;
 import org.dromara.customer.domain.vo.SupplierInfoImportVo;
 import org.dromara.customer.domain.vo.SupplierInfoVo;
 import org.dromara.customer.listener.SupplierImportListener;
@@ -254,4 +256,24 @@ public class SupplierInfoController extends BaseController {
         ExcelUtil.exportExcel(new ArrayList<>(), "供应商数据", SupplierInfoImportVo.class, response);
     }
 
+    /**
+     * 获取供应商名称模糊查询供应商列表信息
+     *
+     * @param supplierName 主键
+     */
+    @GetMapping("/selectBySupplierName/{supplierName}")
+    public R<List<SupplierInfoVo>> selectByPartnerName(
+        @PathVariable("supplierName") String supplierName) {
+
+        if (StringUtils.isBlank(supplierName)) {
+            return R.fail("供应商名称不能为空");
+        }
+
+        List<SupplierInfoVo> partnerfoVoList = supplierInfoService.selectBySupplierName(supplierName);
+        if (null == partnerfoVoList || partnerfoVoList.size() == 0) {
+            return R.fail("未查询到供应商信息");
+        }
+
+        return R.ok(partnerfoVoList);
+    }
 }

+ 32 - 4
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java

@@ -7,15 +7,16 @@ package org.dromara.customer.controller.pc;
 
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
+import org.dromara.common.core.utils.StringUtils;
 import org.dromara.customer.domain.bo.CustomerRegisterBo;
 import org.dromara.customer.domain.bo.SupplierRegisterBo;
+import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.dromara.customer.service.ICustomerInfoService;
 import org.dromara.customer.service.ISupplierInfoService;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+
+import java.util.List;
 
 @Validated
 @RequiredArgsConstructor
@@ -27,6 +28,24 @@ public class CustomerRegisterController {
 
     private final ISupplierInfoService supplierInfoService;
 
+    /**
+     * 获取客户名称模糊查询客户列表信息
+     *
+     * @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);
+
+        return R.ok(customerInfoVoList);
+    }
+
     /**
      * 验证密码与验证码
      */
@@ -36,6 +55,15 @@ public class CustomerRegisterController {
         return R.ok();
     }
 
+    /**
+    * 个人注册
+    * */
+    @PostMapping("/selfRegister")
+    public R<Void> selfRegister(@RequestBody CustomerRegisterBo bo) {
+        customerInfoService.selfRegister(bo);
+        return R.ok();
+    }
+
     /**
      * 企业注册
      */

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/PcPurchaseHabitController.java

@@ -31,7 +31,7 @@ public class PcPurchaseHabitController extends BaseController {
      */
     @Log(title = "PC-客户采购习惯", businessType = BusinessType.INSERT)
     @PostMapping()
-    public R<Void> add(@Validated(AddGroup.class) @RequestBody PurchaseHabitBo bo) {
+    public R<Void> add( @RequestBody PurchaseHabitBo bo) {
         // 获取当前登录用户的企业ID
         Long customerId = LoginHelper.getLoginUser().getCustomerId();
         // 强制设置企业ID,防止为其他企业添加地址

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

@@ -389,7 +389,7 @@ public class ContractSupplyProductVo {
      * 暂估采购价
      */
     @ExcelProperty(value = "暂估采购价")
-    private BigDecimal estimatedPurchasePrice;
+    private BigDecimal maxPurchasePrice;
 
     /**
      * 产品经理

+ 2 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerContactVo.java

@@ -158,6 +158,8 @@ public class CustomerContactVo implements Serializable {
 
     private Date createTime;
 
+    private String delFlag;
+
     /**
      * 联系人类型 (1公司职员 2关系资源人)
      */

+ 6 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContactMapper.java

@@ -1,10 +1,9 @@
 package org.dromara.customer.mapper;
 
 import org.apache.ibatis.annotations.Param;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 import org.dromara.customer.domain.CustomerContact;
-import org.dromara.customer.domain.CustomerInvoiceInfo;
 import org.dromara.customer.domain.vo.CustomerContactVo;
-import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
 import java.util.List;
 
@@ -18,5 +17,10 @@ public interface CustomerContactMapper extends BaseMapperPlus<CustomerContact, C
 
     void deleteByCustomerId(@Param("customerId") Long customerId);
 
+    /**
+     * 自定义查询:忽略逻辑删除,查询手机号对应的所有记录(含已删除)
+     */
+    CustomerContact selectOneByPhoneIgnoreDelete(@Param("phone") String phone);
+
     List<CustomerContact> selectListByCustomerId(@Param("customerId") Long customerId);
 }

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java

@@ -163,6 +163,11 @@ public interface ICustomerInfoService extends IService<CustomerInfo> {
      */
     Boolean register(CustomerRegisterBo bo);
 
+    /**
+     * 个人注册
+     */
+    Boolean selfRegister(CustomerRegisterBo bo);
+
     /**
      * 新增客户信息 客户导入时只需要导入主数据
      *
@@ -188,4 +193,5 @@ public interface ICustomerInfoService extends IService<CustomerInfo> {
     CustomerInfoVo selectCustomerByName(String customerName);
 
 
+
 }

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/IPartnerInfoService.java

@@ -2,6 +2,7 @@ package org.dromara.customer.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.customer.domain.PartnerInfo;
+import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.dromara.customer.domain.vo.PartnerInfoVo;
 import org.dromara.customer.domain.bo.PartnerInfoBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -79,4 +80,12 @@ public interface IPartnerInfoService extends IService<PartnerInfo> {
 
     /*根据ids查询伙伴商名称*/
     Map<Long, String> selectPartnerNameByIds(Set<Long> ids);
+
+    /**
+     * 查询伙伴商名称查询伙伴商信息
+     *
+     * @param partnerName 主键
+     * @return 伙伴商信息
+     */
+    List<PartnerInfoVo> selectByPartnerName(String partnerName);
 }

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import jakarta.validation.constraints.NotNull;
 import org.dromara.customer.domain.SupplierInfo;
 import org.dromara.customer.domain.bo.*;
+import org.dromara.customer.domain.vo.PartnerInfoVo;
 import org.dromara.customer.domain.vo.SupplierInfoVo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -145,4 +146,12 @@ public interface ISupplierInfoService extends IService<SupplierInfo> {
      * @return 供应商对象信息
      */
     SupplierInfoVo selectSupplierByEnterpriseName(String enterpriseName);
+
+    /**
+     * 查询供应商名称查询供应商信息
+     *
+     * @param supplierName 主键
+     * @return 供应商信息
+     */
+    List<SupplierInfoVo> selectBySupplierName(String supplierName);
 }

+ 33 - 10
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerContactServiceImpl.java

@@ -86,7 +86,7 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
 
     @Override
     public CustomerContactVo selectCustomerContactByCustomerIdAndUserId(Long customerId, Long userId) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<CustomerContact>().eq(CustomerContact::getCustomerId, customerId).eq(CustomerContact::getUserId, userId).last("limit 1"));
+        return baseMapper.selectVoOne(new LambdaQueryWrapper<CustomerContact>().eq(CustomerContact::getCustomerId, customerId).eq(CustomerContact::getUserId, userId).eq(CustomerContact::getDelFlag, '0').last("limit 1"));
     }
 
     /**
@@ -144,7 +144,7 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
     private LambdaQueryWrapper<CustomerContact> buildQueryWrapper(CustomerContactBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<CustomerContact> lqw = Wrappers.lambdaQuery();
-        lqw.orderByDesc(CustomerContact::getId);
+        lqw.orderByDesc(CustomerContact::getCreateTime);
         lqw.eq(bo.getCustomerId() != null, CustomerContact::getCustomerId, bo.getCustomerId());
         lqw.like(StringUtils.isNotBlank(bo.getContactNo()), CustomerContact::getContactNo, bo.getContactNo());
         lqw.like(StringUtils.isNotBlank(bo.getContactName()), CustomerContact::getContactName, bo.getContactName());
@@ -219,19 +219,34 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
                 throw new RuntimeException("客户编号为空,数据异常 (ID: " + bo.getCustomerId() + ")");
             }
         }
-
         // 1. 准备创建系统用户的数据
         RemoteUserBo remoteUserBo = new RemoteUserBo();
         remoteUserBo.setNickName(bo.getContactName());
         remoteUserBo.setDeptId(bo.getDeptId());
         remoteUserBo.setUserName(bo.getPhone());// 用手机号做账号
+        remoteUserBo.setPhonenumber(bo.getPhone());
         String defaultPassword = "123456";
         remoteUserBo.setPassword(BCrypt.hashpw(defaultPassword));
         remoteUserBo.setUserSonType("3");
         remoteUserBo.setTenantId(LoginHelper.getTenantId());
-
-        // 2. 调用远程服务创建用户
-        Long userId = remoteUserService.addUser(remoteUserBo);
+        remoteUserBo.setRoleIds(new Long[]{bo.getRoleId()});
+        Long userId = null;
+        // 使用自定义方法查询
+        CustomerContact customerContact = baseMapper.selectOneByPhoneIgnoreDelete(bo.getPhone());
+
+        if (customerContact != null) {
+            // 如果查到了数据
+            if ("1".equals(customerContact.getDelFlag())) {
+                // 情况 A:数据已删除 -> 复用原有的 userId
+                userId = customerContact.getUserId();
+            } else {
+                // 情况 B:数据未删除 -> 报错,禁止重复
+                throw new ServiceException("该手机号已存在有效联系人,请勿重复添加");
+            }
+        } else {
+            // 情况 C:完全没数据 -> 创建新用户
+            userId = remoteUserService.addUser(remoteUserBo);
+        }
 
         if (userId == null) {
             throw new ServiceException("创建系统用户失败:" + userId);
@@ -279,6 +294,14 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
         syncDeptName(bo);
         CustomerContact update = MapstructUtils.convert(bo, CustomerContact.class);
         validEntityBeforeSave(update);
+        //查询角色有变更,如果角色有变更,则需要更新用户角色
+        CustomerContact customerContact = baseMapper.selectById(bo.getId());
+        if (!Objects.equals(customerContact.getRoleId(), update.getRoleId())) {
+            RemoteUserBo remoteUserBo = new RemoteUserBo();
+            remoteUserBo.setUserId(customerContact.getUserId());
+            remoteUserBo.setRoleId(update.getRoleId());
+            remoteUserService.addUserRole(remoteUserBo);
+        }
         boolean flag = baseMapper.updateById(update) > 0;
         if (flag) {
             try {
@@ -379,7 +402,7 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
             return false;
         }
 
-        // 5. 提取 userId 列表
+        /*// 5. 提取 userId 列表
         List<Long> userIds = contactList.stream()
             .map(CustomerContact::getUserId)
             .filter(Objects::nonNull) // 过滤掉 userId 为 null 的情况
@@ -392,10 +415,10 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
             try {
                 remoteUserService.deleteUser(uid);
             } catch (Exception e) {
-                // 仅记录错误,不中断删除流程,防止因账号问题导致联系人无法删除
-                log.error("删除远程用户 {} 失败,可能用户已被手动删除: {}", uid, e.getMessage());
+                log.error("删除远程用户 {} 失败", uid, e);
+                throw new ServiceException("依赖服务异常,删除中止"); // 抛出异常触发回滚
             }
-        }
+        }*/  //联系人删除时不删除用户  后续可能会复用之前的 用户
         // 7. 执行本地数据库删除
         int rows = baseMapper.deleteByIds(ids);
         if (rows > 0) {

+ 304 - 105
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -59,6 +59,10 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
     @DubboReference
     private RemoteDeptService remoteDeptService;
 
+    @DubboReference
+    private RemoteErpDeptService remoteErpDeptService;
+    @DubboReference
+    private RemoteErpStaffService remoteErpStaffService;
     @DubboReference
     private RemoteUserService remoteUserService;
     @DubboReference
@@ -134,6 +138,12 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 vo.setIndustryName(industryCategoryVo.getIndustryCategoryName());
             }
         }
+        // 2. 查询关联信息
+        vo.setCustomerBusinessInfoVo(
+            Optional.ofNullable(customerBusinessInfoMapper.selectByCustomerId(id))
+                .map(entity -> MapstructUtils.convert(entity, CustomerBusinessInfoVo.class))
+                .orElse(null)
+        );
 
         // 企业类型名称 (Q0001)
         if (vo.getCustomerTypeId() != null) {
@@ -205,86 +215,111 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
 
         // 销售信息
         CustomerSalesInfo customerSalesInfo = customerSalesInfoMapper.selectByCustomerId(id);
-        if (customerSalesInfo != null) {
-            if (ObjectUtils.isNotEmpty(customerSalesInfo.getCreditAmount()) && ObjectUtils.isNotEmpty(customerSalesInfo.getTemporaryQuota())) {
-                customerSalesInfo.setRemainingQuota(customerSalesInfo.getCreditAmount().add(customerSalesInfo.getTemporaryQuota()));
-            }
+        if (customerSalesInfo == null) {
+            vo.setCustomerSalesInfoVo(null);
+            return vo;
+        }
+        if (ObjectUtils.isNotEmpty(customerSalesInfo.getCreditAmount()) && ObjectUtils.isNotEmpty(customerSalesInfo.getTemporaryQuota())) {
+            customerSalesInfo.setRemainingQuota(customerSalesInfo.getCreditAmount().add(customerSalesInfo.getTemporaryQuota()));
+        }
+        Set<Long> staffIds = new HashSet<>();
+        Set<Long> deptIds = new HashSet<>();
 
-            CustomerSalesInfoVo voObj = MapstructUtils.convert(customerSalesInfo, CustomerSalesInfoVo.class);
+        if (customerSalesInfo.getSalesPersonId() != null) {
+            staffIds.add(customerSalesInfo.getSalesPersonId());
+        }
+        if (customerSalesInfo.getServiceStaffId() != null) {
+            staffIds.add(customerSalesInfo.getServiceStaffId());
+        }
+        if (customerSalesInfo.getBelongingDepartmentId() != null) {
+            deptIds.add(customerSalesInfo.getBelongingDepartmentId());
+        }
 
-            // 补充客户来源名称 (customer_source)
-            if (StringUtils.isNotBlank(customerSalesInfo.getCustomerSource())) {
-                List<RemoteDictDataVo> sourceDicts = remoteDictService.selectDictDataByType("customer_source");
-                sourceDicts.stream()
-                    .filter(d -> customerSalesInfo.getCustomerSource().equals(d.getDictValue()))
-                    .findFirst()
-                    .ifPresent(d -> vo.setCustomerSourceName(d.getDictLabel()));
-            }
+        Map<Long, String> staffMap = staffIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteErpStaffService.selectStaffNameByIds(staffIds);
 
-            // 补充人员和部门名称
-            Set<Long> staffIds = new HashSet<>();
-            if (vo.getSalesPersonId() != null) staffIds.add(vo.getSalesPersonId());
-            if (vo.getServiceStaffId() != null) staffIds.add(vo.getServiceStaffId());
+        Map<Long, String> deptMap = deptIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteErpDeptService.selectDeptNameByIds(deptIds);
 
-            // 补充人员信息(包含部门)
-            Map<Long, RemoteComStaffVo> staffFullMap = staffIds.isEmpty() ? Collections.emptyMap() : 
-                remoteComStaffService.selectStaffByIds(staffIds).stream().collect(Collectors.toMap(RemoteComStaffVo::getStaffId, Function.identity(), (k1, k2) -> k1));
-            
-            // 归属部门逻辑:优先从销售信息的 belongingDepartmentId 获取,其次从业务负责人所在部门获取
-            String deptName = null;
-            if (customerSalesInfo.getBelongingDepartmentId() != null) {
-                RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptById(customerSalesInfo.getBelongingDepartmentId());
-                if (remoteDeptVo != null) {
-                    deptName = remoteDeptVo.getDeptName();
-                }
-            }
-            if (StringUtils.isBlank(deptName) && vo.getSalesPersonId() != null && staffFullMap.containsKey(vo.getSalesPersonId())) {
-                deptName = staffFullMap.get(vo.getSalesPersonId()).getDeptName();
-            }
-            
-            vo.setBelongingDepartmentName(deptName);
-            vo.setDeptName(deptName);
-            if (voObj != null) {
-                voObj.setBelongingDepartment(deptName);
-                voObj.setSalesPerson(staffFullMap.get(vo.getSalesPersonId()) != null ? staffFullMap.get(vo.getSalesPersonId()).getStaffName() : null);
-                voObj.setServiceStaff(staffFullMap.get(vo.getServiceStaffId()) != null ? staffFullMap.get(vo.getServiceStaffId()).getStaffName() : null);
-            }
-            vo.setSalesPersonName(staffFullMap.get(vo.getSalesPersonId()) != null ? staffFullMap.get(vo.getSalesPersonId()).getStaffName() : null);
-            vo.setServiceStaffName(staffFullMap.get(vo.getServiceStaffId()) != null ? staffFullMap.get(vo.getServiceStaffId()).getStaffName() : null);
-            // 信用等级名称
-            if (voObj != null && voObj.getCreditLevelId() != null) {
-                Map<Long, String> creditMap = remoteCreditLevelService.selectCreditLevelNameByIds(Collections.singleton(voObj.getCreditLevelId()));
-                voObj.setCreditLevel(creditMap.get(voObj.getCreditLevelId()));
-            }
-            vo.setCustomerSalesInfoVo(voObj);
+        // 先转换
+        CustomerSalesInfoVo voObj = MapstructUtils.convert(customerSalesInfo, CustomerSalesInfoVo.class);
+
+        // 再补充名称
+        if (voObj != null) {
+            voObj.setSalesPerson(staffMap.get(customerSalesInfo.getSalesPersonId()));
+            voObj.setServiceStaff(staffMap.get(customerSalesInfo.getServiceStaffId()));
+            voObj.setBelongingDepartment(deptMap.get(customerSalesInfo.getBelongingDepartmentId()));
+        }
+
+        vo.setCustomerSalesInfoVo(voObj);
+
+        Set<Long> comStaffIds = new HashSet<>();
+        Set<Long> comDeptIds = new HashSet<>(); //系统的部门
+
+        if (vo.getSalesPersonId() != null) {
+            comStaffIds.add(vo.getSalesPersonId());
+        }
+        if (vo.getServiceStaffId() != null) {
+            comStaffIds.add(vo.getServiceStaffId());
+        }
+        if (vo.getBelongingDepartmentId() != null) {
+            comDeptIds.add(vo.getBelongingDepartmentId());
         }
 
+        Map<Long, String> comStaffMap = comStaffIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteComStaffService.selectStaffNameByIds(comStaffIds);
+
+        Map<Long, String> comDeptMap = comDeptIds.isEmpty()//系统的部门
+            ? Collections.emptyMap()
+            : remoteDeptService.selectDeptNameByIds(comDeptIds);
+
+        /*回填系统的人员与部门*/
+        vo.setSalesPersonName(comStaffMap.get(vo.getSalesPersonId()));
+        vo.setServiceStaffName(comStaffMap.get(vo.getServiceStaffId()));
+        vo.setBelongingDepartmentName(comDeptMap.get(vo.getBelongingDepartmentId()));
+
+
         // 补充开票类型 (来自主表 sell_invoice_type)
         vo.setInvoiceType(vo.getSellInvoiceType());
         vo.setInvoiceTypeName(vo.getSellInvoiceType());
 
         // 联系人列表
         List<CustomerContact> contactEntities = customerContactMapper.selectListByCustomerId(id);
-        vo.setCustomerContactVoList(CollUtil.isEmpty(contactEntities) ? Collections.emptyList() :
-            contactEntities.stream().map(c -> MapstructUtils.convert(c, CustomerContactVo.class)).collect(Collectors.toList()));
+        vo.setCustomerContactVoList(
+            contactEntities != null
+                ? contactEntities.stream()
+                .map(contact -> MapstructUtils.convert(contact, CustomerContactVo.class))
+                .collect(Collectors.toList())
+                : Collections.emptyList()
+        );
 
         // 发票列表
         List<CustomerInvoiceInfo> invoiceEntities = customerInvoiceInfoMapper.selectListByCustomerId(id);
-        vo.setCustomerInvoiceInfoVoList(CollUtil.isEmpty(invoiceEntities) ? Collections.emptyList() :
-            invoiceEntities.stream().map(i -> MapstructUtils.convert(i, CustomerInvoiceInfoVo.class)).collect(Collectors.toList()));
-
-        // 3. 计算部门额度
+        vo.setCustomerInvoiceInfoVoList(
+            invoiceEntities != null
+                ? invoiceEntities.stream()
+                .map(invoice -> MapstructUtils.convert(invoice, CustomerInvoiceInfoVo.class))
+                .collect(Collectors.toList())
+                : Collections.emptyList()
+        );
         Long userId = LoginHelper.getLoginUser().getUserId();
-        if (Objects.nonNull(userId) && CollUtil.isNotEmpty(contactEntities)) {
-            contactEntities.stream()
+        // 2. 使用 Optional 和 Stream 查找并处理
+        if (Objects.nonNull(userId)) { // 或者使用 userId != null
+            Optional<CustomerContact> optionalContact = contactEntities.stream()
                 .filter(contactEntity -> Objects.equals(contactEntity.getUserId(), userId))
-                .findFirst()
-                .ifPresent(contact -> {
-                    CustomerDeptVo customerDeptVo = customerDeptMapper.selectVoById(contact.getDeptId());
-                    if (customerDeptVo != null) {
-                        vo.setDeptCredit(customerDeptVo.getResidueYearlyBudget());
-                    }
-                });
+                .findFirst();
+
+            // 3. 只有当找到匹配的 contact 时,才执行后续逻辑
+            optionalContact.ifPresent(contact -> {
+                CustomerDeptVo customerDeptVo = customerDeptMapper.selectVoById(contact.getDeptId());
+                // 建议增加对 customerDeptVo 的非空判断,防止 selectVoById 返回 null
+                if (customerDeptVo != null) {
+                    vo.setDeptCredit(customerDeptVo.getResidueYearlyBudget());
+                }
+            });
         }
         // 4. 补全管理信息人名
         Set<Long> userIds = new HashSet<>();
@@ -342,6 +377,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                     IndustryCategoryVo::getIndustryCategoryName,
                     (e, r) -> e
                 ));
+            records.forEach(vo -> vo.setIndustryCategory(industryMap.get(vo.getIndustryCategoryId())));
         }
 
         // === 2. 提取客户ID,查询销售信息 ===
@@ -381,39 +417,60 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 (existing, replacement) -> existing // 若有重复,保留第一个
             ));
 
+        // === 4. 收集人员和部门ID ===
         Set<Long> staffIds = new HashSet<>();
+        Set<Long> deptIds = new HashSet<>();
 
-        // === 3. 提取人员和部门ID用于查询名称 ===
-        for (CustomerInfoVo vo : records) {
+        for (CustomerSalesInfoVo vo : salesInfoVos) {
             if (vo.getSalesPersonId() != null) staffIds.add(vo.getSalesPersonId());
             if (vo.getServiceStaffId() != null) staffIds.add(vo.getServiceStaffId());
-            
-            CustomerSalesInfoVo salesVo = salesInfoMap.get(vo.getId());
+            if (vo.getBelongingDepartmentId() != null) deptIds.add(vo.getBelongingDepartmentId());
         }
 
         // === 5. 远程调用获取名称 ===
         Map<Long, String> companyMap = companyIds.isEmpty()
             ? Collections.emptyMap()
             : remoteComCompanyService.selectCompanyNameByIds(companyIds);
-        
-        List<RemoteComStaffVo> staffVos = staffIds.isEmpty() ? Collections.emptyList() : remoteComStaffService.selectStaffByIds(staffIds);
-        Map<Long, RemoteComStaffVo> staffFullMap = CollUtil.isEmpty(staffVos) ? Collections.emptyMap() : 
-            staffVos.stream().collect(Collectors.toMap(RemoteComStaffVo::getStaffId, Function.identity(), (k1, k2) -> k1));
+        Map<Long, String> staffMap = staffIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteErpStaffService.selectStaffNameByIds(staffIds);
+
+        Map<Long, String> deptMap = deptIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteErpDeptService.selectDeptNameByIds(deptIds);
+
+        // === 6. 回填人员和部门名称到 salesInfoVo ===
+        for (CustomerSalesInfoVo vo : salesInfoVos) {
+            vo.setSalesPerson(staffMap.get(vo.getSalesPersonId()));
+            vo.setServiceStaff(staffMap.get(vo.getServiceStaffId()));
+            vo.setBelongingDepartment(deptMap.get(vo.getBelongingDepartmentId()));
+        }
+        //系统人员与部门
+        Set<Long> comStaffIds = new HashSet<>();
+        Set<Long> comDeptIds = new HashSet<>();
 
-        // === 6. 回填人员和部门名称到 vo ===
         for (CustomerInfoVo vo : records) {
-            RemoteComStaffVo salesPerson = staffFullMap.get(vo.getSalesPersonId());
-            RemoteComStaffVo serviceStaff = staffFullMap.get(vo.getServiceStaffId());
-            
-            vo.setSalesPersonName(salesPerson != null ? salesPerson.getStaffName() : null);
-            vo.setServiceStaffName(serviceStaff != null ? serviceStaff.getStaffName() : null);
-            
-            // 部门统一使用业务负责人所在的部门
-            String deptName = salesPerson != null ? salesPerson.getDeptName() : null;
-            vo.setBelongingDepartmentName(deptName);
-            vo.setDeptName(deptName);
+            if (vo.getSalesPersonId() != null) comStaffIds.add(vo.getSalesPersonId());
+            if (vo.getServiceStaffId() != null) comStaffIds.add(vo.getServiceStaffId());
+            if (vo.getBelongingDepartmentId() != null) comDeptIds.add(vo.getBelongingDepartmentId());
         }
 
+        // === 远程调用获取名称 ===
+        Map<Long, String> comStaffMap = staffIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteComStaffService.selectStaffNameByIds(comStaffIds);
+
+        Map<Long, String> comDeptMap = deptIds.isEmpty()
+            ? Collections.emptyMap()
+            : remoteDeptService.selectDeptNameByIds(comDeptIds);
+
+        // === 回填系统人员和部门名称到 customerInfoVo ===
+        records.forEach(v -> {
+            v.setSalesPersonName(comStaffMap.get(v.getSalesPersonId()));
+            v.setServiceStaffName(comStaffMap.get(v.getServiceStaffId()));
+            v.setBelongingDepartmentName(comDeptMap.get(v.getBelongingDepartmentId()));
+        });
+
         // === 7. 将销售信息回填到客户VO ===
         for (CustomerInfoVo customerVo : records) {
             customerVo.setCompanyName(companyMap.get(customerVo.getBelongCompanyId()));
@@ -612,7 +669,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 }
                 if (vo.getBelongCompanyId() != null) companyIds.add(vo.getBelongCompanyId());
                 if (vo.getCustomerLevelId() != null) customerLevelIds.add(vo.getCustomerLevelId());
-                
+
                 // 处理部门ID收集
                 if (vo.getBelongingDepartmentId() != null) {
                     deptIds.add(vo.getBelongingDepartmentId());
@@ -654,13 +711,13 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 }
                 vo.setCreditLevelName(creditLevelMap.get(vo.getCreditLevelId()));
                 vo.setCompanyName(companyMap.get(vo.getBelongCompanyId()));
-                
+
                 // 企业类型翻译
                 String typeValue = vo.getEnterpriseTypeId() != null ? String.valueOf(vo.getEnterpriseTypeId()) : null;
                 vo.setEnterpriseTypeName(enterpriseTypeMap.get(typeValue));
 
                 vo.setCustomerLevelName(customerLevelMap.get(vo.getCustomerLevelId()));
-                
+
                 // 合作状态翻译
                 vo.setCooperationName(cooperationMap.get(vo.getStatus()));
             });
@@ -708,7 +765,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         lqw.eq(StringUtils.isNotBlank(bo.getRegCityNo()), CustomerInfo::getRegCityNo, bo.getRegCityNo());
         lqw.eq(StringUtils.isNotBlank(bo.getRegCountyNo()), CustomerInfo::getRegCountyNo, bo.getRegCountyNo());
         lqw.eq(StringUtils.isNotBlank(bo.getProvincialCityCounty()), CustomerInfo::getProvincialCityCounty, bo.getProvincialCityCounty());
-
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), CustomerInfo::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerInfo::getPlatformCode, bo.getPlatformCode());
         lqw.eq(bo.getSalesPersonId() != null, CustomerInfo::getSalesPersonId, bo.getSalesPersonId());
         lqw.eq(bo.getServiceStaffId() != null, CustomerInfo::getServiceStaffId, bo.getServiceStaffId());
@@ -1295,7 +1352,8 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         remoteUserBo.setUserName(bo.getPurchasePhone());
         remoteUserBo.setNickName(bo.getPurchaseName());
         remoteUserBo.setPhonenumber(bo.getPurchasePhone());
-        remoteUserBo.setRoleId(1996816313015631873L);
+        remoteUserBo.setRoleId(2049022448332603393L);
+        remoteUserBo.setRoleIds(new Long[]{2049022448332603393L});
         remoteUserBo.setPassword(BCrypt.hashpw(bo.getPassword()));
         remoteUserBo.setUserSonType("3"); // 商城用户
         remoteUserBo.setTenantId(LoginHelper.getTenantId());
@@ -1303,6 +1361,8 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         Long userId = remoteUserService.addUser(remoteUserBo);
 
 
+        remoteUserBo.setUserId(userId);
+        remoteUserService.addUserRole(remoteUserBo);
         // 添加客户联系人信息
         CustomerContact contact = new CustomerContact();
         contact.setCustomerId(customerId);
@@ -1335,6 +1395,63 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         return true;
     }
 
+    /**
+     * 个人注册
+     *
+     * @param bo
+     */
+    @Override
+    public Boolean selfRegister(CustomerRegisterBo bo) {
+        //先校验验证码是否正确
+        String code = RedisUtils.getCacheObject(GlobalConstants.CAPTCHA_CODE_KEY + bo.getPurchasePhone());
+        if (code == null) {
+            throw new ServiceException("验证码已过期");
+        }
+
+        if (!code.equals(bo.getCode())) {
+            throw new ServiceException("验证码错误");
+        }
+
+        //校验密码与确认密码是否一致
+        if (!bo.getPassword().equals(bo.getConfirmPassword())) {
+            throw new ServiceException("密码与确认密码不一致");
+        }
+        // 创建系统用户
+        RemoteUserBo remoteUserBo = new RemoteUserBo();
+        remoteUserBo.setUserName(bo.getPurchasePhone());
+        remoteUserBo.setNickName(bo.getPurchaseName());
+        remoteUserBo.setPhonenumber(bo.getPurchasePhone());
+        remoteUserBo.setRoleId(2049023315869859841L);
+        remoteUserBo.setRoleIds(new Long[]{2049023315869859841L});
+        remoteUserBo.setPassword(BCrypt.hashpw(bo.getPassword()));
+        remoteUserBo.setUserSonType("4"); // 商城用户
+        remoteUserBo.setTenantId(LoginHelper.getTenantId());
+        remoteUserBo.setStatus("0"); // 正常状态
+        Long userId = remoteUserService.addUser(remoteUserBo);
+
+
+        // 添加客户联系人信息
+        CustomerContact contact = new CustomerContact();
+        contact.setUserId(userId);
+        contact.setRoleId(1L);
+        contact.setContactName(bo.getPurchaseName());
+        contact.setPhone(bo.getPurchasePhone());
+        contact.setCustomLoginName(bo.getPurchasePhone());
+        contact.setIsPrimary("0"); // 设为主联系人
+        contact.setStatus("0");
+        contact.setDelFlag("0");
+
+        if (customerContactMapper.insert(contact) <= 0) {
+            throw new ServiceException("注册失败");
+        }
+
+
+        if (null != code) {
+            RedisUtils.deleteObject(GlobalConstants.CAPTCHA_CODE_KEY + bo.getPurchasePhone());
+        }
+        return null;
+    }
+
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int transferSalesPerson(List<Long> customerIds, Long salesPersonId, Long deptId) {
@@ -1342,27 +1459,107 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
             return 0;
         }
 
-        // 直接进行批量更新,不再循环查询
-        return baseMapper.update(null, new LambdaUpdateWrapper<CustomerInfo>()
-            .set(CustomerInfo::getSalesPersonId, salesPersonId)
-            // 如果传了部门ID则更新,没传则不更新
-            .set(deptId != null, CustomerInfo::getBelongingDepartmentId, deptId)
-            .in(CustomerInfo::getId, customerIds)
-        );
+        if (salesPersonId == null || deptId == null) {
+            log.warn("转移业务人员失败,业务人员 ID 或部门 ID 为空");
+            throw new ServiceException("业务人员和所属部门不能为空");
+        }
+
+        try {
+            List<CustomerInfo> updateList = new ArrayList<>();
+            CustomerInfo customerInfo = null;
+            for (Long customerId : customerIds) {
+                if (customerId == null) {
+                    continue;
+                }
+
+                customerInfo = baseMapper.selectById(customerId);
+                if (customerInfo != null) {
+                    customerInfo.setSalesPersonId(salesPersonId);
+                    customerInfo.setBelongingDepartmentId(deptId);
+                    updateList.add(customerInfo);
+                } else {
+                    log.warn("客户 ID: {} 不存在,跳过更新", customerId);
+                }
+            }
+
+            if (!updateList.isEmpty()) {
+                boolean success = baseMapper.updateBatchById(updateList);
+                if (success) {
+                    log.info("成功转移 {} 个客户的业务人员,目标业务员 ID: {}, 部门 ID: {}",
+                        updateList.size(), salesPersonId, deptId);
+                    return updateList.size();
+                } else {
+                    log.error("批量更新客户信息失败");
+                    throw new ServiceException("批量更新客户信息失败");
+                }
+            }
+
+            log.info("没有需要更新的客户销售信息");
+            return 0;
+
+        } catch (Exception e) {
+            log.error("转移业务人员失败,客户 IDs: {}, 业务员 ID: {}, 部门 ID: {}, 错误:{}",
+                customerIds, salesPersonId, deptId, e.getMessage(), e);
+            throw new ServiceException("转移业务人员失败:" + e.getMessage());
+        }
     }
 
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int transferServiceStaff(List<Long> customerIds, Long serviceStaffId) {
-        if (CollUtil.isEmpty(customerIds) || serviceStaffId == null) {
+        if (CollUtil.isEmpty(customerIds)) {
+            log.warn("转移客服人员失败,客户 ID 列表为空");
+            return 0;
+        }
+
+        if (serviceStaffId == null) {
+            log.warn("转移客服人员失败,客服人员 ID 为空");
+            throw new ServiceException("客服人员和不能为空");
+        }
+
+        try {
+            List<CustomerInfo> updateList = new ArrayList<>();
+            CustomerInfo customerInfo = null;
+            for (Long customerId : customerIds) {
+                if (customerId == null) {
+                    continue;
+                }
+
+                customerInfo = baseMapper.selectById(customerId);
+                if (customerInfo != null) {
+                    customerInfo.setServiceStaffId(serviceStaffId);
+                    updateList.add(customerInfo);
+                } else {
+                    log.warn("客户 ID: {} 不存在,跳过更新", customerId);
+                }
+            }
+
+            if (!updateList.isEmpty()) {
+                boolean success = baseMapper.updateBatchById(updateList);
+                if (success) {
+                    log.info("成功转移 {} 个客户的客服人员,目标客服人员 ID: {}",
+                        updateList.size(), serviceStaffId);
+                    return updateList.size();
+                } else {
+                    log.error("批量更新客户信息失败");
+                    throw new ServiceException("批量更新客户信息失败");
+                }
+            }
+
+            log.info("没有需要更新的客户销售信息");
             return 0;
+
+        } catch (Exception e) {
+            log.error("转移客服人员失败,客户 IDs: {}, 客服人员 ID: {},  错误:{}",
+                customerIds, serviceStaffId, e.getMessage(), e);
+            throw new ServiceException("转移客服人员失败:" + e.getMessage());
         }
 
         // 直接进行批量更新
-        return baseMapper.update(null, new LambdaUpdateWrapper<CustomerInfo>()
-            .set(CustomerInfo::getServiceStaffId, serviceStaffId)
-            .in(CustomerInfo::getId, customerIds)
-        );
+//        return baseMapper.update(null, new LambdaUpdateWrapper<CustomerInfo>()
+//            .set(CustomerInfo::getServiceStaffId, serviceStaffId)
+//            .in(CustomerInfo::getId, customerIds)
+//        );
     }
 
     /**
@@ -1410,6 +1607,8 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
             CustomerBusinessInfo customerBusinessInfo = customerBusinessInfoMapper.selectOne(new LambdaQueryWrapper<CustomerBusinessInfo>().eq(CustomerBusinessInfo::getCustomerId, update.getId()));
 
             if (customerSalesInfo != null) {
+                customerSalesInfo.setSalesPersonId(customerSalesInfoBo.getSalesPersonId());
+                customerSalesInfo.setServiceStaffId(customerSalesInfoBo.getServiceStaffId());
                 customerSalesInfo.setCreditLevelId(customerSalesInfoBo.getCreditLevelId());
                 customerSalesInfoMapper.updateById(customerSalesInfo);
             }
@@ -1431,14 +1630,14 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
         if (customer == null) {
             return false;
         }
-        
+
         // 1. 认领操作更新客户主表
         customer.setSalesPersonId(claimBo.getSalesPersonId());
         customer.setServiceStaffId(claimBo.getServiceStaffId());
         customer.setBelongingDepartmentId(claimBo.getDeptId());
         customer.setStatus("0"); // 认领成功后,将客户主表状态改为有效
         boolean updated = baseMapper.updateById(customer) > 0;
-        
+
         if (updated && claimBo.getSalesPersonId() != null) {
             // 2. 将业务员加入团队成员
             // 检查是否已在团队中
@@ -1446,7 +1645,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 .eq(TeamMember::getDataType, 12)
                 .eq(TeamMember::getObjectNo, customer.getCustomerNo())
                 .eq(TeamMember::getUserNo, claimBo.getSalesPersonId()));
-            
+
             if (count == 0) {
                 TeamMember member = new TeamMember();
                 member.setDataType(12); // 客户类型
@@ -1456,17 +1655,17 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 member.setIzManager(1);
                 member.setUpdateAccredit(1);
                 member.setPlatformCode(PlatformContext.getPlatform());
-                
+
                 // 获取真实姓名:直接从业务人员表获取
                 CrmStaff staff = crmStaffMapper.selectById(claimBo.getSalesPersonId());
                 if (staff != null) {
                     member.setRealName(staff.getStaffName());
                 }
-                
+
                 teamMemberMapper.insert(member);
             }
         }
-        
+
         return updated;
     }
 

+ 14 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/PartnerInfoServiceImpl.java

@@ -10,7 +10,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.domain.CustomerInfo;
 import org.dromara.customer.domain.SupplierInfo;
+import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.PartnerInfoBo;
 import org.dromara.customer.domain.vo.PartnerInfoVo;
@@ -186,4 +188,16 @@ public class PartnerInfoServiceImpl extends ServiceImpl<PartnerInfoMapper, Partn
 
         return resultMap;
     }
+
+    @Override
+    public List<PartnerInfoVo> selectByPartnerName(String partnerName) {
+        if (StringUtils.isBlank(partnerName)) {
+            return Collections.emptyList();
+        }
+
+        LambdaQueryWrapper<PartnerInfo> wrapper = new LambdaQueryWrapper<PartnerInfo>()
+            .like(PartnerInfo::getPartnerName, partnerName);
+
+        return baseMapper.selectVoList(wrapper);
+    }
 }

+ 6 - 6
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAddressServiceImpl.java

@@ -144,12 +144,12 @@ public class SupplierAddressServiceImpl extends ServiceImpl<SupplierAddressMappe
         SupplierAddress add = MapstructUtils.convert(bo, SupplierAddress.class);
         validEntityBeforeSave(add);
         // 如果设置为自身地址
-        if (IsDefault.Yes.getCode().equals(add.getIsSelf())) {
+        if ("1".equals(add.getIsSelf())) {
 
             // 把该供应商下其他地址全部改为否
             LambdaUpdateWrapper<SupplierAddress> updateWrapper = Wrappers.lambdaUpdate();
             updateWrapper.eq(SupplierAddress::getSupplierId, add.getSupplierId())
-                .set(SupplierAddress::getIsSelf, IsDefault.No.getCode());
+                .set(SupplierAddress::getIsSelf, 0);
 
             baseMapper.update(null, updateWrapper);
         }
@@ -190,12 +190,12 @@ public class SupplierAddressServiceImpl extends ServiceImpl<SupplierAddressMappe
         SupplierAddress update = MapstructUtils.convert(bo, SupplierAddress.class);
         validEntityBeforeSave(update);
         // 如果本次修改设置为自身地址
-        if (IsDefault.Yes.getCode().equals(update.getIsSelf())) {
-
+        // 如果设置为自身地址
+        if ("1".equals(update.getIsSelf())) {
+            // 把该供应商下其他地址全部改为否
             LambdaUpdateWrapper<SupplierAddress> updateWrapper = Wrappers.lambdaUpdate();
             updateWrapper.eq(SupplierAddress::getSupplierId, update.getSupplierId())
-                .ne(SupplierAddress::getId, update.getId()) // 排除自己
-                .set(SupplierAddress::getIsSelf, IsDefault.No.getCode());
+                .set(SupplierAddress::getIsSelf, 0);
 
             baseMapper.update(null, updateWrapper);
         }

+ 17 - 17
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContactServiceImpl.java

@@ -182,14 +182,14 @@ public class SupplierContactServiceImpl extends ServiceImpl<SupplierContactMappe
         //4.如果是待修改审核  能登录  user是能登录的 status = 0
         SupplierContact add = MapstructUtils.convert(bo, SupplierContact.class);
         // ====== 主联系人唯一控制 ======
-//        if ("1".equals(add.getIsPrimaryContact())) {
-//
-//            LambdaUpdateWrapper<SupplierContact> updateWrapper = Wrappers.lambdaUpdate();
-//            updateWrapper.eq(SupplierContact::getSupplierId, add.getSupplierId())
-//                .set(SupplierContact::getIsPrimaryContact, "0");
-//
-//            baseMapper.update(null, updateWrapper);
-//        }
+        if ("1".equals(add.getIsPrimaryContact())) {
+
+            LambdaUpdateWrapper<SupplierContact> updateWrapper = Wrappers.lambdaUpdate();
+            updateWrapper.eq(SupplierContact::getSupplierId, add.getSupplierId())
+                .set(SupplierContact::getIsPrimaryContact, "0");
+
+            baseMapper.update(null, updateWrapper);
+        }
         List<SupplierContact> supplierContacts = baseMapper.selectList(new LambdaQueryWrapper<SupplierContact>().eq(SupplierContact::getSupplierId, add.getSupplierId()).eq(SupplierContact::getIsPrimaryContact, SysPlatformYesNo.YES.getCode()));
         if (ObjectUtil.isNotEmpty(supplierContacts) && supplierContacts.size() > 0) {
             add.setIsPrimaryContact(SysPlatformYesNo.NO.getCode());
@@ -247,15 +247,15 @@ public class SupplierContactServiceImpl extends ServiceImpl<SupplierContactMappe
     public Boolean updateByBo(SupplierContactBo bo) {
         SupplierContact update = MapstructUtils.convert(bo, SupplierContact.class);
         // ====== 主联系人唯一控制 ======
-//        if ("1".equals(update.getIsPrimaryContact())) {
-//
-//            LambdaUpdateWrapper<SupplierContact> updateWrapper = Wrappers.lambdaUpdate();
-//            updateWrapper.eq(SupplierContact::getSupplierId, update.getSupplierId())
-//                .ne(SupplierContact::getId, update.getId()) // 排除自己
-//                .set(SupplierContact::getIsPrimaryContact, "0");
-//
-//            baseMapper.update(null, updateWrapper);
-//        }
+        if ("1".equals(update.getIsPrimaryContact())) {
+
+            LambdaUpdateWrapper<SupplierContact> updateWrapper = Wrappers.lambdaUpdate();
+            updateWrapper.eq(SupplierContact::getSupplierId, update.getSupplierId())
+                .ne(SupplierContact::getId, update.getId()) // 排除自己
+                .set(SupplierContact::getIsPrimaryContact, "0");
+
+            baseMapper.update(null, updateWrapper);
+        }
         if (update.getUserId() != null) {
             RemoteUserBo remoteUserBo = new RemoteUserBo();
             remoteUserBo.setNickName(bo.getUserName());

+ 18 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java

@@ -607,9 +607,11 @@ public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, Sup
         SupplierInfoVo supplierInfoVo1 = baseMapper.selectVoOne(new LambdaQueryWrapper<SupplierInfo>().select(SupplierInfo::getSupplyStatus)
             .eq(SupplierInfo::getId, id));
         SupplierInfoVo supplierInfoVo = new SupplierInfoVo();
-        if (supplierInfoVo1.getSupplyStatus() == SupplierStatusEnum.REVIEW_UPDATED.getCode()) {
+        if (supplierInfoVo1 != null && supplierInfoVo1.getSupplyStatus() == SupplierStatusEnum.REVIEW_UPDATED.getCode()) {
             SupplierInfoTemporaryVo supplierInfoTemporaryVo = supplierInfoTemporaryService.getVoOne(id);
-            BeanUtils.copyProperties(supplierInfoTemporaryVo, supplierInfoVo);
+            if (supplierInfoTemporaryVo != null) {
+                BeanUtils.copyProperties(supplierInfoTemporaryVo, supplierInfoVo);
+            }
         } else {
             supplierInfoVo = baseMapper.selectVoById(id);
         }
@@ -2216,7 +2218,7 @@ public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, Sup
         remoteUserBo.setRoleId(1996815844478320642L);
         remoteUserBo.setPhonenumber(bo.getPurchasePhone());
         remoteUserBo.setPassword(BCrypt.hashpw(bo.getPassword()));
-        remoteUserBo.setUserSonType("3"); // 商城用户
+        remoteUserBo.setUserSonType("1"); // 供应商
         remoteUserBo.setTenantId(LoginHelper.getTenantId());
         remoteUserBo.setStatus("0"); // 正常状态
 
@@ -2296,6 +2298,7 @@ public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, Sup
     public int scmUpdateByBo(SupplierInfoBo bo) {
         SupplierInfo update = MapstructUtils.convert(bo, SupplierInfo.class);
         saveSupplierBusinessInfoFromJson(bo.getOtherCustomers(), bo.getId());
+        update.setSupplyStatus(4L);
         return baseMapper.updateById(update);
     }
 
@@ -2410,4 +2413,16 @@ public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, Sup
     public SupplierInfoVo selectSupplierByEnterpriseName(String enterpriseName) {
         return baseMapper.selectVoOne(new LambdaQueryWrapper<SupplierInfo>().eq(SupplierInfo::getEnterpriseName, enterpriseName));
     }
+
+    @Override
+    public List<SupplierInfoVo> selectBySupplierName(String supplierName) {
+        if (StringUtils.isBlank(supplierName)) {
+            return Collections.emptyList();
+        }
+
+        LambdaQueryWrapper<SupplierInfo> wrapper = new LambdaQueryWrapper<SupplierInfo>()
+            .like(SupplierInfo::getEnterpriseName, supplierName);
+
+        return baseMapper.selectVoList(wrapper);
+    }
 }

+ 4 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerContactMapper.xml

@@ -14,4 +14,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         WHERE customer_id = #{customerId}
         ORDER BY id
     </select>
+
+    <select id="selectOneByPhoneIgnoreDelete" resultType="org.dromara.customer.domain.CustomerContact">
+        SELECT * FROM customer_contact WHERE phone = #{phone} ORDER BY create_time desc LIMIT 1
+    </select>
 </mapper>

+ 3 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalItem.java

@@ -27,6 +27,9 @@ public class ExternalItem extends TenantEntity {
     @TableId(value = "id")
     private Long id;
 
+    /*
+    * 1+DDDDD
+    * */
     private String itemNo;
 
     /**

+ 1 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java

@@ -342,7 +342,7 @@ public class ExternalProductVo implements Serializable {
     /**
      * 暂估采购价
      */
-    private java.math.BigDecimal estimatedPurchasePrice;
+    private java.math.BigDecimal maxPurchasePrice;
 
     /**
      * 产品经理

+ 35 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/mini/MiniNavigationConfigController.java

@@ -0,0 +1,35 @@
+package org.dromara.mall.controller.mini;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.mall.domain.vo.MNavigationConfigVo;
+import org.dromara.mall.service.IMNavigationConfigService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * mini底部导航栏
+ * 前端访问路由地址为:/mall/miniNavigationConfig
+ *
+ * @author LionLi
+ * @date 2026-05-06
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/miniNavigationConfig")
+public class MiniNavigationConfigController extends BaseController {
+
+    private final IMNavigationConfigService navigationConfigService;
+
+    /**
+     * 获取当前导航配置
+     */
+    @GetMapping("/current")
+    public R<MNavigationConfigVo> getCurrent() {
+        return R.ok(navigationConfigService.getCurrentConfig());
+    }
+}

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

@@ -21,6 +21,7 @@ import org.dromara.common.tenant.helper.PlatformHelper;
 import org.dromara.common.web.core.BaseController;
 import org.dromara.order.domain.bo.OrderMainBo;
 import org.dromara.order.domain.bo.OrderProductBo;
+import org.dromara.order.domain.dto.ChangeReturnedStatusRequestDto;
 import org.dromara.order.domain.vo.OrderMainVo;
 import org.dromara.order.domain.vo.OrderProductVo;
 import org.dromara.order.domain.vo.OrderStatusStats;
@@ -225,4 +226,20 @@ public class OrderMainController extends BaseController {
     public R<Void> changePayStatus(@RequestBody OrderMainBo bo) {
         return toAjax(orderMainService.updatePayStatus(bo));
     }
+
+    /**
+     * 修改订单回款状态
+     *
+     */
+    @Log(title = "订单主信息", businessType = BusinessType.UPDATE)
+    @PutMapping("changeReturnedStatus") //
+    public R<Void> changeReturnedStatus(@RequestBody ChangeReturnedStatusRequestDto request) {
+
+        // 从请求对象中获取参数
+        Long[] ids = request.getIds();
+        String returnedStatus = request.getReturnedStatus();
+
+        // 调用服务层方法
+        return toAjax(orderMainService.changeReturnedStatusByIds(List.of(ids), returnedStatus));
+    }
 }

+ 0 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/OrderStatusLogController.java

@@ -105,7 +105,6 @@ public class OrderStatusLogController extends BaseController {
     }
 
     @Log(title = "订单状态流转记录", businessType = BusinessType.INSERT)
-    @RepeatSubmit()
     @PostMapping("/selectNewOne")
     public R<OrderStatusLogVo> selectNewOne(@Validated(AddGroup.class) @RequestBody OrderStatusLogBo bo) {
         return R.ok(orderStatusLogService.selectNewOne(bo));

+ 41 - 5
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/mini/MiniOrderController.java

@@ -1,5 +1,6 @@
 package org.dromara.order.controller.mini;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import jakarta.validation.constraints.NotNull;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboReference;
@@ -16,16 +17,17 @@ import org.dromara.common.web.core.BaseController;
 import org.dromara.customer.api.RemoteCustomerContactService;
 import org.dromara.customer.api.RemoteCustomerService;
 import org.dromara.customer.api.domain.CustomerApiVo;
+import org.dromara.order.domain.OrderCustomerFlowNodeLink;
+import org.dromara.order.domain.bo.OrderDeliverBo;
 import org.dromara.order.domain.bo.OrderMainBo;
 import org.dromara.order.domain.bo.OrderProductBo;
 import org.dromara.order.domain.bo.PcSubmitOrderBo;
 import org.dromara.order.domain.dto.OrderPayDto;
+import org.dromara.order.domain.vo.OrderDeliverVo;
 import org.dromara.order.domain.vo.OrderMainVo;
 import org.dromara.order.domain.vo.OrderProductVo;
-import org.dromara.order.service.IOrderCustomerFlowLinkService;
-import org.dromara.order.service.IOrderCustomerFlowNodeLinkService;
-import org.dromara.order.service.IOrderCustomerFlowService;
-import org.dromara.order.service.IOrderMainService;
+import org.dromara.order.service.*;
+import org.dromara.order.utils.kd100.domain.TrackVO;
 import org.dromara.product.api.RemoteProductService;
 import org.dromara.product.api.RemoteProductShoppingCartService;
 import org.dromara.product.api.domain.ProductVo;
@@ -77,6 +79,8 @@ public class MiniOrderController extends BaseController {
 
     private final IOrderMainService orderMainService;
 
+    private final IOrderDeliverService orderDeliverService;
+
 
     private final IOrderCustomerFlowNodeLinkService orderCustomerFlowNodeLinkService;
 
@@ -182,7 +186,7 @@ public class MiniOrderController extends BaseController {
 
         // 强制设置企业ID
         bo.setCustomerId(customerId);
-        bo.setOrderStatuses(OrderStatus.CANCEL.getCode());
+        bo.setOrderStatus(OrderStatus.CANCEL.getCode());
 
         return toAjax(orderMainService.updateStatus(bo));
     }
@@ -344,6 +348,9 @@ public class MiniOrderController extends BaseController {
         return R.ok(orderPayResult);
     }
 
+    /**
+     * 确认订单
+     */
     @GetMapping("/batchConfirmation")
     public R<Void> batchConfirmation(@RequestParam("orderIds") List<Long> orderIds) {
         if (orderIds == null || orderIds.isEmpty()) {
@@ -372,4 +379,33 @@ public class MiniOrderController extends BaseController {
         Set<Long> uniqueOrderIds = new HashSet<>(orderIds);
         return toAjax(orderMainService.batchConfirmation(uniqueOrderIds));
     }
+
+
+    /**
+     * 根据订单id查询发货订单
+     */
+    @GetMapping("/selectOrderDeliverByOrderId")
+    public TableDataInfo<OrderDeliverVo> selectOrderDeliverList(OrderDeliverBo bo) {
+        return orderDeliverService.selectOrderDeliverByOrderId(bo.getOrderId());
+    }
+
+    /**
+     * 查询订单物流信息列表
+     */
+    @GetMapping("/queryTrack")
+    public TrackVO queryTrack(OrderDeliverBo bo) {
+        return orderDeliverService.queryTrack(bo);
+    }
+
+    /**
+     * 查询当前订单的流程节点列表
+     */
+    @GetMapping("/getOrderFlowNodes/{orderId}")
+    public R<List<OrderCustomerFlowNodeLink>> getOrderFlowNodes(@PathVariable("orderId") Long orderId) {
+        return R.ok(orderCustomerFlowNodeLinkService.list(
+            Wrappers.lambdaQuery(OrderCustomerFlowNodeLink.class)
+                .eq(OrderCustomerFlowNodeLink::getOrderId, orderId)
+                .orderByAsc(OrderCustomerFlowNodeLink::getSort)
+        ));
+    }
 }

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

@@ -304,4 +304,12 @@ public class OrderMain extends TenantEntity {
      */
     private Integer evaluationStatus;
 
+    /*回款状态0未汇款 部分回款 2 全部回款*/
+    private String returnedStatus;
+
+    /**
+     * 联系人ID
+     */
+    private Long contactId;
+
 }

+ 8 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/bo/OrderMainBo.java

@@ -308,6 +308,14 @@ public class OrderMainBo extends BaseEntity {
      */
     private Integer evaluationStatus;
 
+    /*回款状态0未汇款 部分回款 2 全部回款*/
+    private String returnedStatus;
+
+    /**
+     * 联系人ID
+     */
+    private Long contactId;
+
     List<OrderProductBo> orderProductBos;
 
 

+ 11 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/domain/dto/ChangeReturnedStatusRequestDto.java

@@ -0,0 +1,11 @@
+package org.dromara.order.domain.dto;
+
+import lombok.Data;
+
+@Data
+public class ChangeReturnedStatusRequestDto {
+
+    private Long[] ids;
+
+    private String returnedStatus;
+}

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

@@ -439,4 +439,12 @@ public class OrderMainVo implements Serializable {
      */
     private String projectOrderNo;
 
+    /*回款状态0未汇款 部分回款 2 全部回款*/
+    private String returnedStatus;
+
+    /**
+     * 联系人ID
+     */
+    private Long contactId;
+
 }

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

@@ -127,4 +127,7 @@ public interface IOrderMainService extends IService<OrderMain> {
 
     /*根据id查询订单编号*/
     Map<Long, String> selectOrderNoByIds(Set<Long> ids);
+
+    Boolean changeReturnedStatusByIds(List<Long> ids, String returnedStatus);
+
 }

+ 44 - 12
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -11,7 +11,10 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboReference;
-import org.dromara.common.core.enums.*;
+import org.dromara.common.core.enums.AssigneeTypeConstants;
+import org.dromara.common.core.enums.OrderPayType;
+import org.dromara.common.core.enums.OrderStatus;
+import org.dromara.common.core.enums.SysPlatformYesNo;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.exception.api.ZhongcheException;
 import org.dromara.common.core.utils.MapstructUtils;
@@ -20,10 +23,9 @@ 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.dromara.customer.api.RemoteCustomerSalesService;
-import org.dromara.customer.api.RemoteCustomerService;
-import org.dromara.customer.api.RemotePartnerInfoService;
-import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.dromara.customer.api.*;
+import org.dromara.customer.api.domain.dto.CustomerInfoDTO;
+import org.dromara.customer.api.domain.vo.RemoteCustomerContactVo;
 import org.dromara.customer.api.domain.vo.RemoteCustomerSalesVo;
 import org.dromara.external.api.zhongche.RemoteZhongChePullService;
 import org.dromara.external.api.zhongche.domain.bo.OrderConfirmBo;
@@ -100,6 +102,9 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
     //客户订单流程
     private final IOrderCustomerFlowService orderCustomerFlowService;
 
+    @DubboReference
+    private RemoteCustomerContactService remoteCustomerContactService;
+
     @DubboReference
     private RemoteProductShoppingCartService remoteProductShoppingCartService;
 
@@ -363,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());
@@ -576,7 +582,12 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
     @Override
     @Transactional(rollbackFor = Exception.class)
     public Long insertOrder(PcSubmitOrderBo bo, OrderMainBo mainBo) {
-        RemoteCustomerSalesVo remoteCustomerSalesVo = remoteCustomerSalesService.selectCustomerSalesInfoByCustomerId(mainBo.getCustomerId());
+        CustomerInfoDTO customerInfoDTO = remoteCustomerService.selectCustomerInfoById(mainBo.getCustomerId());
+
+        RemoteCustomerContactVo remoteCustomerContactVo = remoteCustomerContactService.selectCustomerContactByCustomerIdAndUserId(mainBo.getCustomerId(), mainBo.getUserId());
+        if (ObjectUtils.isNotEmpty(remoteCustomerContactVo)) {
+            mainBo.setContactId(remoteCustomerContactVo.getId());
+        }
 
         LoginUser userInfo = remoteUserService.getUserInfo(mainBo.getUserId(), "000000");
         if (ObjectUtils.isNotEmpty(userInfo)) {
@@ -585,10 +596,10 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
                 mainBo.setCreateDept(userInfo.getDeptId());
             }
         }
-        if (null != remoteCustomerSalesVo) {
-            Long salesPersonId = remoteCustomerSalesVo.getSalesPersonId();//销售人员id
-            Long serviceStaffId = remoteCustomerSalesVo.getServiceStaffId();//服务人员
-            Long belongingDepartmentId = remoteCustomerSalesVo.getBelongingDepartmentId();//所属部门
+        if (null != customerInfoDTO) {
+            Long salesPersonId = customerInfoDTO.getSalesPersonId();//销售人员id
+            Long serviceStaffId = customerInfoDTO.getServiceStaffId();//服务人员
+            Long belongingDepartmentId = customerInfoDTO.getBelongingDepartmentId();//所属部门
             Set<Long> staffIds = new HashSet<>();
             Set<Long> deptIds = new HashSet<>();
 
@@ -602,7 +613,7 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
 
             Map<Long, String> deptMap = deptIds.isEmpty()
                 ? Collections.emptyMap()
-                : remoteComDeptService.selectDeptNameByIds(deptIds);
+                : remoteDeptService.selectDeptNameByIds(deptIds);
 
             mainBo.setBusinessStaff(staffMap.get(salesPersonId));
             mainBo.setCustomerService(staffMap.get(serviceStaffId));
@@ -1191,4 +1202,25 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
         }
         return resultMap;
     }
+
+    @Override
+    public Boolean changeReturnedStatusByIds(List<Long> ids, String returnedStatus) {
+        if (ids == null || ids.isEmpty()) {
+            return false;
+        }
+        try {
+            if (ids != null && !ids.isEmpty()) {
+                for (Long id : ids) {
+                    OrderMain update = new OrderMain();
+                    update.setId(id);
+                    update.setReturnedStatus(returnedStatus);
+                    baseMapper.updateById(update);
+                }
+            }
+        } catch (Exception e) {
+            log.error("修改回款状态失败", e);
+            return false;
+        }
+        return true;
+    }
 }

+ 8 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderReturnServiceImpl.java

@@ -20,6 +20,7 @@ import org.dromara.order.domain.OrderReturnItem;
 import org.dromara.order.domain.OrderReturnPickCrrc;
 import org.dromara.order.domain.bo.OrderReturnBo;
 import org.dromara.order.domain.bo.OrderReturnItemBo;
+import org.dromara.order.domain.vo.OrderReturnItemVo;
 import org.dromara.order.domain.vo.OrderReturnVo;
 import org.dromara.order.mapper.OrderReturnItemMapper;
 import org.dromara.order.mapper.OrderReturnMapper;
@@ -136,6 +137,13 @@ public class OrderReturnServiceImpl extends ServiceImpl<OrderReturnMapper, Order
         if (CollUtil.isNotEmpty(records)) {
             Set<Long> customerIds = records.stream().map(OrderReturnVo::getCustomerId).collect(Collectors.toSet());
             Map<Long, String> customerMap = remoteCustomerService.selectCustomerNameByIds(customerIds);
+            List<OrderReturnItemVo> orderReturnItemList=null;
+            for (OrderReturnVo record : records) {
+                orderReturnItemList=orderReturnItemMapper.selectVoList(new LambdaQueryWrapper<OrderReturnItem>()
+                    .eq(OrderReturnItem::getReturnId, record.getId()));
+                record.setOrderReturnItemList(orderReturnItemList);
+            }
+
             records.forEach(vo -> {
                 vo.setCustomerName(customerMap.get(vo.getCustomerId()));
             });

+ 44 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderStatusLogServiceImpl.java

@@ -10,6 +10,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.order.domain.OrderMain;
+import org.dromara.order.domain.vo.OrderMainVo;
+import org.dromara.order.mapper.OrderMainMapper;
 import org.springframework.stereotype.Service;
 import org.dromara.order.domain.bo.OrderStatusLogBo;
 import org.dromara.order.domain.vo.OrderStatusLogVo;
@@ -17,9 +20,11 @@ import org.dromara.order.domain.OrderStatusLog;
 import org.dromara.order.mapper.OrderStatusLogMapper;
 import org.dromara.order.service.IOrderStatusLogService;
 
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.Collection;
+import java.util.stream.Collectors;
 
 /**
  * 订单状态流转记录Service业务层处理
@@ -34,6 +39,8 @@ public class OrderStatusLogServiceImpl extends ServiceImpl<OrderStatusLogMapper,
 
     private final OrderStatusLogMapper baseMapper;
 
+    private final OrderMainMapper orderMainMapper;
+
     /**
      * 查询订单状态流转记录
      *
@@ -54,11 +61,16 @@ public class OrderStatusLogServiceImpl extends ServiceImpl<OrderStatusLogMapper,
      */
     @Override
     public TableDataInfo<OrderStatusLogVo> queryPageList(OrderStatusLogBo bo, PageQuery pageQuery) {
+
         LambdaQueryWrapper<OrderStatusLog> lqw = buildQueryWrapper(bo);
+
         Page<OrderStatusLogVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+
         return TableDataInfo.build(result);
     }
 
+
+
     /**
      * 查询符合条件的订单状态流转记录列表
      *
@@ -74,9 +86,40 @@ public class OrderStatusLogServiceImpl extends ServiceImpl<OrderStatusLogMapper,
     private LambdaQueryWrapper<OrderStatusLog> buildQueryWrapper(OrderStatusLogBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<OrderStatusLog> lqw = Wrappers.lambdaQuery();
+        // 核心逻辑:处理主订单ID,查询其关联的所有子订单日志
+        // ==========================================
+        if (null != bo.getOrderId()) {
+            // 1. 查询订单主表信息 (注意:这里会产生一次数据库查询)
+            OrderMainVo orderMainVo = orderMainMapper.selectVoById(bo.getOrderId());
+
+            if (null != orderMainVo) {
+                List<Long> targetOrderIds = new ArrayList<>();
+
+                // 2. 加入自身ID (兼容传入的是子单ID的情况,确保能查到当前单的数据)
+                targetOrderIds.add(orderMainVo.getId());
+
+                // 3. 查询该订单下的所有子订单
+                List<OrderMain> subOrderList = orderMainMapper.selectList(
+                    new LambdaQueryWrapper<OrderMain>()
+                        .eq(OrderMain::getParentOrderId, orderMainVo.getId())
+                );
+
+                // 4. 如果有子订单,将子订单ID加入列表
+                if (subOrderList != null && !subOrderList.isEmpty()) {
+                    List<Long> subOrderIds = subOrderList.stream()
+                        .map(OrderMain::getId)
+                        .collect(Collectors.toList());
+                    targetOrderIds.addAll(subOrderIds);
+                }
+
+                // 5. 构建 IN 查询条件
+                // 这一步会替代原本的 eq("order_id", ...) 逻辑
+                lqw.in(OrderStatusLog::getOrderId, targetOrderIds);
+            }
+        }
         lqw.orderByAsc(OrderStatusLog::getId);
         lqw.eq(StringUtils.isNotBlank(bo.getOrderNo()), OrderStatusLog::getOrderNo, bo.getOrderNo());
-        lqw.eq(bo.getOrderId() != null, OrderStatusLog::getOrderId, bo.getOrderId());
+//        lqw.eq(bo.getOrderId() != null, OrderStatusLog::getOrderId, bo.getOrderId());
         lqw.eq(StringUtils.isNotBlank(bo.getCustomerNo()), OrderStatusLog::getCustomerNo, bo.getCustomerNo());
         lqw.eq(bo.getCustomerId() != null, OrderStatusLog::getCustomerId, bo.getCustomerId());
         lqw.eq(StringUtils.isNotBlank(bo.getDeliverMethod()), OrderStatusLog::getDeliverMethod, bo.getDeliverMethod());

+ 2 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java

@@ -136,7 +136,7 @@ public class ProductCategoryController extends BaseController {
     * 查询产品分类树(排除节点)
     * */
     @GetMapping("/tree/exclude/{excludeIds}")
-    public R<List<Tree<Long>>> listExclude(@PathVariable("excludeIds") String excludeIds) {
-        return R.ok(productCategoryService.queryPageListExclude(excludeIds));
+    public R<List<Tree<Long>>> listExclude(@PathVariable("excludeIds") String excludeIds,@RequestParam Long platform) {
+        return R.ok(productCategoryService.queryPageListExclude(excludeIds, platform));
     }
 }

+ 129 - 9
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/mini/MiniProductController.java

@@ -1,27 +1,28 @@
 package org.dromara.product.controller.mini;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
 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.product.domain.ProductBrowsingHistory;
+import org.dromara.product.domain.ProductCollect;
+import org.dromara.product.domain.ProductFavorites;
 import org.dromara.product.domain.ProductShoppingCart;
-import org.dromara.product.domain.bo.PcProductBo;
-import org.dromara.product.domain.bo.ProductBaseBo;
-import org.dromara.product.domain.bo.ProductShoppingCartBo;
+import org.dromara.product.domain.bo.*;
 import org.dromara.product.domain.vo.PcProductVo;
 import org.dromara.product.domain.vo.ProductBaseVo;
-import org.dromara.product.service.IProductBaseService;
-import org.dromara.product.service.IProductShoppingCartService;
+import org.dromara.product.domain.vo.ProductCategoryVo;
+import org.dromara.product.service.*;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
-import java.util.Arrays;
-import java.util.Objects;
+import java.util.*;
 
 /**
- * 首页
+ * 小程序商品
  *
  * @author
  * @date 2026/1/26 下午6:41
@@ -34,9 +35,24 @@ public class MiniProductController {
 
     //商品
     private final IProductBaseService productBaseService;
-
     //购物车
     private final IProductShoppingCartService productShoppingCartService;
+    //商品浏览记录
+    private final IProductBrowsingHistoryService productBrowsingHistoryService;
+    //商品收藏
+    private final IProductCollectService productCollectService;
+    //商品收藏夹
+    private final IProductFavoritesService productFavoritesService;
+    //商品分类
+    private final IProductCategoryService productCategoryService;
+
+    /**
+     * 查询产品分类树
+     * */
+    @GetMapping("getProductCategoryTree")
+    public R<List<Tree<Long>>> getProductCategoryTree(ProductCategoryBo bo) {
+        return R.ok(productCategoryService.selectCategoryTreeList(bo));
+    }
 
     /**
      * 获取客户商品池的商品
@@ -142,4 +158,108 @@ public class MiniProductController {
         bo.setCustomerId(LoginHelper.getLoginUser().getCustomerId());
         return productBaseService.getProtocolProductsPage(bo, pageQuery);
     }
+
+    /**
+     * 新增商品浏览记录
+     */
+    @PostMapping("/addProductBrowsingHistory/{productId}")
+    public R addProductBrowsingHistory(@PathVariable Long productId) {
+        ProductBrowsingHistoryBo productBrowsingHistoryBo = new ProductBrowsingHistoryBo();
+        productBrowsingHistoryBo.setProductId(productId);
+        productBrowsingHistoryBo.setUserId(LoginHelper.getUserId());
+        productBrowsingHistoryBo.setCustomerId(LoginHelper.getLoginUser().getCustomerId());
+        productBrowsingHistoryService.insertByBo(productBrowsingHistoryBo);
+        return R.ok();
+    }
+
+    /**
+     * 删除浏览记录
+     */
+    @DeleteMapping("/deleteProductBrowsingHistory/{ids}")
+    public R deleteProductBrowsingHistory(@PathVariable Long[] ids) {
+        productBrowsingHistoryService.remove(Wrappers.lambdaQuery(ProductBrowsingHistory.class)
+            .in(ProductBrowsingHistory::getProductId, ids)
+            .eq(ProductBrowsingHistory::getUserId, LoginHelper.getUserId())
+        );
+        return R.ok();
+    }
+
+    /**
+     * 浏览记录的商品
+     */
+    @GetMapping("/getProductBrowsingHistory")
+    public R<Map<String, List<PcProductVo>>> getProductBrowsingHistory(@RequestParam(required = false) Date startTime, @RequestParam(required = false) Date endTime) {
+        return R.ok(productBaseService.getProductBrowsingHistory(LoginHelper.getUserId(), startTime, endTime));
+    }
+
+    /**
+     * 收藏商品
+     */
+    @PostMapping("/addProductCollect")
+    public R addProductCollect(@RequestBody ProductCollectBo bo) {
+        //如果未传收藏夹id,则查询有没有默认收藏夹,如果没有就新增收藏夹
+        if (bo.getFavoritesId() == null) {
+            ProductFavorites one = productFavoritesService.getOne(Wrappers.lambdaQuery(ProductFavorites.class)
+                .eq(ProductFavorites::getUserId, LoginHelper.getUserId())
+                .eq(ProductFavorites::getIsDefault, "0")
+            );
+            if (one == null) {
+                one = new ProductFavorites();
+                one.setUserId(LoginHelper.getUserId());
+                one.setCustomerId(LoginHelper.getLoginUser().getCustomerId());
+                one.setTitle("默认收藏夹");
+                one.setIsDefault("0");
+                productFavoritesService.save(one);
+            }
+            bo.setFavoritesId(one.getId());
+        }
+        bo.setUserId(LoginHelper.getUserId());
+        bo.setCustomerId(LoginHelper.getLoginUser().getCustomerId());
+        productCollectService.insertByBo(bo);
+        return R.ok();
+    }
+
+    /**
+     * 取消收藏
+     */
+    @DeleteMapping("/cancelProductCollect")
+    public R cancelProductCollect(ProductCollectBo bo) {
+        productCollectService.remove(Wrappers.lambdaQuery(ProductCollect.class)
+            .eq(ProductCollect::getUserId, LoginHelper.getUserId())
+            .eq(ProductCollect::getProductId, bo.getProductId())
+        );
+        return R.ok();
+    }
+
+    /**
+     * 收藏夹商品列表
+     */
+    @GetMapping("/getFavoritesProductPage")
+    public TableDataInfo<PcProductVo> getFavoritesProductPage(Long favoritesId, PageQuery pageQuery) {
+        return productBaseService.getFavoritesProductPage(favoritesId, LoginHelper.getUserId(), pageQuery);
+    }
+
+    /**
+     * 查询商品是否在默认收藏夹收藏
+     */
+    @GetMapping("/isProductInDefaultCollect/{productIds}")
+    public R isProductInDefaultCollect(@PathVariable Long[] productIds) {
+        //查询商品是否在默认收藏夹收藏
+        ProductFavorites one = productFavoritesService.getOne(Wrappers.lambdaQuery(ProductFavorites.class)
+            .eq(ProductFavorites::getUserId, LoginHelper.getUserId())
+            .eq(ProductFavorites::getIsDefault, "0")
+        );
+        if (one == null) {
+            one = new ProductFavorites();
+            one.setUserId(LoginHelper.getUserId());
+            one.setTitle("默认收藏夹");
+            one.setIsDefault("0");
+            productFavoritesService.save(one);
+        }
+        return R.ok(productCollectService.exists(Wrappers.lambdaQuery(ProductCollect.class)
+            .eq(ProductCollect::getUserId, LoginHelper.getUserId())
+            .eq(ProductCollect::getFavoritesId, one.getId())
+            .in(ProductCollect::getProductId, productIds)));
+    }
+
 }

+ 13 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/IndexProductController.java

@@ -2,6 +2,7 @@ package org.dromara.product.controller.pc;
 
 import cn.hutool.core.lang.tree.Tree;
 import cn.hutool.http.HttpUtil;
+import cn.hutool.json.JSONUtil;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -29,6 +30,8 @@ import java.util.Map;
 public class IndexProductController {
     //商品
     private final IProductBaseService productBaseService;
+    //商品审核
+    private final IProductBaseAuditService productBaseAuditService;
     //商品分类
     private final IProductCategoryService productCategoryService;
     //商品品牌
@@ -112,6 +115,16 @@ public class IndexProductController {
         return R.ok(productBaseVo);
     }
 
+    /**
+    * 获取商品预览界面
+    * */
+    @GetMapping("getProductPreview/{id}")
+    public R<ProductBaseVo> getProductPreview(@PathVariable Long id) {
+        String productData = productBaseAuditService.queryById(id).getProductData();
+
+        return R.ok(JSONUtil.toBean(productData, ProductBaseVo.class));
+    }
+
 
 
     /**

+ 3 - 7
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/MyProductController.java

@@ -21,11 +21,7 @@ import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
 import java.math.BigDecimal;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
+import java.util.*;
 
 /**
  * 我的商品相关接口
@@ -84,8 +80,8 @@ public class MyProductController {
      * 浏览记录的商品
      */
     @GetMapping("/getProductBrowsingHistory")
-    public R<Map<String, List<PcProductVo>>> getProductBrowsingHistory() {
-        return R.ok(productBaseService.getProductBrowsingHistory(LoginHelper.getUserId()));
+    public R<Map<String, List<PcProductVo>>> getProductBrowsingHistory(@RequestParam(required = false) Date startTime, @RequestParam(required = false) Date endTime) {
+        return R.ok(productBaseService.getProductBrowsingHistory(LoginHelper.getUserId(), startTime, endTime));
     }
 
     /**

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java

@@ -299,7 +299,7 @@ public class ProductBaseBo extends BaseEntity {
     /**
      * 暂估采购价
      */
-    private java.math.BigDecimal estimatedPurchasePrice;
+    private java.math.BigDecimal maxPurchasePrice;
 
     /**
      * 供应价

+ 2 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java

@@ -8,6 +8,7 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 
 import java.util.Collection;
+import java.util.Date;
 import java.util.List;
 import java.util.Map;
 
@@ -171,7 +172,7 @@ public interface IProductBaseService extends IService<ProductBase>{
     /**
     * PC端商品浏览记录
     * */
-    Map<String,List<PcProductVo>> getProductBrowsingHistory(Long userId);
+    Map<String,List<PcProductVo>> getProductBrowsingHistory(Long userId , Date startTime, Date endTime);
 
     /**
     * PC端商品收藏夹

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductCategoryService.java

@@ -101,7 +101,7 @@ public interface IProductCategoryService extends IService<ProductCategory>{
      * @param excludeIds 排除节点
      * @return 产品分类列表
      */
-    List<Tree<Long>> queryPageListExclude(String excludeIds);
+    List<Tree<Long>> queryPageListExclude(String excludeIds,Long platform);
 
     /**
      * 获取分类下一级的分类列表

+ 6 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseAuditServiceImpl.java

@@ -172,6 +172,12 @@ public class ProductBaseAuditServiceImpl extends ServiceImpl<ProductBaseAuditMap
             lqw.eq(bo.getQueryType()==1,ProductBaseAudit::getCreateById,LoginHelper.getLoginUser().getSupplierId());
             lqw.eq(bo.getQueryType()==2,ProductBaseAudit::getCreateByType,2);
             lqw.eq(bo.getQueryType()==2,ProductBaseAudit::getCreateById,LoginHelper.getLoginUser().getPartnerId());
+        }else{
+            if(bo.getAuditStatus()==0){
+                lqw.eq(ProductBaseAudit::getCreateByType,0);
+                lqw.eq(ProductBaseAudit::getCreateById,LoginHelper.getUserId());
+            }
+
         }
 //        if(ObjectUtil.isNotEmpty(bo.getQueryType())){
 //            lqw.apply(bo.getQueryType()==1,"JSON_EXTRACT(product_data, '$.createByType') = {0}", 1);

+ 16 - 9
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java

@@ -769,7 +769,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
 
         // 映射扩展字段
         extend.setSupplierNo(bo.getSupplierNo());
-        extend.setPromotionTitle(extend.getPromotionTitle());
+        extend.setPromotionTitle(bo.getPromotionTitle());
         extend.setInvoiceName(bo.getInvoiceName());
         extend.setSpecificationsCode(bo.getSpecificationsCode());
         extend.setInvoiceSpecs(bo.getInvoiceSpecs());
@@ -804,7 +804,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         priceInventory.setMemberPrice(bo.getMemberPrice());
         priceInventory.setMinSellingPrice(bo.getMinSellingPrice());
         priceInventory.setPurchasingPrice(bo.getPurchasingPrice());
-        priceInventory.setMaxPurchasePrice(bo.getEstimatedPurchasePrice());
+        priceInventory.setMaxPurchasePrice(bo.getMaxPurchasePrice());
         priceInventory.setCurrency(bo.getCurrency());
         priceInventory.setTaxRate(bo.getTaxRate());
         priceInventory.setMinOrderQuantity(bo.getMinOrderQuantity());
@@ -889,8 +889,12 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         // 如果没有传价格相关信息,不做任何操作
         if (bo.getMarketPrice() == null && bo.getMemberPrice() == null &&
             bo.getMinSellingPrice() == null && bo.getPurchasingPrice() == null &&
-            bo.getEstimatedPurchasePrice() == null && bo.getTotalInventory() == null &&
-            bo.getNowInventory() == null && bo.getVirtualInventory() == null) {
+            bo.getMaxPurchasePrice() == null && bo.getTotalInventory() == null &&
+            bo.getNowInventory() == null && bo.getVirtualInventory() == null &&
+            bo.getTaxRate() == null && bo.getTaxationId() == null &&
+            bo.getSupplyPrice() == null && bo.getSupplyValidityPeriod() == null &&
+            bo.getSupplyPostStatus() == null
+            ) {
             return;
         }
 
@@ -903,7 +907,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             if (bo.getPurchasingPrice() != null) existing.setPurchasingPrice(bo.getPurchasingPrice());
             if (bo.getTaxRate() != null) existing.setTaxRate(bo.getTaxRate());
             if (bo.getTaxationId() != null) existing.setTaxationId(bo.getTaxationId());
-            if (bo.getEstimatedPurchasePrice() != null) existing.setMaxPurchasePrice(bo.getEstimatedPurchasePrice());
+            if (bo.getMaxPurchasePrice() != null) existing.setMaxPurchasePrice(bo.getMaxPurchasePrice());
             if(bo.getTotalInventory() != null) existing.setTotalInventory(bo.getVirtualInventory()+existing.getNowInventory());
             if(bo.getNowInventory() != null) existing.setNowInventory(bo.getNowInventory());
             if(bo.getVirtualInventory() != null) existing.setVirtualInventory(bo.getVirtualInventory());
@@ -1589,10 +1593,13 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
      * @param userId
      */
     @Override
-    public Map<String,List<PcProductVo>> getProductBrowsingHistory(Long userId) {
-        List<ProductBrowsingHistoryVo> productBrowsingHistoryVos = productBrowsingHistoryMapper.selectVoList(Wrappers.lambdaQuery(ProductBrowsingHistory.class)
-            .eq(ProductBrowsingHistory::getUserId, userId)
-        );
+    public Map<String,List<PcProductVo>> getProductBrowsingHistory(Long userId, Date startTime, Date endTime) {
+        LambdaQueryWrapper<ProductBrowsingHistory> wrapper = Wrappers.lambdaQuery(ProductBrowsingHistory.class)
+            .eq(ProductBrowsingHistory::getUserId, userId);
+        if(ObjectUtil.isNotEmpty(startTime)){
+            wrapper.between(ProductBrowsingHistory::getCreateTime, DateUtil.beginOfDay(startTime), DateUtil.endOfDay(endTime));
+        }
+        List<ProductBrowsingHistoryVo> productBrowsingHistoryVos = productBrowsingHistoryMapper.selectVoList(wrapper);
         if (CollUtil.isNotEmpty(productBrowsingHistoryVos)) {
             //将浏览记录通过创建时间的日分组
             Map<String, List<ProductBrowsingHistoryVo>> collect =

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java

@@ -366,7 +366,7 @@ public class ProductBrandServiceImpl  extends ServiceImpl<ProductBrandMapper, Pr
         if (CollUtil.isEmpty(buckets)) {
             return null;
         }
-        List<Long> brandIds = buckets.stream().map(LongTermsBucket::key).toList();
+        List<Long> brandIds = buckets.stream().map(bucket -> Long.parseLong(String.valueOf(bucket.key()))).toList();
         List<ProductBrandVo> productBrandVos = baseMapper.selectVoList(Wrappers.lambdaQuery(ProductBrand.class)
             .in(ProductBrand::getId, brandIds));
         return productBrandVos;

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryRecommendedLinkServiceImpl.java

@@ -85,7 +85,7 @@ public class ProductCategoryRecommendedLinkServiceImpl  extends ServiceImpl<Prod
     private LambdaQueryWrapper<ProductCategoryRecommendedLink> buildQueryWrapper(ProductCategoryRecommendedLinkBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<ProductCategoryRecommendedLink> lqw = Wrappers.lambdaQuery();
-        lqw.orderByAsc(ProductCategoryRecommendedLink::getId);
+        lqw.orderByAsc(ProductCategoryRecommendedLink::getCreateTime);
         lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), ProductCategoryRecommendedLink::getProductNo, bo.getProductNo());
         lqw.eq(bo.getCategoryId() != null, ProductCategoryRecommendedLink::getCategoryId, bo.getCategoryId());
         lqw.eq(bo.getSort() != null, ProductCategoryRecommendedLink::getSort, bo.getSort());

+ 3 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java

@@ -273,9 +273,10 @@ public class ProductCategoryServiceImpl  extends ServiceImpl<ProductCategoryMapp
      * @return 产品分类列表
      */
     @Override
-    public List<Tree<Long>> queryPageListExclude(String excludeIds) {
+    public List<Tree<Long>> queryPageListExclude(String excludeIds,Long platform) {
         LambdaQueryWrapper<ProductCategory> lqw = new LambdaQueryWrapper<>();
         lqw.ne(StringUtils.isNotBlank(excludeIds), ProductCategory::getId, excludeIds);
+        lqw.eq(ProductCategory::getPlatform, platform);
         return buildTreeSelect(baseMapper.selectVoList(lqw));
     }
 
@@ -321,7 +322,7 @@ public class ProductCategoryServiceImpl  extends ServiceImpl<ProductCategoryMapp
         if (CollUtil.isEmpty(buckets)) {
             return null;
         }
-        List<Long> categoryIds = buckets.stream().map(LongTermsBucket::key).toList();
+        List<Long> categoryIds = buckets.stream().map(bucket -> Long.parseLong(String.valueOf(bucket.key()))).toList();
         List<ProductCategoryVo> productBrandVos = baseMapper.selectVoList(Wrappers.lambdaQuery(ProductCategory.class)
             .in(ProductCategory::getId, categoryIds));
         return productBrandVos;

+ 18 - 3
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProtocolInfoServiceImpl.java

@@ -1,5 +1,6 @@
 package org.dromara.product.service.impl;
 
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
@@ -11,6 +12,8 @@ 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.api.RemoteCustomerService;
+import org.dromara.customer.api.domain.dto.CustomerInfoDTO;
 import org.dromara.product.domain.ProtocolProducts;
 import org.dromara.product.mapper.ProtocolProductsMapper;
 import org.dromara.system.api.RemoteComStaffService;
@@ -41,6 +44,9 @@ public class ProtocolInfoServiceImpl  extends ServiceImpl<ProtocolInfoMapper, Pr
     @DubboReference
     private RemoteComStaffService remoteComStaffService;
 
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
     /**
      * 查询协议信息
      *
@@ -50,9 +56,18 @@ public class ProtocolInfoServiceImpl  extends ServiceImpl<ProtocolInfoMapper, Pr
     @Override
     public ProtocolInfoVo queryById(Long id){
         ProtocolInfoVo item = baseMapper.selectVoById(id);
-        Map<Long, String> staffMap = remoteComStaffService.selectStaffNameByIds(Set.of(item.getSalesmanId(), item.getServiceId()));
-        item.setSalesmanName(staffMap.get(item.getSalesmanId()));
-        item.setServiceName(staffMap.get(item.getServiceId()));
+        if(ObjectUtil.isNotEmpty(item.getSalesmanId()) && ObjectUtil.isNotEmpty(item.getServiceId())){
+            Map<Long, String> staffMap = remoteComStaffService.selectStaffNameByIds(Set.of(item.getSalesmanId(), item.getServiceId()));
+            item.setSalesmanName(staffMap.get(item.getSalesmanId()));
+            item.setServiceName(staffMap.get(item.getServiceId()));
+        }
+        //获取客户信息
+        if (ObjectUtil.isNotEmpty(item.getCustomerId())){
+            CustomerInfoDTO customerInfoDTO = remoteCustomerService.selectCustomerInfoById(item.getCustomerId());
+
+            item.setCustomerName(customerInfoDTO.getCustomerName());
+            item.setCustomerNo(customerInfoDTO.getCustomerNo());
+        }
         return item;
     }
 

+ 0 - 45
ruoyi-modules/ruoyi-product/src/main/resources/application.yml

@@ -34,48 +34,3 @@ spring:
       - optional:nacos:application-common.yml
       - optional:nacos:datasource.yml
       - optional:nacos:${spring.application.name}.yml
---- # elasticsearch 功能配置
-# 文档地址: https://www.easy-es.cn/
-# 更改包名需要去 EasyEsConfiguration 修改包扫描(后续版本支持配置文件读取)
-easy-es:
-  # 是否开启EE自动配置
-  enable: true
-  # 兼容模式
-  compatible: true
-  # es连接地址+端口 格式必须为ip:port,如果是集群则可用逗号隔开
-  address : 119.97.180.88:9200
-  # 默认为http
-  schema: http
-  # 注意ES建议使用账号认证 不使用会报警告日志
-  #如果无账号密码则可不配置此行
-  username: elastic
-  #如果无账号密码则可不配置此行
-  password: kRhwhe4Mf4pyPYHN
-  # 心跳策略时间 单位:ms
-  keep-alive-millis: 18000
-  # 连接超时时间 单位:ms
-  connectTimeout: 100000
-  # 通信超时时间 单位:ms
-  socketTimeout: 100000
-  # 连接请求超时时间 单位:ms
-  connectionRequestTimeout: 100000
-  # 最大连接数 单位:个
-  maxConnTotal: 100
-  # 最大连接路由数 单位:个
-  maxConnPerRoute: 100
-  global-config:
-    # 开启控制台打印通过本框架生成的DSL语句,默认为开启,测试稳定后的生产环境建议关闭,以提升少量性能
-    print-dsl: true
-    # 异步处理索引是否阻塞主线程 默认阻塞 数据量过大时调整为非阻塞异步进行 项目启动更快
-    asyncProcessIndexBlocking: true
-    db-config:
-      # 是否开启下划线转驼峰 默认为false
-      map-underscore-to-camel-case: true
-      # id生成策略 customize为自定义,id值由用户生成,比如取MySQL中的数据id,如缺省此项配置,则id默认策略为es自动生成
-      id-type: customize
-      # 字段更新策略 默认为not_null
-      field-strategy: not_null
-      # 默认开启,查询若指定了size超过1w条时也会自动开启,开启后查询所有匹配数据,若不开启,会导致无法获取数据总条数,其它功能不受影响.
-      enable-track-total-hits: true
-      # 数据刷新策略,默认为不刷新
-      refresh-policy: immediate

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml

@@ -301,7 +301,7 @@
             p.member_price AS standardPrice,
             p.min_selling_price AS certificatePrice,
             p.purchasing_price AS purchasePrice,
-            p.max_purchase_price AS estimatedPurchasePrice,
+            p.max_purchase_price AS maxPurchasePrice,
             p.tax_rate AS taxRate,
             p.currency,
             p.min_order_quantity AS minOrderQuantity,

+ 144 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/MenuSqlGenerator.java

@@ -0,0 +1,144 @@
+package org.dromara.system;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class MenuSqlGenerator {
+
+    // 内部类:模拟菜单数据结构
+    static class MenuItem {
+        String path;
+        String title;
+        String icon;
+        List<MenuItem> children;
+
+        public MenuItem(String path, String title, String icon) {
+            this.path = path;
+            this.title = title;
+            this.icon = icon;
+            this.children = new ArrayList<>();
+        }
+    }
+
+    public static void main(String[] args) {
+        // 1. 构建数据源 (模拟你提供的JSON数组)
+        List<MenuItem> menus = new ArrayList<>();
+
+        // --- 企业账户 ---
+        MenuItem enterprise = new MenuItem("/enterprise", "企业账户", "workbench1");
+        enterprise.children.add(new MenuItem("/enterprise/companyInfo", "企业信息", ""));
+        enterprise.children.add(new MenuItem("/enterprise/messageNotice", "消息通知", ""));
+        enterprise.children.add(new MenuItem("/easybuv", "地址管理", "")); // 注意:原数据path似乎不在enterprise下,这里按原样保留
+        enterprise.children.add(new MenuItem("/enterprise/invoiceManage", "发票抬头管理", ""));
+        enterprise.children.add(new MenuItem("/enterprise/purchasePlan", "专属采购方案", ""));
+        enterprise.children.add(new MenuItem("/enterprise/agreementSupply", "协议供货", ""));
+        enterprise.children.add(new MenuItem("/enterprise/myCollection", "我的收藏", ""));
+        enterprise.children.add(new MenuItem("/enterprise/purchaseHistory", "历史购买", ""));
+        enterprise.children.add(new MenuItem("/enterprise/myFootprint", "我的足迹", ""));
+        menus.add(enterprise);
+
+        // --- 交易管理 ---
+        MenuItem order = new MenuItem("/order", "交易管理", "workbench2");
+        order.children.add(new MenuItem("/order/orderManage", "订单管理", ""));
+        order.children.add(new MenuItem("/order/orderAudit", "审核订单", ""));
+        order.children.add(new MenuItem("/order/afterSale", "售后服务", ""));
+        order.children.add(new MenuItem("/order/batchOrder", "批量下单", ""));
+        order.children.add(new MenuItem("/order/orderEvaluation", "订单评价", ""));
+        menus.add(order);
+
+        // --- 组织管理 ---
+        MenuItem org = new MenuItem("/organization", "组织管理", "workbench3");
+        org.children.add(new MenuItem("/i", "个人信息", ""));
+        org.children.add(new MenuItem("/organization/deptManage", "部门管理", ""));
+        org.children.add(new MenuItem("/organization/staffManage", "人员管理", ""));
+        org.children.add(new MenuItem("/organization/roleManage", "角色管理", ""));
+        org.children.add(new MenuItem("/organization/approvalFlow", "审批流程", ""));
+        org.children.add(new MenuItem("/organization/groupEnterprise", "集团关联企业", ""));
+        menus.add(org);
+
+        // --- 成本管理 ---
+        MenuItem cost = new MenuItem("/cost", "成本管理", "workbench4");
+        cost.children.add(new MenuItem("/cost/itemExpense", "分项费用", ""));
+        cost.children.add(new MenuItem("/cost/quotaControl", "额度控制", ""));
+        menus.add(cost);
+
+        // --- 对账管理 ---
+        MenuItem recon = new MenuItem("/reconciliation", "对账管理", "workbench5");
+        recon.children.add(new MenuItem("/reconciliation/billManage", "对账单管理", ""));
+        recon.children.add(new MenuItem("/reconciliation/invoiceManage", "开票管理", ""));
+        menus.add(recon);
+
+        // --- 增值服务 ---
+        MenuItem valueAdded = new MenuItem("/valueAdded", "增值服务", "workbench6");
+        valueAdded.children.add(new MenuItem("/valueAdded/maintenance", "维保服务", ""));
+        valueAdded.children.add(new MenuItem("/valueAdded/complaint", "投诉与建议", ""));
+        menus.add(valueAdded);
+
+        // --- 采购分析 ---
+        MenuItem analysis = new MenuItem("/analysis", "采购分析", "workbench7");
+        analysis.children.add(new MenuItem("/analysis/orderAnalysis", "订单交易分析", ""));
+        analysis.children.add(new MenuItem("/analysis/purchaseDetail", "商品采购明细", ""));
+        analysis.children.add(new MenuItem("/analysis/orderStatus", "订单执行状态", ""));
+        analysis.children.add(new MenuItem("/analysis/settlementStatus", "对账结算状况", ""));
+        analysis.children.add(new MenuItem("/analysis/deptPurchase", "部门采购金额", ""));
+        menus.add(analysis);
+
+        // 2. 执行生成
+        generateSql(menus);
+    }
+
+    /**
+     * 生成SQL逻辑
+     */
+    public static void generateSql(List<MenuItem> menus) {
+        // 基础ID计数器,模拟数据库自增或雪花算法
+        long currentId = 2049013816429805570L;
+
+        StringBuilder sqlBuilder = new StringBuilder();
+        String tableName = "yoe_system_db.sys_menu";
+
+        // 公共字段常量
+        String component = "NULL"; // 根据你的参考SQL,component 都是 NULL
+        String queryParam = "NULL";
+        int isFrame = 1;
+        int isCache = 0;
+        int visible = 0;
+        int status = 0;
+        String perms = "NULL";
+        String createDept = "103";
+        String createBy = "1";
+        String createTime = "NOW()"; // 使用数据库函数或填入具体时间字符串
+        String updateBy = "1";
+        String updateTime = "NOW()";
+        String remark = "";
+        String platformCode = "home";
+
+        for (MenuItem menu : menus) {
+            // --- 生成父级菜单 SQL ---
+            long parentId = currentId++;
+            String parentPath = menu.path.replace("/", ""); // 去除斜杠作为path字段
+
+            sqlBuilder.append(String.format(
+                "INSERT INTO `%s` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `platform_code`) VALUES (%d, '%s', 0, 1, '%s', %s, %s, %d, %d, 'M', '%d', '%d', %s, '%s', %s, %s, %s, %s, %s, '%s', '%s');\n",
+                tableName, parentId, menu.title, parentPath, component, queryParam, isFrame, isCache, visible, status, perms, menu.icon, createDept, createBy, createTime, updateBy, updateTime, remark, platformCode
+            ));
+
+            // --- 生成子级菜单 SQL ---
+            int childOrder = 1;
+            for (MenuItem child : menu.children) {
+                long childId = currentId++;
+                String childPath = child.path.startsWith("/") ? child.path.substring(1) : child.path;
+
+                sqlBuilder.append(String.format(
+                    "INSERT INTO `%s` (`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`, `platform_code`) VALUES (%d, '%s', %d, %d, '%s', %s, %s, %d, %d, 'C', '%d', '%d', %s, '%s', %s, %s, %s, %s, %s, '%s', '%s');\n",
+                    tableName, childId, child.title, parentId, childOrder, childPath, component,
+                    queryParam, isFrame, isCache, visible, status, perms, child.icon, createDept, createBy, createTime, updateBy, updateTime, remark, platformCode
+                ));
+                childOrder++;
+            }
+        }
+
+        // 3. 输出结果
+        System.out.println(sqlBuilder.toString());
+    }
+}

+ 10 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysTaxCodeController.java

@@ -2,6 +2,7 @@ package org.dromara.system.controller;
 
 import java.util.List;
 
+import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
@@ -103,4 +104,13 @@ public class SysTaxCodeController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(sysTaxCodeService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+    * 获取税收编码树
+    * */
+    @GetMapping("/tree")
+    public R<List<Tree<Long>>> tree(SysTaxCodeBo bo) {
+        List<SysTaxCodeVo> sysTaxCodeVos = sysTaxCodeService.queryList(bo);
+        return R.ok(sysTaxCodeService.buildTaxCodeTreeSelect(sysTaxCodeVos));
+    }
 }

+ 52 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/mini/MiniSystemController.java

@@ -0,0 +1,52 @@
+package org.dromara.system.controller.mini;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.system.domain.SysAnnouncement;
+import org.dromara.system.service.ISysAnnouncementService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+
+/**
+ * 小程序系统
+ *
+ * @author
+ * @date 2026/1/26 下午6:41
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/miniSystem")
+public class MiniSystemController {
+
+    //平台公告
+    private final ISysAnnouncementService sysAnnouncementService;
+
+
+    /**
+     * 优易咨迅(平台公告)
+     */
+    @GetMapping("/getYouYiZiXunPage")
+    public R<List<SysAnnouncement>> getYouYiZiXunPage(PageQuery pageQuery) {
+        List<SysAnnouncement> list = sysAnnouncementService.list(Wrappers.<SysAnnouncement>lambdaQuery(SysAnnouncement.class)
+            .eq(SysAnnouncement::getIsShow, 1)
+        );
+        return R.ok(list);
+    }
+
+    /**
+     * 咨迅详情
+     */
+    @GetMapping("/getYouYiZiXunInfo/{id}")
+    public R<SysAnnouncement> getYouYiZiXunInfo(@PathVariable Long id) {
+        SysAnnouncement sysAnnouncement = sysAnnouncementService.getById(id);
+        return R.ok(sysAnnouncement);
+    }
+}

+ 5 - 3
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSysUserController.java

@@ -27,13 +27,14 @@ public class PcSysUserController extends BaseController {
     /**
      * 根据手机号查询用户(用于注册前校验)
      */
-    @GetMapping("/selectByPhone/{phonenumber}")
-    public R<SysUserVo> selectUserByPhonenumber(@PathVariable String phonenumber) {
+    @GetMapping("/selectByPhone")
+    public R<SysUserVo> selectUserByPhonenumber(@RequestParam String phonenumber,
+                                                @RequestParam String type) {
         if (StringUtils.isEmpty(phonenumber)) {
             return R.fail("手机号不能为空");
         }
 
-        SysUserVo user = sysUserService.selectUserByPhonenumber(phonenumber);
+        SysUserVo user = sysUserService.selectUserByPhonenumber(phonenumber, type);
         if (user != null) {
             // 可选:返回用户信息,前端可提示“该手机号已注册”
             return R.fail("该手机号已注册");
@@ -110,4 +111,5 @@ public class PcSysUserController extends BaseController {
         sysUserService.checkUserDataScope(user.getUserId());
         return toAjax(sysUserService.resetUserPhonenumber(user.getUserId(), user.getNewPhonenumber()));
     }
+
 }

+ 53 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSystemController.java

@@ -0,0 +1,53 @@
+package org.dromara.system.controller.pc;
+
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.bo.SysRoleBo;
+import org.dromara.system.domain.vo.SysMenuVo;
+import org.dromara.system.domain.vo.SysRoleVo;
+import org.dromara.system.service.ISysMenuService;
+import org.dromara.system.service.ISysRoleService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.List;
+import java.util.Objects;
+
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/pc/system")
+public class PcSystemController {
+
+    private final ISysMenuService sysMenuService;
+
+    private final ISysRoleService sysRoleService;
+
+
+    /**
+     * 获取工作台菜单列表
+     * */
+    @GetMapping("/getWorkbenchMenuList")
+    public R<List<Tree<Long>>> getWorkbenchMenuList() {
+        List<SysMenuVo> menuList = sysMenuService.selectMenuList(LoginHelper.getUserId(),"home");
+        List<Tree<Long>> trees = sysMenuService.buildMenuTreeSelect(menuList);
+        return R.ok(trees);
+    }
+
+    /**
+     * 获取工作台角色列表
+     * */
+    @GetMapping("/getWorkbenchRoleList")
+    public R<List<SysRoleVo>> getWorkbenchRoleList(SysRoleBo bo) {
+        bo.setPlatformCode("home");
+        List<SysRoleVo> roleList = sysRoleService.selectRoleList(bo);
+        //将游客角色过滤掉
+      roleList = roleList.stream().filter(role -> !Objects.equals(role.getRoleKey(), "tourist")&& !Objects.equals(role.getRoleKey(), "admin")).toList();
+        return R.ok(roleList);
+    }
+}

+ 7 - 7
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SysDeptController.java

@@ -47,7 +47,7 @@ public class SysDeptController extends BaseController {
      *
      * @param deptId 部门ID
      */
-    @SaCheckPermission("system:dept:list")
+//    @SaCheckPermission("system:dept:list")
     @GetMapping("/list/exclude/{deptId}")
     public R<List<SysDeptVo>> excludeChild(@PathVariable(value = "deptId", required = false) Long deptId) {
         List<SysDeptVo> depts = deptService.selectDeptList(new SysDeptBo());
@@ -59,7 +59,7 @@ public class SysDeptController extends BaseController {
     /**
      * 获取部门列表
      */
-    @SaCheckPermission("system:dept:list")
+//    @SaCheckPermission("system:dept:list")
     @GetMapping("/customerDeptList/{customerId}")
     public R<List<SysDeptVo>> customerDeptList(@PathVariable(value = "customerId", required = false) Long customerId) {
         List<SysDeptVo> depts = deptService.selectCustomerDeptList(customerId);
@@ -71,7 +71,7 @@ public class SysDeptController extends BaseController {
      *
      * @param deptId 部门ID
      */
-    @SaCheckPermission("system:dept:query")
+//    @SaCheckPermission("system:dept:query")
     @GetMapping(value = "/{deptId}")
     public R<SysDeptVo> getInfo(@PathVariable Long deptId) {
         deptService.checkDeptDataScope(deptId);
@@ -81,7 +81,7 @@ public class SysDeptController extends BaseController {
     /**
      * 新增部门
      */
-    @SaCheckPermission("system:dept:add")
+//    @SaCheckPermission("system:dept:add")
     @Log(title = "部门管理", businessType = BusinessType.INSERT)
     @PostMapping
     public R<Void> add(@Validated @RequestBody SysDeptBo dept) {
@@ -94,7 +94,7 @@ public class SysDeptController extends BaseController {
     /**
      * 修改部门
      */
-    @SaCheckPermission("system:dept:edit")
+//    @SaCheckPermission("system:dept:edit")
     @Log(title = "部门管理", businessType = BusinessType.UPDATE)
     @PutMapping
     public R<Void> edit(@Validated @RequestBody SysDeptBo dept) {
@@ -119,7 +119,7 @@ public class SysDeptController extends BaseController {
      *
      * @param deptId 部门ID
      */
-    @SaCheckPermission("system:dept:remove")
+//    @SaCheckPermission("system:dept:remove")
     @Log(title = "部门管理", businessType = BusinessType.DELETE)
     @DeleteMapping("/{deptId}")
     public R<Void> remove(@PathVariable Long deptId) {
@@ -141,7 +141,7 @@ public class SysDeptController extends BaseController {
      *
      * @param deptIds 部门ID串
      */
-    @SaCheckPermission("system:dept:query")
+//    @SaCheckPermission("system:dept:query")
     @GetMapping("/optionselect")
     public R<List<SysDeptVo>> optionselect(@RequestParam(required = false) Long[] deptIds) {
         return R.ok(deptService.selectDeptByIds(deptIds == null ? null : List.of(deptIds)));

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

@@ -90,7 +90,7 @@ public class SysTaxCodeVo implements Serializable {
     private String remark;
 
     /**
-     * 是否有下级 0存在 1存在
+     * 是否有下级 0存在 1存在
      * */
     private String isBottom;
 

+ 13 - 5
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java

@@ -81,10 +81,15 @@ public class RemoteUserServiceImpl implements RemoteUserService {
      * @return 结果
      */
     @Override
-    public LoginUser getUserInfo(String username, String tenantId) throws UserException {
-        SysUserVo sysUser1 = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
+    public LoginUser getUserInfo(String username, String tenantId,String userSonType) throws UserException {
+//        SysUserVo sysUser1 = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
         return TenantHelper.dynamic(tenantId, () -> {
-            SysUserVo sysUser = userMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserName, username));
+            LambdaQueryWrapper<SysUser> wrapper = new LambdaQueryWrapper<SysUser>();
+            wrapper.eq(SysUser::getUserName, username);
+            if (StringUtils.isNotBlank(userSonType)) {
+                wrapper.in(SysUser::getUserSonType, userSonType.split(","));
+            }
+            SysUserVo sysUser = userMapper.selectVoOne(wrapper);
             if (ObjectUtil.isNull(sysUser)) {
                 throw new UserException("user.not.exists", username);
             }
@@ -511,7 +516,9 @@ public class RemoteUserServiceImpl implements RemoteUserService {
         SysUserBo sysUserBo = MapstructUtils.convert(remoteUserBo, SysUserBo.class);
         String username = sysUserBo.getUserName();
         boolean exist = userMapper.exists(new LambdaQueryWrapper<SysUser>()
-            .eq(SysUser::getUserName, sysUserBo.getUserName()));
+            .eq(SysUser::getUserName, sysUserBo.getUserName())
+            .eq(SysUser::getUserSonType, sysUserBo.getUserSonType())
+        );
         if (exist) {
             throw new ServiceException("账号已经存在:" + username);
         }
@@ -528,7 +535,8 @@ public class RemoteUserServiceImpl implements RemoteUserService {
 
             userRoleMapper.delete(new LambdaQueryWrapper<SysUserRole>()
                 .eq(SysUserRole::getUserId, sysUserRole.getUserId())
-                .eq(SysUserRole::getRoleId, sysUserRole.getRoleId()));
+//                .eq(SysUserRole::getRoleId, sysUserRole.getRoleId())
+            );
 
             return userRoleMapper.insert(sysUserRole);
         } catch (DuplicateKeyException e) {

+ 10 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTaxCodeService.java

@@ -1,7 +1,9 @@
 package org.dromara.system.service;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.system.domain.SysTaxCode;
+import org.dromara.system.domain.vo.SysDeptVo;
 import org.dromara.system.domain.vo.SysTaxCodeVo;
 import org.dromara.system.domain.bo.SysTaxCodeBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -67,4 +69,12 @@ public interface ISysTaxCodeService extends IService<SysTaxCode>{
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 构建前端所需要下拉树结构
+     *
+     * @param depts 部门列表
+     * @return 下拉树结构列表
+     */
+    List<Tree<Long>> buildTaxCodeTreeSelect(List<SysTaxCodeVo> depts);
 }

+ 1 - 2
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysUserService.java

@@ -1,6 +1,5 @@
 package org.dromara.system.service;
 
-import org.apache.ibatis.jdbc.Null;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.system.domain.bo.SysUserBo;
@@ -63,7 +62,7 @@ public interface ISysUserService {
      * @param phonenumber 手机号
      * @return 用户对象信息
      */
-    SysUserVo selectUserByPhonenumber(String phonenumber);
+    SysUserVo selectUserByPhonenumber(String phonenumber, String type);
 
     /**
      * 通过用户ID查询用户

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java

@@ -266,6 +266,7 @@ public class SysMenuServiceImpl implements ISysMenuService {
                 .setWeight(menu.getOrderNum());
             menuTree.put("menuType", menu.getMenuType());
             menuTree.put("icon", menu.getIcon());
+            menuTree.put("path", menu.getPath());
         });
     }
 

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysRoleServiceImpl.java

@@ -80,6 +80,7 @@ public class SysRoleServiceImpl implements ISysRoleService {
             .like(StringUtils.isNotBlank(bo.getRoleName()), "r.role_name", bo.getRoleName())
             .eq(StringUtils.isNotBlank(bo.getStatus()), "r.status", bo.getStatus())
             .like(StringUtils.isNotBlank(bo.getRoleKey()), "r.role_key", bo.getRoleKey())
+            .eq(ObjectUtil.isNotEmpty(bo.getPlatformCode()), "r.platform_code", bo.getPlatformCode())
             .between(params.get("beginTime") != null && params.get("endTime") != null,
                 "r.create_time", params.get("beginTime"), params.get("endTime"))
             .orderByAsc("r.role_sort").orderByAsc("r.create_time");

+ 31 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaxCodeServiceImpl.java

@@ -1,8 +1,13 @@
 package org.dromara.system.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.constant.SystemConstants;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.core.utils.TreeBuildUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -10,6 +15,8 @@ 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.mybatis.helper.DataBaseHelper;
+import org.dromara.system.domain.vo.SysDeptVo;
 import org.springframework.stereotype.Service;
 import org.dromara.system.domain.bo.SysTaxCodeBo;
 import org.dromara.system.domain.vo.SysTaxCodeVo;
@@ -75,7 +82,6 @@ public class SysTaxCodeServiceImpl  extends ServiceImpl<SysTaxCodeMapper, SysTax
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<SysTaxCode> lqw = Wrappers.lambdaQuery();
         lqw.orderByAsc(SysTaxCode::getId);
-        lqw.eq(bo.getParentId() != null, SysTaxCode::getParentId, bo.getParentId());
         lqw.like(StringUtils.isNotBlank(bo.getName()), SysTaxCode::getName, bo.getName());
         lqw.eq(StringUtils.isNotBlank(bo.getAbbreviation()), SysTaxCode::getAbbreviation, bo.getAbbreviation());
         lqw.eq(StringUtils.isNotBlank(bo.getTaxationNo()), SysTaxCode::getTaxationNo, bo.getTaxationNo());
@@ -84,6 +90,8 @@ public class SysTaxCodeServiceImpl  extends ServiceImpl<SysTaxCodeMapper, SysTax
         lqw.eq(StringUtils.isNotBlank(bo.getAncestors()), SysTaxCode::getAncestors, bo.getAncestors());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysTaxCode::getStatus, bo.getStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), SysTaxCode::getPlatformCode, bo.getPlatformCode());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsBottom()), SysTaxCode::getIsBottom, bo.getIsBottom());
+        lqw.apply(ObjectUtil.isNotEmpty(bo.getParentId()),DataBaseHelper.findInSet(bo.getParentId(), "ancestors"));
         return lqw;
     }
 
@@ -138,4 +146,26 @@ public class SysTaxCodeServiceImpl  extends ServiceImpl<SysTaxCodeMapper, SysTax
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    /**
+     * 构建前端所需要下拉树结构
+     *
+     * @param sysTaxCodeVos 部门列表
+     * @return 下拉树结构列表
+     */
+    @Override
+    public List<Tree<Long>> buildTaxCodeTreeSelect(List<SysTaxCodeVo> sysTaxCodeVos) {
+        if (CollUtil.isEmpty(sysTaxCodeVos)) {
+            return CollUtil.newArrayList();
+        }
+        return TreeBuildUtils.buildMultiRoot(
+            sysTaxCodeVos,
+            SysTaxCodeVo::getId,
+            SysTaxCodeVo::getParentId,
+            (node, treeNode) -> treeNode
+                .setId(node.getId())
+                .setParentId(node.getParentId())
+                .setName(node.getName())
+        );
+    }
 }

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

@@ -169,8 +169,8 @@ public class SysUserServiceImpl implements ISysUserService {
      * @return 用户对象信息
      */
     @Override
-    public SysUserVo selectUserByPhonenumber(String phonenumber) {
-        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber));
+    public SysUserVo selectUserByPhonenumber(String phonenumber, String type) {
+        return baseMapper.selectVoOne(new LambdaQueryWrapper<SysUser>().eq(SysUser::getPhonenumber, phonenumber).eq(SysUser::getUserSonType, type));
     }
 
     /**