feat:修复已知问题,提升系统稳定性

This commit is contained in:
njydsz
2024-09-25 11:38:06 +08:00
parent bbed2aadbc
commit 8d094e48ac
493 changed files with 5108 additions and 22521 deletions

View File

@@ -0,0 +1,50 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>remi-boot-server</artifactId>
<name>remi-boot-server</name>
<description>remi-boot-server</description>
<parent>
<groupId>ai.remi.top.boot</groupId>
<artifactId>remi-boot</artifactId>
<version>3.1.0</version>
</parent>
<dependencies>
<!--瑞米公共模块-->
<dependency>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-exception</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-redis</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-thread</artifactId>
</dependency>
<dependency>
<groupId>ai.remi.top.comm</groupId>
<artifactId>remi-comm-util</artifactId>
</dependency>
<!--remi-boot-infra-->
<dependency>
<groupId>ai.remi.top.boot</groupId>
<artifactId>remi-boot-infra</artifactId>
</dependency>
<!--slf4j-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-nop</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,28 @@
package ai.remi.boot.server.exception;
import ai.remi.comm.exception.enums.ExceptionCode;
import lombok.AllArgsConstructor;
import lombok.Getter;
@AllArgsConstructor
@Getter
public enum IamExceptionCode implements ExceptionCode {
/**
* 业务异常code
*/
INVENTORY_CHECK_FAIL("B2006", "库存不足"),
QUERY_ORDER_FAIL("B2007", "查询订单失败"),
ORDER_STATUS_EXCEPTION("B2008", "订单状态不合法"),
ORDER_PRODUCT_EXCEPTION("B2010", "查询商品失败"),
ORDER_SHIPPING_RATE_PLAN_EXCEPTION("B2011", "邮费方案不存在"),
ORDER_VARIANTS_EXCEPTION("B2012", "库存扣减异常"),
PROMOTION_CODE_EXCEPTION("B2013", "优惠码错误"),
CUSTOMER_DISABLE("B2014", "用户被禁用"),
;
private String code;
private String key;
}

View File

@@ -0,0 +1,22 @@
package ai.remi.boot.server.exception;
import ai.remi.comm.exception.custom.BusinessException;
public class IamServiceException extends BusinessException {
public IamServiceException(String code, String message) {
super(code, message);
}
public IamServiceException(String code, Throwable cause) {
super(code, cause);
}
public IamServiceException(String code, String message, Throwable cause) {
super(code, message, cause);
}
public IamServiceException(String code, String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(code, message, cause, enableSuppression, writableStackTrace);
}
}

View File

@@ -0,0 +1,23 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.AccessToken;
import ai.remi.boot.domain.entity.OauthCode;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 鉴权令牌表(AccessToken)服务定义层
*/
public interface AccessTokenService extends IService<AccessToken> {
AccessToken create(String appKey, OauthCode oauthCode) throws Exception;
void set(String token, AccessToken accessToken);
AccessToken get(String token) throws Exception;
void remove(String token);
boolean verifyExpired(String token) throws Exception;
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.AppGroup;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用组织(AppGroup)服务定义层
*/
public interface AppGroupService extends IService<AppGroup> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.AppMenu;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用菜单表(AppMenu)服务定义层
*/
public interface AppMenuService extends IService<AppMenu> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.AppPublish;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用发布表(AppPublish)服务定义层
*/
public interface AppPublishService extends IService<AppPublish> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.App;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用表Application(App)服务定义层
*/
public interface AppService extends IService<App> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Area;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 省市县表(Area)服务定义层
*/
public interface AreaService extends IService<Area> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Bucket;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 存储桶管理(Bucket)服务定义层
*/
public interface BucketService extends IService<Bucket> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.CompanyDept;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 公司部门表(CompanyDept)服务定义层
*/
public interface CompanyDeptService extends IService<CompanyDept> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Company;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 公司表(Company)服务定义层
*/
public interface CompanyService extends IService<Company> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Config;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 全局配置(Config)服务定义层
*/
public interface ConfigService extends IService<Config> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.CordRole;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 组织角色表(CordRole)服务定义层
*/
public interface CordRoleService extends IService<CordRole> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Dept;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 部门表(Dept)服务定义层
*/
public interface DeptService extends IService<Dept> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.DeptUser;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 部门用户表(DeptUser)服务定义层
*/
public interface DeptUserService extends IService<DeptUser> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.DictItem;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 字典项表(DictItem)服务定义层
*/
public interface DictItemService extends IService<DictItem> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Dict;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 字典主表(Dict)服务定义层
*/
public interface DictService extends IService<Dict> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.File;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 文件管理(File)服务定义层
*/
public interface FileService extends IService<File> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Grade;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职系表(Grade)服务定义层
*/
public interface GradeService extends IService<Grade> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.GroupRole;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户组角色表(GroupRole)服务定义层
*/
public interface GroupRoleService extends IService<GroupRole> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Group;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 业务组织(Group)服务定义层
*/
public interface GroupService extends IService<Group> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.GroupUser;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 组织用户(GroupUser)服务定义层
*/
public interface GroupUserService extends IService<GroupUser> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.LogRecord;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 日志记录表(LogRecord)服务定义层
*/
public interface LogRecordService extends IService<LogRecord> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Menu;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 菜单表(Menu)服务定义层
*/
public interface MenuService extends IService<Menu> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import ai.remi.boot.domain.entity.Notice;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 通知公告(Notice)服务定义层
*/
public interface NoticeService extends IService<Notice> {
}

View File

@@ -0,0 +1,23 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.dto.post.OauthCodePostDTO;
import ai.remi.boot.domain.entity.OauthCode;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 授权码表(OauthCode)服务定义层
*/
public interface OauthCodeService extends IService<OauthCode> {
OauthCode create(OauthCodePostDTO oauthCodePost);
void set(String code, OauthCode oauthCode);
OauthCode get(String code) throws Exception;
void remove(String code);
boolean verifyExpired(String code) throws Exception;
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Position;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职位表(Position)服务定义层
*/
public interface PositionService extends IService<Position> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.PostRole;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职位角色表(PostRole)服务定义层
*/
public interface PostRoleService extends IService<PostRole> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Rank;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职级表(Rank)服务定义层
*/
public interface RankService extends IService<Rank> {
}

View File

@@ -0,0 +1,23 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.AccessToken;
import ai.remi.boot.domain.entity.RefreshToken;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 刷新令牌表(RefreshToken)服务定义层
*/
public interface RefreshTokenService extends IService<RefreshToken> {
void create(AccessToken accessToken);
void set(String token, RefreshToken refreshToken);
RefreshToken get(String token) throws Exception;
void remove(String token);
boolean verifyExpired(String token) throws Exception;
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.RestrictIp;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 黑白名单表(RestrictIp)服务定义层
*/
public interface RestrictIpService extends IService<RestrictIp> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.RoleMenu;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 角色菜单表(RoleMenu)服务定义层
*/
public interface RoleMenuService extends IService<RoleMenu> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.Role;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 角色表(Role)服务定义层
*/
public interface RoleService extends IService<Role> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.UserPost;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户岗位表(UserPost)服务定义层
*/
public interface UserPostService extends IService<UserPost> {
}

View File

@@ -0,0 +1,13 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.UserRole;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户角色表(UserRole)服务定义层
*/
public interface UserRoleService extends IService<UserRole> {
}

View File

@@ -0,0 +1,19 @@
package ai.remi.boot.server.service;
import com.baomidou.mybatisplus.extension.service.IService;
import ai.remi.boot.domain.entity.User;
import ai.remi.boot.domain.vo.UserVO;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)服务定义层
*/
public interface UserService extends IService<User> {
UserVO getLoginById(String id);
UserVO getUserById(String id);
User login(String username, String password);
}

View File

@@ -0,0 +1,88 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.date.LocalDateTimeUtils;
import ai.remi.comm.util.id.UUIDUtils;
import ai.remi.comm.util.object.ObjectUtils;
import ai.remi.boot.domain.entity.AccessToken;
import ai.remi.boot.domain.entity.OauthCode;
import ai.remi.boot.domain.enums.RedisKeyEnum;
import ai.remi.boot.domain.vo.UserVO;
import ai.remi.boot.infra.mapper.AccessTokenMapper;
import ai.remi.boot.server.service.AccessTokenService;
import ai.remi.boot.server.service.UserService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Map;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 鉴权令牌表(AccessToken)服务实现层
*/
@Service("accessTokenService")
public class AccessTokenServiceImpl extends ServiceImpl<AccessTokenMapper, AccessToken> implements AccessTokenService {
@Resource
private AccessTokenMapper accessTokenMapper;
@Resource
private RedisService redisService;
@Resource
private UserService userService;
@Override
public AccessToken create(String appKey, OauthCode oauthCode) throws Exception {
// 生成Token信息
String aToken = "AT-" + UUIDUtils.simpleUuid();
String rToken = "RT-" + UUIDUtils.simpleUuid();
// 保存Token信息
LocalDateTime now = LocalDateTime.now();
AccessToken accessToken = AccessToken.builder().accessToken(aToken).refreshToken(rToken).appKey(appKey).expiresTime(LocalDateTimeUtils.plus(now, 3, ChronoUnit.HOURS)).build();
set(aToken, accessToken);
// 刷新Ticket(服务端凭证)
redisService.sSet(RedisKeyEnum.TICKET.getKey(oauthCode.getTicket()), aToken);
redisService.sSet(RedisKeyEnum.TICKET.getKey(oauthCode.getTicket()), rToken);
redisService.expire(RedisKeyEnum.TICKET.getKey(oauthCode.getTicket()), 3 * 60 * 60);
// 缓存用户信息
UserVO userVO = userService.getLoginById(oauthCode.getUserId());
redisService.hmset(RedisKeyEnum.USER_INFO.getKey(aToken), ObjectUtils.objectToMap(userVO), 12 * 60 * 60);
return accessToken;
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void set(String token, AccessToken accessToken) {
accessTokenMapper.insert(accessToken);
redisService.hmset(RedisKeyEnum.ACCESS_TOKEN.getKey(token), ObjectUtils.objectToMap(accessToken), 6 * 60 * 60);
}
@Override
public AccessToken get(String token) throws Exception {
Map<Object, Object> hmget = redisService.hmget(RedisKeyEnum.ACCESS_TOKEN.getKey(token));
if (CollectionUtils.isNotEmpty(hmget)) {
return ObjectUtils.mapToObject(hmget, AccessToken.class);
}
return accessTokenMapper.selectOne(Wrappers.<AccessToken>lambdaQuery().eq(AccessToken::getAccessToken, token).last("limit 1"));
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void remove(String token) {
accessTokenMapper.delete(Wrappers.<AccessToken>lambdaQuery().eq(AccessToken::getAccessToken, token));
redisService.del(RedisKeyEnum.ACCESS_TOKEN.getKey(token));
redisService.del(RedisKeyEnum.USER_INFO.getKey(token));
}
@Override
public boolean verifyExpired(String token) throws Exception {
AccessToken accessToken = get(token);
return LocalDateTimeUtils.isAfter(LocalDateTime.now(), accessToken.getExpiresTime());
}
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.AppGroup;
import ai.remi.boot.infra.mapper.AppGroupMapper;
import ai.remi.boot.server.service.AppGroupService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用组织(AppGroup)服务实现层
*/
@Service("appGroupService")
public class AppGroupServiceImpl extends ServiceImpl<AppGroupMapper, AppGroup> implements AppGroupService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.AppMenu;
import ai.remi.boot.infra.mapper.AppMenuMapper;
import ai.remi.boot.server.service.AppMenuService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用菜单表(AppMenu)服务实现层
*/
@Service("appMenuService")
public class AppMenuServiceImpl extends ServiceImpl<AppMenuMapper, AppMenu> implements AppMenuService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.AppPublish;
import ai.remi.boot.infra.mapper.AppPublishMapper;
import ai.remi.boot.server.service.AppPublishService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用发布表(AppPublish)服务实现层
*/
@Service("appPublishService")
public class AppPublishServiceImpl extends ServiceImpl<AppPublishMapper, AppPublish> implements AppPublishService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.App;
import ai.remi.boot.infra.mapper.AppMapper;
import ai.remi.boot.server.service.AppService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 应用表Application(App)服务实现层
*/
@Service("appService")
public class AppServiceImpl extends ServiceImpl<AppMapper, App> implements AppService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Area;
import ai.remi.boot.infra.mapper.AreaMapper;
import ai.remi.boot.server.service.AreaService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 省市县表(Area)服务实现层
*/
@Service("areaService")
public class AreaServiceImpl extends ServiceImpl<AreaMapper, Area> implements AreaService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Bucket;
import ai.remi.boot.infra.mapper.BucketMapper;
import ai.remi.boot.server.service.BucketService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 存储桶管理(Bucket)服务实现层
*/
@Service("bucketService")
public class BucketServiceImpl extends ServiceImpl<BucketMapper, Bucket> implements BucketService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.CompanyDept;
import ai.remi.boot.infra.mapper.CompanyDeptMapper;
import ai.remi.boot.server.service.CompanyDeptService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 公司部门表(CompanyDept)服务实现层
*/
@Service("companyDeptService")
public class CompanyDeptServiceImpl extends ServiceImpl<CompanyDeptMapper, CompanyDept> implements CompanyDeptService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Company;
import ai.remi.boot.infra.mapper.CompanyMapper;
import ai.remi.boot.server.service.CompanyService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 公司表(Company)服务实现层
*/
@Service("companyService")
public class CompanyServiceImpl extends ServiceImpl<CompanyMapper, Company> implements CompanyService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Config;
import ai.remi.boot.infra.mapper.ConfigMapper;
import ai.remi.boot.server.service.ConfigService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 全局配置(Config)服务实现层
*/
@Service("configService")
public class ConfigServiceImpl extends ServiceImpl<ConfigMapper, Config> implements ConfigService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.CordRole;
import ai.remi.boot.infra.mapper.CordRoleMapper;
import ai.remi.boot.server.service.CordRoleService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 组织角色表(CordRole)服务实现层
*/
@Service("deptRoleService")
public class CordRoleServiceImpl extends ServiceImpl<CordRoleMapper, CordRole> implements CordRoleService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Dept;
import ai.remi.boot.infra.mapper.DeptMapper;
import ai.remi.boot.server.service.DeptService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 部门表(Dept)服务实现层
*/
@Service("deptService")
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements DeptService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.DeptUser;
import ai.remi.boot.infra.mapper.DeptUserMapper;
import ai.remi.boot.server.service.DeptUserService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 部门用户表(DeptUser)服务实现层
*/
@Service("deptUserService")
public class DeptUserServiceImpl extends ServiceImpl<DeptUserMapper, DeptUser> implements DeptUserService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.DictItem;
import ai.remi.boot.infra.mapper.DictItemMapper;
import ai.remi.boot.server.service.DictItemService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 字典项表(DictItem)服务实现层
*/
@Service("dictItemService")
public class DictItemServiceImpl extends ServiceImpl<DictItemMapper, DictItem> implements DictItemService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Dict;
import ai.remi.boot.infra.mapper.DictMapper;
import ai.remi.boot.server.service.DictService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 字典主表(Dict)服务实现层
*/
@Service("dictService")
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.File;
import ai.remi.boot.infra.mapper.FileMapper;
import ai.remi.boot.server.service.FileService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 文件管理(File)服务实现层
*/
@Service("fileService")
public class FileServiceImpl extends ServiceImpl<FileMapper, File> implements FileService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Grade;
import ai.remi.boot.infra.mapper.GradeMapper;
import ai.remi.boot.server.service.GradeService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职系表(Grade)服务实现层
*/
@Service("gradeService")
public class GradeServiceImpl extends ServiceImpl<GradeMapper, Grade> implements GradeService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.GroupRole;
import ai.remi.boot.infra.mapper.GroupRoleMapper;
import ai.remi.boot.server.service.GroupRoleService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户组角色表(GroupRole)服务实现层
*/
@Service("groupRoleService")
public class GroupRoleServiceImpl extends ServiceImpl<GroupRoleMapper, GroupRole> implements GroupRoleService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Group;
import ai.remi.boot.infra.mapper.GroupMapper;
import ai.remi.boot.server.service.GroupService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 业务组织(Group)服务实现层
*/
@Service("groupService")
public class GroupServiceImpl extends ServiceImpl<GroupMapper, Group> implements GroupService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.GroupUser;
import ai.remi.boot.infra.mapper.GroupUserMapper;
import ai.remi.boot.server.service.GroupUserService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 组织用户(GroupUser)服务实现层
*/
@Service("groupUserService")
public class GroupUserServiceImpl extends ServiceImpl<GroupUserMapper, GroupUser> implements GroupUserService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.LogRecord;
import ai.remi.boot.infra.mapper.LogRecordMapper;
import ai.remi.boot.server.service.LogRecordService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 日志记录表(LogRecord)服务实现层
*/
@Service("logRecordService")
public class LogRecordServiceImpl extends ServiceImpl<LogRecordMapper, LogRecord> implements LogRecordService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Menu;
import ai.remi.boot.infra.mapper.MenuMapper;
import ai.remi.boot.server.service.MenuService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 菜单表(Menu)服务实现层
*/
@Service("menuService")
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import ai.remi.boot.domain.entity.Notice;
import ai.remi.boot.infra.mapper.NoticeMapper;
import ai.remi.boot.server.service.NoticeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 通知公告(Notice)服务实现层
*/
@Service("noticeService")
public class NoticeServiceImpl extends ServiceImpl<NoticeMapper, Notice> implements NoticeService {
}

View File

@@ -0,0 +1,81 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.date.LocalDateTimeUtils;
import ai.remi.comm.util.object.ObjectUtils;
import ai.remi.boot.domain.converter.OauthCodeConverter;
import ai.remi.boot.domain.dto.post.OauthCodePostDTO;
import ai.remi.boot.domain.entity.OauthCode;
import ai.remi.boot.domain.enums.RedisKeyEnum;
import ai.remi.boot.infra.mapper.OauthCodeMapper;
import ai.remi.boot.server.service.OauthCodeService;
import ai.remi.boot.server.util.AuthUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.Map;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 授权码表(OauthCode)服务实现层
*/
@Service("oauthCodeService")
public class OauthCodeServiceImpl extends ServiceImpl<OauthCodeMapper, OauthCode> implements OauthCodeService {
@Resource
private OauthCodeMapper oauthCodeMapper;
@Resource
private RedisService redisService;
@Override
public OauthCode create(OauthCodePostDTO oauthCodePost) {
OauthCode oauthCode = OauthCodeConverter.INSTANT.postDtoToEntity(oauthCodePost);
// 生成授权码
String code = "AC-" + AuthUtils.getAuthCode(oauthCodePost.getAppKey(), oauthCodePost.getState());
oauthCode.setAuthCode(code);
// 设置为30分钟后过期
oauthCode.setExpiresTime(LocalDateTimeUtils.plus(LocalDateTime.now(), 30, ChronoUnit.MINUTES));
// 同时保存到数据库和缓存中
set(code, oauthCode);
return oauthCode;
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void set(String code, OauthCode oauthCode) {
oauthCodeMapper.insert(oauthCode);
redisService.hmset(RedisKeyEnum.AUTH_CODE.getKey(code), ObjectUtils.objectToMap(oauthCode), 30 * 60);
}
@Override
public OauthCode get(String code) throws Exception {
Map<Object, Object> hmget = redisService.hmget(RedisKeyEnum.AUTH_CODE.getKey(code));
if(CollectionUtils.isNotEmpty(hmget)){
return ObjectUtils.mapToObject(hmget, OauthCode.class);
}
return oauthCodeMapper.selectOne(Wrappers.<OauthCode>lambdaQuery().eq(OauthCode::getAuthCode, code).last("limit 1"));
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void remove(String code) {
oauthCodeMapper.delete(Wrappers.<OauthCode>lambdaQuery().eq(OauthCode::getAuthCode, code));
redisService.del(RedisKeyEnum.AUTH_CODE.getKey(code));
}
@Override
public boolean verifyExpired(String code) throws Exception {
OauthCode oauthCode = get(code);
return LocalDateTimeUtils.isAfter(LocalDateTime.now(), oauthCode.getExpiresTime());
}
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Position;
import ai.remi.boot.infra.mapper.PositionMapper;
import ai.remi.boot.server.service.PositionService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职位表(Position)服务实现层
*/
@Service("positionService")
public class PositionServiceImpl extends ServiceImpl<PositionMapper, Position> implements PositionService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.PostRole;
import ai.remi.boot.infra.mapper.PostRoleMapper;
import ai.remi.boot.server.service.PostRoleService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职位角色表(PostRole)服务实现层
*/
@Service("postRoleService")
public class PostRoleServiceImpl extends ServiceImpl<PostRoleMapper, PostRole> implements PostRoleService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Rank;
import ai.remi.boot.infra.mapper.RankMapper;
import ai.remi.boot.server.service.RankService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 职级表(Rank)服务实现层
*/
@Service("rankService")
public class RankServiceImpl extends ServiceImpl<RankMapper, Rank> implements RankService {
}

View File

@@ -0,0 +1,70 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.date.LocalDateTimeUtils;
import ai.remi.comm.util.object.ObjectUtils;
import ai.remi.boot.domain.entity.AccessToken;
import ai.remi.boot.domain.entity.RefreshToken;
import ai.remi.boot.domain.enums.RedisKeyEnum;
import ai.remi.boot.infra.mapper.RefreshTokenMapper;
import ai.remi.boot.server.service.RefreshTokenService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.Map;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 刷新令牌表(RefreshToken)服务实现层
*/
@Service("refreshTokenService")
public class RefreshTokenServiceImpl extends ServiceImpl<RefreshTokenMapper, RefreshToken> implements RefreshTokenService {
@Resource
private RefreshTokenMapper refreshTokenMapper;
@Resource
private RedisService redisService;
@Override
public void create(AccessToken accessToken) {
RefreshToken refreshToken = RefreshToken.builder().accessToken(accessToken.getAccessToken()).refreshToken(accessToken.getRefreshToken()).used(0).expiresTime(accessToken.getExpiresTime()).build();
set(accessToken.getRefreshToken(), refreshToken);
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void set(String token, RefreshToken refreshToken) {
refreshTokenMapper.insert(refreshToken);
redisService.hmset(RedisKeyEnum.REFRESH_TOKEN.getKey(token), ObjectUtils.objectToMap(refreshToken), 6 * 60 * 60);
}
@Override
public RefreshToken get(String token) throws Exception {
Map<Object, Object> hmget = redisService.hmget(RedisKeyEnum.REFRESH_TOKEN.getKey(token));
if(CollectionUtils.isNotEmpty(hmget)) {
return ObjectUtils.mapToObject(hmget, RefreshToken.class);
}
return refreshTokenMapper.selectOne(Wrappers.<RefreshToken>lambdaQuery().eq(RefreshToken::getRefreshToken, token).last("limit 1"));
}
@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "transactionManager")
public void remove(String token) {
refreshTokenMapper.delete(Wrappers.<RefreshToken>lambdaQuery().eq(RefreshToken::getRefreshToken, token));
redisService.del(RedisKeyEnum.REFRESH_TOKEN.getKey(token));
}
@Override
public boolean verifyExpired(String token) throws Exception {
RefreshToken refreshToken = get(token);
return LocalDateTimeUtils.isAfter(LocalDateTime.now(), refreshToken.getExpiresTime());
}
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.RestrictIp;
import ai.remi.boot.infra.mapper.RestrictIpMapper;
import ai.remi.boot.server.service.RestrictIpService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 黑白名单表(RestrictIp)服务实现层
*/
@Service("restrictIpService")
public class RestrictIpServiceImpl extends ServiceImpl<RestrictIpMapper, RestrictIp> implements RestrictIpService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.RoleMenu;
import ai.remi.boot.infra.mapper.RoleMenuMapper;
import ai.remi.boot.server.service.RoleMenuService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 角色菜单表(RoleMenu)服务实现层
*/
@Service("roleMenuService")
public class RoleMenuServiceImpl extends ServiceImpl<RoleMenuMapper, RoleMenu> implements RoleMenuService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.Role;
import ai.remi.boot.infra.mapper.RoleMapper;
import ai.remi.boot.server.service.RoleService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 角色表(Role)服务实现层
*/
@Service("roleService")
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.UserPost;
import ai.remi.boot.infra.mapper.UserPostMapper;
import ai.remi.boot.server.service.UserPostService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户岗位表(UserPost)服务实现层
*/
@Service("userPostService")
public class UserPostServiceImpl extends ServiceImpl<UserPostMapper, UserPost> implements UserPostService {
}

View File

@@ -0,0 +1,18 @@
package ai.remi.boot.server.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import ai.remi.boot.domain.entity.UserRole;
import ai.remi.boot.infra.mapper.UserRoleMapper;
import ai.remi.boot.server.service.UserRoleService;
import org.springframework.stereotype.Service;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户角色表(UserRole)服务实现层
*/
@Service("userRoleService")
public class UserRoleServiceImpl extends ServiceImpl<UserRoleMapper, UserRole> implements UserRoleService {
}

View File

@@ -0,0 +1,182 @@
package ai.remi.boot.server.service.impl;
import ai.remi.boot.domain.converter.RoleConverter;
import ai.remi.boot.domain.entity.*;
import ai.remi.boot.domain.tree.MenuTree;
import ai.remi.boot.domain.vo.AppMenuVO;
import ai.remi.boot.domain.vo.ConfigVO;
import ai.remi.boot.domain.vo.RoleVO;
import ai.remi.boot.domain.vo.UserVO;
import ai.remi.boot.infra.mapper.MenuMapper;
import ai.remi.boot.infra.mapper.UserMapper;
import ai.remi.boot.server.service.*;
import ai.remi.comm.domain.tree.TreeBuild;
import ai.remi.comm.util.bean.BeanCopyUtils;
import ai.remi.comm.util.collection.CollectionUtils;
import ai.remi.comm.util.object.ObjectUtils;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author DianJiu
* @email dianjiuxyz@gmail.com
* @desc 用户表(User)服务实现层
*/
@Service("userService")
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {
@Resource
private UserMapper userMapper;
@Resource
private RoleService roleService;
@Resource
private UserRoleService userRoleService;
@Resource
private DeptUserService deptUserService;
@Resource
private CompanyDeptService companyDeptService;
@Resource
private CordRoleService cordRoleService;
@Resource
private UserPostService userPostService;
@Resource
private PostRoleService postRoleService;
@Resource
private GroupUserService groupUserService;
@Resource
private GroupRoleService groupRoleService;
@Resource
private RoleMenuService roleMenuService;
@Resource
private MenuMapper menuMapper;
@Resource
private ConfigService configService;
@Override
public UserVO getLoginById(String id) {
UserVO userVO = userMapper.selectOneById(id);
// 获取用户角色
List<RoleVO> userRoles = getUserRoles(id);
userVO.setUserRoles(userRoles);
// 获取用户菜单
List<AppMenuVO> userMenus = getUserMenus(userRoles);
userVO.setUserMenus(userMenus);
// 用户全局配置
List<Config> list = configService.list(Wrappers.<Config>lambdaQuery().eq(Config::getConfType, 1).eq(Config::getBindId, id));
userVO.setAppConfigs(BeanCopyUtils.coverList(list, ConfigVO.class));
return userVO;
}
@Override
public UserVO getUserById(String id) {
UserVO userVO = userMapper.selectOneById(id);
// 获取用户角色
List<RoleVO> userRoles = getUserRoles(id);
userVO.setUserRoles(userRoles);
// 获取用户菜单
//List<AppMenuVO> userMenus = getUserMenus(userRoles);
//userVO.setUserMenus(userMenus);
return userVO;
}
@Override
public User login(String username, String password) {
Wrapper<User> queryWrapper = Wrappers.<User>lambdaQuery().eq(User::getLoginName, username).eq(User::getPassword, password).eq(User::getStatus, 1).last("limit 1");
User user = userMapper.selectOne(queryWrapper);
return user;
}
private List<AppMenuVO> getUserMenus(List<RoleVO> userRoles) {
List<AppMenuVO> list = new ArrayList<>();
// 获取用户所有的菜单
List<RoleMenu> roleMenus = roleMenuService.list(Wrappers.<RoleMenu>lambdaQuery().in(RoleMenu::getRoleId, userRoles.stream().map(a -> a.getId()).collect(Collectors.toList())));
// 查询出所有菜单信息
List<MenuTree> menuTrees = menuMapper.selectMenuInIds(roleMenus.stream().map(a -> a.getMenuId()).collect(Collectors.toList()), 1);
Map<String, List<MenuTree>> collect = menuTrees.stream().collect(Collectors.groupingBy(menuTree -> menuTree.getAppId()));
collect.forEach((key, value) -> {
AppMenuVO appMenuVO = new AppMenuVO();
appMenuVO.setAppId(key);
if (CollectionUtils.isNotEmpty(value)) {
appMenuVO.setAppCode(value.get(0).getAppCode());
String rootId = "0";
// 创建树形结构并返回
TreeBuild treeBuild = new TreeBuild(rootId, value);
appMenuVO.setMenuTree(treeBuild.buildTree());
}
list.add(appMenuVO);
});
return list;
}
private List<RoleVO> getUserRoles(String userId) {
List<RoleVO> list = new ArrayList<>();
// 1、基础角色
List<UserRole> userRoles = userRoleService.list(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, userId));
if (CollectionUtils.isNotEmpty(userRoles)) {
for (UserRole userRole : userRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, userRole.getRoleId()).eq(Role::getRoleType, 1).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 组织角色
// 所在部门角色
DeptUser deptUser = deptUserService.getOne(Wrappers.<DeptUser>lambdaQuery().eq(DeptUser::getUserId, userId).last("limit 1"));
List<CordRole> deptRoles = cordRoleService.list(Wrappers.<CordRole>lambdaQuery().eq(CordRole::getCordId, deptUser.getDeptId()).eq(CordRole::getCordType, 2));
if (CollectionUtils.isNotEmpty(deptRoles)) {
for (CordRole cordRole : deptRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, cordRole.getRoleId()).eq(Role::getRoleType, 2).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 所在公司角色
CompanyDept companyDept = companyDeptService.getOne(Wrappers.<CompanyDept>lambdaQuery().eq(CompanyDept::getDeptId, deptUser.getDeptId()).last("limit 1"));
List<CordRole> companyRoles = new ArrayList<>();
if (ObjectUtils.isNotEmpty(companyDept)) {
companyRoles = cordRoleService.list(Wrappers.<CordRole>lambdaQuery().eq(CordRole::getCordId, companyDept.getCompanyId()).eq(CordRole::getCordType, 1));
}
if (CollectionUtils.isNotEmpty(companyRoles)) {
for (CordRole cordRole : companyRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, cordRole.getRoleId()).eq(Role::getRoleType, 2).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 业务角色
UserPost userPost = userPostService.getOne(Wrappers.<UserPost>lambdaQuery().eq(UserPost::getUserId, userId).last("limit 1"));
List<PostRole> postRoles = new ArrayList<>();
if (ObjectUtils.isNotEmpty(userPost)) {
postRoles = postRoleService.list(Wrappers.<PostRole>lambdaQuery().eq(PostRole::getPostId, userPost.getPositionId()));
}
if (CollectionUtils.isNotEmpty(postRoles)) {
for (PostRole postRole : postRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, postRole.getRoleId()).eq(Role::getRoleType, 3).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 用户组角色
List<GroupUser> groupUsers = groupUserService.list(Wrappers.<GroupUser>lambdaQuery().eq(GroupUser::getUserId, userId));
List<GroupRole> groupRoles = new ArrayList<>();
if (CollectionUtils.isNotEmpty(groupUsers)) {
groupRoles = groupRoleService.list(Wrappers.<GroupRole>lambdaQuery().in(GroupRole::getGroupId, groupUsers.stream().map(a -> a.getGroupId()).collect(Collectors.toList())));
}
if (CollectionUtils.isNotEmpty(groupRoles)) {
for (GroupRole groupRole : groupRoles) {
Role one = roleService.getOne(Wrappers.<Role>lambdaQuery().eq(Role::getId, groupRole.getRoleId()).eq(Role::getRoleType, 4).last("limit 1"));
list.add(RoleConverter.INSTANT.entityToVO(one));
}
}
// 角色集合去重返回
if (CollectionUtils.isNotEmpty(list)) {
return list.stream().distinct().collect(Collectors.toList());
}
return list;
}
}

View File

@@ -0,0 +1,178 @@
package ai.remi.boot.server.util;
import ai.remi.comm.exception.util.MessageUtils;
import ai.remi.comm.redis.service.RedisService;
import ai.remi.comm.util.asserts.AssertUtils;
import ai.remi.comm.util.id.RandomUtils;
import ai.remi.comm.util.id.UUIDUtils;
import ai.remi.comm.util.security.AesUtils;
import ai.remi.boot.domain.enums.RedisKeyEnum;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.LocalDateTime;
import java.util.Arrays;
;
/**
* @author DianJiu
* @date 2021/12/8
* @Description 随机产生唯一的app_key和app_secret
*/
@Component
public class AppUtils {
@Resource
private RedisService redisService;
public static RedisService redisUtils;
@PostConstruct
public void init() {
redisUtils = this.redisService;
}
private final static String[] chars = new String[]{"a", "b", "c", "d", "e", "f",
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",
"t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5",
"6", "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I",
"J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V",
"W", "X", "Y", "Z"};
/**
* 最大重试次数
*/
public static final int MAX_RETRY_COUNT = 10;
/**
* 最大重试记录
*/
public static int maxCount = 0;
/**
* 生成规则 年份后两位【2位】 + 1年内第几天【3位】 + 随机数【5位】
* 理论上来说,一百年内不会重复
* 注意:1.前五位保证每天生成的id不重复,后五位会在redis缓存 set集合中进行碰撞校验,
* 2.请保证每天0时清除缓存,保证缓存中的短id数量较少提高性能,减少内存浪费
*/
public static String getAppCode() {
String year = String.valueOf(LocalDateTime.now().getYear()).substring(2);
String day = String.valueOf(LocalDateTime.now().getDayOfYear());
if (day.length() < 3) {
StringBuilder sb = new StringBuilder();
for (int i = day.length(); i < 3; i++) {
sb.append("0");
}
day = sb.append(day).toString();
}
String code = year + day;
int count = 0;
boolean exists = true;
while (exists) {
if (count > maxCount) {
maxCount = count;
}
String random = RandomUtils.generateNumberString(10 - code.length());
exists = redisUtils.sSet(RedisKeyEnum.APP_CODE.getKey(code, random), code + random) == 0L;
code = code + random;
count++;
AssertUtils.isFalse(count >= MAX_RETRY_COUNT, MessageUtils.getMessage("app.code.error"));
}
return code;
}
/**
* @Description: <p>
* 短8位UUID思想其实借鉴微博短域名的生成方式,但是其重复概率过高,而且每次生成4个,需要随即选取一个。
* 本算法利用62个可打印字符,通过随机生成32位UUID,由于UUID都为十六进制,所以将UUID分成8组,每4个为一组,然后通过模62操作,结果作为索引取出字符,
* 这样重复率大大降低。
* 经测试,在生成一千万个数据也没有出现重复,完全满足大部分需求。
* </p>
* @author DianJiu
* @date 2019/8/27 16:16
*/
public static String getAppKey() {
StringBuffer shortBuffer = new StringBuffer();
String uuid = UUIDUtils.simpleUuid();
for (int i = 0; i < 8; i++) {
String str = uuid.substring(i * 4, i * 4 + 4);
int x = Integer.parseInt(str, 16);
shortBuffer.append(chars[x % 0x3E]);
}
return shortBuffer.toString().toLowerCase();
}
/**
* <p>
* 通过appId和内置关键词生成APP Secret
* </P>
*
* @author DianJiu
* @date 2019/8/27 16:32
*/
public static String getAppSecret() {
return AesUtils.initHexKey();
}
public static Boolean validate(String appKey,String appSecret) {
return appSecret.equals(getAppSecret(appKey));
}
/**
* <p>
* 通过appId和内置关键词生成APP Secret
* </P>
*
* @author DianJiu
* @date 2019/8/27 16:32
*/
public static String getAppSecret(String appKey) {
try {
String[] array = new String[]{appKey};
StringBuffer sb = new StringBuffer();
// 字符串排序
Arrays.sort(array);
for (int i = 0; i < array.length; i++) {
sb.append(array[i]);
}
String str = sb.toString();
MessageDigest md = MessageDigest.getInstance("SHA-1");
md.update(str.getBytes());
byte[] digest = md.digest();
StringBuffer hexstr = new StringBuffer();
String shaHex = "";
for (int i = 0; i < digest.length; i++) {
shaHex = Integer.toHexString(digest[i] & 0xFF);
if (shaHex.length() < 2) {
hexstr.append(0);
}
hexstr.append(shaHex);
}
return hexstr.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
throw new RuntimeException();
}
}
public static void main(String[] args) {
//for (int i = 0; i < 10000; i++) {
// getAppCode();
//}
//System.out.println("最大碰撞次数为=>" + AppUtils.maxCount);
//String appCode = getAppCode();
String appKey = getAppKey();
String appSecret = getAppSecret(appKey);
//System.out.println("appCode: " + appCode);
System.out.println("appKey: " + appKey);
System.out.println("appSecret: " + appSecret);
}
}

View File

@@ -0,0 +1,21 @@
package ai.remi.boot.server.util;
import ai.remi.comm.util.security.Base64Utils;
import ai.remi.comm.util.string.StringUtils;
import org.springframework.util.DigestUtils;
import java.nio.charset.StandardCharsets;
public class AuthUtils {
public static String getAuthCode(String appKey, String state) {
String encode = Base64Utils.encode(appKey + state);
if (StringUtils.isNotBlank(encode)) {
return DigestUtils.md5DigestAsHex(encode.getBytes(StandardCharsets.UTF_8));
}
return "";
}
public static void main(String[] args) {
System.out.println(getAuthCode("AB123CE","123456"));
}
}