1、角色管理根据原型调整以及优化

2、菜单管理根据原型调整及优化,增加pc端菜单和app端菜单的逻辑
This commit is contained in:
gaoxiong 2025-06-24 23:00:32 +08:00
parent af9fc57463
commit 52d2a2f486
21 changed files with 140 additions and 37 deletions

View File

@ -31,6 +31,7 @@ public class Message implements Serializable {
public static final String POST_ID_NOT_EXIST = "岗位id不存在";
public static final String POST_ID_NOT_EXIST_OR_ILLEGAL = "岗位id不存在或者不合法";
public static final String ROLE_ID_NOT_EXIST = "角色id不存在";
public static final String ROLE_CODE_EXIST = "角色编码已经存在";
public static final String ROLE_ID_NOT_EXIST_OR_ILLEGAL = "角色id不存在或者不合法";
public static final String MENU_ID_NOT_EXIST = "菜单id不存在";
public static final String MENU_ID_NOT_EXIST_OR_ILLEGAL = "菜单id不存在或者不合法";

View File

@ -4,7 +4,7 @@ package com.dite.znpt.context;
import cn.hutool.extra.spring.SpringUtil;
import com.dite.znpt.domain.vo.UserResp;
import com.dite.znpt.service.RedisService;
import com.dite.znpt.service.impl.RedisService;
/**
* @author wujinsong

View File

@ -67,4 +67,8 @@ public class MenuEntity extends AuditableEntity implements Serializable {
@ApiModelProperty("权限标识")
@TableField("perms")
private String perms;
@ApiModelProperty("终端类型PC-电脑端APP-移动端)")
@TableField("terminal_type")
private String terminalType;
}

View File

@ -38,6 +38,11 @@ public class RoleEntity extends AuditableEntity implements Serializable {
@TableField("role_name")
private String roleName;
@ExcelProperty("角色编码")
@ApiModelProperty("角色编码")
@TableField("role_code")
private String roleCode;
@ExcelProperty("角色权限字符")
@ApiModelProperty("角色权限字符")
@TableField("role_key")

View File

@ -47,6 +47,10 @@ public class MenuReq implements Serializable {
@ApiModelProperty("参数")
private String perms;
@NotBlank(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, message = "终端类型不能为空")
@ApiModelProperty("终端类型")
private String terminalType;
}

View File

@ -26,6 +26,11 @@ public class RoleReq implements Serializable {
@ApiModelProperty("角色名称")
private String roleName;
@NotBlank(groups = {ValidationGroup.Insert.class, ValidationGroup.Update.class}, message = "角色编码不能为空")
@Size(max = 20, message = "角色编码不能超过20个字符")
@ApiModelProperty("角色编码")
private String roleCode;
@NotBlank(groups = {ValidationGroup.Insert.class}, message = "角色权限字符不能为空")
@Size(groups = {ValidationGroup.Insert.class}, max = 20, message = "角色权限字符不能超过20个字符")
@ApiModelProperty("角色权限字符")

View File

@ -25,6 +25,9 @@ public class RoleResp implements Serializable {
@ApiModelProperty("角色名称")
private String roleName;
@ApiModelProperty("角色编码")
private String roleCode;
@ApiModelProperty("角色权限字符")
private String roleKey;

View File

@ -0,0 +1,50 @@
package com.dite.znpt.enums;
import cn.hutool.json.JSONObject;
import lombok.Getter;
import java.util.ArrayList;
import java.util.List;
/**
* @Author: gaoxiong
* @Date: 2025/6/24 21:53
* @Description:
*/
@Getter
public enum TerminalTypeEnum {
PC("PC","电脑端"),
APP("APP","移动端");
private final String code;
private final String desc;
TerminalTypeEnum(String code, String desc){
this.code = code;
this.desc = desc;
}
public static TerminalTypeEnum getByCode(String code){
for (TerminalTypeEnum e : TerminalTypeEnum.values() ) {
if(e.code.equals(code)){
return e;
}
}
return null;
}
public static String getDescByCode(String code){
TerminalTypeEnum e = getByCode(code);
return null == e ? null : e.desc;
}
public static List<JSONObject> listAll(){
List<JSONObject> list = new ArrayList<>(TerminalTypeEnum.values().length);
for (TerminalTypeEnum e : TerminalTypeEnum.values() ) {
JSONObject jsonObject = new JSONObject();
jsonObject.set(e.code, e.desc);
list.add(jsonObject);
}
return list;
}
}

View File

@ -20,7 +20,7 @@ public interface MenuMapper extends BaseMapper<MenuEntity> {
* @param menuName
* @return
**/
List<MenuEntity> upwardRecursionSelect(@Param("menuName") String menuName);
List<MenuEntity> upwardRecursionSelect(@Param("menuName") String menuName, @Param("terminalType") String terminalType);
/**
* @Author Bear.G
@ -29,5 +29,5 @@ public interface MenuMapper extends BaseMapper<MenuEntity> {
* @param menuId
* @return
**/
List<MenuEntity> downwardRecursionSelect(@Param("menuId") String menuId);
List<MenuEntity> downwardRecursionSelect(@Param("menuId") String menuId, @Param("terminalType") String terminalType);
}

View File

@ -15,7 +15,7 @@ import java.util.List;
*/
public interface MenuService extends IService<MenuEntity> {
List<Tree<String>> tree(String menuName);
List<Tree<String>> tree(String menuName, String terminalType);
MenuResp detail(String menuId);
void save(MenuReq req);
void update(String menuId, MenuReq req);

View File

@ -2,25 +2,30 @@ package com.dite.znpt.service.impl;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.useragent.UserAgent;
import cn.hutool.http.useragent.UserAgentInfo;
import cn.hutool.http.useragent.UserAgentUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.dite.znpt.constant.Constants;
import com.dite.znpt.converts.Converts;
import com.dite.znpt.domain.Result;
import com.dite.znpt.domain.entity.DeptEntity;
import com.dite.znpt.domain.entity.MenuEntity;
import com.dite.znpt.domain.entity.RoleMenuEntity;
import com.dite.znpt.domain.entity.UserEntity;
import com.dite.znpt.domain.entity.*;
import com.dite.znpt.domain.vo.LoginReq;
import com.dite.znpt.domain.vo.RoleResp;
import com.dite.znpt.domain.vo.UserInfo;
import com.dite.znpt.enums.TerminalTypeEnum;
import com.dite.znpt.service.*;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;
@ -61,13 +66,16 @@ public class AuthServiceImpl implements AuthService {
}catch (Exception e){
return Result.error(Constants.PASSWORD_EXCEPTION, Constants.PASSWORD_EXCEPTION_MESSAGE);
}
if(!user.getStatus().equals(Constants.STATUS_1)){
if(!user.getStatus().equals(Constants.STATUS_0)){
return Result.error(Constants.USER_DISABLE_EXCEPTION, Constants.USER_DISABLE_EXCEPTION_MESSAGE);
}
if(user.getIsDefaultPassword()){
return Result.error(Constants.DEFAULT_PASSWORD_EXCEPTION, Constants.DEFAULT_PASSWORD_EXCEPTION_MESSAGE);
}
StpUtil.login(user.getUserId());
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = servletRequestAttributes.getRequest();
UserAgent userAgent = UserAgentUtil.parse(request .getHeader("User-Agent"));
StpUtil.login(user.getUserId(), new SaLoginParameter().setDeviceType(userAgent.isMobile() ? TerminalTypeEnum.APP.getCode() : TerminalTypeEnum.PC.getCode()));
saveSession(user.getUserId());
return Result.ok(StpUtil.getTokenInfo());
}
@ -110,9 +118,13 @@ public class AuthServiceImpl implements AuthService {
if(CollUtil.isEmpty(roleIds)){
return new ArrayList<>();
}
List<String> menuIds = roleMenuService.list(Wrappers.lambdaQuery(RoleMenuEntity.class).in(CollUtil.isNotEmpty(roleIds), RoleMenuEntity::getRoleId, roleIds)).stream().map(RoleMenuEntity::getMenuId).toList();
List<String> menuIds = roleMenuService.list(
Wrappers.lambdaQuery(RoleMenuEntity.class)
.in(CollUtil.isNotEmpty(roleIds), RoleMenuEntity::getRoleId, roleIds)
).stream().map(RoleMenuEntity::getMenuId).toList();
List<MenuEntity> menuList = menuService.list(
Wrappers.lambdaQuery(MenuEntity.class).in(CollUtil.isNotEmpty(menuIds), MenuEntity::getMenuId,menuIds)
Wrappers.lambdaQuery(MenuEntity.class)
.in(CollUtil.isNotEmpty(menuIds), MenuEntity::getMenuId,menuIds).eq(MenuEntity::getTerminalType, StpUtil.getLoginDeviceType())
).stream().filter(menu -> Constants.VISIBLE_0.equals(menu.getVisible())).toList();
return MenuServiceImpl.buildMenuTree(menuList);
}

View File

@ -1,5 +1,6 @@
package com.dite.znpt.service.impl;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNodeConfig;
import cn.hutool.core.lang.tree.TreeUtil;
@ -27,8 +28,8 @@ import java.util.List;
public class MenuServiceImpl extends ServiceImpl<MenuMapper, MenuEntity> implements MenuService {
@Override
public List<Tree<String>> tree(String menuName) {
List<MenuEntity> menuList = StrUtil.isBlank(menuName) ? this.baseMapper.downwardRecursionSelect(null) : this.baseMapper.upwardRecursionSelect(menuName);
public List<Tree<String>> tree(String menuName, String terminalType) {
List<MenuEntity> menuList = StrUtil.isBlank(menuName) ? this.baseMapper.downwardRecursionSelect(null, terminalType) : this.baseMapper.upwardRecursionSelect(menuName, terminalType);
return buildMenuTree(menuList);
}

View File

@ -1,17 +1,10 @@
package com.dite.znpt.service;
package com.dite.znpt.service.impl;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.BoundSetOperations;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import java.util.*;

View File

@ -1,5 +1,6 @@
package com.dite.znpt.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -45,6 +46,10 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> impleme
@Transactional(rollbackFor = Exception.class)
@Override
public void save(RoleReq req) {
List<RoleEntity> roles = this.list(Wrappers.lambdaQuery(RoleEntity.class).eq(RoleEntity::getRoleCode, req.getRoleCode()).eq(RoleEntity::getDelFlag, Constants.DEL_FLAG_0));
if(CollUtil.isNotEmpty(roles)){
throw new ServiceException(Message.ROLE_CODE_EXIST);
}
RoleEntity entity = Converts.INSTANCE.toRoleEntity(req);
this.save(entity);
}
@ -52,10 +57,16 @@ public class RoleServiceImpl extends ServiceImpl<RoleMapper, RoleEntity> impleme
@Transactional(rollbackFor = Exception.class)
@Override
public void update(String roleId, RoleReq req) {
RoleEntity originEntity = this.getById(roleId);
if(null == originEntity || !Constants.DEL_FLAG_0.equals(originEntity.getDelFlag())) {
RoleEntity role = this.getById(roleId);
if(null == role || !Constants.DEL_FLAG_0.equals(role.getDelFlag())) {
throw new ServiceException(Message.ROLE_ID_NOT_EXIST);
}
if(!role.getRoleCode().equals(req.getRoleCode())){
List<RoleEntity> roles = this.list(Wrappers.lambdaQuery(RoleEntity.class).eq(RoleEntity::getRoleCode, req.getRoleCode()).eq(RoleEntity::getDelFlag, Constants.DEL_FLAG_0));
if(CollUtil.isNotEmpty(roles)){
throw new ServiceException(Message.ROLE_CODE_EXIST);
}
}
RoleEntity entity = Converts.INSTANCE.toRoleEntity(req);
entity.setRoleId(roleId);
entity.setRoleKey(null);

View File

@ -6,7 +6,7 @@
<select id="upwardRecursionSelect" resultType="com.dite.znpt.domain.entity.MenuEntity">
WITH RECURSIVE MenuPath AS (
SELECT * FROM menu
<where>
WHERE terminal_type = #{terminalType}
<choose>
<when test="menuName != null and menuName != ''">
AND menu_name LIKE concat('%',#{menuName}, '%') -- 起始菜单
@ -15,7 +15,6 @@
AND parent_id = '0' -- 起始菜单
</otherwise>
</choose>
</where>
UNION ALL
SELECT m.* FROM menu m INNER JOIN MenuPath mp ON m.menu_id = mp.parent_id
) SELECT DISTINCT * FROM MenuPath;
@ -24,7 +23,7 @@
<select id="downwardRecursionSelect" resultType="com.dite.znpt.domain.entity.MenuEntity">
WITH RECURSIVE SubMenus AS (
SELECT * FROM menu
<where>
WHERE terminal_type = #{terminalType}
<choose>
<when test="menuId != null and menuId != ''">
AND menu_id = #{menuId} -- 起始菜单ID
@ -33,7 +32,6 @@
AND parent_id = '0' -- 起始菜单
</otherwise>
</choose>
</where>
UNION ALL
SELECT d.* FROM menu d INNER JOIN SubMenus sd ON d.parent_id = sd.menu_id
) SELECT * FROM SubMenus;

View File

@ -1,10 +1,9 @@
package com.dite.znpt.monitor.media.zlm.cache;
import com.dite.znpt.monitor.media.zlm.dto.ServerItem;
import com.dite.znpt.service.RedisService;
import com.dite.znpt.service.impl.RedisService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
/**

View File

@ -2,7 +2,7 @@ package com.dite.znpt.monitor.media.zlm.cache;
import cn.hutool.core.util.StrUtil;
import com.dite.znpt.monitor.media.zlm.dto.MediaItem;
import com.dite.znpt.service.RedisService;
import com.dite.znpt.service.impl.RedisService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

View File

@ -24,7 +24,7 @@ import com.dite.znpt.monitor.service.DeviceVideoChannelService;
import com.dite.znpt.monitor.service.DeviceVideoService;
import com.dite.znpt.monitor.sip.transmit.cmd.ISipDeviceCommander;
import com.dite.znpt.monitor.utils.DictUtils;
import com.dite.znpt.service.RedisService;
import com.dite.znpt.service.impl.RedisService;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

View File

@ -6,7 +6,7 @@ import com.dite.znpt.monitor.domain.entity.DeviceVideoEntity;
import com.dite.znpt.monitor.media.zlm.ZlmService;
import com.dite.znpt.monitor.sip.transmit.cmd.ISipDeviceCommander;
import com.dite.znpt.monitor.sip.transmit.cmd.SipRequestHeaderProvider;
import com.dite.znpt.service.RedisService;
import com.dite.znpt.service.impl.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

View File

@ -107,8 +107,7 @@ public class CommonController {
@ApiOperation(value = "上传图片", httpMethod = "POST")
@PostMapping("/upload-image/{imageSource}")
public Result uploadImage(@PathVariable String imageSource, ImageWorkReq workReq,
MultipartFile file) throws IOException {
public Result uploadImage(@PathVariable String imageSource, ImageWorkReq workReq, MultipartFile file) throws IOException {
if(null == file){
throw new ServiceException(Message.IMAGE_IS_EMPTY);
}
@ -128,5 +127,23 @@ public class CommonController {
return Result.ok(MenuTypeEnum.listAll());
}
@ApiOperation(value = "查询终端类型", httpMethod = "GET")
@GetMapping("/list/terminal-type")
public Result listTerminalType(){
return Result.ok(TerminalTypeEnum.listAll());
}
@ApiOperation(value = "查询在职状态", httpMethod = "GET")
@GetMapping("/list/user_status")
public Result listUserStatus(){
return Result.ok(UserStatusEnum.listAll());
}
@ApiOperation(value = "查询员工性质", httpMethod = "GET")
@GetMapping("/list/user_type")
public Result listUserType(){
return Result.ok(UserTypeEnum.listAll());
}
}

View File

@ -25,8 +25,8 @@ public class MenuController {
@ApiOperation(value = "查询菜单树", httpMethod = "GET")
@GetMapping("/tree")
public Result tree (@RequestParam(name = "menuName", required = false) String menuName) {
return Result.ok(menuService.tree(menuName));
public Result tree (@RequestParam(name = "menuName", required = false) String menuName, @RequestParam(defaultValue = "PC") String terminalType) {
return Result.ok(menuService.tree(menuName, terminalType));
}
@ApiOperation(value = "查询菜单详情", httpMethod = "GET")