소스 검색

feat(customer): 添加个人注册功能并优化客户联系人角色管理

- 添加个人注册接口和实现方法
- 实现客户联系人角色变更时同步更新用户角色
- 优化用户创建时的角色ID设置逻辑
- 添加事务注解确保数据一致性
- 移除客户信息视图中的冗余字段
- 修复短信登录认证策略中的客户验证逻辑
- 重构税收编码服务的树形结构构建功能
- 优化系统菜单和角色的移动端接口返回格式
- 移除产品模块中的Elasticsearch配置依赖
- 修复用户角色分配中的重复键异常问题
肖路 1 개월 전
부모
커밋
8b19b54ac6
17개의 변경된 파일236개의 추가작업 그리고 72개의 파일을 삭제
  1. 7 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java
  2. 12 9
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/PasswordAuthStrategy.java
  3. 65 0
      ruoyi-auth/src/main/java/org/dromara/auth/service/impl/SmsAuthStrategy.java
  4. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java
  5. 0 6
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerInfoVo.java
  6. 6 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java
  7. 12 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerContactServiceImpl.java
  8. 59 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  9. 0 45
      ruoyi-modules/ruoyi-product/src/main/resources/application.yml
  10. 10 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/SysTaxCodeController.java
  11. 10 4
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSystemController.java
  12. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SysTaxCodeVo.java
  13. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java
  14. 10 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/ISysTaxCodeService.java
  15. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysMenuServiceImpl.java
  16. 31 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysTaxCodeServiceImpl.java
  17. 1 1
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml

+ 7 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/bo/RemoteUserBo.java

@@ -113,6 +113,13 @@ public class RemoteUserBo implements Serializable {
      */
     private Long roleId;
 
+    /**
+    *
+    * */
+    private Long[] roleIds;
+
+
+
     /**
      * 用户子类型 用户子类型(0=平台用户,1=供应商,2=伙伴商,3=商城用户,4=小程序用户)
      */

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

@@ -138,18 +138,21 @@ public class PasswordAuthStrategy implements IAuthStrategy {
             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 配置

+ 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);
+//            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;
     }
 

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/pc/CustomerRegisterController.java

@@ -36,6 +36,15 @@ public class CustomerRegisterController {
         return R.ok();
     }
 
+    /**
+    * 个人注册
+    * */
+    @PostMapping("/selfRegister")
+    public R<Void> selfRegister(@RequestBody CustomerRegisterBo bo) {
+        customerInfoService.selfRegister(bo);
+        return R.ok();
+    }
+
     /**
      * 企业注册
      */

+ 0 - 6
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerInfoVo.java

@@ -265,12 +265,6 @@ public class CustomerInfoVo implements Serializable {
     private String enterpriseTypeName;
     /** 客户等级名称 */
     private String customerLevelName;
-    /** 业务负责人名称 */
-    private String salesPersonName;
-    /** 客服支持名称 */
-    private String serviceStaffName;
-    /** 部门名称 */
-    private String deptName;
     /** 合作状态名称 */
     private String cooperationName;
 }

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

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

+ 12 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerContactServiceImpl.java

@@ -97,8 +97,8 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
-            Map<Long, String> deptNameMap = deptIds.isEmpty() 
-                ? new HashMap<>() 
+            Map<Long, String> deptNameMap = deptIds.isEmpty()
+                ? new HashMap<>()
                 : remoteDeptService.selectDeptNameByIds(deptIds);
 
             records.forEach(item -> {
@@ -203,7 +203,7 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
         remoteUserBo.setPassword(BCrypt.hashpw(defaultPassword));
         remoteUserBo.setUserSonType("3");
         remoteUserBo.setTenantId(LoginHelper.getTenantId());
-
+        remoteUserBo.setRoleIds(new Long[]{bo.getRoleId()});
         // 2. 调用远程服务创建用户
         Long userId = remoteUserService.addUser(remoteUserBo);
 
@@ -240,9 +240,18 @@ public class CustomerContactServiceImpl extends ServiceImpl<CustomerContactMappe
      * @return 是否修改成功
      */
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public Boolean updateByBo(CustomerContactBo bo) {
         CustomerContact update = MapstructUtils.convert(bo, CustomerContact.class);
         validEntityBeforeSave(update);
+        //查询角色有变更,如果角色有变更,则需要更新用户角色
+        CustomerContact customerContact = baseMapper.selectById(bo.getId());
+        if (!customerContact.getRoleId().equals(update.getRoleId())) {
+            RemoteUserBo remoteUserBo = new RemoteUserBo();
+            remoteUserBo.setUserId(customerContact.getUserId());
+            remoteUserBo.setRoleId(update.getRoleId());
+            remoteUserService.addUserRole(remoteUserBo);
+        }
         return baseMapper.updateById(update) > 0;
     }
 

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

@@ -1154,7 +1154,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());
@@ -1194,6 +1195,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) {

+ 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.50: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

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

+ 10 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcSystemController.java

@@ -1,5 +1,7 @@
 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;
@@ -14,11 +16,12 @@ 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("/pcSystem")
+@RequestMapping("/pc/system")
 public class PcSystemController {
 
     private final ISysMenuService sysMenuService;
@@ -30,9 +33,10 @@ public class PcSystemController {
      * 获取工作台菜单列表
      * */
     @GetMapping("/getWorkbenchMenuList")
-    public R<List<SysMenuVo>> getWorkbenchMenuList() {
+    public R<List<Tree<Long>>> getWorkbenchMenuList() {
         List<SysMenuVo> menuList = sysMenuService.selectMenuList(LoginHelper.getUserId(),"home");
-        return R.ok(menuList);
+        List<Tree<Long>> trees = sysMenuService.buildMenuTreeSelect(menuList);
+        return R.ok(trees);
     }
 
     /**
@@ -42,6 +46,8 @@ public class PcSystemController {
     public R<List<SysRoleVo>> getWorkbenchRoleList(SysRoleBo bo) {
         bo.setPlatformCode("home");
         List<SysRoleVo> roleList = sysRoleService.selectRoleList(bo);
-        return R.ok();
+        //将游客角色过滤掉
+//      roleList = roleList.stream().filter(role -> !Objects.equals(role.getRoleKey(), "tourist")).toList()
+        return R.ok(roleList);
     }
 }

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

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteUserServiceImpl.java

@@ -528,7 +528,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 - 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());
         });
     }
 

+ 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())
+        );
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/SysRoleMapper.xml

@@ -7,7 +7,7 @@
     <resultMap type="org.dromara.system.domain.vo.SysRoleVo" id="SysRoleResult">
     </resultMap>
 
-    <sql id="eselectRoleVo">
+    <sql id="selectRoleVo">
         select distinct r.role_id,
                         r.role_name,
                         r.role_key,