mitao
2024-12-04 1c940b2c9b9cb8f8591045e5048eac8de5923a14
系统管理:区域管理接口
2 文件已重命名
1个文件已删除
20个文件已修改
2个文件已添加
801 ■■■■ 已修改文件
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/SysDepartmentController.java 40 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysDepartmentController.java 97 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysDepartmentInfoController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysLoginController.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysRoleController.java 27 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysUserDepartmentController.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/resources/application.yml 11 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/test/java/DepartmentTest.java 3 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-common/src/main/java/com/sinata/common/constant/CacheConstants.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-common/src/main/java/com/sinata/common/core/domain/entity/SysRole.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-common/src/main/java/com/sinata/common/entity/BaseModel.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-framework/src/main/java/com/sinata/framework/web/service/SysLoginService.java 21 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/domain/SysDepartment.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/domain/dto/SysDepartmentDTO.java 30 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/domain/dto/SysRoleDTO.java 5 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysDepartmentMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysMenuMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysRoleMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/service/ISysRoleService.java 24 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/service/SysDepartmentService.java 55 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/service/impl/SysDepartmentServiceImpl.java 311 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/java/com/sinata/system/service/impl/SysRoleServiceImpl.java 69 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/resources/mapper/system/SysDepartmentMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/resources/mapper/system/SysMenuMapper.xml 23 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-system/src/main/resources/mapper/system/SysRoleMapper.xml 16 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/SysDepartmentController.java
File was deleted
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysDepartmentController.java
New file
@@ -0,0 +1,97 @@
package com.sinata.web.controller.backend.system;
import com.sinata.common.core.domain.R;
import com.sinata.system.domain.dto.SysDepartmentDTO;
import com.sinata.system.domain.vo.SysDepartmentVO;
import com.sinata.system.service.SysDepartmentService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
import javax.validation.constraints.NotNull;
import java.util.List;
/**
 * <p>
 * 区域表 前端控制器
 * </p>
 *
 * @author mitao
 * @since 2024-12-02
 */
@Api(tags = {"区域管理相关接口"})
@RestController
@Validated
@RequestMapping("/backend/sysDepartment")
@RequiredArgsConstructor
public class SysDepartmentController {
    private final SysDepartmentService sysDepartmentService;
    /**
     * 获取区域树
     * @return
     */
    @ApiOperation("获取区域树")
    @GetMapping("/regionTree")
    @ApiImplicitParam(name = "keyword", value = "关键字", required = false)
    public R<List<SysDepartmentVO>> getRegionTree(@RequestParam(required = false) String keyword) {
        return R.ok(sysDepartmentService.getRegionTree(keyword));
    }
    /**
     * 获取区域树
     *
     * @return
     */
    @ApiOperation(value = "获取全部/区域/医疗机构/处置单位/监管单位树-搜索框用", notes = "0:全部 1:区域 2:医疗机构 3:处置单位 4:监管单位")
    @GetMapping("/departmentSearchTree")
    @ApiImplicitParam(name = "type", value = "查询类型", required = true)
    public R<List<SysDepartmentVO>> getDepartmentSearchTree(@RequestParam(value = "type", required = true) @NotNull(message = "类型不能为空") Integer type) {
        return R.ok(sysDepartmentService.listByType(type));
    }
    /**
     * 新增区域
     *
     * @param dto
     * @return
     */
    @ApiOperation("新增区域")
    @PostMapping("/add")
    public R<?> addRegion(@Valid @RequestBody SysDepartmentDTO dto) {
        sysDepartmentService.addRegion(dto);
        return R.ok();
    }
    /**
     * 编辑区域
     *
     * @param dto
     * @return
     */
    @ApiOperation("编辑区域")
    @PostMapping("/edit")
    public R<?> editRegion(@Valid @RequestBody SysDepartmentDTO dto) {
        sysDepartmentService.editRegion(dto);
        return R.ok();
    }
    @ApiOperation("删除区域")
    @DeleteMapping("/{id}")
    public R<?> deleteRegion(@ApiParam(name = "id", value = "区域id", required = true) @NotNull(message = "区域id不能为空") @PathVariable("id") Long id) {
        sysDepartmentService.deleteRegion(id);
        return R.ok();
    }
}
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysDepartmentInfoController.java
File was renamed from medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/SysDepartmentInfoController.java
@@ -1,4 +1,4 @@
package com.sinata.web.controller.backend;
package com.sinata.web.controller.backend.system;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysLoginController.java
@@ -3,15 +3,20 @@
import com.sinata.common.constant.Constants;
import com.sinata.common.core.domain.AjaxResult;
import com.sinata.common.core.domain.entity.SysMenu;
import com.sinata.common.core.domain.entity.SysRole;
import com.sinata.common.core.domain.entity.SysUser;
import com.sinata.common.core.domain.model.LoginBody;
import com.sinata.common.core.domain.model.LoginUser;
import com.sinata.common.utils.SecurityUtils;
import com.sinata.framework.web.service.SysLoginService;
import com.sinata.framework.web.service.SysPermissionService;
import com.sinata.framework.web.service.TokenService;
import com.sinata.system.service.ISysMenuService;
import com.sinata.system.service.ISysRoleService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -40,6 +45,12 @@
    @Autowired
    private SysPermissionService permissionService;
    @Autowired
    private TokenService tokenService;
    @Autowired
    private ISysRoleService roleService;
    /**
     * 登录方法
     * 
@@ -52,9 +63,18 @@
    {
        AjaxResult ajax = AjaxResult.success();
        // 生成令牌
        String token = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
        LoginUser loginUser = loginService.login(loginBody.getUsername(), loginBody.getPassword(), loginBody.getCode(),
                loginBody.getUuid());
        ajax.put(Constants.TOKEN, token);
        ajax.put(Constants.TOKEN, tokenService.createToken(loginUser));
        List<SysRole> roles = loginUser.getUser().getRoles();
        if (CollectionUtils.isEmpty(roles)) {
            return AjaxResult.error("请关联角色!");
        }
        List<SysMenu> menus = roleService.roleInfoFromUserId(loginUser.getUserId());
        ajax.put("menus", menus);
        ajax.put("userInfo", loginUser);
        return ajax;
    }
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysRoleController.java
@@ -41,6 +41,7 @@
import javax.validation.Valid;
import javax.validation.constraints.NotEmpty;
import java.util.List;
import java.util.Objects;
/**
 * 角色信息
@@ -90,6 +91,15 @@
    @PostMapping("/save")
    public R<?> save(@Valid @RequestBody SysRoleDTO dto) {
        roleService.saveRole(dto);
        if (Objects.nonNull(dto.getRoleId())) {
            // 更新缓存用户权限
            LoginUser loginUser = getLoginUser();
            if (StringUtils.isNotNull(loginUser.getUser()) && !loginUser.getUser().isAdmin()) {
                loginUser.setPermissions(permissionService.getMenuPermission(loginUser.getUser()));
                loginUser.setUser(userService.selectUserByUserName(loginUser.getUser().getUserName()));
                tokenService.setLoginUser(loginUser);
            }
        }
        return R.ok();
    }
@@ -105,11 +115,22 @@
        return R.ok(roleService.getDetailInfo(roleId));
    }
    @ApiOperation("删除详情")
    @ApiOperation("批量删除")
    @PostMapping("/deleteBatch")
    public R<?> deleteBatch(@ApiParam(name = "roleIds", value = "角色id列表", required = true) @NotEmpty(message = "角色id列表不能为空") @RequestBody List<Long> roleIds) {
        roleService.removeBatchByIds(roleIds);
        return R.ok();
    }
    /**
     * 获取当前登录用户可管理角色列表
     *
     * @return
     */
    @ApiOperation("获取当前登录用户可管理角色列表")
    @GetMapping("/manageRoleList")
    public List<SysRoleVO> getManageRoleList() {
        return roleService.getManageRoleList(getLoginUser());
    }
    @PreAuthorize("@ss.hasPermi('system:role:list')")
    @GetMapping("/list")
@@ -133,13 +154,13 @@
    /**
     * 根据角色编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:role:query')")
  /*  @PreAuthorize("@ss.hasPermi('system:role:query')")
    @GetMapping(value = "/{roleId}")
    public AjaxResult getInfo(@PathVariable Long roleId)
    {
        roleService.checkRoleDataScope(roleId);
        return success(roleService.selectRoleById(roleId));
    }
    }*/
    /**
     * 新增角色
medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/system/SysUserDepartmentController.java
File was renamed from medicalWaste-admin/src/main/java/com/sinata/web/controller/backend/SysUserDepartmentController.java
@@ -1,4 +1,4 @@
package com.sinata.web.controller.backend;
package com.sinata.web.controller.backend.system;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
medicalWaste-admin/src/main/resources/application.yml
@@ -44,7 +44,6 @@
    maxRetryCount: 5
    # 密码锁定时间(默认10分钟)
    lockTime: 10
# Spring配置
spring:
  # 资源信息
@@ -147,6 +146,14 @@
        wall:
          config:
            multi-statement-allow: true
  jackson:
    # 全局设置@JsonFormat的格式pattern
    date-format: yyyy-MM-dd HH:mm:ss
    # 设置全局时区
    time-zone: GMT+8
    # 当地时区
    locale: zh_CN
# token配置
token:
@@ -155,7 +162,7 @@
  # 令牌密钥
  secret: abcdefghijklmnopqrstuvwxyz
  # 令牌有效期(默认30分钟)
  expireTime: 30
  expireTime: 720
# MyBatis配置
mybatis-plus:
medicalWaste-admin/src/test/java/DepartmentTest.java
@@ -1,5 +1,4 @@
import com.sinata.RuoYiApplication;
import com.sinata.system.enums.DepartmentEnum;
import com.sinata.system.mapper.SysDepartmentMapper;
import com.sinata.system.service.ISysDictTypeService;
import org.junit.jupiter.api.Test;
@@ -20,7 +19,7 @@
    @Test
    public void test(){
        System.out.println(departmentMapper.getDepartmentListByType(1L, DepartmentEnum.REGION.getCode()));
        System.out.println(departmentMapper.getDepartmentByUserId(1L));
    }
    @Test
    public void test2(){
medicalWaste-common/src/main/java/com/sinata/common/constant/CacheConstants.java
@@ -41,4 +41,12 @@
     * 登录账户密码错误次数 redis key
     */
    public static final String PWD_ERR_CNT_KEY = "pwd_err_cnt:";
    /**
     * 全部部门信息缓存
     */
    public static final String SYS_DEPARTS_CACHE = "sys:cache:depart:alldata";
    /**
     * 全部部门org_code 缓存
     */
    public static final String SYS_DEPARTMENT_ORG_CODE = "sys:cache:department:org:code:";
}
medicalWaste-common/src/main/java/com/sinata/common/core/domain/entity/SysRole.java
@@ -58,15 +58,19 @@
    private String delFlag;
    /** 用户是否存在此角色标识 默认不存在 */
    @TableField(exist = false)
    private boolean flag = false;
    /** 菜单组 */
    @TableField(exist = false)
    private Long[] menuIds;
    /** 部门组(数据权限) */
    @TableField(exist = false)
    private Long[] deptIds;
    /** 角色菜单权限 */
    @TableField(exist = false)
    private Set<String> permissions;
    @TableField("MANAGE_ROLE_ID_STR")
@@ -76,6 +80,14 @@
    }
    public String getManageRoleIdStr() {
        return manageRoleIdStr;
    }
    public void setManageRoleIdStr(String manageRoleIdStr) {
        this.manageRoleIdStr = manageRoleIdStr;
    }
    public SysRole(Long roleId)
    {
        this.roleId = roleId;
medicalWaste-common/src/main/java/com/sinata/common/entity/BaseModel.java
@@ -22,7 +22,7 @@
    /** 创建者 */
    @ApiModelProperty(value = "记录创建人,前端忽略")
    @TableField(value = "create_by", fill = FieldFill.INSERT)
    private String createBy;
    private Long createBy;
    /** 创建时间 */
    @ApiModelProperty(value = "记录创建时间,前端忽略")
@@ -32,7 +32,7 @@
    /** 更新者 */
    @ApiModelProperty(value = "记录修改人,前端忽略")
    @TableField(value = "update_by", fill = FieldFill.INSERT_UPDATE)
    private String updateBy;
    private Long updateBy;
    /** 更新时间 */
    @ApiModelProperty(value = "记录修改时间,前端忽略")
medicalWaste-framework/src/main/java/com/sinata/framework/web/service/SysLoginService.java
@@ -1,12 +1,5 @@
package com.sinata.framework.web.service;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import com.sinata.common.constant.CacheConstants;
import com.sinata.common.constant.Constants;
import com.sinata.common.constant.UserConstants;
@@ -28,6 +21,14 @@
import com.sinata.framework.security.context.AuthenticationContextHolder;
import com.sinata.system.service.ISysConfigService;
import com.sinata.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
 * 登录校验方法
@@ -37,8 +38,6 @@
@Component
public class SysLoginService
{
    @Autowired
    private TokenService tokenService;
    @Resource
    private AuthenticationManager authenticationManager;
@@ -61,7 +60,7 @@
     * @param uuid 唯一标识
     * @return 结果
     */
    public String login(String username, String password, String code, String uuid)
    public LoginUser login(String username, String password, String code, String uuid)
    {
        // 验证码校验
        validateCaptcha(username, code, uuid);
@@ -97,7 +96,7 @@
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        recordLoginInfo(loginUser.getUserId());
        // 生成token
        return tokenService.createToken(loginUser);
        return loginUser;
    }
    /**
medicalWaste-system/src/main/java/com/sinata/system/domain/SysDepartment.java
@@ -36,7 +36,7 @@
    @ApiModelProperty("上级区域id")
    @TableField("PARENT_ID")
    private Integer parentId;
    private Long parentId;
    @ApiModelProperty("树编码")
    @TableField("TREE_CODE")
medicalWaste-system/src/main/java/com/sinata/system/domain/dto/SysDepartmentDTO.java
New file
@@ -0,0 +1,30 @@
package com.sinata.system.domain.dto;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.hibernate.validator.constraints.Length;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
/**
 * @author mitao
 * @date 2024/12/4
 */
@Data
@ApiModel("区域数据传输对象")
public class SysDepartmentDTO {
    @ApiModelProperty(value = "区域id", notes = "新增不传,编辑必传")
    private Long id;
    @ApiModelProperty("父级id")
    @NotNull(message = "父级id不能为空")
    private Long parentId;
    @ApiModelProperty("区域名称")
    @NotBlank(message = "区域名称不能为空")
    @Length(max = 20, message = "区域名称长度不能超过20个字符")
    private String departmentName;
}
medicalWaste-system/src/main/java/com/sinata/system/domain/dto/SysRoleDTO.java
@@ -4,6 +4,7 @@
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import javax.validation.constraints.NotBlank;
import java.util.List;
/**
@@ -14,13 +15,15 @@
@ApiModel("角色数据传输对象")
public class SysRoleDTO {
    @ApiModelProperty(value = "角色主键", notes = "更新必传")
    @ApiModelProperty(value = "角色主键", notes = "新增不传,编辑必传")
    private Long roleId;
    @ApiModelProperty("角色名称")
    @NotBlank(message = "角色名称不能为空")
    private String roleName;
    @ApiModelProperty(value = "可管理角色", notes = "使用英文逗号拼接")
    @NotBlank(message = "可管理角色不能为空")
    private String manageRoleStr;
    @ApiModelProperty("备注")
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysDepartmentMapper.java
@@ -1,11 +1,9 @@
package com.sinata.system.mapper;
import com.sinata.system.domain.SysDepartment;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.sinata.system.domain.SysDepartment;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
 * <p>
@@ -23,5 +21,5 @@
     * @param type
     * @return
     */
    List<SysDepartment> getDepartmentListByType(@Param("userId") Long userId, @Param("type") Integer type);
    SysDepartment getDepartmentByUserId(@Param("userId") Long userId);
}
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysMenuMapper.java
@@ -125,4 +125,6 @@
    public SysMenu checkMenuNameUnique(@Param("menuName") String menuName, @Param("parentId") Long parentId);
    List<SysMenu> selectListByRoleId(@Param("roleId") Long roleId);
    List<SysMenu> getAllInIds(@Param("menusId") List<Long> menusId);
}
medicalWaste-system/src/main/java/com/sinata/system/mapper/SysRoleMapper.java
@@ -118,4 +118,6 @@
     * @return
     */
    Page<SysRoleVO> pageList(Page<SysRoleVO> sysRoleVOPage, @Param("keyword") String keyword);
    SysRole selectRoleByUserId(Long userId);
}
medicalWaste-system/src/main/java/com/sinata/system/service/ISysRoleService.java
@@ -1,7 +1,9 @@
package com.sinata.system.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sinata.common.core.domain.entity.SysMenu;
import com.sinata.common.core.domain.entity.SysRole;
import com.sinata.common.core.domain.model.LoginUser;
import com.sinata.common.entity.PageDTO;
import com.sinata.system.domain.SysUserRole;
import com.sinata.system.domain.dto.SysRoleDTO;
@@ -200,4 +202,26 @@
     * @return
     */
    SysRoleVO getDetailInfo(Long roleId);
    /**
     * 获取当前登录用户可管理角色列表
     *
     * @param loginUser
     * @return
     */
    List<SysRoleVO> getManageRoleList(LoginUser loginUser);
    /**
     * 获取菜单列表
     *
     * @param menusId
     * @return
     */
    List<SysMenu> getMenuLevelList(List<Long> menusId);
    /**
     * @param userId
     * @return
     */
    List<SysMenu> roleInfoFromUserId(Long userId);
}
medicalWaste-system/src/main/java/com/sinata/system/service/SysDepartmentService.java
@@ -1,7 +1,8 @@
package com.sinata.system.service;
import com.sinata.system.domain.SysDepartment;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sinata.system.domain.SysDepartment;
import com.sinata.system.domain.dto.SysDepartmentDTO;
import com.sinata.system.domain.vo.SysDepartmentVO;
import java.util.List;
@@ -20,4 +21,56 @@
     * @return
     */
    List<SysDepartmentVO> listByType(Integer type);
    /**
     * 根据父级id获取区域信息
     *
     * @param parentId
     * @return
     */
    SysDepartment getDepartmentByParentId(Long parentId);
    /**
     * 获取区域树
     *
     * @param keyword
     * @return
     */
    List<SysDepartmentVO> getRegionTree(String keyword);
    /**
     * 新增区域
     *
     * @param dto
     * @return
     */
    void addRegion(SysDepartmentDTO dto);
    /**
     * 编辑区域
     *
     * @param dto
     * @return
     */
    void editRegion(SysDepartmentDTO dto);
    /**
     * 获取树编码
     *
     * @param parentId
     * @return
     */
    String getTreeCode(Long parentId);
    /**
     * 生成组织编码
     * 区域、医疗机构、处置单位、监管单位 4位 按组织类型不重复
     *
     * @param parentId
     * @param orgType
     * @return
     */
    String getOrgCode(Long parentId, Integer orgType);
    void deleteRegion(Long id);
}
medicalWaste-system/src/main/java/com/sinata/system/service/impl/SysDepartmentServiceImpl.java
@@ -1,19 +1,34 @@
package com.sinata.system.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sinata.common.constant.CacheConstants;
import com.sinata.common.exception.ServiceException;
import com.sinata.common.utils.BeanUtils;
import com.sinata.common.utils.CollUtils;
import com.sinata.common.utils.SecurityUtils;
import com.sinata.common.utils.StringUtils;
import com.sinata.system.domain.SysDepartment;
import com.sinata.system.domain.SysUserDepartment;
import com.sinata.system.domain.dto.SysDepartmentDTO;
import com.sinata.system.domain.vo.SysDepartmentVO;
import com.sinata.system.enums.DepartmentEnum;
import com.sinata.system.mapper.SysDepartmentMapper;
import com.sinata.system.service.SysDepartmentService;
import com.sinata.system.service.SysUserDepartmentService;
import lombok.RequiredArgsConstructor;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
@@ -28,18 +43,300 @@
@RequiredArgsConstructor
public class SysDepartmentServiceImpl extends ServiceImpl<SysDepartmentMapper, SysDepartment> implements SysDepartmentService {
    private final SysUserDepartmentService sysUserDepartmentService;
    private final RedisTemplate<Object, Object> redisTemplate;
    /**
     * 获取区域树
     * @return
     */
    @Override
    public List<SysDepartmentVO> listByType(Integer type) {
        Long userId = SecurityUtils.getUserId();
        List<SysDepartment> departmentList =  baseMapper.getDepartmentListByType(userId, type);
        if (CollUtils.isNotEmpty(departmentList)) {
            Map<Long, SysDepartment> departmentMap = departmentList.stream().collect(Collectors.toMap(SysDepartment::getId, Function.identity()));
        List<SysDepartmentVO> root = new ArrayList<>();
        SysDepartment myDepartment = getMyDepartment();
        if (Objects.isNull(myDepartment)) {
            return root;
        }
        return null;
        Map<Long, List<SysDepartment>> childrenMap;
        switch (type) {
            case 1:
                if (!myDepartment.getOrgType().equals(DepartmentEnum.REGION.getCode())) {
                    return root;
                }
                childrenMap = getChildrenDepartmentByOrgType(myDepartment, Collections.singletonList(DepartmentEnum.REGION.getCode()));
                break;
            case 2:
                childrenMap = getChildrenDepartmentByOrgType(myDepartment, Arrays.asList(DepartmentEnum.REGION.getCode(), DepartmentEnum.MEDICAL_INSTITUTION.getCode()));
                break;
            case 3:
                childrenMap = getChildrenDepartmentByOrgType(myDepartment, Arrays.asList(DepartmentEnum.REGION.getCode(), DepartmentEnum.DISPOSAL_UNIT.getCode()));
                break;
            case 4:
                childrenMap = getChildrenDepartmentByOrgType(myDepartment, Arrays.asList(DepartmentEnum.REGION.getCode(), DepartmentEnum.REGULATORY_UNIT.getCode()));
                break;
            default:
                childrenMap = getChildrenDepartmentByOrgType(myDepartment, null);
        }
        SysDepartmentVO sysDepartmentVO = fillChildrenTreeModel(myDepartment, childrenMap);
        root.add(sysDepartmentVO);
        return root;
    }
    /**
     * @param myDepartment
     * @param orgTypes     查询区域类型列表
     * @return
     */
    @NotNull
    private Map<Long, List<SysDepartment>> getChildrenDepartmentByOrgType(SysDepartment myDepartment, List<Integer> orgTypes) {
        List<SysDepartment> sysDepartmentList = this.lambdaQuery()
                .likeRight(SysDepartment::getTreeCode, myDepartment.getTreeCode())
                .in(CollUtils.isNotEmpty(orgTypes), SysDepartment::getOrgType, orgTypes)
                .orderByDesc(SysDepartment::getCreateTime)
                .list();
        return sysDepartmentList.stream()
                .collect(Collectors.groupingBy(SysDepartment::getParentId));
    }
    @Override
    public SysDepartment getDepartmentByParentId(Long parentId) {
        return this.lambdaQuery().eq(SysDepartment::getId, parentId).one();
    }
    /**
     * 获取区域树
     *
     * @return
     */
    @Override
    public List<SysDepartmentVO> getRegionTree(String keyword) {
        List<SysDepartmentVO> root = new ArrayList<>();
        SysDepartment currentDepartment = getMyDepartment();
        if (Objects.isNull(currentDepartment)) {
            return root;
        }
        if (!currentDepartment.getOrgType().equals(DepartmentEnum.REGION.getCode())) {
            return root;
        }
        Map<Long, List<SysDepartment>> childrenMap = getChildrenDepartmentByOrgType(currentDepartment, Collections.singletonList(DepartmentEnum.REGION.getCode()));
        SysDepartmentVO sysDepartmentVO = fillChildrenTreeModel(currentDepartment, childrenMap);
        root.add(sysDepartmentVO);
        if (StringUtils.isNotBlank(keyword)) {
            treeMatch(root, keyword);
        }
        return root;
    }
    /**
     * 获取当前登录用户所属区域
     *
     * @return
     */
    private SysDepartment getMyDepartment() {
        Long userId = SecurityUtils.getUserId();
        return baseMapper.getDepartmentByUserId(userId);
    }
    /**
     * 构建树结构
     *
     * @param myDepartment
     * @param childrenMap
     * @return
     */
    private SysDepartmentVO fillChildrenTreeModel(SysDepartment myDepartment, Map<Long, List<SysDepartment>> childrenMap) {
        SysDepartmentVO currentNode = BeanUtils.copyBean(myDepartment, SysDepartmentVO.class);
        // 使用部门映射直接获取子部门,避免了遍历整个列表
        List<SysDepartment> children = childrenMap.getOrDefault(currentNode.getId(),
                Collections.emptyList());
        List<SysDepartmentVO> childrenList = children.stream().map(child -> fillChildrenTreeModel(child, childrenMap)).collect(Collectors.toList());
        currentNode.setChildren(childrenList.isEmpty() ? new ArrayList<>() : childrenList);
        childrenMap.remove(currentNode.getId());
        return currentNode;
    }
    /**
     * 递归方法
     *
     * @param tree    任意层级的目录集合
     * @param keyword 关键字
     */
    public static void treeMatch(List<SysDepartmentVO> tree, String keyword) {
        Iterator<SysDepartmentVO> iter = tree.iterator();
        while (iter.hasNext()) {
            // 获取当前遍历到的目录
            SysDepartmentVO department = iter.next();
            // 如果当前目录名称包含关键字,则什么也不做(不移除),否则就看下一级
            if (!department.getDepartmentName().contains(keyword)) {
                // 取出下一级目录集合
                List<SysDepartmentVO> childrenSysDepartmentVOList = department.getChildren();
                // 递归
                if (!CollUtils.isEmpty(childrenSysDepartmentVOList)) {
                    treeMatch(childrenSysDepartmentVOList, keyword);
                }
                // 下一级目录看完了,如果下一级目录全部被移除,则移除当前目录
                if (CollUtils.isEmpty(department.getChildren())) {
                    iter.remove();
                }
            }
        }
    }
    /**
     * 新增区域
     *
     * @param dto
     * @return
     */
    @Override
    public void addRegion(SysDepartmentDTO dto) {
        SysDepartment currentDepartment = getMyDepartment();
        if (Objects.isNull(currentDepartment)) {
            throw new ServiceException("无操作权限");
        }
        SysDepartment parent = this.getById(dto.getParentId());
        if (Objects.isNull(parent)) {
            throw new ServiceException("找不到对应父级组织");
        }
        if (!parent.getTreeCode().startsWith(currentDepartment.getTreeCode())) {
            throw new ServiceException("无操作权限");
        }
        Long count = this.lambdaQuery().eq(SysDepartment::getDepartmentName, dto.getDepartmentName())
                .eq(SysDepartment::getOrgType, DepartmentEnum.REGION.getCode())
                .count();
        if (count > 0) {
            throw new ServiceException("区域已存在");
        }
        SysDepartment department = BeanUtils.copyBean(dto, SysDepartment.class);
        //获取部门树编码
        department.setOrgType(DepartmentEnum.REGION.getCode());
        department.setTreeCode(getTreeCode(dto.getParentId()));
        department.setOrgCode(getOrgCode(dto.getParentId(), DepartmentEnum.REGION.getCode()));
        save(department);
    }
    /**
     * 编辑区域
     *
     * @param dto
     * @return
     */
    @Override
    public void editRegion(SysDepartmentDTO dto) {
        SysDepartment currentDepartment = getMyDepartment();
        if (Objects.isNull(currentDepartment)) {
            throw new ServiceException("无操作权限");
        }
        SysDepartment parent = this.getById(dto.getParentId());
        if (Objects.isNull(parent)) {
            throw new ServiceException("找不到对应父级组织");
        }
        if (!parent.getTreeCode().startsWith(currentDepartment.getTreeCode())) {
            throw new ServiceException("无操作权限");
        }
        Long count = this.lambdaQuery().eq(SysDepartment::getDepartmentName, dto.getDepartmentName())
                .eq(SysDepartment::getOrgType, DepartmentEnum.REGION.getCode())
                .ne(SysDepartment::getId, dto.getId())
                .count();
        if (count > 0) {
            throw new ServiceException("区域已存在");
        }
        SysDepartment department = BeanUtils.copyBean(dto, SysDepartment.class);
        SysDepartment sysDepartment = getById(dto.getId());
        if (!dto.getParentId().equals(sysDepartment.getParentId())) {
            //获取部门树编码
            department.setTreeCode(getTreeCode(dto.getParentId()));
        }
        updateById(department);
    }
    /**
     * 获取树编码
     *
     * @param parentId
     * @return
     */
    @Override
    public String getTreeCode(Long parentId) {
        String treeId;
        String preTreeCode = "";
        StringBuilder sb = new StringBuilder();
        SysDepartment sysDepartment = getById(parentId);
        if (sysDepartment != null) {
            preTreeCode = sysDepartment.getTreeCode();
        }
        //设置key
        String key = CacheConstants.SYS_DEPARTS_CACHE + parentId;
        int count = 0;
        //判断是否存在key
        if (redisTemplate.hasKey(key)) {
            count = (int) redisTemplate.opsForValue().get(key);
        }
        do {
            count++;
            treeId = sb.append(preTreeCode).append(StringUtils.leftPad(String.valueOf(count), 4, "0")).toString();
            SysDepartment department = getOne(new QueryWrapper<SysDepartment>().lambda().eq(SysDepartment::getTreeCode, treeId));
            if (department == null) {
                break;
            }
            sb = new StringBuilder();
        } while (true);
        //设置缓存过期时间
        redisTemplate.opsForValue().set(key, count, 365, TimeUnit.DAYS);
        return treeId;
    }
    /**
     * 生成组织编码
     * 区域、医疗机构、处置单位、监管单位 4位 按组织类型不重复
     *
     * @param parentId
     * @param orgType
     * @return
     */
    @Override
    public String getOrgCode(Long parentId, Integer orgType) {
        String key = CacheConstants.SYS_DEPARTMENT_ORG_CODE + orgType;
        int length = 4;
        int count = 0;
        //判断是否存在key
        if (redisTemplate.hasKey(key)) {
            count = (int) redisTemplate.opsForValue().get(key);
        }
        //组织编码
        String orgCode;
        do {
            count++;
            orgCode = StringUtils.leftPad(String.valueOf(count), length, "0");
            SysDepartment department = getOne(new QueryWrapper<SysDepartment>().lambda().eq(SysDepartment::getOrgCode, orgCode).eq(SysDepartment::getOrgType, orgType).last("limit 1"));
            if (department == null) {
                break;
            }
        } while (true);
        //设置缓存过期时间
        redisTemplate.opsForValue().set(key, count, 365, TimeUnit.DAYS);
        return orgCode;
    }
    @Override
    public void deleteRegion(Long id) {
        SysDepartment myDepartment = getMyDepartment();
        SysDepartment sysDepartment = getById(id);
        if (!sysDepartment.getTreeCode().startsWith(myDepartment.getTreeCode())) {
            throw new ServiceException("无操作权限");
        }
        List<SysDepartment> sysDepartmentList = this.lambdaQuery()
                .likeRight(SysDepartment::getTreeCode, sysDepartment.getTreeCode())
                .eq(SysDepartment::getOrgType, DepartmentEnum.REGION.getCode())
                .orderByDesc(SysDepartment::getCreateTime)
                .list();
        List<Long> departmentIds = sysDepartmentList.stream().map(SysDepartment::getId).collect(Collectors.toList());
        Long count = sysUserDepartmentService.lambdaQuery().in(SysUserDepartment::getDepartmentId, departmentIds).count();
        if (count > 0) {
            throw new ServiceException("该区域已存在用户,无法删除");
        }
        removeById(id);
    }
}
medicalWaste-system/src/main/java/com/sinata/system/service/impl/SysRoleServiceImpl.java
@@ -7,6 +7,7 @@
import com.sinata.common.core.domain.entity.SysMenu;
import com.sinata.common.core.domain.entity.SysRole;
import com.sinata.common.core.domain.entity.SysUser;
import com.sinata.common.core.domain.model.LoginUser;
import com.sinata.common.entity.PageDTO;
import com.sinata.common.exception.ServiceException;
import com.sinata.common.utils.BeanUtils;
@@ -20,6 +21,7 @@
import com.sinata.system.domain.dto.SysRoleDTO;
import com.sinata.system.domain.query.KeyWordQuery;
import com.sinata.system.domain.vo.SysRoleVO;
import com.sinata.system.mapper.SysMenuMapper;
import com.sinata.system.mapper.SysRoleDeptMapper;
import com.sinata.system.mapper.SysRoleMapper;
import com.sinata.system.mapper.SysRoleMenuMapper;
@@ -59,6 +61,8 @@
    private SysRoleDeptMapper roleDeptMapper;
    @Autowired
    private ISysMenuService menuService;
    @Autowired
    private SysMenuMapper menuMapper;
    /**
     * 根据条件分页查询角色数据
@@ -461,6 +465,9 @@
    @Override
    public void saveRole(SysRoleDTO dto) {
        SysRole sysRole = BeanUtils.copyBean(dto, SysRole.class);
        if (!this.checkRoleNameUnique(sysRole)) {
            throw new ServiceException("保存角色'" + sysRole.getRoleName() + "'失败,角色名称已存在");
        }
        if (Objects.nonNull(sysRole.getRoleId())) {
            baseMapper.insert(sysRole);
        } else {
@@ -485,4 +492,66 @@
        }
        return sysRoleVO;
    }
    /**
     * 获取当前登录用户可管理角色列表
     *
     * @param loginUser
     * @return
     */
    @Override
    public List<SysRoleVO> getManageRoleList(LoginUser loginUser) {
        List<SysRoleVO> res = CollUtils.emptyList();
        Long roleId = loginUser.getUser().getRoleId();
        SysRole role = this.getById(roleId);
        if (Objects.nonNull(role)) {
            List<SysRole> list = this.lambdaQuery().in(SysRole::getRoleId, Arrays.asList(role.getManageRoleIdStr().split(","))).list();
            if (CollUtils.isNotEmpty(list)) {
                res = BeanUtils.copyToList(list, SysRoleVO.class);
            }
        }
        return res;
    }
    @Override
    public List<SysMenu> getMenuLevelList(List<Long> menusId) {
        //获取当前的权限菜单
        List<SysMenu> all = menuMapper.getAllInIds(menusId);
        // 第三级
        List<SysMenu> s3 = all.stream().filter(e -> e.getMenuType().equals("F"))
                .collect(Collectors.toList());
        // 第二级
        List<SysMenu> s2 = all.stream().filter(e -> e.getMenuType().equals("C"))
                .collect(Collectors.toList());
        // 第一级
        List<SysMenu> s1 = all.stream().filter(e -> e.getMenuType().equals("M"))
                .collect(Collectors.toList());
        for (SysMenu menu : s2) {
            List<SysMenu> collect = s3.stream()
                    .filter(e -> e.getParentId().equals(menu.getMenuId()))
                    .collect(Collectors.toList());
            menu.setChildren(collect);
        }
        for (SysMenu menu : s1) {
            List<SysMenu> collect = s2.stream()
                    .filter(e -> e.getParentId().equals(menu.getMenuId()))
                    .collect(Collectors.toList());
            menu.setChildren(collect);
        }
        return s1;
    }
    @Override
    public List<SysMenu> roleInfoFromUserId(Long userId) {
        SysRole sysRole = roleMapper.selectRoleByUserId(userId);
        // 获取当前角色的菜单列表
        List<SysMenu> menus = menuMapper.selectListByRoleId(sysRole.getRoleId());
        if (menus.size() == 0) {
            return new ArrayList<>();
        }
        List<Long> menusId = menus.stream().map(SysMenu::getMenuId).collect(Collectors.toList());
        // 获取当前的权限菜单(有层级)
        return this.getMenuLevelList(menusId);
    }
}
medicalWaste-system/src/main/resources/mapper/system/SysDepartmentMapper.xml
@@ -34,11 +34,12 @@
        UPDATE_TIME,
        ID, DEPARTMENT_NAME, PARENT_ID, TREE_CODE, ORG_TYPE, ORG_CODE, ADDRESS, LONGITUDE, LATITUDE, CONTACT_PERSON, CONTACT_PHONE, REMARK, LEGAL_PERSON, UNIFIED_SOCIAL_CREDIT_CODE
    </sql>
    <select id="getDepartmentListByType" resultType="com.sinata.system.domain.SysDepartment">
    <select id="getDepartmentByUserId" resultType="com.sinata.system.domain.SysDepartment">
        SELECT t2.* FROM SYS_USER_DEPARTMENT t1 LEFT JOIN SYS_DEPARTMENT t2 ON t1.DEPARTMENT_ID = t2.ID
        <where>
            t1.USER_ID = #{userId} AND t2.ORG_TYPE = #{type}
            t1.USER_ID = #{userId}
        </where>
        LIMIT 1
    </select>
</mapper>
medicalWaste-system/src/main/resources/mapper/system/SysMenuMapper.xml
@@ -222,5 +222,26 @@
                 left join sys_menu sm on srm.menu_id = sm.menu_id
        WHERE srm.role_id = #{roleId}
    </select>
    <select id="getAllInIds" resultType="com.sinata.common.core.domain.entity.SysMenu">
        select
        menu_id AS menuId,
        menu_name AS menuName,
        parent_id AS parentId,
        order_num AS orderNum,
        "path" AS path,
        component AS component,
        "query" AS query,
        is_frame AS isFrame,
        is_cache AS isCache,
        menu_type AS menuType,
        visible AS visible,
        STATUS AS STATUS,
        IFNULL( perms, '' ) AS perms,
        icon AS icon,
        create_time AS createTime
        from sys_menu where menu_id in
        <foreach collection="menusId" close=")" index="index" item="id" open="(" separator=",">
            #{id}
        </foreach>
    </select>
</mapper>
medicalWaste-system/src/main/resources/mapper/system/SysRoleMapper.xml
@@ -180,5 +180,21 @@
             #{roleId}
        </foreach> 
     </delete>
    <select id="selectRoleByUserId" resultType="com.sinata.common.core.domain.entity.SysRole">
        select distinct r.role_id             AS roleId,
                        r.role_name           AS roleName,
                        r.role_key            AS roleKey,
                        r.role_sort           AS roleSort,
                        r.data_scope          AS dataScope,
                        r.menu_check_strictly AS menuCheckStrictly,
                        r.dept_check_strictly AS deptCheckStrictly,
                        r.status              AS status,
                        r.del_flag            AS delFlag,
                        r.create_time         AS createTime,
                        r.create_by           AS createBy
        from sys_role r
                 left join sys_user_role ur on ur.role_id = r.role_id
        where ur.user_id = #{userId}
    </select>
     
</mapper>