Commit 9ee6fd83 by HuAnYing

Merge branch 'master' of http://47.122.114.111:9999/lizhonghong/custom-server

# Conflicts:
#	custom-server-app/src/main/java/com/jomalls/custom/app/service/SysUserService.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/service/impl/SysUserServiceImpl.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysMenuVo.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRoleDeptPageVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRoleDeptVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRoleMenuPageVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRoleMenuVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRolePageVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysRoleVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysUserOldPageVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysUserOldVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysUserRolePageVO.java
#	custom-server-app/src/main/java/com/jomalls/custom/app/vo/SysUserRoleVO.java
#	custom-server-webapp/src/main/java/com/jomalls/custom/webapp/controller/SysUserController.java
parents e2e51aad 4f5249ae
......@@ -10,4 +10,6 @@
.settings
*.log
/logs/
.trae/
.vscode/
......@@ -23,6 +23,11 @@
</dependency>
<dependency>
<groupId>com.jomalls.custom</groupId>
<artifactId>custom-server-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jomalls.custom</groupId>
<artifactId>custom-server-domain</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
......@@ -35,6 +40,13 @@
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- Spring AOP for permission aspect -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<!--<version>${spring-boot.version}</version>-->
<version>4.0.0-M2</version>
</dependency>
</dependencies>
</project>
package com.jomalls.custom.app.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 权限控制注解
* 用于标注需要权限校验的 Controller 方法
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequiresPermissions {
/**
* 权限字符串,支持多个权限(逗号分隔)
* 例如: "system:user:list" 或 "system:user:add,system:user:edit"
*/
String value();
/**
* 权限校验模式
* ALL - 必须拥有所有权限
* ANY - 拥有任意一个权限即可
*/
RequireMode mode() default RequireMode.ANY;
/**
* 权限校验失败时的错误信息
*/
String message() default "无访问权限";
/**
* 权限校验模式枚举
*/
enum RequireMode {
/**
* 必须拥有所有权限
*/
ALL,
/**
* 拥有任意一个权限即可
*/
ANY
}
}
package com.jomalls.custom.app.aspect;
import com.jomalls.custom.app.annotation.RequiresPermissions;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.PermissionService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
/**
* 权限校验切面
*/
@Aspect
@Component
public class PermissionAspect {
private static final Logger log = LoggerFactory.getLogger(PermissionAspect.class);
@Autowired
private PermissionService permissionService;
@Before("@annotation(com.jomalls.custom.app.annotation.RequiresPermissions)")
public void doBefore(JoinPoint point) throws Throwable {
checkPermissions(point);
}
/**
* 权限校验
*
* @param joinPoint 切点
*/
private void checkPermissions(JoinPoint joinPoint) {
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
RequiresPermissions requiresPermissions = method.getAnnotation(RequiresPermissions.class);
if (requiresPermissions == null) {
return;
}
String permission = requiresPermissions.value();
RequiresPermissions.RequireMode mode = requiresPermissions.mode();
String message = requiresPermissions.message();
boolean hasPermission;
if (mode == RequiresPermissions.RequireMode.ALL) {
String[] permissions = permission.split(",");
hasPermission = true;
for (String p : permissions) {
if (!permissionService.hasPermi(p.trim())) {
hasPermission = false;
break;
}
}
} else {
hasPermission = permissionService.hasAnyPermi(permission);
}
if (!hasPermission) {
log.warn("用户无权限访问,权限标识: {},方法: {}", permission, method.getName());
throw new ServiceException(message, 403);
}
}
}
......@@ -2,6 +2,8 @@ package com.jomalls.custom.app.exception;
import lombok.Getter;
import java.io.Serial;
/**
* @Author: Lizh
* @Date: 2026/5/28 10:27
......@@ -9,6 +11,7 @@ import lombok.Getter;
* @Version: 1.0
*/
public final class ServiceException extends RuntimeException {
@Serial
private static final long serialVersionUID = 1L;
/**
......
package com.jomalls.custom.app.service;
/**
* 权限服务接口
*/
public interface PermissionService {
/**
* 验证用户是否具备某权限
*
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
boolean hasPermi(String permission);
/**
* 验证用户是否不具备某权限
*
* @param permission 权限字符串
* @return 用户是否不具备某权限
*/
boolean lacksPermi(String permission);
/**
* 验证用户是否具有以下任意一个权限
*
* @param permissions 以逗号为分隔符的权限列表
* @return 用户是否具有以下任意一个权限
*/
boolean hasAnyPermi(String permissions);
/**
* 判断用户是否拥有某个角色
*
* @param role 角色字符串
* @return 用户是否具备某角色
*/
boolean hasRole(String role);
/**
* 验证用户是否不具备某角色
*
* @param role 角色名称
* @return 用户是否不具备某角色
*/
boolean lacksRole(String role);
/**
* 验证用户是否具有以下任意一个角色
*
* @param roles 以逗号为分隔符的角色列表
* @return 用户是否具有以下任意一个角色
*/
boolean hasAnyRoles(String roles);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.model.SysRoleDeptVO;
import com.jomalls.custom.app.model.SysRoleDeptPageVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 角色和部门关联表 接口
* @date 2026-06-01 12:30:00
*/
public interface SysRoleDeptService {
/**
* 列表查询接口
*
* @param sysRoleDeptVO 条件model
* @return list集合
*/
List<SysRoleDeptVO> list(SysRoleDeptVO sysRoleDeptVO);
/**
* 根据条件查询分页列表接口
*
* @param sysRoleDeptPageVO 分页入参model
* @return 分页对象
*/
IPage<SysRoleDeptVO> pageList(SysRoleDeptPageVO sysRoleDeptPageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
SysRoleDeptVO info(String id);
/**
* 保存对象
*
* @param sysRoleDeptVO 保存对象
*/
void save(SysRoleDeptVO sysRoleDeptVO);
/**
* 根据id修改对象
*
* @param sysRoleDeptVO 修改对象
*/
void updateById(SysRoleDeptVO sysRoleDeptVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(String id);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.model.SysRoleMenuVO;
import com.jomalls.custom.app.model.SysRoleMenuPageVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 角色和菜单关联表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysRoleMenuService {
/**
* 列表查询接口
*
* @param sysRoleMenuVO 条件model
* @return list集合
*/
List<SysRoleMenuVO> list(SysRoleMenuVO sysRoleMenuVO);
/**
* 根据条件查询分页列表接口
*
* @param sysRoleMenuPageVO 分页入参model
* @return 分页对象
*/
IPage<SysRoleMenuVO> pageList(SysRoleMenuPageVO sysRoleMenuPageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
SysRoleMenuVO info(String id);
/**
* 保存对象
*
* @param sysRoleMenuVO 保存对象
*/
void save(SysRoleMenuVO sysRoleMenuVO);
/**
* 根据id修改对象
*
* @param sysRoleMenuVO 修改对象
*/
void updateById(SysRoleMenuVO sysRoleMenuVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(String id);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.model.SysRoleVO;
import com.jomalls.custom.app.model.SysRolePageVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 角色信息表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysRoleService {
/**
* 列表查询接口
*
* @param sysRoleVO 条件model
* @return list集合
*/
List<SysRoleVO> list(SysRoleVO sysRoleVO);
/**
* 根据条件查询分页列表接口
*
* @param sysRolePageVO 分页入参model
* @return 分页对象
*/
IPage<SysRoleVO> pageList(SysRolePageVO sysRolePageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
SysRoleVO info(String id);
/**
* 保存对象
*
* @param sysRoleVO 保存对象
*/
void save(SysRoleVO sysRoleVO);
/**
* 根据id修改对象
*
* @param sysRoleVO 修改对象
*/
void updateById(SysRoleVO sysRoleVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(String id);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.model.SysUserOldVO;
import com.jomalls.custom.app.model.SysUserOldPageVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 系统用户 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserOldService {
/**
* 列表查询接口
*
* @param sysUserOldVO 条件model
* @return list集合
*/
List<SysUserOldVO> list(SysUserOldVO sysUserOldVO);
/**
* 根据条件查询分页列表接口
*
* @param sysUserOldPageVO 分页入参model
* @return 分页对象
*/
IPage<SysUserOldVO> pageList(SysUserOldPageVO sysUserOldPageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
SysUserOldVO info(String id);
/**
* 保存对象
*
* @param sysUserOldVO 保存对象
*/
void save(SysUserOldVO sysUserOldVO);
/**
* 根据id修改对象
*
* @param sysUserOldVO 修改对象
*/
void updateById(SysUserOldVO sysUserOldVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(String id);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.model.SysUserRoleVO;
import com.jomalls.custom.app.model.SysUserRolePageVO;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 用户和角色关联表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserRoleService {
/**
* 列表查询接口
*
* @param sysUserRoleVO 条件model
* @return list集合
*/
List<SysUserRoleVO> list(SysUserRoleVO sysUserRoleVO);
/**
* 根据条件查询分页列表接口
*
* @param sysUserRolePageVO 分页入参model
* @return 分页对象
*/
IPage<SysUserRoleVO> pageList(SysUserRolePageVO sysUserRolePageVO);
/**
* 根据id查询详情
*
* @param id 主键
* @return 实体model
*/
SysUserRoleVO info(String id);
/**
* 保存对象
*
* @param sysUserRoleVO 保存对象
*/
void save(SysUserRoleVO sysUserRoleVO);
/**
* 根据id修改对象
*
* @param sysUserRoleVO 修改对象
*/
void updateById(SysUserRoleVO sysUserRoleVO);
/**
* 根据主键ID进行删除
*
* @param id 主键
*/
void deleteById(String id);
}
package com.jomalls.custom.app.service;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.SysUserPageVO;
import com.jomalls.custom.app.vo.SysUserVO;
import com.jomalls.custom.app.model.SysUserVO;
import com.jomalls.custom.app.model.SysUserPageVO;
import java.util.List;
/**
* 用户服务接口
* @author Lizh
* @version 0.01
* @description: 用户信息表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserService {
/**
* 列表查询接口
*
* @param sysUser 条件model
* @param sysUserVO 条件model
* @return list集合
*/
List<SysUserVO> list(SysUserVO sysUser);
List<SysUserVO> list(SysUserVO sysUserVO);
/**
* 根据条件查询分页列表接口
*
* @param sysUserPage 分页入参model
* @param sysUserPageVO 分页入参model
* @return 分页对象
*/
IPage<SysUserVO> pageList(SysUserPageVO sysUserPage);
IPage<SysUserVO> pageList(SysUserPageVO sysUserPageVO);
/**
* 根据id查询详情
......@@ -38,16 +41,16 @@ public interface SysUserService {
/**
* 保存对象
*
* @param sysUser 保存对象
* @param sysUserVO 保存对象
*/
void save(SysUserVO sysUser);
void save(SysUserVO sysUserVO);
/**
* 根据id修改对象
*
* @param sysUser 修改对象
* @param sysUserVO 修改对象
*/
void updateById(SysUserVO sysUser);
void updateById(SysUserVO sysUserVO);
/**
* 根据主键ID进行删除
......@@ -56,4 +59,5 @@ public interface SysUserService {
*/
void deleteById(Long id);
}
\ No newline at end of file
}
package com.jomalls.custom.app.service.impl;
import com.jomalls.custom.app.service.PermissionService;
import com.jomalls.custom.domain.service.SysMenuDomainService;
import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 权限服务实现
*/
@Service
public class PermissionServiceImpl implements PermissionService {
private static final Logger log = LoggerFactory.getLogger(PermissionServiceImpl.class);
@Autowired
private SysMenuDomainService sysMenuDomainService;
/**
* 所有权限标识
*/
private static final String ALL_PERMISSION = "*:*:*";
/**
* 权限分隔符
*/
private static final String PERMISSION_DELIMETER = ",";
/**
* 管理员角色标识
*/
private static final String ADMIN_ROLE = "admin";
@Override
public boolean hasPermi(String permission) {
if (!StringUtils.hasText(permission)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return false;
}
Set<String> permissions = getPermissionsFromCache(loginUser);
return hasPermissions(permissions, permission);
}
@Override
public boolean lacksPermi(String permission) {
return !hasPermi(permission);
}
@Override
public boolean hasAnyPermi(String permissions) {
if (!StringUtils.hasText(permissions)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return false;
}
Set<String> authorities = getPermissionsFromCache(loginUser);
for (String permission : permissions.split(PERMISSION_DELIMETER)) {
if (permission != null && hasPermissions(authorities, permission.trim())) {
return true;
}
}
return false;
}
@Override
public boolean hasRole(String role) {
if (!StringUtils.hasText(role)) {
return false;
}
LoginUser loginUser = SecurityUtils.getLoginUser();
if (loginUser == null) {
return false;
}
// 简单实现:检查是否是管理员
return ADMIN_ROLE.equalsIgnoreCase(role);
}
@Override
public boolean lacksRole(String role) {
return !hasRole(role);
}
@Override
public boolean hasAnyRoles(String roles) {
if (!StringUtils.hasText(roles)) {
return false;
}
for (String role : roles.split(PERMISSION_DELIMETER)) {
if (hasRole(role.trim())) {
return true;
}
}
return false;
}
/**
* 从缓存或数据库获取用户权限
*
* @param loginUser 登录用户
* @return 权限集合
*/
private Set<String> getPermissionsFromCache(LoginUser loginUser) {
// 首先检查缓存的权限
if (!CollectionUtils.isEmpty(loginUser.getPermissions())) {
return loginUser.getPermissions();
}
// 如果缓存中没有,从数据库查询
Set<String> permissions = queryUserPermissions(loginUser.getUserId());
// 更新缓存
loginUser.setPermissions(permissions);
SecurityUtils.setLoginUser(loginUser);
return permissions;
}
/**
* 查询用户权限
*
* @param userId 用户ID
* @return 权限集合
*/
private Set<String> queryUserPermissions(Long userId) {
Set<String> permissions = new HashSet<>();
try {
// 根据用户ID查询权限字符串列表
List<String> permsList = sysMenuDomainService.selectMenuPermsByUserId(userId);
// 过滤空权限并添加到集合
for (String perms : permsList) {
if (StringUtils.hasText(perms)) {
// 处理可能包含逗号分隔的权限字符串
String[] permsArray = perms.split(PERMISSION_DELIMETER);
for (String perm : permsArray) {
if (StringUtils.hasText(perm)) {
permissions.add(perm.trim());
}
}
}
}
log.debug("用户[{}]查询到权限数量: {}", userId, permissions.size());
} catch (Exception e) {
log.error("查询用户权限异常: {}", e.getMessage());
}
return permissions;
}
/**
* 判断是否包含权限
*
* @param permissions 权限列表
* @param permission 权限字符串
* @return 用户是否具备某权限
*/
private boolean hasPermissions(Set<String> permissions, String permission) {
return permissions.contains(ALL_PERMISSION) || permissions.contains(permission.trim());
}
}
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.SysRoleDeptService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysRoleDeptEntity;
import com.jomalls.custom.domain.service.SysRoleDeptDomainService;
import com.jomalls.custom.app.model.SysRoleDeptVO;
import com.jomalls.custom.app.model.SysRoleDeptPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 角色和部门关联表 接口实现
* @date 2026-06-01 12:30:00
*/
@Slf4j
@Service
public class SysRoleDeptServiceImpl implements SysRoleDeptService {
private final SysRoleDeptDomainService sysRoleDeptDomainService;
@Autowired
public SysRoleDeptServiceImpl(SysRoleDeptDomainService sysRoleDeptDomainService) {
this.sysRoleDeptDomainService = sysRoleDeptDomainService;
}
@Override
public List<SysRoleDeptVO> list(SysRoleDeptVO sysRoleDeptVO) {
QueryWrapper<SysRoleDeptEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<SysRoleDeptEntity> list = sysRoleDeptDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysRoleDeptVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysRoleDeptVO> pageList(SysRoleDeptPageVO sysRoleDeptPageVO) {
CustomAsserts.nonNull(sysRoleDeptPageVO, "分页查询参数不能为空");
QueryWrapper<SysRoleDeptEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<SysRoleDeptEntity> page = sysRoleDeptDomainService.selectPage(queryWrapper, sysRoleDeptPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysRoleDeptVO.class));
}
@Override
public SysRoleDeptVO info(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysRoleDeptEntity sysRoleDept = sysRoleDeptDomainService.getById(id);
return BeanMapper.mapper().convert(sysRoleDept, SysRoleDeptVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysRoleDeptVO sysRoleDeptVO) {
CustomAsserts.nonNull(sysRoleDeptVO, "实体对象不能为空");
SysRoleDeptEntity sysRoleDeptEntity = BeanMapper.mapper().convert(sysRoleDeptVO, SysRoleDeptEntity.class);
try {
sysRoleDeptDomainService.save(sysRoleDeptEntity);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleDeptServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysRoleDeptVO sysRoleDeptVO) {
CustomAsserts.nonNull(sysRoleDeptVO, "实体对象不能为空");
SysRoleDeptEntity sysRoleDept = BeanMapper.mapper().convert(sysRoleDeptVO, SysRoleDeptEntity.class);
try {
sysRoleDeptDomainService.updateById(sysRoleDept);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleDeptServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
sysRoleDeptDomainService.removeById(id);
}
}
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.SysRoleMenuService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysRoleMenuEntity;
import com.jomalls.custom.domain.service.SysRoleMenuDomainService;
import com.jomalls.custom.app.model.SysRoleMenuVO;
import com.jomalls.custom.app.model.SysRoleMenuPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 角色和菜单关联表 接口实现
* @date 2026-06-01 12:29:59
*/
@Slf4j
@Service
public class SysRoleMenuServiceImpl implements SysRoleMenuService {
private final SysRoleMenuDomainService sysRoleMenuDomainService;
@Autowired
public SysRoleMenuServiceImpl(SysRoleMenuDomainService sysRoleMenuDomainService) {
this.sysRoleMenuDomainService = sysRoleMenuDomainService;
}
@Override
public List<SysRoleMenuVO> list(SysRoleMenuVO sysRoleMenuVO) {
QueryWrapper<SysRoleMenuEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<SysRoleMenuEntity> list = sysRoleMenuDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysRoleMenuVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysRoleMenuVO> pageList(SysRoleMenuPageVO sysRoleMenuPageVO) {
CustomAsserts.nonNull(sysRoleMenuPageVO, "分页查询参数不能为空");
QueryWrapper<SysRoleMenuEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<SysRoleMenuEntity> page = sysRoleMenuDomainService.selectPage(queryWrapper, sysRoleMenuPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysRoleMenuVO.class));
}
@Override
public SysRoleMenuVO info(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysRoleMenuEntity sysRoleMenu = sysRoleMenuDomainService.getById(id);
return BeanMapper.mapper().convert(sysRoleMenu, SysRoleMenuVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysRoleMenuVO sysRoleMenuVO) {
CustomAsserts.nonNull(sysRoleMenuVO, "实体对象不能为空");
SysRoleMenuEntity sysRoleMenuEntity = BeanMapper.mapper().convert(sysRoleMenuVO, SysRoleMenuEntity.class);
try {
sysRoleMenuDomainService.save(sysRoleMenuEntity);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleMenuServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysRoleMenuVO sysRoleMenuVO) {
CustomAsserts.nonNull(sysRoleMenuVO, "实体对象不能为空");
SysRoleMenuEntity sysRoleMenu = BeanMapper.mapper().convert(sysRoleMenuVO, SysRoleMenuEntity.class);
try {
sysRoleMenuDomainService.updateById(sysRoleMenu);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleMenuServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
sysRoleMenuDomainService.removeById(id);
}
}
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.SysRoleService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysRoleEntity;
import com.jomalls.custom.domain.service.SysRoleDomainService;
import com.jomalls.custom.app.model.SysRoleVO;
import com.jomalls.custom.app.model.SysRolePageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 角色信息表 接口实现
* @date 2026-06-01 12:29:59
*/
@Slf4j
@Service
public class SysRoleServiceImpl implements SysRoleService {
private final SysRoleDomainService sysRoleDomainService;
@Autowired
public SysRoleServiceImpl(SysRoleDomainService sysRoleDomainService) {
this.sysRoleDomainService = sysRoleDomainService;
}
@Override
public List<SysRoleVO> list(SysRoleVO sysRoleVO) {
QueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<SysRoleEntity> list = sysRoleDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysRoleVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysRoleVO> pageList(SysRolePageVO sysRolePageVO) {
CustomAsserts.nonNull(sysRolePageVO, "分页查询参数不能为空");
QueryWrapper<SysRoleEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<SysRoleEntity> page = sysRoleDomainService.selectPage(queryWrapper, sysRolePageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysRoleVO.class));
}
@Override
public SysRoleVO info(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysRoleEntity sysRole = sysRoleDomainService.getById(id);
return BeanMapper.mapper().convert(sysRole, SysRoleVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysRoleVO sysRoleVO) {
CustomAsserts.nonNull(sysRoleVO, "实体对象不能为空");
SysRoleEntity sysRoleEntity = BeanMapper.mapper().convert(sysRoleVO, SysRoleEntity.class);
try {
sysRoleDomainService.save(sysRoleEntity);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysRoleVO sysRoleVO) {
CustomAsserts.nonNull(sysRoleVO, "实体对象不能为空");
SysRoleEntity sysRole = BeanMapper.mapper().convert(sysRoleVO, SysRoleEntity.class);
try {
sysRoleDomainService.updateById(sysRole);
} catch (DuplicateKeyException e) {
log.info("[ SysRoleServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
sysRoleDomainService.removeById(id);
}
}
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.SysUserOldService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysUserOldEntity;
import com.jomalls.custom.domain.service.SysUserOldDomainService;
import com.jomalls.custom.app.model.SysUserOldVO;
import com.jomalls.custom.app.model.SysUserOldPageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 系统用户 接口实现
* @date 2026-06-01 12:29:59
*/
@Slf4j
@Service
public class SysUserOldServiceImpl implements SysUserOldService {
private final SysUserOldDomainService sysUserOldDomainService;
@Autowired
public SysUserOldServiceImpl(SysUserOldDomainService sysUserOldDomainService) {
this.sysUserOldDomainService = sysUserOldDomainService;
}
@Override
public List<SysUserOldVO> list(SysUserOldVO sysUserOldVO) {
QueryWrapper<SysUserOldEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<SysUserOldEntity> list = sysUserOldDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysUserOldVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysUserOldVO> pageList(SysUserOldPageVO sysUserOldPageVO) {
CustomAsserts.nonNull(sysUserOldPageVO, "分页查询参数不能为空");
QueryWrapper<SysUserOldEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<SysUserOldEntity> page = sysUserOldDomainService.selectPage(queryWrapper, sysUserOldPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysUserOldVO.class));
}
@Override
public SysUserOldVO info(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysUserOldEntity sysUserOld = sysUserOldDomainService.getById(id);
return BeanMapper.mapper().convert(sysUserOld, SysUserOldVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysUserOldVO sysUserOldVO) {
CustomAsserts.nonNull(sysUserOldVO, "实体对象不能为空");
SysUserOldEntity sysUserOldEntity = BeanMapper.mapper().convert(sysUserOldVO, SysUserOldEntity.class);
try {
sysUserOldDomainService.save(sysUserOldEntity);
} catch (DuplicateKeyException e) {
log.info("[ SysUserOldServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysUserOldVO sysUserOldVO) {
CustomAsserts.nonNull(sysUserOldVO, "实体对象不能为空");
SysUserOldEntity sysUserOld = BeanMapper.mapper().convert(sysUserOldVO, SysUserOldEntity.class);
try {
sysUserOldDomainService.updateById(sysUserOld);
} catch (DuplicateKeyException e) {
log.info("[ SysUserOldServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
sysUserOldDomainService.removeById(id);
}
}
package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.service.SysUserRoleService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysUserRoleEntity;
import com.jomalls.custom.domain.service.SysUserRoleDomainService;
import com.jomalls.custom.app.model.SysUserRoleVO;
import com.jomalls.custom.app.model.SysUserRolePageVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author Lizh
* @version 0.01
* @description: 用户和角色关联表 接口实现
* @date 2026-06-01 12:29:59
*/
@Slf4j
@Service
public class SysUserRoleServiceImpl implements SysUserRoleService {
private final SysUserRoleDomainService sysUserRoleDomainService;
@Autowired
public SysUserRoleServiceImpl(SysUserRoleDomainService sysUserRoleDomainService) {
this.sysUserRoleDomainService = sysUserRoleDomainService;
}
@Override
public List<SysUserRoleVO> list(SysUserRoleVO sysUserRoleVO) {
QueryWrapper<SysUserRoleEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
List<SysUserRoleEntity> list = sysUserRoleDomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysUserRoleVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysUserRoleVO> pageList(SysUserRolePageVO sysUserRolePageVO) {
CustomAsserts.nonNull(sysUserRolePageVO, "分页查询参数不能为空");
QueryWrapper<SysUserRoleEntity> queryWrapper = new QueryWrapper<>();
// TODO 根据业务条件组装入参
IPage<SysUserRoleEntity> page = sysUserRoleDomainService.selectPage(queryWrapper, sysUserRolePageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysUserRoleVO.class));
}
@Override
public SysUserRoleVO info(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysUserRoleEntity sysUserRole = sysUserRoleDomainService.getById(id);
return BeanMapper.mapper().convert(sysUserRole, SysUserRoleVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysUserRoleVO sysUserRoleVO) {
CustomAsserts.nonNull(sysUserRoleVO, "实体对象不能为空");
SysUserRoleEntity sysUserRoleEntity = BeanMapper.mapper().convert(sysUserRoleVO, SysUserRoleEntity.class);
try {
sysUserRoleDomainService.save(sysUserRoleEntity);
} catch (DuplicateKeyException e) {
log.info("[ SysUserRoleServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysUserRoleVO sysUserRoleVO) {
CustomAsserts.nonNull(sysUserRoleVO, "实体对象不能为空");
SysUserRoleEntity sysUserRole = BeanMapper.mapper().convert(sysUserRoleVO, SysUserRoleEntity.class);
try {
sysUserRoleDomainService.updateById(sysUserRole);
} catch (DuplicateKeyException e) {
log.info("[ SysUserRoleServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(String id) {
CustomAsserts.nonNull(id, "主键id不能为空");
sysUserRoleDomainService.removeById(id);
}
}
......@@ -3,114 +3,94 @@ package com.jomalls.custom.app.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.exception.ServiceException;
import com.jomalls.custom.app.vo.SysUserPageVO;
import com.jomalls.custom.app.vo.SysUserVO;
import com.jomalls.custom.app.service.SysUserService;
import com.jomalls.custom.app.utils.BeanMapper;
import com.jomalls.custom.app.utils.CustomAsserts;
import com.jomalls.custom.dal.entity.SysUserEntity;
import com.jomalls.custom.domain.service.SysUserDomainService;
import com.jomalls.custom.app.service.SysUserService;
import com.jomalls.custom.app.model.SysUserVO;
import com.jomalls.custom.app.model.SysUserPageVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import java.util.List;
import java.util.stream.Collectors;
/**
* 用户服务实现类
* @author Lizh
* @version 0.01
* @description: 用户信息表 接口实现
* @date 2026-06-01 12:29:59
*/
@Slf4j
@Service
public class SysUserServiceImpl implements SysUserService {
private final SysUserDomainService sysUserDomainService;
private final SysUserDomainService sysUser11DomainService;
@Autowired
public SysUserServiceImpl(SysUserDomainService sysUserDomainService) {
this.sysUserDomainService = sysUserDomainService;
public SysUserServiceImpl(SysUserDomainService sysUser11DomainService) {
this.sysUser11DomainService = sysUser11DomainService;
}
@Override
public List<SysUserVO> list(SysUserVO sysUser) {
public List<SysUserVO> list(SysUserVO sysUserVO) {
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
// 根据业务条件组装入参
if (null != sysUser) {
queryWrapper.lambda().like(StringUtils.isNotBlank(sysUser.getUsername()),
SysUserEntity::getUsername, sysUser.getUsername());
}
List<SysUserEntity> list = sysUserDomainService.list(queryWrapper);
// TODO 根据业务条件组装入参
List<SysUserEntity> list = sysUser11DomainService.list(queryWrapper);
return list.stream().map(e -> BeanMapper.mapper().convert(e, SysUserVO.class)).collect(Collectors.toList());
}
@Override
public IPage<SysUserVO> pageList(SysUserPageVO sysUserPage) {
CustomAsserts.nonNull(sysUserPage, "分页查询参数不能为空");
public IPage<SysUserVO> pageList(SysUserPageVO sysUserPageVO) {
CustomAsserts.nonNull(sysUserPageVO, "分页查询参数不能为空");
QueryWrapper<SysUserEntity> queryWrapper = new QueryWrapper<>();
// 根据业务条件组装入参
queryWrapper.lambda().like(StringUtils.isNotBlank(sysUserPage.getUsername()),
SysUserEntity::getUsername, sysUserPage.getUsername());
IPage<SysUserEntity> page = sysUserDomainService.selectPage(queryWrapper, sysUserPage);
// TODO 根据业务条件组装入参
IPage<SysUserEntity> page = sysUser11DomainService.selectPage(queryWrapper, sysUserPageVO);
return page.convert(e -> BeanMapper.mapper().convert(e, SysUserVO.class));
}
@Override
public SysUserVO info(Long id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysUserEntity sysUser = sysUserDomainService.getById(id);
return BeanMapper.mapper().convert(sysUser, SysUserVO.class);
SysUserEntity sysUser11 = sysUser11DomainService.getById(id);
return BeanMapper.mapper().convert(sysUser11, SysUserVO.class);
}
@Transactional(rollbackFor = Exception.class)
@Override
public void save(SysUserVO sysUser) {
CustomAsserts.nonNull(sysUser, "实体对象不能为空");
SysUserEntity sysUserEntity = BeanMapper.mapper().convert(sysUser, SysUserEntity.class);
public void save(SysUserVO sysUserVO) {
CustomAsserts.nonNull(sysUserVO, "实体对象不能为空");
SysUserEntity sysUser11Entity = BeanMapper.mapper().convert(sysUserVO, SysUserEntity.class);
try {
sysUserDomainService.save(sysUserEntity);
sysUser11DomainService.save(sysUser11Entity);
} catch (DuplicateKeyException e) {
log.info("[ AppInfoServiceImpl save ] 应用编码/应用APK重复,请调整后再试!", e);
throw new ServiceException("应用编码/应用APK重复,请调整后再试!");
} catch (DataIntegrityViolationException e) {
if (e.getCause() != null && e.getCause().getMessage().contains("duplicate key")) {
throw new ServiceException("应用编码/应用APK重复,请调整后再试!");
}
throw new ServiceException(e.getCause() == null ? "操作数据库异常:" + e.getMessage() : e.getCause().getMessage());
log.info("[ SysUser11ServiceImpl save ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void updateById(SysUserVO sysUser) {
CustomAsserts.nonNull(sysUser, "实体对象不能为空");
SysUserEntity appInfo = BeanMapper.mapper().convert(sysUser, SysUserEntity.class);
public void updateById(SysUserVO sysUserVO) {
CustomAsserts.nonNull(sysUserVO, "实体对象不能为空");
SysUserEntity sysUser11 = BeanMapper.mapper().convert(sysUserVO, SysUserEntity.class);
try {
sysUserDomainService.updateById(appInfo);
sysUser11DomainService.updateById(sysUser11);
} catch (DuplicateKeyException e) {
log.info("[ AppInfoServiceImpl updateById ] 应用编码/应用APK重复,请调整后再试!", e);
throw new ServiceException("应用编码/应用APK重复,请调整后再试!");
} catch (DataIntegrityViolationException e) {
if (e.getCause() != null && e.getCause().getMessage().contains("duplicate key")) {
throw new ServiceException("应用编码/应用APK重复,请调整后再试!");
}
throw new ServiceException(e.getCause() == null ? "操作数据库异常:" + e.getMessage() : e.getCause().getMessage());
log.info("[ SysUser11ServiceImpl updateById ] 实体对象唯一约束重复,请调整后再试!", e);
throw new ServiceException("实体对象唯一约束重复,请调整后再试!");
}
}
@Transactional(rollbackFor = Exception.class)
@Override
public void deleteById(Long id) {
CustomAsserts.nonNull(id, "主键id不能为空");
SysUserVO sysUser = info(id);
if (sysUser == null) {
throw new ServiceException("应用信息不存在!");
}
sysUserDomainService.removeById(id);
sysUser11DomainService.removeById(id);
}
}
\ No newline at end of file
}
......@@ -17,7 +17,7 @@ import java.io.Serializable;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@EqualsAndHashCode(callSuper = false)
@Schema(description = "CustomProductDiyUserRelPageVo")
public class CustomProductDiyUserRelPageVO extends PageRequest implements Serializable {
@Serial
......
package com.jomalls.custom.app.model;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
* 菜单权限表
*/
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SysMenuVo implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 菜单ID
*/
@Schema(description = "菜单ID")
private Long menuId;
/**
* 菜单名称
*/
@Schema(description = "菜单名称")
private String menuName;
/**
* 父菜单ID
*/
@Schema(description = "父菜单ID")
private Long parentId;
/**
* 显示顺序
*/
@Schema(description = "显示顺序")
private Integer orderNum;
/**
* 路由地址
*/
@Schema(description = "路由地址")
private String path;
/**
* 组件路径
*/
@Schema(description = "组件路径")
private String component;
/**
* 路由参数
*/
@Schema(description = "路由参数")
private String query;
/**
* 路由名称
*/
@Schema(description = "路由名称")
private String routeName;
/**
* 是否为外链(0是 1否)
*/
@Schema(description = "是否为外链(0是 1否)")
private Integer isFrame;
/**
* 是否缓存(0缓存 1不缓存)
*/
@Schema(description = "是否缓存(0缓存 1不缓存)")
private Integer isCache;
/**
* 菜单类型(M目录 C菜单 F按钮)
*/
@Schema(description = "菜单类型(M目录 C菜单 F按钮)")
private String menuType;
/**
* 菜单状态(0显示 1隐藏)
*/
@Schema(description = "菜单状态(0显示 1隐藏)")
private String visible;
/**
* 菜单状态
*/
@Schema(description = "菜单状态")
private String status;
/**
* 权限标识
*/
@Schema(description = "权限标识")
private String perms;
/**
* 菜单图标
*/
@Schema(description = "菜单图标")
private String icon;
/**
* 创建人
*/
@Schema(description = "创建人")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private String createTime;
/**
* 更新人
*/
@Schema(description = "更新人")
private String updateBy;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private String updateTime;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
/**
* 子菜单
*/
@Schema(description = "子菜单")
private List<SysMenuVo> children = new ArrayList<>();
}
package com.jomalls.custom.app.model;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 角色和部门关联表 PageModel
*
* @author Lizh
* @date 2026-06-01 12:30:00
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysRoleDeptPageVo")
public class SysRoleDeptPageVO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 部门ID
*/
@Schema(description = "部门ID")
private Long deptId;
}
package com.jomalls.custom.app.model;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 角色和部门关联表 Model
*
* @author Lizh
* @date 2026-06-01 12:30:00
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "角色和部门关联表VO")
public class SysRoleDeptVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 部门ID
*/
@Schema(description = "部门ID")
private Long deptId;
}
package com.jomalls.custom.app.model;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 角色和菜单关联表 PageModel
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysRoleMenuPageVo")
public class SysRoleMenuPageVO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 菜单ID
*/
@Schema(description = "菜单ID")
private Long menuId;
}
package com.jomalls.custom.app.model;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 角色和菜单关联表 Model
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "角色和菜单关联表VO")
public class SysRoleMenuVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 菜单ID
*/
@Schema(description = "菜单ID")
private Long menuId;
}
package com.jomalls.custom.app.model;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 角色信息表 PageModel
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysRolePageVo")
public class SysRolePageVO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 角色名称
*/
@Schema(description = "角色名称")
private String roleName;
/**
* 角色权限字符串
*/
@Schema(description = "角色权限字符串")
private String roleKey;
/**
* 显示顺序
*/
@Schema(description = "显示顺序")
private Integer roleSort;
/**
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
*/
@Schema(description = "数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)")
private String dataScope;
/**
* 菜单树选择项是否关联显示
*/
@Schema(description = "菜单树选择项是否关联显示")
private Integer menuCheckStrictly;
/**
* 部门树选择项是否关联显示
*/
@Schema(description = "部门树选择项是否关联显示")
private Integer deptCheckStrictly;
/**
* 角色状态(0正常 1停用)
*/
@Schema(description = "角色状态(0正常 1停用)")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
/**
* 创建者
*/
@Schema(description = "创建者")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新者
*/
@Schema(description = "更新者")
private String updateBy;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private Date updateTime;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
}
package com.jomalls.custom.app.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 角色信息表 Model
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "角色信息表VO")
public class SysRoleVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
/**
* 角色名称
*/
@Schema(description = "角色名称")
private String roleName;
/**
* 角色权限字符串
*/
@Schema(description = "角色权限字符串")
private String roleKey;
/**
* 显示顺序
*/
@Schema(description = "显示顺序")
private Integer roleSort;
/**
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
*/
@Schema(description = "数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)")
private String dataScope;
/**
* 菜单树选择项是否关联显示
*/
@Schema(description = "菜单树选择项是否关联显示")
private Integer menuCheckStrictly;
/**
* 部门树选择项是否关联显示
*/
@Schema(description = "部门树选择项是否关联显示")
private Integer deptCheckStrictly;
/**
* 角色状态(0正常 1停用)
*/
@Schema(description = "角色状态(0正常 1停用)")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
/**
* 创建者
*/
@Schema(description = "创建者")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新者
*/
@Schema(description = "更新者")
private String updateBy;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private Date updateTime;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
}
package com.jomalls.custom.app.model;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 系统用户 PageModel
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysUserOldPageVo")
public class SysUserOldPageVO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@Schema(description = "id")
private Integer id;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String account;
/**
* 头像
*/
@Schema(description = "头像")
private String imgUrl;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 账号状态(0禁用 1启用)
*/
@Schema(description = "账号状态(0禁用 1启用)")
private Boolean status;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
}
package com.jomalls.custom.app.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 系统用户 Model
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "系统用户VO")
public class SysUserOldVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@Schema(description = "id")
private Integer id;
/**
* 登录账号
*/
@Schema(description = "登录账号")
private String account;
/**
* 头像
*/
@Schema(description = "头像")
private String imgUrl;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 账号状态(0禁用 1启用)
*/
@Schema(description = "账号状态(0禁用 1启用)")
private Boolean status;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
}
......@@ -4,64 +4,145 @@ import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 用户信息表 PageModel
*
* @author Lizh
* createDate 2023/12/1 14:18
* @date 2026-06-01 12:29:59
*/
@Getter
@Setter
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysUser11PageVo")
public class SysUserPageVO extends PageRequest implements Serializable {
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long id;
/**
* 用户名
*/
@Schema(description = "username")
private String username;
/**
* 密码
*/
@Schema(description = "password")
private String password;
/**
* 邮箱
*/
@Schema(description = "email")
private String email;
/**
* 手机号
*/
@Schema(description = "phone")
private String phone;
/**
* 状态:0-禁用,1-启用
*/
@Schema(description = "status")
private Integer status;
/**
* 创建时间
*/
@Schema(description = "created_at")
private LocalDateTime createdAt;
/**
* 更新时间
*/
@Schema(description = "updated_at")
private LocalDateTime updatedAt;
}
\ No newline at end of file
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long userId;
/**
* 部门ID
*/
@Schema(description = "部门ID")
private Long deptId;
/**
* 用户账号
*/
@Schema(description = "用户账号")
private String userName;
/**
* 用户昵称
*/
@Schema(description = "用户昵称")
private String nickName;
/**
* 用户类型(00系统用户)
*/
@Schema(description = "用户类型(00系统用户)")
private String userType;
/**
* 用户邮箱
*/
@Schema(description = "用户邮箱")
private String email;
/**
* 手机号码
*/
@Schema(description = "手机号码")
private String phonenumber;
/**
* 用户性别(0男 1女 2未知)
*/
@Schema(description = "用户性别(0男 1女 2未知)")
private String sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String avatar;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 账号状态(0正常 1停用)
*/
@Schema(description = "账号状态(0正常 1停用)")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@Schema(description = "最后登录时间")
private Date loginDate;
/**
* 密码最后更新时间
*/
@Schema(description = "密码最后更新时间")
private Date pwdUpdateDate;
/**
* 创建者
*/
@Schema(description = "创建者")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新者
*/
@Schema(description = "更新者")
private String updateBy;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private Date updateTime;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
}
package com.jomalls.custom.app.model;
import com.jomalls.custom.page.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户和角色关联表 PageModel
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@Schema(description = "SysUserRolePageVo")
public class SysUserRolePageVO extends PageRequest implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long userId;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
}
package com.jomalls.custom.app.model;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serial;
import java.io.Serializable;
/**
* 用户和角色关联表 Model
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户和角色关联表VO")
public class SysUserRoleVO implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long userId;
/**
* 角色ID
*/
@Schema(description = "角色ID")
private Long roleId;
}
package com.jomalls.custom.app.vo;
import lombok.*;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
/**
* 用户信息表 Model
*
* @author Lizh
* createDate 2023/12/1 14:18
* @date 2026-06-01 12:29:59
*/
@Getter
@Setter
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Schema(description = "用户信息表VO")
public class SysUserVO implements Serializable {
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long id;
/**
* 用户名
*/
@Schema(description = "username")
private String username;
/**
* 密码
*/
@Schema(description = "password")
private String password;
/**
* 邮箱
*/
@Schema(description = "email")
private String email;
/**
* 手机号
*/
@Schema(description = "phone")
private String phone;
/**
* 状态:0-禁用,1-启用
*/
@Schema(description = "status")
private Integer status;
/**
* 创建时间
*/
@Schema(description = "created_at")
private LocalDateTime createdAt;
/**
* 更新时间
*/
@Schema(description = "updated_at")
private LocalDateTime updatedAt;
}
\ No newline at end of file
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@Schema(description = "用户ID")
private Long userId;
/**
* 部门ID
*/
@Schema(description = "部门ID")
private Long deptId;
/**
* 用户账号
*/
@Schema(description = "用户账号")
private String userName;
/**
* 用户昵称
*/
@Schema(description = "用户昵称")
private String nickName;
/**
* 用户类型(00系统用户)
*/
@Schema(description = "用户类型(00系统用户)")
private String userType;
/**
* 用户邮箱
*/
@Schema(description = "用户邮箱")
private String email;
/**
* 手机号码
*/
@Schema(description = "手机号码")
private String phonenumber;
/**
* 用户性别(0男 1女 2未知)
*/
@Schema(description = "用户性别(0男 1女 2未知)")
private String sex;
/**
* 头像地址
*/
@Schema(description = "头像地址")
private String avatar;
/**
* 密码
*/
@Schema(description = "密码")
private String password;
/**
* 账号状态(0正常 1停用)
*/
@Schema(description = "账号状态(0正常 1停用)")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@Schema(description = "删除标志(0代表存在 2代表删除)")
private String delFlag;
/**
* 最后登录IP
*/
@Schema(description = "最后登录IP")
private String loginIp;
/**
* 最后登录时间
*/
@Schema(description = "最后登录时间")
private Date loginDate;
/**
* 密码最后更新时间
*/
@Schema(description = "密码最后更新时间")
private Date pwdUpdateDate;
/**
* 创建者
*/
@Schema(description = "创建者")
private String createBy;
/**
* 创建时间
*/
@Schema(description = "创建时间")
private Date createTime;
/**
* 更新者
*/
@Schema(description = "更新者")
private String updateBy;
/**
* 更新时间
*/
@Schema(description = "更新时间")
private Date updateTime;
/**
* 备注
*/
@Schema(description = "备注")
private String remark;
}
......@@ -20,6 +20,24 @@
<artifactId>commons-lang3</artifactId>
<scope>compile</scope>
</dependency>
<!-- JJWT for JWT token parsing -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-api</artifactId>
<version>0.12.3</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-impl</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt-jackson</artifactId>
<version>0.12.3</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
......
......@@ -15,7 +15,8 @@ import java.util.List;
* @Version: 1.0
*/
@Data
@Getter
@Setter
public class PageRequest implements Pageable, Serializable {
@Serial
private static final long serialVersionUID = 8280485938848398236L;
......
package com.jomalls.custom.security;
import java.io.Serializable;
import java.util.Set;
/**
* 登录用户身份权限
*/
public class LoginUser implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
private Long userId;
/**
* 部门ID
*/
private Long deptId;
/**
* 用户唯一标识
*/
private String token;
/**
* 登录时间
*/
private Long loginTime;
/**
* 过期时间
*/
private Long expireTime;
/**
* 登录IP地址
*/
private String ipaddr;
/**
* 登录地点
*/
private String loginLocation;
/**
* 浏览器类型
*/
private String browser;
/**
* 操作系统
*/
private String os;
/**
* 权限列表
*/
private Set<String> permissions;
/**
* 用户名
*/
private String username;
public LoginUser() {
}
public LoginUser(Long userId, Long deptId, String username) {
this.userId = userId;
this.deptId = deptId;
this.username = username;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getDeptId() {
return deptId;
}
public void setDeptId(Long deptId) {
this.deptId = deptId;
}
public String getToken() {
return token;
}
public void setToken(String token) {
this.token = token;
}
public Long getLoginTime() {
return loginTime;
}
public void setLoginTime(Long loginTime) {
this.loginTime = loginTime;
}
public Long getExpireTime() {
return expireTime;
}
public void setExpireTime(Long expireTime) {
this.expireTime = expireTime;
}
public String getIpaddr() {
return ipaddr;
}
public void setIpaddr(String ipaddr) {
this.ipaddr = ipaddr;
}
public String getLoginLocation() {
return loginLocation;
}
public void setLoginLocation(String loginLocation) {
this.loginLocation = loginLocation;
}
public String getBrowser() {
return browser;
}
public void setBrowser(String browser) {
this.browser = browser;
}
public String getOs() {
return os;
}
public void setOs(String os) {
this.os = os;
}
public Set<String> getPermissions() {
return permissions;
}
public void setPermissions(Set<String> permissions) {
this.permissions = permissions;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
package com.jomalls.custom.security;
/**
* 安全服务工具类
* 支持子线程继承登录信息
*/
public class SecurityUtils {
/**
* 线程本地变量 - 支持子线程继承
* InheritableThreadLocal 允许子线程继承父线程的值
*/
private static final InheritableThreadLocal<LoginUser> THREAD_LOCAL = new InheritableThreadLocal<>();
/**
* 设置登录用户
*
* @param loginUser 用户信息
*/
public static void setLoginUser(LoginUser loginUser) {
THREAD_LOCAL.set(loginUser);
}
/**
* 获取登录用户
*
* @return 用户信息
*/
public static LoginUser getLoginUser() {
return THREAD_LOCAL.get();
}
/**
* 获取用户ID
*
* @return 用户ID
*/
public static Long getUserId() {
LoginUser loginUser = THREAD_LOCAL.get();
return loginUser != null ? loginUser.getUserId() : null;
}
/**
* 获取部门ID
*
* @return 部门ID
*/
public static Long getDeptId() {
LoginUser loginUser = THREAD_LOCAL.get();
return loginUser != null ? loginUser.getDeptId() : null;
}
/**
* 获取用户名
*
* @return 用户名
*/
public static String getUsername() {
LoginUser loginUser = THREAD_LOCAL.get();
return loginUser != null ? loginUser.getUsername() : null;
}
/**
* 清除登录用户
*/
public static void clearLoginUser() {
THREAD_LOCAL.remove();
}
/**
* 判断是否已登录
*
* @return true-已登录, false-未登录
*/
public static boolean isLoggedIn() {
return THREAD_LOCAL.get() != null;
}
}
package com.jomalls.custom.security;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.security.Keys;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import javax.crypto.SecretKey;
import java.nio.charset.StandardCharsets;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* Token验证处理服务
*/
@Slf4j
@Component
public class TokenHandle {
// 令牌自定义标识
@Value("${token.header:Authorization}")
private String header;
// 令牌秘钥
@Value("${token.secret:custom}")
private String secret;
/**
* 获取用户身份信息
*
* @param request 请求对象
* @return 用户信息
*/
public LoginUser getLoginUser(HttpServletRequest request) {
// 获取请求携带的令牌
String token = getToken(request);
if (StringUtils.hasText(token)) {
try {
Claims claims = parseToken(token);
// 解析用户信息
Long userId = claims.get("id", Long.class);
String username = claims.get("account", String.class);
if (username == null) {
username = claims.get("username", String.class);
}
if (userId != null && StringUtils.hasText(username)) {
LoginUser loginUser = new LoginUser(userId, null, username);
loginUser.setToken(token);
loginUser.setExpireTime(claims.getExpiration().getTime());
// 解析权限信息
Set<String> permissions = parsePermissions(claims);
loginUser.setPermissions(permissions);
return loginUser;
}
} catch (JwtException e) {
log.error("JWT解析异常: {}", e.getMessage());
} catch (Exception e) {
log.error("获取用户信息异常: {}", e.getMessage());
}
}
return null;
}
/**
* 解析权限信息
*
* @param claims JWT claims
* @return 权限集合
*/
@SuppressWarnings("unchecked")
private Set<String> parsePermissions(Claims claims) {
Set<String> permissions = new HashSet<>();
// 从 claims 中解析权限列表
Object permissionsObj = claims.get("permissions");
if (permissionsObj instanceof List) {
List<String> permsList = (List<String>) permissionsObj;
permissions.addAll(permsList);
} else if (permissionsObj instanceof String) {
// 如果是逗号分隔的字符串
String[] permsArray = ((String) permissionsObj).split(",");
for (String perm : permsArray) {
if (StringUtils.hasText(perm)) {
permissions.add(perm.trim());
}
}
}
return permissions;
}
/**
* 从请求头获取令牌
*
* @param request 请求对象
* @return 令牌字符串
*/
private String getToken(HttpServletRequest request) {
String token = request.getHeader(header);
// 如果令牌以 Bearer 开头,去掉前缀
if (StringUtils.hasText(token) && token.startsWith("Bearer ")) {
token = token.replace("Bearer ", "");
}
return token;
}
/**
* 解析令牌 (JJWT 0.12.x API)
*
* @param token 令牌
* @return 声明
*/
private Claims parseToken(String token) {
SecretKey key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
return Jwts.parser()
.verifyWith(key)
.build()
.parseSignedClaims(token)
.getPayload();
}
/**
* 验证令牌有效期
*
* @param loginUser 登录信息
* @return 是否有效
*/
public boolean verifyToken(LoginUser loginUser) {
if (loginUser == null || loginUser.getExpireTime() == null) {
return false;
}
return loginUser.getExpireTime() > System.currentTimeMillis();
}
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 菜单权限表 Entity
*
* @author Lizh
* @date 2026-06-01 16:29:32
*/
@Data
@TableName("sys_menu")
public class SysMenuEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 菜单ID
*/
@TableId(value = "menu_id",type= IdType.ASSIGN_ID)
private Long menuId;
/**
* 菜单名称
*/
@TableField("menu_name")
private String menuName;
/**
* 父菜单ID
*/
@TableField("parent_id")
private Long parentId;
/**
* 显示顺序
*/
@TableField("order_num")
private Integer orderNum;
/**
* 路由地址
*/
@TableField("path")
private String path;
/**
* 组件路径
*/
@TableField("component")
private String component;
/**
* 路由参数
*/
@TableField("query")
private String query;
/**
* 路由名称
*/
@TableField("route_name")
private String routeName;
/**
* 是否为外链(0是 1否)
*/
@TableField("is_frame")
private Integer isFrame;
/**
* 是否缓存(0缓存 1不缓存)
*/
@TableField("is_cache")
private Integer isCache;
/**
* 菜单类型(M目录 C菜单 F按钮)
*/
@TableField("menu_type")
private String menuType;
/**
* 菜单状态(0显示 1隐藏)
*/
@TableField("visible")
private String visible;
/**
* 菜单状态(0正常 1停用)
*/
@TableField("status")
private String status;
/**
* 权限标识
*/
@TableField("perms")
private String perms;
/**
* 菜单图标
*/
@TableField("icon")
private String icon;
/**
* 创建者
*/
@TableField("create_by")
private String createBy;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新者
*/
@TableField("update_by")
private String updateBy;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 备注
*/
@TableField("remark")
private String remark;
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 角色和部门关联表 Entity
*
* @author Lizh
* @date 2026-06-01 12:30:00
*/
@Data
@TableName("sys_role_dept")
public class SysRoleDeptEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(value = "role_id",type= IdType.ASSIGN_ID)
private Long roleId;
/**
* 部门ID
*/
@TableField("dept_id")
private Long deptId;
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.util.Date;
/**
* 角色信息表 Entity
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@TableName("sys_role")
public class SysRoleEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(value = "role_id",type= IdType.ASSIGN_ID)
private Long roleId;
/**
* 角色名称
*/
@TableField("role_name")
private String roleName;
/**
* 角色权限字符串
*/
@TableField("role_key")
private String roleKey;
/**
* 显示顺序
*/
@TableField("role_sort")
private Integer roleSort;
/**
* 数据范围(1:全部数据权限 2:自定数据权限 3:本部门数据权限 4:本部门及以下数据权限)
*/
@TableField("data_scope")
private String dataScope;
/**
* 菜单树选择项是否关联显示
*/
@TableField("menu_check_strictly")
private Integer menuCheckStrictly;
/**
* 部门树选择项是否关联显示
*/
@TableField("dept_check_strictly")
private Integer deptCheckStrictly;
/**
* 角色状态(0正常 1停用)
*/
@TableField("status")
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@TableField("del_flag")
private String delFlag;
/**
* 创建者
*/
@TableField("create_by")
private String createBy;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
/**
* 更新者
*/
@TableField("update_by")
private String updateBy;
/**
* 更新时间
*/
@TableField("update_time")
private Date updateTime;
/**
* 备注
*/
@TableField("remark")
private String remark;
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
/**
* 角色和菜单关联表 Entity
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@TableName("sys_role_menu")
public class SysRoleMenuEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 角色ID
*/
@TableId(value = "role_id",type= IdType.ASSIGN_ID)
private Long roleId;
/**
* 菜单ID
*/
@TableField("menu_id")
private Long menuId;
}
......@@ -4,96 +4,126 @@ import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Getter;
import lombok.Setter;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 用户实体类
* 用户信息表 Entity
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Getter
@Setter
@TableName("sys_user")
@Data
@TableName("sys_user11")
public class SysUserEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
// Getters and Setters
/**
* 用户ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
@TableId(value = "user_id",type= IdType.ASSIGN_ID)
private Long userId;
/**
* 用户名
* 部门ID
*/
@TableField("username")
private String username;
@TableField("dept_id")
private Long deptId;
/**
* 密码
* 用户账号
*/
@TableField("password")
private String password;
@TableField("user_name")
private String userName;
/**
* 邮箱
* 用户昵称
*/
@TableField("nick_name")
private String nickName;
/**
* 用户类型(00系统用户)
*/
@TableField("user_type")
private String userType;
/**
* 用户邮箱
*/
@TableField("email")
private String email;
/**
* 手机号
* 手机号
*/
@TableField("phone")
private String phone;
@TableField("phonenumber")
private String phonenumber;
/**
* 用户性别(0男 1女 2未知)
*/
@TableField("sex")
private String sex;
/**
* 头像地址
*/
@TableField("avatar")
private String avatar;
/**
* 密码
*/
@TableField("password")
private String password;
/**
* 状态:0-禁用,1-启用
* 账号状态(0正常 1停用)
*/
@TableField("status")
private Integer status;
private String status;
/**
* 删除标志(0代表存在 2代表删除)
*/
@TableField("del_flag")
private String delFlag;
/**
* 最后登录IP
*/
@TableField("login_ip")
private String loginIp;
/**
* 最后登录时间
*/
@TableField("login_date")
private Date loginDate;
/**
* 密码最后更新时间
*/
@TableField("pwd_update_date")
private Date pwdUpdateDate;
/**
* 创建者
*/
@TableField("create_by")
private String createBy;
/**
* 创建时间
*/
@TableField("created_at")
private LocalDateTime createdAt;
@TableField("create_time")
private Date createTime;
/**
* 更新者
*/
@TableField("update_by")
private String updateBy;
/**
* 更新时间
*/
@TableField("updated_at")
private LocalDateTime updatedAt;
public SysUserEntity() {
}
public SysUserEntity(String username, String password, String email, String phone) {
this.username = username;
this.password = password;
this.email = email;
this.phone = phone;
this.status = 1;
this.createdAt = LocalDateTime.now();
this.updatedAt = LocalDateTime.now();
}
@Override
public String toString() {
return "SysUser{" +
"id=" + id +
", username='" + username + '\'' +
", email='" + email + '\'' +
", phone='" + phone + '\'' +
", status=" + status +
", createdAt=" + createdAt +
", updatedAt=" + updatedAt +
'}';
}
}
\ No newline at end of file
@TableField("update_time")
private Date updateTime;
/**
* 备注
*/
@TableField("remark")
private String remark;
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 系统用户 Entity
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@TableName("sys_user_old")
public class SysUserOldEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id",type= IdType.ASSIGN_ID)
private Integer id;
/**
* 登录账号
*/
@TableField("account")
private String account;
/**
* 头像
*/
@TableField("img_url")
private String imgUrl;
/**
* 密码
*/
@TableField("password")
private String password;
/**
* 账号状态(0禁用 1启用)
*/
@TableField("status")
private Boolean status;
/**
* 备注
*/
@TableField("remark")
private String remark;
/**
* 创建时间
*/
@TableField("create_time")
private Date createTime;
}
package com.jomalls.custom.dal.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 用户和角色关联表 Entity
*
* @author Lizh
* @date 2026-06-01 12:29:59
*/
@Data
@TableName("sys_user_role")
public class SysUserRoleEntity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@TableId(value = "user_id",type= IdType.ASSIGN_ID)
private Long userId;
/**
* 角色ID
*/
@TableField("role_id")
private Long roleId;
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysMenuEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 菜单权限表 mapper
* @date 2026-06-01 16:29:32
*/
@Mapper
public interface SysMenuMapper extends BaseMapper<SysMenuEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysRoleDeptEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 角色和部门关联表 mapper
* @date 2026-06-01 12:30:00
*/
@Mapper
public interface SysRoleDeptMapper extends BaseMapper<SysRoleDeptEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysRoleEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 角色信息表 mapper
* @date 2026-06-01 12:29:59
*/
@Mapper
public interface SysRoleMapper extends BaseMapper<SysRoleEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysRoleMenuEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 角色和菜单关联表 mapper
* @date 2026-06-01 12:29:59
*/
@Mapper
public interface SysRoleMenuMapper extends BaseMapper<SysRoleMenuEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysUserEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* 用户Mapper接口
* @author Lizh
* @version 0.01
* @description: 用户信息表 mapper
* @date 2026-06-01 12:29:59
*/
@Mapper
public interface SysUserMapper extends BaseMapper<SysUserEntity> {
}
\ No newline at end of file
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysUserOldEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 系统用户 mapper
* @date 2026-06-01 12:29:59
*/
@Mapper
public interface SysUserOldMapper extends BaseMapper<SysUserOldEntity> {
}
package com.jomalls.custom.dal.mapper;
import com.jomalls.custom.dal.entity.SysUserRoleEntity;
import com.jomalls.custom.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;
/**
* @author Lizh
* @version 0.01
* @description: 用户和角色关联表 mapper
* @date 2026-06-01 12:29:59
*/
@Mapper
public interface SysUserRoleMapper extends BaseMapper<SysUserRoleEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysMenuEntity;
import com.jomalls.custom.service.IBaseService;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 菜单权限表 接口
* @date 2026-06-01 16:29:32
*/
public interface SysMenuDomainService extends IBaseService<SysMenuEntity> {
List<String> selectMenuPermsByUserId(Long userId);
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysRoleDeptEntity;
import com.jomalls.custom.service.IBaseService;
/**
* @author Lizh
* @version 0.01
* @description: 角色和部门关联表 接口
* @date 2026-06-01 12:30:00
*/
public interface SysRoleDeptDomainService extends IBaseService<SysRoleDeptEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysRoleEntity;
import com.jomalls.custom.service.IBaseService;
/**
* @author Lizh
* @version 0.01
* @description: 角色信息表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysRoleDomainService extends IBaseService<SysRoleEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysRoleMenuEntity;
import com.jomalls.custom.service.IBaseService;
/**
* @author Lizh
* @version 0.01
* @description: 角色和菜单关联表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysRoleMenuDomainService extends IBaseService<SysRoleMenuEntity> {
}
......@@ -4,8 +4,12 @@ import com.jomalls.custom.dal.entity.SysUserEntity;
import com.jomalls.custom.service.IBaseService;
/**
* 用户领域服务接口
* @author Lizh
* @version 0.01
* @description: 用户信息表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserDomainService extends IBaseService<SysUserEntity> {
}
\ No newline at end of file
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysUserOldEntity;
import com.jomalls.custom.service.IBaseService;
/**
* @author Lizh
* @version 0.01
* @description: 系统用户 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserOldDomainService extends IBaseService<SysUserOldEntity> {
}
package com.jomalls.custom.domain.service;
import com.jomalls.custom.dal.entity.SysUserRoleEntity;
import com.jomalls.custom.service.IBaseService;
/**
* @author Lizh
* @version 0.01
* @description: 用户和角色关联表 接口
* @date 2026-06-01 12:29:59
*/
public interface SysUserRoleDomainService extends IBaseService<SysUserRoleEntity> {
}
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysMenuMapper;
import com.jomalls.custom.dal.entity.SysMenuEntity;
import com.jomalls.custom.domain.service.SysMenuDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.commons.collections.CollectionUtils;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author Lizh
* @version 0.01
* @description: 菜单权限表 接口实现
* @date 2026-06-01 16:29:32
*/
@Service
public class SysMenuDomainServiceImpl extends BaseServiceImpl<SysMenuMapper,SysMenuEntity> implements SysMenuDomainService {
@Autowired
public SysMenuDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
public List<String> selectMenuPermsByUserId(Long userId) {
//return baseMapper.selectMenuPermsByUserId(userId);
return null;
}
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysRoleDeptMapper;
import com.jomalls.custom.dal.entity.SysRoleDeptEntity;
import com.jomalls.custom.domain.service.SysRoleDeptDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Lizh
* @version 0.01
* @description: 角色和部门关联表 接口实现
* @date 2026-06-01 12:30:00
*/
@Service
public class SysRoleDeptDomainServiceImpl extends BaseServiceImpl<SysRoleDeptMapper,SysRoleDeptEntity> implements SysRoleDeptDomainService {
@Autowired
public SysRoleDeptDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysRoleMapper;
import com.jomalls.custom.dal.entity.SysRoleEntity;
import com.jomalls.custom.domain.service.SysRoleDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Lizh
* @version 0.01
* @description: 角色信息表 接口实现
* @date 2026-06-01 12:29:59
*/
@Service
public class SysRoleDomainServiceImpl extends BaseServiceImpl<SysRoleMapper,SysRoleEntity> implements SysRoleDomainService {
@Autowired
public SysRoleDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysRoleMenuMapper;
import com.jomalls.custom.dal.entity.SysRoleMenuEntity;
import com.jomalls.custom.domain.service.SysRoleMenuDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Lizh
* @version 0.01
* @description: 角色和菜单关联表 接口实现
* @date 2026-06-01 12:29:59
*/
@Service
public class SysRoleMenuDomainServiceImpl extends BaseServiceImpl<SysRoleMenuMapper,SysRoleMenuEntity> implements SysRoleMenuDomainService {
@Autowired
public SysRoleMenuDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
}
\ No newline at end of file
......@@ -8,8 +8,12 @@ import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* 用户领域服务实现类
* @author Lizh
* @version 0.01
* @description: 用户信息表 接口实现
* @date 2026-06-01 12:29:59
*/
@Service
public class SysUserDomainServiceImpl extends BaseServiceImpl<SysUserMapper, SysUserEntity> implements SysUserDomainService {
......@@ -18,7 +22,6 @@ public class SysUserDomainServiceImpl extends BaseServiceImpl<SysUserMapper, Sys
public SysUserDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
// 用户 Mapper 接口,自定义方法或者基础方法重写
}
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysUserOldMapper;
import com.jomalls.custom.dal.entity.SysUserOldEntity;
import com.jomalls.custom.domain.service.SysUserOldDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Lizh
* @version 0.01
* @description: 系统用户 接口实现
* @date 2026-06-01 12:29:59
*/
@Service
public class SysUserOldDomainServiceImpl extends BaseServiceImpl<SysUserOldMapper,SysUserOldEntity> implements SysUserOldDomainService {
@Autowired
public SysUserOldDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
}
\ No newline at end of file
package com.jomalls.custom.domain.service.impl;
import com.jomalls.custom.dal.mapper.SysUserRoleMapper;
import com.jomalls.custom.dal.entity.SysUserRoleEntity;
import com.jomalls.custom.domain.service.SysUserRoleDomainService;
import com.jomalls.custom.service.impl.BaseServiceImpl;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author Lizh
* @version 0.01
* @description: 用户和角色关联表 接口实现
* @date 2026-06-01 12:29:59
*/
@Service
public class SysUserRoleDomainServiceImpl extends BaseServiceImpl<SysUserRoleMapper,SysUserRoleEntity> implements SysUserRoleDomainService {
@Autowired
public SysUserRoleDomainServiceImpl(SqlSessionFactory sqlSessionFactory) {
super(sqlSessionFactory);
}
// 自定义方法或者基础方法重写
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysMenuMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysMenuEntity" id="sysMenuMap">
<result property="menuId" column="menu_id"/>
<result property="menuName" column="menu_name"/>
<result property="parentId" column="parent_id"/>
<result property="orderNum" column="order_num"/>
<result property="path" column="path"/>
<result property="component" column="component"/>
<result property="query" column="query"/>
<result property="routeName" column="route_name"/>
<result property="isFrame" column="is_frame"/>
<result property="isCache" column="is_cache"/>
<result property="menuType" column="menu_type"/>
<result property="visible" column="visible"/>
<result property="status" column="status"/>
<result property="perms" column="perms"/>
<result property="icon" column="icon"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
menu_id,
menu_name,
parent_id,
order_num,
path,
component,
query,
route_name,
is_frame,
is_cache,
menu_type,
visible,
status,
perms,
icon,
create_by,
create_time,
update_by,
update_time,
remark,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysRoleDeptMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysRoleDeptEntity" id="sysRoleDeptMap">
<result property="roleId" column="role_id"/>
<result property="deptId" column="dept_id"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
role_id,
dept_id,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysRoleMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysRoleEntity" id="sysRoleMap">
<result property="roleId" column="role_id"/>
<result property="roleName" column="role_name"/>
<result property="roleKey" column="role_key"/>
<result property="roleSort" column="role_sort"/>
<result property="dataScope" column="data_scope"/>
<result property="menuCheckStrictly" column="menu_check_strictly"/>
<result property="deptCheckStrictly" column="dept_check_strictly"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
role_id,
role_name,
role_key,
role_sort,
data_scope,
menu_check_strictly,
dept_check_strictly,
status,
del_flag,
create_by,
create_time,
update_by,
update_time,
remark,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysRoleMenuMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysRoleMenuEntity" id="sysRoleMenuMap">
<result property="roleId" column="role_id"/>
<result property="menuId" column="menu_id"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
role_id,
menu_id,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysUser11Mapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysUserEntity" id="sysUser11Map">
<result property="userId" column="user_id"/>
<result property="deptId" column="dept_id"/>
<result property="userName" column="user_name"/>
<result property="nickName" column="nick_name"/>
<result property="userType" column="user_type"/>
<result property="email" column="email"/>
<result property="phonenumber" column="phonenumber"/>
<result property="sex" column="sex"/>
<result property="avatar" column="avatar"/>
<result property="password" column="password"/>
<result property="status" column="status"/>
<result property="delFlag" column="del_flag"/>
<result property="loginIp" column="login_ip"/>
<result property="loginDate" column="login_date"/>
<result property="pwdUpdateDate" column="pwd_update_date"/>
<result property="createBy" column="create_by"/>
<result property="createTime" column="create_time"/>
<result property="updateBy" column="update_by"/>
<result property="updateTime" column="update_time"/>
<result property="remark" column="remark"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
user_id,
dept_id,
user_name,
nick_name,
user_type,
email,
phonenumber,
sex,
avatar,
password,
status,
del_flag,
login_ip,
login_date,
pwd_update_date,
create_by,
create_time,
update_by,
update_time,
remark,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysUserOldMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysUserOldEntity" id="sysUserOldMap">
<result property="id" column="id"/>
<result property="account" column="account"/>
<result property="imgUrl" column="img_url"/>
<result property="password" column="password"/>
<result property="status" column="status"/>
<result property="remark" column="remark"/>
<result property="createTime" column="create_time"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
id,
account,
img_url,
password,
status,
remark,
create_time,
</sql>
</mapper>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jomalls.custom.dal.mapper.SysUserRoleMapper">
<!-- 可根据自己的需求,是否要使用 -->
<resultMap type="com.jomalls.custom.dal.entity.SysUserRoleEntity" id="sysUserRoleMap">
<result property="userId" column="user_id"/>
<result property="roleId" column="role_id"/>
</resultMap>
<!-- 注意去掉最后一行的逗号 -->
<sql id="tableColumns">
user_id,
role_id,
</sql>
</mapper>
......@@ -21,6 +21,11 @@
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.jomalls.custom</groupId>
<artifactId>custom-server-core</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<scope>provided</scope>
......
......@@ -2,6 +2,7 @@ package com.jomalls.custom;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
......@@ -12,6 +13,7 @@ import org.springframework.scheduling.annotation.EnableScheduling;
*/
@SpringBootApplication
@EnableScheduling
@EnableAspectJAutoProxy
public class CustomServerApplication {
public static void main(String[] args) {
......
package com.jomalls.custom.config;
import com.jomalls.custom.security.LoginUser;
import com.jomalls.custom.security.SecurityUtils;
import com.jomalls.custom.security.TokenHandle;
import org.jspecify.annotations.NonNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
/**
* 安全拦截器
* 负责用户登录权限检查,保存登录信息到线程本地变量
*/
@Component
public class SecurityInterceptor implements HandlerInterceptor {
}
\ No newline at end of file
private static final Logger log = LoggerFactory.getLogger(SecurityInterceptor.class);
@Autowired
private TokenHandle tokenHandle;
/**
* 请求处理前执行
* 验证用户登录状态,保存登录信息到线程本地变量
*/
@Override
public boolean preHandle(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler) throws Exception {
// 获取登录用户信息
LoginUser loginUser = tokenHandle.getLoginUser(request);
// 如果有登录用户,保存到线程本地变量
if (loginUser != null) {
// 验证token是否有效
if (tokenHandle.verifyToken(loginUser)) {
SecurityUtils.setLoginUser(loginUser);
log.debug("用户[{}]登录验证通过,请求URI: {}", loginUser.getUsername(), request.getRequestURI());
return true;
} else {
log.warn("用户[{}]token已过期,请求URI: {}", loginUser.getUsername(), request.getRequestURI());
}
}
// 未登录或token无效,允许继续(由后续业务逻辑决定是否需要登录)
// 如果需要强制登录,这里可以抛出异常或返回401
return true;
}
/**
* 请求处理后执行
* 清除线程本地变量,防止内存泄漏
*/
@Override
public void afterCompletion(@NonNull HttpServletRequest request, @NonNull HttpServletResponse response, @NonNull Object handler, Exception ex) throws Exception {
// 清除线程本地变量
SecurityUtils.clearLoginUser();
}
}
......@@ -31,4 +31,11 @@ data.version.control.switch=false
default.scp.data.version=1.0
## 时区配置
TZ=Asia/Shanghai
\ No newline at end of file
TZ=Asia/Shanghai
# 令牌自定义标识
token.header=Authorization
# 令牌密钥
token.secret=custom
# 令牌有效期(默认30分钟)
token.expireTime=720
\ No newline at end of file
package com.jomalls.custom.webapp.controller;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.jomalls.custom.app.vo.SysUserPageVO;
import com.jomalls.custom.app.vo.SysUserVO;
import com.jomalls.custom.app.service.SysUserService;
import com.jomalls.custom.app.model.SysUserVO;
import com.jomalls.custom.app.model.SysUserPageVO;
import com.jomalls.custom.app.service.SysUserService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
......
......@@ -14,6 +14,7 @@
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>21</java.version>
<spring-boot.version>4.0.5</spring-boot.version>
<commons-lang3.version>3.14.0</commons-lang3.version>
<commons-io.version>2.15.1</commons-io.version>
<maven.compiler.source>21</maven.compiler.source>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment