feat(upms): 重构国际化消息和错误码模块化架构

- 移除全局ErrorCodes接口,按模块拆分Auth/Upms/App错误码定义
- 新增模块化i18n消息文件,支持多JAR包扫描加载机制
- 重构MsgUtils支持LocaleContextHolder动态区域解析
- 统一OAuthClientException异常处理支持错误码和描述参数
- 优化企业微信/钉钉同步错误消息国际化支持
This commit is contained in:
PIGCLOUD committed 2025-12-28 11:27:03 +08:00
1 parent 7911761653
commit f30b32a28a
32 files changed
+1719 -1321

No files matched your search

@@ -0,0 +1,28 @@
package com.pig4cloud.pigx.app.api.enums;
/**
* App Server 模块错误编码
*
* @author lengleng
* @date 2022/3/30
*/
public interface AppErrorCodes {
// === App 用户相关 ===
String APP_USER_USERINFO_EMPTY = "app.user.userInfo.empty";
String APP_USER_USERNAME_EXISTING = "app.user.username.existing";
String APP_USER_IMPORT_SUCCEED = "app.user.import.succeed";
String APP_USER_QUERY_ERROR = "app.user.query.error";
// === App 角色相关 ===
String APP_ROLE_ROLENAME_INEXISTENCE = "app.role.roleName.inexistence";
String APP_ROLE_NAMEORCODE_EXISTING = "app.role.nameOrCode.existing";
// === App 短信相关 ===
String APP_SMS_OFTEN = "app.sms.often";
}
@@ -0,0 +1,14 @@
# App Server Module i18n Messages - English
# App user related
app.user.userInfo.empty=App user information is empty for {0}
app.user.username.existing=Username {0} already exists
app.user.import.succeed=User import succeeded; default password is the phone number
app.user.query.error=Failed to fetch current user information
# App role related
app.role.roleName.inexistence=Role name {0} does not exist
app.role.nameOrCode.existing=Role name or code already exists ({0} {1})
# App SMS related
app.sms.often=Verification code sent too frequently
@@ -0,0 +1,14 @@
# App Server 模块国际化消息 - 中文
# App 用户相关
app.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A
app.user.username.existing={0} \u7528\u6237\u540D\u5DF2\u5B58\u5728
app.user.import.succeed=\u7528\u6237\u5BFC\u5165\u6210\u529F\uFF0C\u9ED8\u8BA4\u5BC6\u7801\u4E3A\u624B\u673A\u53F7
app.user.query.error=\u83B7\u53D6\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5931\u8D25
# App 角色相关
app.role.roleName.inexistence={0} \u89D2\u8272\u540D\u79F0\u4E0D\u5B58\u5728
app.role.nameOrCode.existing={0} {1} \u89D2\u8272\u540D\u6216\u89D2\u8272\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
# App 短信相关
app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41
@@ -21,11 +21,11 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pig4cloud.pigx.app.api.dto.AppUserDTO;
import com.pig4cloud.pigx.app.api.entity.AppUser;
import com.pig4cloud.pigx.app.api.enums.AppErrorCodes;
import com.pig4cloud.pigx.app.api.vo.AppUserExcelVO;
import com.pig4cloud.pigx.app.service.AppUserService;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.annotation.RequestExcel;
@@ -58,150 +58,158 @@ import java.util.List;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class AppUserController {
private final AppUserService appUserService;
private final AppUserService appUserService;
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query()
.lambda()
.eq(AppUser::getUsername, username)
.or()
.eq(AppUser::getPhone, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.APP_USER_USERINFO_EMPTY, username));
}
return R.ok(appUserService.findUserInfo(user));
}
@Inner
@GetMapping("/info/{username}")
public R info(@PathVariable String username) {
AppUser user = appUserService.getOne(Wrappers.<AppUser>query()
.lambda()
.eq(AppUser::getUsername, username)
.or()
.eq(AppUser::getPhone, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(AppErrorCodes.APP_USER_USERINFO_EMPTY, username));
}
return R.ok(appUserService.findUserInfo(user));
}
/**
* 获取当前用户全部信息
* @return 用户信息
*/
@GetMapping(value = { "/info" })
public R info() {
String username = SecurityUtils.getUser().getUsername();
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getUsername, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_QUERY_ERROR));
}
return R.ok(appUserService.findUserInfo(user));
}
/**
* 获取当前用户全部信息
*
* @return 用户信息
*/
@GetMapping(value = {"/info"})
public R info() {
String username = SecurityUtils.getUser().getUsername();
AppUser user = appUserService.getOne(Wrappers.<AppUser>query().lambda().eq(AppUser::getUsername, username));
if (user == null) {
return R.failed(MsgUtils.getMessage(AppErrorCodes.APP_USER_QUERY_ERROR));
}
return R.ok(appUserService.findUserInfo(user));
}
/**
* 分页查询
* @param page 分页对象
* @param appUserDTO app用户表
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getAppUserPage(Page page, AppUserDTO appUserDTO) {
return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO));
}
/**
* 分页查询
*
* @param page 分页对象
* @param appUserDTO app用户表
* @return
*/
@Operation(summary = "分页查询", description = "分页查询")
@GetMapping("/page")
public R getAppUserPage(Page page, AppUserDTO appUserDTO) {
return R.ok(appUserService.getUsersWithRolePage(page, appUserDTO));
}
/**
* 通过id查询app用户表
* @param userId id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/details/{userId}")
public R getById(@PathVariable("userId") Long userId) {
return R.ok(appUserService.selectUserVoById(userId));
}
/**
* 通过id查询app用户表
*
* @param userId id
* @return R
*/
@Operation(summary = "通过id查询", description = "通过id查询")
@GetMapping("/details/{userId}")
public R getById(@PathVariable("userId") Long userId) {
return R.ok(appUserService.selectUserVoById(userId));
}
/**
* @return R
*/
@Operation(summary = "通过userName查询", description = "通过userName查询")
@GetMapping("/details")
public R getByUserName(AppUser user) {
AppUser one = appUserService.getOne(Wrappers.query(user), false);
return R.ok(one == null ? null : CommonConstants.SUCCESS);
}
/**
* @return R
*/
@Operation(summary = "通过userName查询", description = "通过userName查询")
@GetMapping("/details")
public R getByUserName(AppUser user) {
AppUser one = appUserService.getOne(Wrappers.query(user), false);
return R.ok(one == null ? null : CommonConstants.SUCCESS);
}
/**
* 新增app用户表
* @param appUser app用户表
* @return R
*/
@Operation(summary = "新增app用户表", description = "新增app用户表")
@SysLog("新增app用户表")
@PostMapping
@HasPermission("app_appuser_add")
public R save(@RequestBody AppUserDTO appUser) {
appUserService.saveUser(appUser);
return R.ok();
}
/**
* 新增app用户表
*
* @param appUser app用户表
* @return R
*/
@Operation(summary = "新增app用户表", description = "新增app用户表")
@SysLog("新增app用户表")
@PostMapping
@HasPermission("app_appuser_add")
public R save(@RequestBody AppUserDTO appUser) {
appUserService.saveUser(appUser);
return R.ok();
}
/**
* 修改app用户表
* @param appUser app用户表
* @return R
*/
@Operation(summary = "修改app用户表", description = "修改app用户表")
@SysLog("修改app用户表")
@PutMapping
@HasPermission("app_appuser_edit")
public R updateById(@RequestBody AppUserDTO appUser) {
return R.ok(appUserService.updateUser(appUser));
}
/**
* 修改app用户表
*
* @param appUser app用户表
* @return R
*/
@Operation(summary = "修改app用户表", description = "修改app用户表")
@SysLog("修改app用户表")
@PutMapping
@HasPermission("app_appuser_edit")
public R updateById(@RequestBody AppUserDTO appUser) {
return R.ok(appUserService.updateUser(appUser));
}
/**
* 通过id删除app用户表
* @param ids userIds
* @return R
*/
@Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表")
@SysLog("通过id删除app用户表")
@DeleteMapping
@HasPermission("app_appuser_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appUserService.deleteAppUserByIds(ids));
}
/**
* 通过id删除app用户表
*
* @param ids userIds
* @return R
*/
@Operation(summary = "通过ids删除app用户表", description = "通过ids删除app用户表")
@SysLog("通过id删除app用户表")
@DeleteMapping
@HasPermission("app_appuser_del")
public R removeById(@RequestBody Long[] ids) {
return R.ok(appUserService.deleteAppUserByIds(ids));
}
/**
* 导出excel 表格
* @param appUser 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("app_appuser_export")
public List<AppUserExcelVO> export(AppUserDTO appUser) {
return appUserService.listUser(appUser);
}
/**
* 导出excel 表格
*
* @param appUser 查询条件
* @return excel 文件流
*/
@ResponseExcel
@GetMapping("/export")
@HasPermission("app_appuser_export")
public List<AppUserExcelVO> export(AppUserDTO appUser) {
return appUserService.listUser(appUser);
}
@SysLog("修改个人信息")
@PutMapping("/edit")
public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) {
if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) {
userDto.setUserId(SecurityUtils.getUser().getId());
// TOC 以手机号为key
userDto.setUsername(SecurityUtils.getUser().getUsername());
}
return appUserService.updateUserInfo(userDto);
}
@SysLog("修改个人信息")
@PutMapping("/edit")
public R updateUserInfo(@Valid @RequestBody AppUserDTO userDto) {
if (UserTypeEnum.TOC.getStatus().equals(SecurityUtils.getUser().getUserType())) {
userDto.setUserId(SecurityUtils.getUser().getId());
// TOC 以手机号为key
userDto.setUsername(SecurityUtils.getUser().getUsername());
}
return appUserService.updateUserInfo(userDto);
}
/**
* 导入用户
* @param excelVOList 用户列表
* @param bindingResult 错误信息列表
* @return R
*/
@PostMapping("/import")
@HasPermission("app_appuser_export")
public R importUser(@RequestExcel List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
return appUserService.importUser(excelVOList, bindingResult);
}
/**
* 导入用户
*
* @param excelVOList 用户列表
* @param bindingResult 错误信息列表
* @return R
*/
@PostMapping("/import")
@HasPermission("app_appuser_export")
public R importUser(@RequestExcel List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
return appUserService.importUser(excelVOList, bindingResult);
}
@Operation(summary = "注册app用户表", description = "注册app用户表")
@SysLog("注册app用户表")
@Inner(value = false)
@PostMapping("/register")
public R register(@RequestBody AppUserDTO appUser) {
return appUserService.registerAppUser(appUser);
}
@Operation(summary = "注册app用户表", description = "注册app用户表")
@SysLog("注册app用户表")
@Inner(value = false)
@PostMapping("/register")
public R register(@RequestBody AppUserDTO appUser) {
return appUserService.registerAppUser(appUser);
}
}
@@ -20,11 +20,11 @@ package com.pig4cloud.pigx.app.service.impl;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.pig4cloud.pigx.app.api.enums.AppErrorCodes;
import com.pig4cloud.pigx.app.service.AppMobileService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
@@ -43,24 +43,25 @@ import org.springframework.stereotype.Service;
@AllArgsConstructor
public class AppMobileServiceImpl implements AppMobileService {
/**
* 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
* @param mobile mobile
* @return code
*/
@Override
public R<Boolean> sendSmsCode(String mobile) {
String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile);
/**
* 发送手机验证码 TODO: 调用短信网关发送验证码,测试返回前端
*
* @param mobile mobile
* @return code
*/
@Override
public R<Boolean> sendSmsCode(String mobile) {
String codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile);
if (StrUtil.isNotBlank(codeObj)) {
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
}
if (StrUtil.isNotBlank(codeObj)) {
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(AppErrorCodes.APP_SMS_OFTEN));
}
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
log.debug("手机号生成验证码成功:{},{}", mobile, code);
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME);
return R.ok(Boolean.TRUE);
}
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
log.debug("手机号生成验证码成功:{},{}", mobile, code);
RedisUtils.set(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT + mobile, code, SecurityConstants.CODE_TIME);
return R.ok(Boolean.TRUE);
}
}
@@ -17,16 +17,20 @@
package com.pig4cloud.pigx.app.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.app.api.entity.AppPageEntity;
import com.pig4cloud.pigx.app.api.entity.AppRole;
import com.pig4cloud.pigx.app.api.enums.AppErrorCodes;
import com.pig4cloud.pigx.app.api.enums.PageTypeEnums;
import com.pig4cloud.pigx.app.api.vo.AppRoleExcelVO;
import com.pig4cloud.pigx.app.mapper.AppPageMapper;
import com.pig4cloud.pigx.app.mapper.AppRoleMapper;
import com.pig4cloud.pigx.app.service.AppRoleService;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
import lombok.AllArgsConstructor;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.validation.BindingResult;
@@ -35,79 +39,97 @@ import java.util.List;
import java.util.Set;
/**
* app角色表
* APP角色服务实现类
* <p>
* 提供对APP角色相关的业务操作实现。
*
* @author aeizzz
* @date 2022-12-07 09:52:03
* @author lengleng
* @date 2025/05/29
*/
@Service
@AllArgsConstructor
@RequiredArgsConstructor
public class AppRoleServiceImpl extends ServiceImpl<AppRoleMapper, AppRole> implements AppRoleService {
@Override
public List<AppRole> findRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId);
}
private final AppPageMapper appPageMapper;
/**
* 删除用户的同时,把role_menu关系删除
* @param ids roleIds
*/
@Override
public Boolean deleteRoleByIds(Long[] ids) {
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
private final AppRoleMapper appRoleMapper;
/**
* 导入角色
* @param excelVOList
* @param bindingResult
* @return
*/
@Override
public R importRole(List<AppRoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
@Override
public List<AppRole> findRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId);
}
// 个性化校验逻辑
List<AppRole> roleList = this.list();
/**
* 删除用户的同时,把role_menu关系删除
*
* @param ids roleIds
*/
@Override
public Boolean deleteRoleByIds(Long[] ids) {
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
// 执行数据插入操作 组装 RoleDto
for (AppRoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream()
.anyMatch(appRole -> excel.getRoleName().equals(appRole.getRoleName())
|| excel.getRoleCode().equals(appRole.getRoleCode()));
/**
* 导入角色
*
* @param excelVOList
* @param bindingResult
* @return
*/
@Override
public R importRole(List<AppRoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
if (existRole) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
// 个性化校验逻辑
List<AppRole> roleList = this.list();
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
// 执行数据插入操作 组装 RoleDto
for (AppRoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream()
.anyMatch(appRole -> excel.getRoleName().equals(appRole.getRoleName())
|| excel.getRoleCode().equals(appRole.getRoleCode()));
}
if (existRole) {
errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
private void insertExcelRole(AppRoleExcelVO excel) {
AppRole appRole = new AppRole();
appRole.setRoleName(excel.getRoleName());
appRole.setRoleDesc(excel.getRoleDesc());
appRole.setRoleCode(excel.getRoleCode());
this.save(appRole);
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
} else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 获取列表菜单对象
*
* @return 列表菜单对象的实例
*/
@Override
public AppPageEntity listMenu() {
return appPageMapper.selectOne(Wrappers.<AppPageEntity>lambdaQuery()
.eq(AppPageEntity::getPageType, PageTypeEnums.WORKBENCH.getPageType()));
}
private void insertExcelRole(AppRoleExcelVO excel) {
AppRole appRole = new AppRole();
appRole.setRoleName(excel.getRoleName());
appRole.setRoleDesc(excel.getRoleDesc());
appRole.setRoleCode(excel.getRoleCode());
this.save(appRole);
}
}
@@ -29,6 +29,7 @@ import com.pig4cloud.pigx.app.api.dto.AppUserInfo;
import com.pig4cloud.pigx.app.api.entity.AppRole;
import com.pig4cloud.pigx.app.api.entity.AppUser;
import com.pig4cloud.pigx.app.api.entity.AppUserRole;
import com.pig4cloud.pigx.app.api.enums.AppErrorCodes;
import com.pig4cloud.pigx.app.api.vo.AppUserExcelVO;
import com.pig4cloud.pigx.app.api.vo.AppUserVO;
import com.pig4cloud.pigx.app.mapper.AppUserMapper;
@@ -39,7 +40,6 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.constant.enums.UserTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
@@ -72,328 +72,338 @@ import java.util.Set;
@Slf4j
public class AppUserServiceImpl extends ServiceImpl<AppUserMapper, AppUser> implements AppUserService {
/**
* 密码编码器,用于密码加密
*/
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
/**
* 密码编码器,用于密码加密
*/
private static final PasswordEncoder ENCODER = new BCryptPasswordEncoder();
/**
* 用户角色关联服务
*/
private final AppUserRoleService appUserRoleService;
/**
* 用户角色关联服务
*/
private final AppUserRoleService appUserRoleService;
/**
* 角色服务
*/
private final AppRoleService appRoleService;
/**
* 角色服务
*/
private final AppRoleService appRoleService;
/**
* 缓存管理器
*/
private final CacheManager cacheManager;
/**
* 缓存管理器
*/
private final CacheManager cacheManager;
/**
* 更新用户信息
* @param userDTO 用户数据传输对象
* @return 更新结果
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username")
public Boolean updateUser(AppUserDTO userDTO) {
// 创建用户实体并复制属性
AppUser appUser = new AppUser();
BeanUtils.copyProperties(userDTO, appUser);
/**
* 更新用户信息
*
* @param userDTO 用户数据传输对象
* @return 更新结果
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username")
public Boolean updateUser(AppUserDTO userDTO) {
// 创建用户实体并复制属性
AppUser appUser = new AppUser();
BeanUtils.copyProperties(userDTO, appUser);
// 如果密码不为空,进行加密处理
if (StrUtil.isNotBlank(userDTO.getPassword())) {
appUser.setPassword(ENCODER.encode(userDTO.getPassword()));
}
// 更新用户基本信息
this.updateById(appUser);
// 如果密码不为空,进行加密处理
if (StrUtil.isNotBlank(userDTO.getPassword())) {
appUser.setPassword(ENCODER.encode(userDTO.getPassword()));
}
// 更新用户基本信息
this.updateById(appUser);
// 删除用户与角色的关联关系
appUserRoleService.remove(Wrappers.<AppUserRole>lambdaQuery().eq(AppUserRole::getUserId, appUser.getUserId()));
// 重新建立用户与角色的关联关系
userDTO.getRole().forEach(roleId -> {
AppUserRole appUserRole = new AppUserRole();
appUserRole.setRoleId(roleId);
appUserRole.setUserId(userDTO.getUserId());
appUserRole.insert();
});
// 删除用户与角色的关联关系
appUserRoleService.remove(Wrappers.<AppUserRole>lambdaQuery().eq(AppUserRole::getUserId, appUser.getUserId()));
// 重新建立用户与角色的关联关系
userDTO.getRole().forEach(roleId -> {
AppUserRole appUserRole = new AppUserRole();
appUserRole.setRoleId(roleId);
appUserRole.setUserId(userDTO.getUserId());
appUserRole.insert();
});
// 清除以手机号为key的用户缓存
AppUser appUserInfo = baseMapper.selectById(userDTO.getUserId());
cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(appUserInfo.getPhone());
return Boolean.TRUE;
}
// 清除以手机号为key的用户缓存
AppUser appUserInfo = baseMapper.selectById(userDTO.getUserId());
cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(appUserInfo.getPhone());
return Boolean.TRUE;
}
/**
* 新增用户
* @param userDTO 用户数据传输对象
* @return 保存结果
*/
@Override
public Boolean saveUser(AppUserDTO userDTO) {
// 创建用户实体并复制属性
AppUser appUser = new AppUser();
BeanUtils.copyProperties(userDTO, appUser);
// 设置删除标志为正常状态
appUser.setDelFlag(CommonConstants.STATUS_NORMAL);
// 对密码进行加密
appUser.setPassword(ENCODER.encode(userDTO.getPassword()));
// 插入用户记录
baseMapper.insert(appUser);
/**
* 新增用户
*
* @param userDTO 用户数据传输对象
* @return 保存结果
*/
@Override
public Boolean saveUser(AppUserDTO userDTO) {
// 创建用户实体并复制属性
AppUser appUser = new AppUser();
BeanUtils.copyProperties(userDTO, appUser);
// 设置删除标志为正常状态
appUser.setDelFlag(CommonConstants.STATUS_NORMAL);
// 对密码进行加密
appUser.setPassword(ENCODER.encode(userDTO.getPassword()));
// 插入用户记录
baseMapper.insert(appUser);
// 如果角色列表不为空,建立用户与角色的关联关系
if (CollUtil.isNotEmpty(userDTO.getRole())) {
List<AppUserRole> userRoleList = userDTO.getRole().stream().map(roleId -> {
AppUserRole userRole = new AppUserRole();
userRole.setUserId(appUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).toList();
// 批量保存用户角色关联
appUserRoleService.saveBatch(userRoleList);
}
return Boolean.TRUE;
}
// 如果角色列表不为空,建立用户与角色的关联关系
if (CollUtil.isNotEmpty(userDTO.getRole())) {
List<AppUserRole> userRoleList = userDTO.getRole().stream().map(roleId -> {
AppUserRole userRole = new AppUserRole();
userRole.setUserId(appUser.getUserId());
userRole.setRoleId(roleId);
return userRole;
}).toList();
// 批量保存用户角色关联
appUserRoleService.saveBatch(userRoleList);
}
return Boolean.TRUE;
}
/**
* 查询全部用户(用于Excel导出)
* @param appUser 查询条件
* @return 用户Excel视图对象列表
*/
@Override
public List<AppUserExcelVO> listUser(AppUserDTO appUser) {
// 查询所有用户
List<AppUser> appUsers = baseMapper.selectList(null);
// 将用户实体转换为Excel视图对象
List<AppUserExcelVO> appUserExcelVOS = appUsers.stream().map(item -> {
AppUserExcelVO appUserExcelVO = new AppUserExcelVO();
BeanUtils.copyProperties(item, appUserExcelVO);
return appUserExcelVO;
}).toList();
return appUserExcelVOS;
}
/**
* 查询全部用户(用于Excel导出)
*
* @param appUser 查询条件
* @return 用户Excel视图对象列表
*/
@Override
public List<AppUserExcelVO> listUser(AppUserDTO appUser) {
// 查询所有用户
List<AppUser> appUsers = baseMapper.selectList(null);
// 将用户实体转换为Excel视图对象
List<AppUserExcelVO> appUserExcelVOS = appUsers.stream().map(item -> {
AppUserExcelVO appUserExcelVO = new AppUserExcelVO();
BeanUtils.copyProperties(item, appUserExcelVO);
return appUserExcelVO;
}).toList();
return appUserExcelVOS;
}
/**
* 分页查询用户(包含角色信息)
* @param page 分页参数
* @param appUserDTO 查询条件
* @return 分页结果
*/
@Override
public IPage getUsersWithRolePage(Page page, AppUserDTO appUserDTO) {
return baseMapper.getUserVosPage(page, appUserDTO);
}
/**
* 分页查询用户(包含角色信息)
*
* @param page 分页参数
* @param appUserDTO 查询条件
* @return 分页结果
*/
@Override
public IPage getUsersWithRolePage(Page page, AppUserDTO appUserDTO) {
return baseMapper.getUserVosPage(page, appUserDTO);
}
/**
* 查询用户详细信息(包含角色和权限)
* @param user 用户对象
* @return 用户信息对象
*/
@Override
public AppUserInfo findUserInfo(AppUser user) {
// 创建用户信息对象
AppUserInfo info = new AppUserInfo();
info.setAppUser(user);
/**
* 查询用户详细信息(包含角色和权限)
*
* @param user 用户对象
* @return 用户信息对象
*/
@Override
public AppUserInfo findUserInfo(AppUser user) {
// 创建用户信息对象
AppUserInfo info = new AppUserInfo();
info.setAppUser(user);
// 设置角色列表(ID数组)
List<Long> roleIds = appRoleService.findRolesByUserId(user.getUserId())
.stream()
.map(AppRole::getRoleId)
.toList();
info.setRoles(ArrayUtil.toArray(roleIds, Long.class));
// 设置角色列表(ID数组)
List<Long> roleIds = appRoleService.findRolesByUserId(user.getUserId())
.stream()
.map(AppRole::getRoleId)
.toList();
info.setRoles(ArrayUtil.toArray(roleIds, Long.class));
// 设置权限列表(暂为空)
Set<String> permissions = new HashSet<>();
info.setPermissions(ArrayUtil.toArray(permissions, String.class));
return info;
}
// 设置权限列表(暂为空)
Set<String> permissions = new HashSet<>();
info.setPermissions(ArrayUtil.toArray(permissions, String.class));
return info;
}
/**
* 更新用户个人信息
* @param userDTO 用户数据传输对象
* @return 操作结果
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username")
public R updateUserInfo(AppUserDTO userDTO) {
// 获取当前登录用户
PigxUser user = SecurityUtils.getUser();
/**
* 更新用户个人信息
*
* @param userDTO 用户数据传输对象
* @return 操作结果
*/
@Override
@CacheEvict(value = CacheConstants.USER_DETAILS_MINI, key = "#userDTO.username")
public R updateUserInfo(AppUserDTO userDTO) {
// 获取当前登录用户
PigxUser user = SecurityUtils.getUser();
// C端客户修改手机号需要验证短信验证码
if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDTO.getPhone())) {
// 构建验证码缓存key
String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT
+ userDTO.getPhone();
// 获取缓存中的验证码
String codeObj = RedisUtils.get(key);
// C端客户修改手机号需要验证短信验证码
if (UserTypeEnum.TOC.getStatus().equals(user.getUserType()) && StrUtil.isNotBlank(userDTO.getPhone())) {
// 构建验证码缓存key
String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT
+ userDTO.getPhone();
// 获取缓存中的验证码
String codeObj = RedisUtils.get(key);
// 验证码不匹配,返回错误
if (!userDTO.getMobileCode().equals(codeObj)) {
return R.failed("验证码错误");
}
}
// 验证码不匹配,返回错误
if (!userDTO.getMobileCode().equals(codeObj)) {
return R.failed("验证码错误");
}
}
// 更新密码(如果提供了新密码)
if (StrUtil.isNotBlank(userDTO.getPassword())) {
userDTO.setPassword(ENCODER.encode(userDTO.getPassword()));
}
// 更新密码(如果提供了新密码)
if (StrUtil.isNotBlank(userDTO.getPassword())) {
userDTO.setPassword(ENCODER.encode(userDTO.getPassword()));
}
// 获取原用户信息并更新
AppUser appUser = baseMapper.selectById(userDTO.getUserId());
BeanUtils.copyProperties(userDTO, appUser);
// 获取原用户信息并更新
AppUser appUser = baseMapper.selectById(userDTO.getUserId());
BeanUtils.copyProperties(userDTO, appUser);
// 清除以手机号为key的用户缓存
cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(user.getPhone());
return R.ok(this.updateById(appUser));
}
// 清除以手机号为key的用户缓存
cacheManager.getCache(CacheConstants.USER_DETAILS_MINI).evict(user.getPhone());
return R.ok(this.updateById(appUser));
}
/**
* 根据用户ID查询用户视图对象
* @param userId 用户ID
* @return 用户视图对象
*/
@Override
public AppUserVO selectUserVoById(Long userId) {
return baseMapper.getUserVoById(userId);
}
/**
* 根据用户ID查询用户视图对象
*
* @param userId 用户ID
* @return 用户视图对象
*/
@Override
public AppUserVO selectUserVoById(Long userId) {
return baseMapper.getUserVoById(userId);
}
/**
* 批量删除用户
* @param ids 用户ID数组
* @return 删除结果
*/
@Override
public Boolean deleteAppUserByIds(Long[] ids) {
// 获取缓存对象
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS_MINI);
// 清除用户缓存
for (AppUser appUser : baseMapper.selectByIds(CollUtil.toList(ids))) {
cache.evict(appUser.getUsername());
}
/**
* 批量删除用户
*
* @param ids 用户ID数组
* @return 删除结果
*/
@Override
public Boolean deleteAppUserByIds(Long[] ids) {
// 获取缓存对象
Cache cache = cacheManager.getCache(CacheConstants.USER_DETAILS_MINI);
// 清除用户缓存
for (AppUser appUser : baseMapper.selectByIds(CollUtil.toList(ids))) {
cache.evict(appUser.getUsername());
}
// 删除用户角色关联关系
this.appUserRoleService
.remove(Wrappers.<AppUserRole>lambdaQuery().in(AppUserRole::getUserId, CollUtil.toList(ids)));
// 删除用户角色关联关系
this.appUserRoleService
.remove(Wrappers.<AppUserRole>lambdaQuery().in(AppUserRole::getUserId, CollUtil.toList(ids)));
// 删除用户记录
this.removeBatchByIds(CollUtil.toList(ids));
// 删除用户记录
this.removeBatchByIds(CollUtil.toList(ids));
return Boolean.TRUE;
}
return Boolean.TRUE;
}
/**
* 注册APP用户
* @param appUser 用户数据传输对象
* @return 操作结果
*/
@Override
public R registerAppUser(AppUserDTO appUser) {
// 检查手机号是否已被注册
List<AppUser> appUserList = baseMapper
.selectList(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getPhone, appUser.getPhone()));
/**
* 注册APP用户
*
* @param appUser 用户数据传输对象
* @return 操作结果
*/
@Override
public R registerAppUser(AppUserDTO appUser) {
// 检查手机号是否已被注册
List<AppUser> appUserList = baseMapper
.selectList(Wrappers.<AppUser>lambdaQuery().eq(AppUser::getPhone, appUser.getPhone()));
if (CollUtil.isNotEmpty(appUserList)) {
return R.failed("手机号已注册,请使用验证码直接登录");
}
if (CollUtil.isNotEmpty(appUserList)) {
return R.failed("手机号已注册,请使用验证码直接登录");
}
// 验证短信验证码
String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT
+ appUser.getPhone();
String codeObj = RedisUtils.get(key);
// 验证短信验证码
String key = CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.APPSMS.getType() + StringPool.AT
+ appUser.getPhone();
String codeObj = RedisUtils.get(key);
if (!appUser.getMobileCode().equals(codeObj)) {
return R.failed("验证码错误");
}
if (!appUser.getMobileCode().equals(codeObj)) {
return R.failed("验证码错误");
}
// 创建用户并保存
AppUser app = new AppUser();
BeanUtils.copyProperties(appUser, app);
appUser.setUsername(app.getPhone()); // 默认使用手机号作为用户名
appUser.setDelFlag(CommonConstants.STATUS_NORMAL);
appUser.setPassword(ENCODER.encode(appUser.getPassword()));
baseMapper.insert(appUser);
return null;
}
// 创建用户并保存
AppUser app = new AppUser();
BeanUtils.copyProperties(appUser, app);
appUser.setUsername(app.getPhone()); // 默认使用手机号作为用户名
appUser.setDelFlag(CommonConstants.STATUS_NORMAL);
appUser.setPassword(ENCODER.encode(appUser.getPassword()));
baseMapper.insert(appUser);
return null;
}
/**
* 导入用户(从Excel导入)
* @param excelVOList Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@Override
public R importUser(List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
// 获取通用校验失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
/**
* 导入用户(从Excel导入)
*
* @param excelVOList Excel数据列表
* @param bindingResult 数据校验结果
* @return 导入结果
*/
@Override
public R importUser(List<AppUserExcelVO> excelVOList, BindingResult bindingResult) {
// 获取通用校验失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 获取现有用户和角色列表,用于校验
List<AppUser> userList = this.list();
List<AppRole> roleList = appRoleService.list();
// 获取现有用户和角色列表,用于校验
List<AppUser> userList = this.list();
List<AppRole> roleList = appRoleService.list();
// 遍历Excel数据进行处理
for (AppUserExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 遍历Excel数据进行处理
for (AppUserExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 校验用户名是否已存在
boolean exsitUserName = userList.stream()
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
// 校验用户名是否已存在
boolean exsitUserName = userList.stream()
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_USER_USERNAME_EXISTING, excel.getUsername()));
}
// 校验角色名称是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<AppRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.toList();
// 校验角色名称是否合法
List<String> roleNameList = StrUtil.split(excel.getRoleNameList(), StrUtil.COMMA);
List<AppRole> roleCollList = roleList.stream()
.filter(role -> roleNameList.stream().anyMatch(name -> role.getRoleName().equals(name)))
.toList();
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(AppErrorCodes.APP_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
// 数据合法时执行插入
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, roleCollList);
}
else {
// 记录不合法数据的错误信息
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
// 数据合法时执行插入
if (CollUtil.isEmpty(errorMsg)) {
insertExcelUser(excel, roleCollList);
} else {
// 记录不合法数据的错误信息
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
// 存在错误信息时返回失败
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED));
}
// 存在错误信息时返回失败
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(AppErrorCodes.APP_USER_IMPORT_SUCCEED));
}
/**
* 插入Excel导入的用户数据
* @param excel Excel用户数据
* @param roleCollList 角色列表
*/
private void insertExcelUser(AppUserExcelVO excel, List<AppRole> roleCollList) {
// 创建用户DTO并设置基本信息
AppUserDTO userDTO = new AppUserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入时初始密码设置为手机号
userDTO.setPassword(userDTO.getPhone());
/**
* 插入Excel导入的用户数据
*
* @param excel Excel用户数据
* @param roleCollList 角色列表
*/
private void insertExcelUser(AppUserExcelVO excel, List<AppRole> roleCollList) {
// 创建用户DTO并设置基本信息
AppUserDTO userDTO = new AppUserDTO();
userDTO.setUsername(excel.getUsername());
userDTO.setPhone(excel.getPhone());
userDTO.setNickname(excel.getNickname());
userDTO.setName(excel.getName());
userDTO.setEmail(excel.getEmail());
// 批量导入时初始密码设置为手机号
userDTO.setPassword(userDTO.getPhone());
// 获取角色ID列表
List<Long> roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList();
userDTO.setRole(roleIdList);
// 获取角色ID列表
List<Long> roleIdList = roleCollList.stream().map(AppRole::getRoleId).toList();
userDTO.setRole(roleIdList);
// 保存用户
this.saveUser(userDTO);
}
// 保存用户
this.saveUser(userDTO);
}
}
@@ -26,9 +26,11 @@ import com.pig4cloud.pigx.admin.api.entity.SysTenant;
import com.pig4cloud.pigx.admin.api.feign.RemoteClientDetailsService;
import com.pig4cloud.pigx.admin.api.feign.RemoteTenantService;
import com.pig4cloud.pigx.admin.api.vo.TokenVO;
import com.pig4cloud.pigx.auth.support.core.AuthErrorCodes;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.core.util.RetOps;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
@@ -48,6 +50,7 @@ import org.springframework.http.HttpStatus;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.authentication.event.LogoutSuccessEvent;
import org.springframework.security.oauth2.core.OAuth2AccessToken;
import org.springframework.security.oauth2.core.OAuth2ErrorCodes;
import org.springframework.security.oauth2.core.endpoint.OAuth2ParameterNames;
import org.springframework.security.oauth2.server.authorization.OAuth2Authorization;
import org.springframework.security.oauth2.server.authorization.OAuth2AuthorizationService;
@@ -111,7 +114,8 @@ public class PigxTokenEndpoint {
@RequestParam(OAuth2ParameterNames.STATE) String state) {
SysOauthClientDetails clientDetails = RetOps.of(clientDetailsService.getClientDetailsById(clientId))
.getData()
.orElseThrow(() -> new OAuthClientException("clientId 不合法"));
.orElseThrow(() -> new OAuthClientException(OAuth2ErrorCodes.INVALID_CLIENT,
MsgUtils.getMessage(AuthErrorCodes.AUTH_CLIENT_INVALID)));
Set<String> authorizedScopes = StringUtils.commaDelimitedListToSet(clientDetails.getScope());
// Note: XSS prevention is handled by FreeMarker template using ?html directive
@@ -0,0 +1,18 @@
package com.pig4cloud.pigx.auth.support.core;
/**
* Auth 模块错误编码
*
* @author lengleng
* @date 2022/3/30
*/
public interface AuthErrorCodes {
// === 验证码相关 ===
String AUTH_CAPTCHA_EMPTY = "auth.captcha.empty";
String AUTH_CAPTCHA_INVALID = "auth.captcha.invalid";
// === 客户端相关 ===
String AUTH_CLIENT_INVALID = "auth.client.invalid";
}
@@ -12,11 +12,13 @@ import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.anji.captcha.model.vo.CaptchaVO;
import com.anji.captcha.service.CaptchaService;
import com.pig4cloud.pigx.auth.support.core.AuthErrorCodes;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.CaptchaFlagTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ValidateCodeException;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.SpringContextHolder;
import com.pig4cloud.pigx.common.core.util.WebUtils;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
@@ -99,7 +101,7 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
String code = request.getParameter("code");
if (StrUtil.isBlank(code)) {
throw new ValidateCodeException("验证码不能为空");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_EMPTY));
}
String randomStr = request.getParameter("randomStr");
@@ -117,30 +119,30 @@ public class ValidateCodeFilter extends OncePerRequestFilter {
vo.setCaptchaVerification(code);
vo.setCaptchaType(randomStr);
if (!captchaService.verification(vo).isSuccess()) {
throw new ValidateCodeException("验证码不能为空");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_EMPTY));
}
return;
}
String key = CacheConstants.DEFAULT_CODE_KEY + randomStr;
if (!RedisUtils.hasKey(key)) {
throw new ValidateCodeException("验证码不合法");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_INVALID));
}
String codeObj = RedisUtils.get(key);
if (codeObj == null) {
throw new ValidateCodeException("验证码不合法");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_INVALID));
}
if (StrUtil.isBlank(codeObj)) {
RedisUtils.delete(key);
throw new ValidateCodeException("验证码不合法");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_INVALID));
}
if (!StrUtil.equals(codeObj, code)) {
RedisUtils.delete(key);
throw new ValidateCodeException("验证码不合法");
throw new ValidateCodeException(MsgUtils.getMessage(AuthErrorCodes.AUTH_CAPTCHA_INVALID));
}
RedisUtils.delete(key);
@@ -0,0 +1,5 @@
# Auth Module i18n Messages - English
# Captcha related
auth.captcha.empty=Captcha cannot be empty
auth.captcha.invalid=Invalid captcha
auth.client.invalid=Invalid client
@@ -0,0 +1,5 @@
# Auth \u6A21\u5757\u56FD\u9645\u5316\u6D88\u606F - \u4E2D\u6587
# \u9A8C\u8BC1\u7801\u76F8\u5173
auth.captcha.empty=\u9A8C\u8BC1\u7801\u4E0D\u80FD\u4E3A\u7A7A
auth.captcha.invalid=\u9A8C\u8BC1\u7801\u4E0D\u5408\u6CD5
auth.client.invalid=\u65E0\u6548\u7684\u5BA2\u6237\u7AEF
@@ -17,25 +17,149 @@
package com.pig4cloud.pigx.common.core.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.util.ResourceUtils;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.regex.Pattern;
/**
* @author lengleng
* @date 2018/11/14
* @author Hccake
* @date 2025-12-12
* <p>
* 国际化配置
* 国际化配置 - 支持多 JAR 包扫描
*/
@Slf4j
@Configuration
public class MessageSourceConfiguration {
@Bean
public MessageSource pigxMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename("classpath:i18n/messages");
return messageSource;
}
/**
* 创建并配置国际化消息源Bean
*
* @return 配置好的消息源实例,支持通配符资源加载
*/
@Bean
public MessageSource pigxMessageSource() {
WildcardReloadableResourceBundleMessageSource messageSource = new WildcardReloadableResourceBundleMessageSource();
// 设置基础包名,支持通配符扫描多个 JAR
messageSource.setBasename("i18n/messages");
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3600);
return messageSource;
}
/**
* 支持 classpath*: 通配符的 MessageSource 实现 能够扫描所有 JAR 包中的 i18n 资源文件
*/
@Slf4j
static class WildcardReloadableResourceBundleMessageSource extends ReloadableResourceBundleMessageSource {
private static final String PROPERTIES_SUFFIX = ".properties";
private final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
private static final Pattern LOCALE_PROPERTIES_FILE_NAME_PATTERN = Pattern.compile(".*_([a-z]{2}(_[A-Z]{2})?(_[A-Z]+)?)\\.properties$");
public WildcardReloadableResourceBundleMessageSource() {
super.setResourceLoader(this.resolver);
}
/**
* 计算给定bundle基名和Locale的所有文件名。会计算指定Locale、系统Locale(如果适用)和默认文件的文件名。
* 当基名包含通配符时,会移除基名并添加通配符匹配到的资源文件路径。
*
* @param basename bundle的基名
* @param locale 区域设置
* @return 要检查的文件名列表
* @see #setFallbackToSystemLocale
* @see #calculateFilenamesForLocale
*/
@Override
protected List<String> calculateAllFilenames(String basename, Locale locale) {
// 父类默认的方法会将 basename 也放入 filenames 列表
List<String> filenames = super.calculateAllFilenames(basename, locale);
// 当 basename 有匹配符时,从 filenames 中移除,否则扫描文件将抛出 Illegal char <*> 的异常
if (containsWildcard(basename)) {
filenames.remove(basename);
try {
Resource[] resources = getResources(basename);
for (Resource resource : resources) {
String resourceUriStr = resource.getURI().toString();
// 根据通配符匹配到的多个 basename 对应的文件添加到文件列表末尾,作为兜底匹配
if (!LOCALE_PROPERTIES_FILE_NAME_PATTERN.matcher(resourceUriStr).matches()) {
String sourcePath = resourceUriStr.replace(PROPERTIES_SUFFIX, "");
filenames.add(sourcePath);
}
}
} catch (IOException ex) {
log.error("读取国际化信息文件异常", ex);
}
}
return filenames;
}
/**
* 计算指定基名和区域设置的资源文件名列表
*
* @param basename 资源文件基名
* @param locale 区域设置
* @return 存在的资源文件名列表(不包含.properties后缀)
*/
@Override
protected List<String> calculateFilenamesForLocale(String basename, Locale locale) {
// 资源文件名
List<String> fileNames = new ArrayList<>();
// 获取到待匹配的国际化信息文件名集合
List<String> matchFilenames = super.calculateFilenamesForLocale(basename, locale);
for (String matchFilename : matchFilenames) {
try {
Resource[] resources = getResources(matchFilename);
for (Resource resource : resources) {
if (resource.exists()) {
String sourcePath = resource.getURI().toString().replace(PROPERTIES_SUFFIX, "");
fileNames.add(sourcePath);
}
}
} catch (IOException ex) {
log.error("读取国际化信息文件异常", ex);
}
}
return fileNames;
}
/**
* 根据资源路径模式获取资源数组
*
* @param resourceLocationPattern 资源路径模式(支持用"."表示文件层级)
* @return 匹配的资源数组
* @throws IOException 获取资源过程中发生IO异常时抛出
*/
private Resource[] getResources(String resourceLocationPattern) throws IOException {
// 支持用 . 表示文件层级
resourceLocationPattern = resourceLocationPattern.replace(".", "/");
return this.resolver.getResources("classpath*:" + resourceLocationPattern + PROPERTIES_SUFFIX);
}
/**
* 检查字符串是否包含通配符
*
* @param str 要检查的字符串
* @return 如果字符串包含通配符返回true,否则返回false
*/
private boolean containsWildcard(String str) {
if (str.startsWith(ResourceUtils.CLASSPATH_URL_PREFIX)) {
str = str.substring(ResourceUtils.CLASSPATH_URL_PREFIX.length());
}
return str.contains("*");
}
}
}
@@ -1,118 +0,0 @@
package com.pig4cloud.pigx.common.core.exception;
/**
* 错误编码
*
* @author lengleng
* @date 2022/3/30
*/
public interface ErrorCodes {
/**
* 系统编码错误
*/
String SYS_PARAM_CONFIG_ERROR = "sys.param.config.error";
/**
* 系统内置参数不能删除
*/
String SYS_PARAM_DELETE_SYSTEM = "sys.param.delete.system";
/**
* 用户已存在
*/
String SYS_USER_USERNAME_EXISTING = "sys.user.username.existing";
/**
* 用户已存在
*/
String SYS_USER_PHONE_EXISTING = "sys.user.phone.existing";
/**
* 用户原密码错误,修改失败
*/
String SYS_USER_UPDATE_PASSWORDERROR = "sys.user.update.passwordError";
/**
* 用户信息为空
*/
String SYS_USER_USERINFO_EMPTY = "sys.user.userInfo.empty";
/**
* 获取当前用户信息失败
*/
String SYS_USER_QUERY_ERROR = "sys.user.query.error";
String SYS_USER_IMPORT_SUCCEED = "sys.user.import.succeed";
/**
* 部门名称不存在
*/
String SYS_DEPT_DEPTNAME_INEXISTENCE = "sys.dept.deptName.inexistence";
/**
* 岗位名称不存在
*/
String SYS_POST_POSTNAME_INEXISTENCE = "sys.post.postName.inexistence";
/**
* 岗位名称或编码已经存在
*/
String SYS_POST_NAMEORCODE_EXISTING = "sys.post.nameOrCode.existing";
/**
* 角色名称不存在
*/
String SYS_ROLE_ROLENAME_INEXISTENCE = "sys.role.roleName.inexistence";
/**
* 角色名或角色编码已经存在
*/
String SYS_ROLE_NAMEORCODE_EXISTING = "sys.role.nameOrCode.existing";
/**
* 菜单存在下级节点 删除失败
*/
String SYS_MENU_DELETE_EXISTING = "sys.menu.delete.existing";
/**
* 系统内置字典不允许删除
*/
String SYS_DICT_DELETE_SYSTEM = "sys.dict.delete.system";
/**
* 系统内置字典不能修改
*/
String SYS_DICT_UPDATE_SYSTEM = "sys.dict.update.system";
/**
* 验证码发送频繁
*/
String SYS_APP_SMS_OFTEN = "sys.app.sms.often";
/**
* 系统应用短信错误编码
*/
String SYS_APP_SMS_ERROR = "sys.app.sms.error";
/**
* 手机号未注册
*/
String SYS_APP_PHONE_UNREGISTERED = "sys.app.phone.unregistered";
/**
* 企微调用接口错误
*/
String SYS_CONNECT_CP_DEPT_SYNC_ERROR = "sys.connect.cp.dept.sync.error";
/**
* 企微调用接口错误
*/
String SYS_CONNECT_CP_USER_SYNC_ERROR = "sys.connect.cp.user.sync.error";
/**
* 用户信息为空
*/
String APP_USER_USERINFO_EMPTY = "app.user.userInfo.empty";
}
@@ -2,6 +2,8 @@ package com.pig4cloud.pigx.common.core.util;
import lombok.experimental.UtilityClass;
import org.springframework.context.MessageSource;
import org.springframework.context.NoSuchMessageException;
import org.springframework.context.i18n.LocaleContextHolder;
import java.util.Locale;
@@ -14,34 +16,55 @@ import java.util.Locale;
@UtilityClass
public class MsgUtils {
/**
* 通过code 获取中文错误信息
* @param code
* @return
*/
public String getMessage(String code) {
MessageSource messageSource = SpringContextHolder.getBean("pigxMessageSource");
return messageSource.getMessage(code, null, Locale.CHINA);
}
/**
* 通过code 获取中文错误信息
*
* @param code
* @return
*/
public String getMessage(String code) {
MessageSource messageSource = SpringContextHolder.getBean("pigxMessageSource");
return resolveMessage(messageSource, code, null);
}
/**
* 通过code 和参数获取中文错误信息
* @param code
* @return
*/
public String getMessage(String code, Object... objects) {
MessageSource messageSource = SpringContextHolder.getBean("pigxMessageSource");
return messageSource.getMessage(code, objects, Locale.CHINA);
}
/**
* 通过code 和参数获取中文错误信息
*
* @param code
* @return
*/
public String getMessage(String code, Object... objects) {
MessageSource messageSource = SpringContextHolder.getBean("pigxMessageSource");
return resolveMessage(messageSource, code, objects);
}
/**
* security 通过code 和参数获取中文错误信息
* @param code
* @return
*/
public String getSecurityMessage(String code, Object... objects) {
MessageSource messageSource = SpringContextHolder.getBean("securityMessageSource");
return messageSource.getMessage(code, objects, Locale.CHINA);
}
/**
* 通过错误码和参数获取安全相关的中文错误信息
*
* @param code 错误码
* @param objects 格式化参数
* @return 格式化后的错误信息
*/
public String getSecurityMessage(String code, Object... objects) {
MessageSource messageSource = SpringContextHolder.getBean("securityMessageSource");
return resolveMessage(messageSource, code, objects);
}
/**
* 解析消息,根据当前区域设置获取消息,如果找不到消息则使用中国区域设置重试
*
* @param messageSource 消息源
* @param code 消息代码
* @param objects 消息参数
* @return 解析后的消息
*/
private String resolveMessage(MessageSource messageSource, String code, Object[] objects) {
Locale locale = LocaleContextHolder.getLocale();
try {
return messageSource.getMessage(code, objects, locale);
} catch (NoSuchMessageException ex) {
return messageSource.getMessage(code, objects, Locale.CHINA);
}
}
}
@@ -22,8 +22,6 @@ import org.springframework.context.annotation.Bean;
import org.springframework.context.support.ReloadableResourceBundleMessageSource;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.util.Locale;
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.SERVLET;
/**
@@ -35,12 +33,14 @@ import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebA
@ConditionalOnWebApplication(type = SERVLET)
public class PigxSecurityMessageSourceConfiguration implements WebMvcConfigurer {
@Bean
public MessageSource securityMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.addBasenames("classpath:errors/messages");
messageSource.setDefaultLocale(Locale.CHINA);
return messageSource;
}
@Bean
public MessageSource securityMessageSource() {
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.addBasenames("classpath:errors/messages");
//messageSource.setDefaultLocale(Locale.CHINA); 没有国际化的需求可以关闭
messageSource.setDefaultEncoding("UTF-8");
messageSource.setCacheSeconds(3600);
return messageSource;
}
}
@@ -9,6 +9,14 @@ import org.springframework.security.oauth2.core.OAuth2Error;
*/
public class OAuthClientException extends OAuth2AuthenticationException {
public OAuthClientException(String errorCode, String description) {
super(new OAuth2Error(errorCode, description, null), description);
}
public OAuthClientException(String errorCode, String description, Throwable cause) {
super(new OAuth2Error(errorCode, description, null), cause);
}
/**
* Constructs a <code>ScopeException</code> with the specified message.
* @param msg the detail message.
@@ -0,0 +1,97 @@
package com.pig4cloud.pigx.admin.api.constant;
/**
* UPMS 模块错误编码
*
* @author lengleng
* @date 2022/3/30
*/
public interface UpmsErrorCodes {
// === 用户相关 ===
String SYS_USER_USERNAME_EXISTING = "sys.user.username.existing";
String SYS_USER_PHONE_EXISTING = "sys.user.phone.existing";
String SYS_USER_UPDATE_PASSWORDERROR = "sys.user.update.passwordError";
String SYS_USER_OLD_PASSWORD_EMPTY = "sys.user.oldPassword.empty";
String SYS_USER_NEW_PASSWORD_EMPTY = "sys.user.newPassword.empty";
String SYS_USER_UNBIND_TYPE_NOT_FOUND = "sys.user.unbind.type.notFound";
String SYS_USER_PASSWORD_MISMATCH = "sys.user.password.mismatch";
String SYS_USER_PASSWORD_SAME = "sys.user.password.same";
String SYS_USER_USERINFO_EMPTY = "sys.user.userInfo.empty";
String SYS_USER_QUERY_ERROR = "sys.user.query.error";
String SYS_USER_IMPORT_SUCCEED = "sys.user.import.succeed";
// === 部门相关 ===
String SYS_DEPT_DEPTNAME_INEXISTENCE = "sys.dept.deptName.inexistence";
String SYS_DEPT_IMPORT_SUCCEED = "sys.dept.import.succeed";
String SYS_DEPT_SWITCH_SUCCEED = "sys.dept.switch.succeed";
// === 岗位相关 ===
String SYS_POST_POSTNAME_INEXISTENCE = "sys.post.postName.inexistence";
String SYS_POST_NAMEORCODE_EXISTING = "sys.post.nameOrCode.existing";
// === 角色相关 ===
String SYS_ROLE_ROLENAME_INEXISTENCE = "sys.role.roleName.inexistence";
String SYS_ROLE_NAMEORCODE_EXISTING = "sys.role.nameOrCode.existing";
// === 菜单相关 ===
String SYS_MENU_DELETE_EXISTING = "sys.menu.delete.existing";
String SYS_MENU_NOT_FOUND = "sys.menu.notFound";
String SYS_MENU_HOME_SET_SUCCEED = "sys.menu.home.set.succeed";
String SYS_MENU_HOME_CANCEL_SUCCEED = "sys.menu.home.cancel.succeed";
String SYS_MENU_BUTTON_CANNOT_HOME = "sys.menu.button.cannot.home";
// === 字典相关 ===
String SYS_DICT_DELETE_SYSTEM = "sys.dict.delete.system";
String SYS_DICT_UPDATE_SYSTEM = "sys.dict.update.system";
// === 参数相关 ===
String SYS_PARAM_CONFIG_ERROR = "sys.param.config.error";
String SYS_PARAM_DELETE_SYSTEM = "sys.param.delete.system";
String SYS_PARAM_ILLEGAL = "sys.param.illegal";
// === 消息相关 ===
String SYS_MESSAGE_SMS_CHANNEL_MISSING = "sys.message.sms.channel.missing";
String SYS_MESSAGE_CHANNEL_MISSING = "sys.message.channel.missing";
// === 小程序相关 ===
String SYS_MINIAPP_LOGIN_FAILED = "sys.miniapp.login.failed";
// === 系统缓存 ===
String SYS_SYSTEM_CACHE_FETCH_ERROR = "sys.system.cache.fetch.error";
// === 企业微信相关 ===
String SYS_CONNECT_CP_DEPT_SYNC_ERROR = "sys.connect.cp.dept.sync.error";
String SYS_CONNECT_CP_USER_SYNC_ERROR = "sys.connect.cp.user.sync.error";
// === 短信验证相关 (在 UPMS 消息和用户服务中使用) ===
String SYS_APP_SMS_OFTEN = "sys.app.sms.often";
String SYS_APP_SMS_ERROR = "sys.app.sms.error";
String SYS_APP_PHONE_UNREGISTERED = "sys.app.phone.unregistered";
}
@@ -0,0 +1,62 @@
# UPMS Module i18n Messages - English
# User related
sys.user.update.passwordError=Incorrect current password; update failed
sys.user.oldPassword.empty=Current password cannot be empty
sys.user.newPassword.empty=New password cannot be empty
sys.user.unbind.type.notFound=Unknown account type to unbind
sys.user.password.mismatch=Incorrect password
sys.user.password.same=New and old passwords cannot be the same
sys.user.query.error=Failed to fetch current user information
sys.user.import.succeed=User import succeeded; default password is the phone number
sys.user.username.existing=Username {0} already exists
sys.user.phone.existing=Phone number {0} already exists
sys.user.userInfo.empty=User information is empty for {0}
# Department related
sys.dept.deptName.inexistence=Department name {0} does not exist
sys.dept.import.succeed=Department import succeeded
sys.dept.switch.succeed=Department switched successfully
# Post related
sys.post.postName.inexistence=Post name {0} does not exist
sys.post.nameOrCode.existing=Post name or code already exists ({0} {1})
# Role related
sys.role.roleName.inexistence=Role name {0} does not exist
sys.role.nameOrCode.existing=Role name or code already exists ({0} {1})
# Menu related
sys.menu.delete.existing=Menu contains sub-menus; cannot delete
sys.menu.notFound=Menu does not exist
sys.menu.home.set.succeed=Homepage set successfully
sys.menu.home.cancel.succeed=Homepage removed successfully
sys.menu.button.cannot.home=Button-type menu cannot be set as homepage
# Dictionary related
sys.dict.delete.system=Built-in dictionary items cannot be deleted
sys.dict.update.system=Built-in dictionary items cannot be modified
# Parameter related
sys.param.config.error=System parameter configuration error: {0}
sys.param.delete.system=Built-in system parameters cannot be deleted
sys.param.illegal=Invalid parameter
# Message related
sys.message.sms.channel.missing=Send failed; SMS channel configuration not found
sys.message.channel.missing=Send failed; channel configuration not found
# Mini-program related
sys.miniapp.login.failed=WeChat mini-program login failed
# System cache
sys.system.cache.fetch.error=Failed to fetch cache statistics
# WeCom related
sys.connect.cp.dept.sync.error=Failed to fetch WeCom department list
sys.connect.cp.user.sync.error=Failed to fetch WeCom user list
# SMS verification related (used in UPMS message and user services)
sys.app.sms.often=Verification code sent too frequently
sys.app.sms.error=Invalid verification code
sys.app.phone.unregistered=Phone number {0} is not registered
@@ -1,22 +1,62 @@
# UPMS 模块国际化消息 - 中文
# 用户相关
sys.user.update.passwordError=\u539F\u5BC6\u7801\u9519\u8BEF\uFF0C\u4FEE\u6539\u5931\u8D25
sys.user.oldPassword.empty=\u539F\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A
sys.user.newPassword.empty=\u65B0\u5BC6\u7801\u4E0D\u80FD\u4E3A\u7A7A
sys.user.unbind.type.notFound=\u89E3\u7ED1\u8D26\u53F7\u7C7B\u578B\u4E0D\u5B58\u5728
sys.user.password.mismatch=\u5BC6\u7801\u8F93\u5165\u9519\u8BEF
sys.user.password.same=\u65B0\u65E7\u5BC6\u7801\u4E0D\u80FD\u76F8\u540C
sys.user.query.error=\u83B7\u53D6\u5F53\u524D\u7528\u6237\u4FE1\u606F\u5931\u8D25
sys.user.import.succeed=\u7528\u6237\u5BFC\u5165\u6210\u529F\uFF0C\u9ED8\u8BA4\u5BC6\u7801\u4E3A\u624B\u673A\u53F7
sys.user.username.existing={0} \u7528\u6237\u540D\u5DF2\u5B58\u5728
sys.user.phone.existing={0} \u624B\u673A\u53F7\u5DF2\u5B58\u5728
sys.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A
# 部门相关
sys.dept.deptName.inexistence={0} \u90E8\u95E8\u540D\u79F0\u4E0D\u5B58\u5728
sys.dept.import.succeed=\u90E8\u95E8\u5BFC\u5165\u6210\u529F
sys.dept.switch.succeed=\u90E8\u95E8\u5207\u6362\u6210\u529F
# 岗位相关
sys.post.postName.inexistence={0} \u5C97\u4F4D\u540D\u79F0\u4E0D\u5B58\u5728
sys.post.nameOrCode.existing={0} {1} \u5C97\u4F4D\u540D\u6216\u5C97\u4F4D\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
# 角色相关
sys.role.roleName.inexistence={0} \u89D2\u8272\u540D\u79F0\u4E0D\u5B58\u5728
sys.role.nameOrCode.existing={0} {1} \u89D2\u8272\u540D\u6216\u89D2\u8272\u7F16\u7801\u5DF2\u7ECF\u5B58\u5728
sys.param.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u53C2\u6570\u4E0D\u80FD\u5220\u9664
sys.param.config.error={0} \u7CFB\u7EDF\u53C2\u6570\u914D\u7F6E\u9519\u8BEF
# 菜单相关
sys.menu.delete.existing=\u83DC\u5355\u542B\u6709\u4E0B\u7EA7\u4E0D\u80FD\u5220\u9664
sys.menu.notFound=\u83DC\u5355\u4E0D\u5B58\u5728
sys.menu.home.set.succeed=\u8BBE\u7F6E\u9996\u9875\u6210\u529F
sys.menu.home.cancel.succeed=\u53D6\u6D88\u9996\u9875\u6210\u529F
sys.menu.button.cannot.home=\u6309\u94AE\u7C7B\u578B\u4E0D\u80FD\u8BBE\u7F6E\u4E3A\u9996\u9875
# 字典相关
sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664
sys.dict.update.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u4FEE\u6539
# 参数相关
sys.param.config.error={0} \u7CFB\u7EDF\u53C2\u6570\u914D\u7F6E\u9519\u8BEF
sys.param.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u53C2\u6570\u4E0D\u80FD\u5220\u9664
sys.param.illegal=\u975E\u6CD5\u53C2\u6570
# 消息相关
sys.message.sms.channel.missing=\u53D1\u9001\u5931\u8D25\uFF0C\u77ED\u4FE1\u901A\u9053\u914D\u7F6E\u4E0D\u5B58\u5728
sys.message.channel.missing=\u53D1\u9001\u5931\u8D25\uFF0C\u901A\u9053\u914D\u7F6E\u4E0D\u5B58\u5728
# 小程序相关
sys.miniapp.login.failed=\u5FAE\u4FE1\u5C0F\u7A0B\u5E8F\u767B\u5F55\u5931\u8D25
# 系统缓存
sys.system.cache.fetch.error=\u83B7\u53D6\u5F02\u5E38
# 企业微信相关
sys.connect.cp.dept.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u90E8\u95E8\u5217\u8868\u5931\u8D25
sys.connect.cp.user.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237\u5217\u8868\u5931\u8D25
# 短信验证相关 (在 UPMS 消息和用户服务中使用)
sys.app.sms.often=\u9A8C\u8BC1\u7801\u53D1\u9001\u8FC7\u9891\u7E41
sys.app.sms.error=\u9A8C\u8BC1\u7801\u9519\u8BEF
sys.app.phone.unregistered={0} \u624B\u673A\u53F7\u672A\u6CE8\u518C
sys.dict.delete.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u5220\u9664
sys.dict.update.system=\u7CFB\u7EDF\u5185\u7F6E\u5B57\u5178\u9879\u76EE\u4E0D\u80FD\u4FEE\u6539
sys.connect.cp.dept.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u90E8\u95E8\u5217\u8868\u5931\u8D25
sys.connect.cp.user.sync.error=\u83B7\u53D6\u4F01\u4E1A\u5FAE\u4FE1\u7528\u6237\u5217\u8868\u5931\u8D25
app.user.userInfo.empty={0} \u7528\u6237\u4FE1\u606F\u4E3A\u7A7A
@@ -1,5 +1,7 @@
package com.pig4cloud.pigx.admin.controller;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
@@ -22,36 +24,37 @@ import java.util.*;
@SecurityRequirement(name = HttpHeaders.AUTHORIZATION)
public class SysSystemInfoController {
/**
* 缓存监控
* @return R<Object>
*/
@GetMapping("/cache")
public R cache() {
/**
* 缓存监控
*
* @return R<Object>
*/
@GetMapping("/cache")
public R cache() {
Properties info = RedisUtils.execute((RedisCallback<Properties>) RedisServerCommands::info);
Properties commandStats = RedisUtils
.execute((RedisCallback<Properties>) connection -> connection.serverCommands().info("commandstats"));
Object dbSize = RedisUtils.execute((RedisCallback<Object>) RedisServerCommands::dbSize);
if (commandStats == null) {
return R.failed("获取异常");
}
if (commandStats == null) {
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_SYSTEM_CACHE_FETCH_ERROR));
}
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
Map<String, Object> result = new HashMap<>(3);
result.put("info", info);
result.put("dbSize", dbSize);
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
List<Map<String, String>> pieList = new ArrayList<>();
commandStats.stringPropertyNames().forEach(key -> {
Map<String, String> data = new HashMap<>(2);
String property = commandStats.getProperty(key);
data.put("name", StringUtils.removeStart(key, "cmdstat_"));
data.put("value", StringUtils.substringBetween(property, "calls=", ",usec"));
pieList.add(data);
});
result.put("commandStats", pieList);
return R.ok(result);
}
result.put("commandStats", pieList);
return R.ok(result);
}
}
@@ -22,6 +22,7 @@ import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.dto.UserInfo;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
@@ -31,6 +32,7 @@ import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.CheckedException;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
@@ -73,7 +75,7 @@ public class MiniAppLoginHandler extends AbstractLoginHandler {
if (resultJsonObj.containsKey("errcode")) {
log.error("微信小程序登录失败:{}", result);
throw new CheckedException("微信小程序登录失败");
throw new CheckedException(MsgUtils.getMessage(UpmsErrorCodes.SYS_MINIAPP_LOGIN_FAILED));
}
return resultJsonObj.getStr("openid");
@@ -18,6 +18,7 @@ import com.dingtalk.api.response.OapiGettokenResponse;
import com.dingtalk.api.response.OapiUserListidResponse;
import com.dingtalk.api.response.OapiV2DepartmentListsubResponse;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
import com.pig4cloud.pigx.admin.api.entity.SysDept;
import com.pig4cloud.pigx.admin.api.entity.SysSocialDetails;
@@ -28,7 +29,6 @@ import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.admin.service.SysUserService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.RequiredArgsConstructor;
@@ -213,7 +213,7 @@ public class ConnectServiceImpl implements ConnectService {
departList = wxCpService.getDepartmentService().list(null);
} catch (WxErrorException e) {
log.error("获取企业微信部门列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_CONNECT_CP_DEPT_SYNC_ERROR));
}
if (CollUtil.isEmpty(departList)) {
@@ -251,7 +251,7 @@ public class ConnectServiceImpl implements ConnectService {
cpUserList = wxCpService.getUserService().listByDepartment(1L, true, 0);
} catch (WxErrorException e) {
log.error("获取企业微信用户列表失败", e);
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_CONNECT_CP_USER_SYNC_ERROR));
}
if (CollUtil.isEmpty(cpUserList)) {
@@ -30,12 +30,14 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.pig4cloud.pigx.admin.api.constant.OrgTypeEnum;
import com.pig4cloud.pigx.admin.api.constant.PostCodeEnum;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.*;
import com.pig4cloud.pigx.admin.api.utils.DataUtil;
import com.pig4cloud.pigx.admin.api.vo.DeptExcelVO;
import com.pig4cloud.pigx.admin.api.vo.OrgTreeVO;
import com.pig4cloud.pigx.admin.mapper.*;
import com.pig4cloud.pigx.admin.service.SysDeptService;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.datascope.DataScope;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
@@ -59,329 +61,336 @@ import java.util.*;
@AllArgsConstructor
public class SysDeptServiceImpl extends ServiceImpl<SysDeptMapper, SysDept> implements SysDeptService {
private final SysUserMapper userMapper;
private final SysUserMapper userMapper;
private final SysDeptMapper deptMapper;
private final SysDeptMapper deptMapper;
private final SysPostMapper postMapper;
private final SysPostMapper postMapper;
private final SysRoleMapper roleMapper;
private final SysRoleMapper roleMapper;
private final SysUserDeptMapper userDeptMapper;
private final SysUserDeptMapper userDeptMapper;
private final SysUserPostMapper userPostMapper;
private final SysUserPostMapper userPostMapper;
/**
* 删除部门
* @param id 部门 ID
* @return 成功、失败
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendant(id).stream().map(SysDept::getDeptId).toList();
/**
* 删除部门
*
* @param id 部门 ID
* @return 成功、失败
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeDeptById(Long id) {
// 级联删除部门
List<Long> idList = this.listDescendant(id).stream().map(SysDept::getDeptId).toList();
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
Optional.ofNullable(idList).filter(CollUtil::isNotEmpty).ifPresent(this::removeByIds);
return Boolean.TRUE;
}
return Boolean.TRUE;
}
/**
* 查询全部部门树
* @param deptName
* @param parentId
* @return 树 部门名称
*/
@Override
public List<Tree<Long>> selectTree(String deptName, Long parentId) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper
.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 查询数据权限内部门
List<Long> deptOwnIdList = deptMapper
.selectListByScope(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
DataScope.of())
.stream()
.map(SysDept::getDeptId)
.toList();
/**
* 查询全部部门树
*
* @param deptName
* @param parentId
* @return 树 部门名称
*/
@Override
public List<Tree<Long>> selectTree(String deptName, Long parentId) {
// 查询全部部门
List<SysDept> deptAllList = deptMapper
.selectList(Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName));
// 查询数据权限内部门
List<Long> deptOwnIdList = deptMapper
.selectListByScope(
Wrappers.<SysDept>lambdaQuery().like(StrUtil.isNotBlank(deptName), SysDept::getName, deptName),
DataScope.of())
.stream()
.map(SysDept::getDeptId)
.toList();
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder))
.map(dept -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId()));
extra.put("createTime", dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
})
.toList();
// 权限内部门
List<TreeNode<Long>> collect = deptAllList.stream()
.filter(dept -> dept.getDeptId().intValue() != dept.getParentId())
.sorted(Comparator.comparingInt(SysDept::getSortOrder))
.map(dept -> {
TreeNode<Long> treeNode = new TreeNode<>();
treeNode.setId(dept.getDeptId());
treeNode.setParentId(dept.getParentId());
treeNode.setName(dept.getName());
treeNode.setWeight(dept.getSortOrder());
// 有权限不返回标识
Map<String, Object> extra = new HashMap<>(8);
extra.put("isLock", !deptOwnIdList.contains(dept.getDeptId()));
extra.put("createTime", dept.getCreateTime());
treeNode.setExtra(extra);
return treeNode;
})
.toList();
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).toList();
}
// 模糊查询 不组装树结构 直接返回 表格方便编辑
if (StrUtil.isNotBlank(deptName)) {
return collect.stream().map(node -> {
Tree<Long> tree = new Tree<>();
tree.putAll(node.getExtra());
BeanUtils.copyProperties(node, tree);
return tree;
}).toList();
}
return TreeUtil.build(collect, parentId == null ? 0 : parentId);
}
return TreeUtil.build(collect, parentId == null ? 0 : parentId);
}
/**
* 导出部门
* @return
*/
@Override
public List<DeptExcelVO> listExcelVo() {
List<SysDept> list = this.list();
List<DeptExcelVO> deptExcelVos = list.stream().map(item -> {
DeptExcelVO deptExcelVo = new DeptExcelVO();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list()
.stream()
.filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName)
.findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).toList();
return deptExcelVos;
}
/**
* 导出部门
*
* @return
*/
@Override
public List<DeptExcelVO> listExcelVo() {
List<SysDept> list = this.list();
List<DeptExcelVO> deptExcelVos = list.stream().map(item -> {
DeptExcelVO deptExcelVo = new DeptExcelVO();
deptExcelVo.setName(item.getName());
Optional<String> first = this.list()
.stream()
.filter(it -> item.getParentId().equals(it.getDeptId()))
.map(SysDept::getName)
.findFirst();
deptExcelVo.setParentName(first.orElse("根部门"));
deptExcelVo.setSortOrder(item.getSortOrder());
return deptExcelVo;
}).toList();
return deptExcelVos;
}
@Override
public R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
@Override
public R importDept(List<DeptExcelVO> excelVOList, BindingResult bindingResult) {
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
List<SysDept> deptList = this.list();
for (DeptExcelVO item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, "部门导入成功");
}
List<SysDept> deptList = this.list();
for (DeptExcelVO item : excelVOList) {
Set<String> errorMsg = new HashSet<>();
boolean exsitUsername = deptList.stream().anyMatch(sysDept -> item.getName().equals(sysDept.getName()));
if (exsitUsername) {
errorMsg.add("部门名称已经存在");
}
SysDept one = this.getOne(Wrappers.<SysDept>lambdaQuery().eq(SysDept::getName, item.getParentName()));
if (item.getParentName().equals("根部门")) {
one = new SysDept();
one.setDeptId(0L);
}
if (one == null) {
errorMsg.add("上级部门不存在");
}
if (CollUtil.isEmpty(errorMsg)) {
SysDept sysDept = new SysDept();
sysDept.setName(item.getName());
sysDept.setParentId(one.getDeptId());
sysDept.setSortOrder(item.getSortOrder());
baseMapper.insert(sysDept);
} else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(item.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_IMPORT_SUCCEED));
}
/**
* 查询所有子节点 (包含当前节点)
* @param deptId 部门ID 目标部门ID
* @return ID
*/
@Override
public List<SysDept> listDescendant(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
/**
* 查询所有子节点 (包含当前节点)
*
* @param deptId 部门ID 目标部门ID
* @return ID
*/
@Override
public List<SysDept> listDescendant(Long deptId) {
// 查询全部部门
List<SysDept> allDeptList = baseMapper.selectList(Wrappers.emptyWrapper());
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 递归查询所有子节点
List<SysDept> resDeptList = new ArrayList<>();
recursiveDept(allDeptList, deptId, resDeptList);
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList());
return resDeptList;
}
// 添加当前节点
resDeptList.addAll(allDeptList.stream().filter(sysDept -> deptId.equals(sysDept.getDeptId())).toList());
return resDeptList;
}
/**
* 获取部门负责人
* <p>
* 1. 根据dept 查询用户 2. 筛选用户列表中 post
* @param deptId deptId
* @return user id list
*/
@Override
public List<Long> listDeptLeader(Long deptId) {
/**
* 获取部门负责人
* <p>
* 1. 根据dept 查询用户 2. 筛选用户列表中 post
*
* @param deptId deptId
* @return user id list
*/
@Override
public List<Long> listDeptLeader(Long deptId) {
List<SysUserDept> userDeptList = userDeptMapper
.selectList(Wrappers.<SysUserDept>lambdaQuery().eq(SysUserDept::getDeptId, deptId));
if (CollUtil.isEmpty(userDeptList)) {
return null;
}
List<SysUserDept> userDeptList = userDeptMapper
.selectList(Wrappers.<SysUserDept>lambdaQuery().eq(SysUserDept::getDeptId, deptId));
if (CollUtil.isEmpty(userDeptList)) {
return null;
}
SysPost deptLeader = postMapper
.selectOne(Wrappers.<SysPost>lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode()));
if (deptLeader == null) {
return null;
}
SysPost deptLeader = postMapper
.selectOne(Wrappers.<SysPost>lambdaQuery().eq(SysPost::getPostCode, PostCodeEnum.TEAM_LEADER.getCode()));
if (deptLeader == null) {
return null;
}
List<Long> userIdList = userDeptList.stream().map(SysUserDept::getUserId).toList();
return userPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery().in(SysUserPost::getUserId, userIdList))
.stream()
.filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId()))
.map(SysUserPost::getUserId)
.toList();
}
List<Long> userIdList = userDeptList.stream().map(SysUserDept::getUserId).toList();
return userPostMapper.selectList(Wrappers.<SysUserPost>lambdaQuery().in(SysUserPost::getUserId, userIdList))
.stream()
.filter(post -> Objects.equals(post.getPostId(), deptLeader.getPostId()))
.map(SysUserPost::getUserId)
.toList();
}
/**
* 根据父部门ID和类型获取组织树
* @param parentDeptId 父部门ID
* @param type 类型
* @return 组织树信息
*/
public Map<String, Object> listOrgTree(Long parentDeptId, String type) {
/**
* 根据父部门ID和类型获取组织树
*
* @param parentDeptId 父部门ID
* @param type 类型
* @return 组织树信息
*/
public Map<String, Object> listOrgTree(Long parentDeptId, String type) {
List<OrgTreeVO> orgs = new LinkedList<>();
List<OrgTreeVO> orgs = new LinkedList<>();
if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) {
// 角色
List<SysRole> roleList = roleMapper.selectList(Wrappers.emptyWrapper());
if (StrUtil.equals(type, OrgTypeEnum.ROLE.getType())) {
// 角色
List<SysRole> roleList = roleMapper.selectList(Wrappers.emptyWrapper());
roleList.forEach(role -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(role.getRoleId());
orgTreeVo.setName(role.getRoleName());
orgTreeVo.setType(OrgTypeEnum.ROLE.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
roleList.forEach(role -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(role.getRoleId());
orgTreeVo.setName(role.getRoleName());
orgTreeVo.setType(OrgTypeEnum.ROLE.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
return Dict.create()
.set("roleList", orgs)
.set("postList", new ArrayList<>())
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
return Dict.create()
.set("roleList", orgs)
.set("postList", new ArrayList<>())
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
if (StrUtil.equals(type, OrgTypeEnum.POST.getType())) {
// 角色
List<SysPost> postList = postMapper.selectList(Wrappers.emptyWrapper());
if (StrUtil.equals(type, OrgTypeEnum.POST.getType())) {
// 角色
List<SysPost> postList = postMapper.selectList(Wrappers.emptyWrapper());
postList.forEach(post -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(post.getPostId());
orgTreeVo.setName(post.getPostName());
orgTreeVo.setType(OrgTypeEnum.POST.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
postList.forEach(post -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(post.getPostId());
orgTreeVo.setName(post.getPostName());
orgTreeVo.setType(OrgTypeEnum.POST.getType());
orgTreeVo.setSelected(false);
orgs.add(orgTreeVo);
});
return Dict.create()
.set("roleList", new ArrayList<>())
.set("postList", orgs)
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
return Dict.create()
.set("roleList", new ArrayList<>())
.set("postList", orgs)
.set("childDepartments", orgs)
.set("employees", new ArrayList<>());
}
Dict dict = Dict.create()
.set("titleDepartments", new ArrayList<>())
.set("roleList", new ArrayList<>())
.set("postList", new ArrayList<>())
.set("employees", new ArrayList<>());
Dict dict = Dict.create()
.set("titleDepartments", new ArrayList<>())
.set("roleList", new ArrayList<>())
.set("postList", new ArrayList<>())
.set("employees", new ArrayList<>());
List<SysDept> deptList = this.list(
Wrappers.<SysDept>lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId));
List<SysDept> deptList = this.list(
Wrappers.<SysDept>lambdaQuery().eq(Objects.nonNull(parentDeptId), SysDept::getParentId, parentDeptId));
// 查询所有部门及员工
List<OrgTreeVO> deptVoList = new ArrayList<>();
deptList.forEach(dept -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(dept.getDeptId());
orgTreeVo.setName(dept.getName());
orgTreeVo.setType(OrgTypeEnum.DEPT.getType());
orgTreeVo.setSelected(false);
deptVoList.add(orgTreeVo);
});
dict.set("childDepartments", deptVoList);
// 查询所有部门及员工
List<OrgTreeVO> deptVoList = new ArrayList<>();
deptList.forEach(dept -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(dept.getDeptId());
orgTreeVo.setName(dept.getName());
orgTreeVo.setType(OrgTypeEnum.DEPT.getType());
orgTreeVo.setSelected(false);
deptVoList.add(orgTreeVo);
});
dict.set("childDepartments", deptVoList);
if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) {
if (!StrUtil.equals(type, OrgTypeEnum.DEPT.getType())) {
List<OrgTreeVO> userVoList = new ArrayList<>();
List<OrgTreeVO> userVoList = new ArrayList<>();
MPJLambdaWrapper<SysUser> userQuery = new MPJLambdaWrapper<>();
userQuery.selectAll(SysUser.class)
.leftJoin(SysUserDept.class, SysUserDept::getUserId, SysUser::getUserId)
.eq(SysUserDept::getDeptId, parentDeptId);
MPJLambdaWrapper<SysUser> userQuery = new MPJLambdaWrapper<>();
userQuery.selectAll(SysUser.class)
.leftJoin(SysUserDept.class, SysUserDept::getUserId, SysUser::getUserId)
.eq(SysUserDept::getDeptId, parentDeptId);
List<SysUser> userList = userMapper.selectJoinList(userQuery);
List<SysUser> userList = userMapper.selectJoinList(userQuery);
userList.forEach(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
userVoList.add(orgTreeVo);
});
dict.set("employees", userVoList);
}
userList.forEach(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
userVoList.add(orgTreeVo);
});
dict.set("employees", userVoList);
}
if (parentDeptId > 0) {
List<SysDept> allDept = this.list();
List<SysDept> depts = DataUtil.selectParentByDept(parentDeptId, allDept);
dict.set("titleDepartments", CollUtil.reverse(depts));
}
if (parentDeptId > 0) {
List<SysDept> allDept = this.list();
List<SysDept> depts = DataUtil.selectParentByDept(parentDeptId, allDept);
dict.set("titleDepartments", CollUtil.reverse(depts));
}
return dict;
}
return dict;
}
/**
* 模糊搜索用户
* @param username 用户名/拼音/首字母
* @return 匹配到的用户
*/
public List<OrgTreeVO> getOrgTreeUser(String username) {
return userMapper.selectList(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, username))
.stream()
.map(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
return orgTreeVo;
})
.toList();
}
/**
* 模糊搜索用户
*
* @param username 用户名/拼音/首字母
* @return 匹配到的用户
*/
public List<OrgTreeVO> getOrgTreeUser(String username) {
return userMapper.selectList(Wrappers.<SysUser>lambdaQuery().like(SysUser::getUsername, username))
.stream()
.map(user -> {
OrgTreeVO orgTreeVo = new OrgTreeVO();
orgTreeVo.setId(user.getUserId());
orgTreeVo.setName(user.getUsername());
orgTreeVo.setType(OrgTypeEnum.USER.getType());
orgTreeVo.setSelected(false);
orgTreeVo.setAvatar(user.getAvatar());
return orgTreeVo;
})
.toList();
}
/**
* 递归查询所有子节点。
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
/**
* 递归查询所有子节点。
*
* @param allDeptList 所有部门列表
* @param parentId 父部门ID
* @param resDeptList 结果集合
*/
private void recursiveDept(List<SysDept> allDeptList, Long parentId, List<SysDept> resDeptList) {
// 使用 Stream API 进行筛选和遍历
allDeptList.stream().filter(sysDept -> sysDept.getParentId().equals(parentId)).forEach(sysDept -> {
resDeptList.add(sysDept);
recursiveDept(allDeptList, sysDept.getDeptId(), resDeptList);
});
}
}
@@ -17,6 +17,7 @@
package com.pig4cloud.pigx.admin.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper;
@@ -24,7 +25,6 @@ import com.pig4cloud.pigx.admin.service.SysDictItemService;
import com.pig4cloud.pigx.admin.service.SysDictService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
@@ -41,41 +41,43 @@ import org.springframework.stereotype.Service;
@AllArgsConstructor
public class SysDictItemServiceImpl extends ServiceImpl<SysDictItemMapper, SysDictItem> implements SysDictItemService {
private final SysDictService dictService;
private final SysDictService dictService;
/**
* 删除字典项
* @param id 字典项ID
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictItem(Long id) {
// 根据ID查询字典ID
SysDictItem dictItem = this.getById(id);
SysDict dict = dictService.getById(dictItem.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_DELETE_SYSTEM));
}
return R.ok(this.removeById(id));
}
/**
* 删除字典项
*
* @param id 字典项ID
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictItem(Long id) {
// 根据ID查询字典ID
SysDictItem dictItem = this.getById(id);
SysDict dict = dictService.getById(dictItem.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_DELETE_SYSTEM));
}
return R.ok(this.removeById(id));
}
/**
* 更新字典项
* @param item 字典项
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType")
public R updateDictItem(SysDictItem item) {
// 查询字典
SysDict dict = dictService.getById(item.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
return R.ok(this.updateById(item));
}
/**
* 更新字典项
*
* @param item 字典项
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#item.dictType")
public R updateDictItem(SysDictItem item) {
// 查询字典
SysDict dict = dictService.getById(item.getDictId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(dict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
return R.ok(this.updateById(item));
}
}
@@ -19,6 +19,7 @@ package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysDict;
import com.pig4cloud.pigx.admin.api.entity.SysDictItem;
import com.pig4cloud.pigx.admin.mapper.SysDictItemMapper;
@@ -26,7 +27,6 @@ import com.pig4cloud.pigx.admin.mapper.SysDictMapper;
import com.pig4cloud.pigx.admin.service.SysDictService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
@@ -46,55 +46,58 @@ import java.util.List;
@AllArgsConstructor
public class SysDictServiceImpl extends ServiceImpl<SysDictMapper, SysDict> implements SysDictService {
private final SysDictItemMapper dictItemMapper;
private final SysDictItemMapper dictItemMapper;
/**
* 根据ID 删除字典
* @param ids 字典ID 列表
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictByIds(Long[] ids) {
/**
* 根据ID 删除字典
*
* @param ids 字典ID 列表
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R removeDictByIds(Long[] ids) {
List<Long> dictIdList = baseMapper.selectByIds(CollUtil.toList(ids))
.stream()
.filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除
.map(SysDict::getId)
List<Long> dictIdList = baseMapper.selectByIds(CollUtil.toList(ids))
.stream()
.filter(sysDict -> !sysDict.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置类型不删除
.map(SysDict::getId)
.toList();
baseMapper.deleteByIds(dictIdList);
baseMapper.deleteByIds(dictIdList);
dictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId, dictIdList));
return R.ok();
}
dictItemMapper.delete(Wrappers.<SysDictItem>lambdaQuery().in(SysDictItem::getDictId, dictIdList));
return R.ok();
}
/**
* 更新字典
* @param dict 字典
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType")
public R updateDict(SysDict dict) {
SysDict sysDict = this.getById(dict.getId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
this.updateById(dict);
return R.ok(dict);
}
/**
* 更新字典
*
* @param dict 字典
* @return
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, key = "#dict.dictType")
public R updateDict(SysDict dict) {
SysDict sysDict = this.getById(dict.getId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(sysDict.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_DICT_UPDATE_SYSTEM));
}
this.updateById(dict);
return R.ok(dict);
}
/**
* 同步缓存 (清空缓存)
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R syncDictCache() {
return R.ok();
}
/**
* 同步缓存 (清空缓存)
*
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.DICT_DETAILS, allEntries = true)
public R syncDictCache() {
return R.ok();
}
}
@@ -27,6 +27,7 @@ import cn.hutool.core.util.BooleanUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysI18nEntity;
import com.pig4cloud.pigx.admin.api.entity.SysMenu;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
@@ -38,7 +39,6 @@ import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.enums.MenuTypeEnum;
import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.security.util.SecurityUtils;
@@ -85,7 +85,7 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
// 1. 检查菜单是否存在
SysMenu menu = this.getById(id);
if (menu == null) {
return R.failed("菜单不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_NOT_FOUND));
}
// 2. 递归收集当前菜单及所有子孙菜单的ID
@@ -103,7 +103,8 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
/**
* 递归收集菜单ID及其所有子孙菜单ID
* @param menuId 菜单ID
*
* @param menuId 菜单ID
* @param menuIds 收集结果列表
*/
private void collectMenuIds(Long menuId, List<Long> menuIds) {
@@ -232,10 +233,10 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
// 查询菜单是否存在且为菜单类型(非按钮)
SysMenu menu = this.getById(menuId);
if (menu == null) {
return R.failed("菜单不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_NOT_FOUND));
}
if (MenuTypeEnum.BUTTON.getType().equals(menu.getMenuType())) {
return R.failed("按钮类型不能设置为首页");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_BUTTON_CANNOT_HOME));
}
// Toggle 模式:如果已是首页则取消,否则设置为首页
@@ -243,13 +244,13 @@ public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> impl
// 已是首页,取消首页设置
menu.setIsHomePage(YesNoEnum.NO.getCode());
this.updateById(menu);
return R.ok(Boolean.TRUE, "取消首页成功");
return R.ok(Boolean.TRUE, MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_HOME_CANCEL_SUCCEED));
} else {
// 不是首页,先将所有菜单的首页标记重置为0,再设置当前菜单为首页
this.update(Wrappers.<SysMenu>lambdaUpdate().set(SysMenu::getIsHomePage, YesNoEnum.NO.getCode()));
menu.setIsHomePage(YesNoEnum.YES.getCode());
this.updateById(menu);
return R.ok(Boolean.TRUE, "设置首页成功");
return R.ok(Boolean.TRUE, MsgUtils.getMessage(UpmsErrorCodes.SYS_MENU_HOME_SET_SUCCEED));
}
}
@@ -23,6 +23,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.pig4cloud.pigx.admin.api.constant.SmsBizCodeEnum;
import com.pig4cloud.pigx.admin.api.constant.SystemConfigTypeEnum;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.dto.MessageEmailDTO;
import com.pig4cloud.pigx.admin.api.dto.MessageHookDTO;
import com.pig4cloud.pigx.admin.api.dto.MessageSmsDTO;
@@ -39,7 +40,6 @@ import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.constant.enums.YesNoEnum;
import com.pig4cloud.pigx.common.core.exception.CheckedException;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
@@ -284,7 +284,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
if (registered && CollUtil.isEmpty(userList)) {
log.info("手机号未注册:{}", mobile);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
return R.ok(Boolean.FALSE, MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_PHONE_UNREGISTERED, mobile));
}
String codeObj = RedisUtils
@@ -292,7 +292,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
if (StrUtil.isNotBlank(codeObj)) {
log.info("手机号验证码未过期:{},{}", mobile, codeObj);
return R.ok(Boolean.FALSE, MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_OFTEN));
return R.ok(Boolean.FALSE, MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_OFTEN));
}
String code = RandomUtil.randomNumbers(Integer.parseInt(SecurityConstants.CODE_SIZE));
@@ -324,7 +324,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigKey, messageSmsDTO.getBizCode()));
if (CollUtil.isEmpty(configEntityList)) {
return R.failed("发送失败,短信通道配置不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING));
}
SysSystemConfigEntity configEntity = configEntityList.get(0);
@@ -338,7 +338,8 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
.toLowerCase()
.contains(configMap.getStr(MessageSmsDTO.Fields.supplier)))
.findFirst()
.orElseThrow(() -> new CheckedException("发送失败,短信通道配置不存在"));
.orElseThrow(() -> new CheckedException(
MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING)));
BaseConfig baseConfig = (BaseConfig) JSONUtil.toBean(configEntity.getConfigValue(), targetClass);
// 如果渠道扩展参数不为空则增加特性化参数
@@ -388,7 +389,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigKey, messageHookDTO.getBizCode()));
if (CollUtil.isEmpty(configEntityList)) {
return R.failed("发送失败,短信通道配置不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_SMS_CHANNEL_MISSING));
}
SysSystemConfigEntity configEntity = configEntityList.get(0);
@@ -465,7 +466,7 @@ public class SysMessageServiceImpl extends ServiceImpl<SysMessageMapper, SysMess
.eq(SysSystemConfigEntity::getConfigStatus, YesNoEnum.YES.getCode())
.eq(SysSystemConfigEntity::getConfigKey, messageEmailDTO.getBizCode()));
if (CollUtil.isEmpty(configEntityList)) {
return R.failed("发送失败,通道配置不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_MESSAGE_CHANNEL_MISSING));
}
SysSystemConfigEntity configEntity = configEntityList.get(0);
JSONObject configMap = JSONUtil.parseObj(configEntity.getConfigValue());
@@ -21,11 +21,11 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysPost;
import com.pig4cloud.pigx.admin.api.vo.PostExcelVO;
import com.pig4cloud.pigx.admin.mapper.SysPostMapper;
import com.pig4cloud.pigx.admin.service.SysPostService;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.excel.vo.ErrorMessage;
@@ -45,71 +45,72 @@ import java.util.Set;
@Service
public class SysPostServiceImpl extends ServiceImpl<SysPostMapper, SysPost> implements SysPostService {
/**
* 导入岗位
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
/**
* 导入岗位
*
* @param excelVOList 岗位列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importPost(List<PostExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysPost> postList = this.list();
// 个性化校验逻辑
List<SysPost> postList = this.list();
// 执行数据插入操作 组装 PostDto
for (PostExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验岗位名称或者岗位编码是否存在
boolean existPost = postList.stream()
.anyMatch(post -> excel.getPostName().equals(post.getPostName())
|| excel.getPostCode().equals(post.getPostCode()));
// 执行数据插入操作 组装 PostDto
for (PostExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验岗位名称或者岗位编码是否存在
boolean existPost = postList.stream()
.anyMatch(post -> excel.getPostName().equals(post.getPostName())
|| excel.getPostCode().equals(post.getPostCode()));
if (existPost) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
excel.getPostCode()));
}
if (existPost) {
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_NAMEORCODE_EXISTING, excel.getPostName(),
excel.getPostCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelPost(excel);
}
else {
// 数据不合法
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelPost(excel);
} else {
// 数据不合法
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 导出excel 表格
* @return
*/
@Override
public List<PostExcelVO> listPost(SysPost query, Long[] ids) {
List<SysPost> postList = this
.list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids)));
// 转换成execl 对象输出
return postList.stream().map(post -> {
PostExcelVO postExcelVO = new PostExcelVO();
BeanUtil.copyProperties(post, postExcelVO);
return postExcelVO;
/**
* 导出excel 表格
*
* @return
*/
@Override
public List<PostExcelVO> listPost(SysPost query, Long[] ids) {
List<SysPost> postList = this
.list(Wrappers.lambdaQuery(query).in(ArrayUtil.isNotEmpty(ids), SysPost::getPostId, CollUtil.toList(ids)));
// 转换成execl 对象输出
return postList.stream().map(post -> {
PostExcelVO postExcelVO = new PostExcelVO();
BeanUtil.copyProperties(post, postExcelVO);
return postExcelVO;
}).toList();
}
}
/**
* 插入excel Post
*/
private void insertExcelPost(PostExcelVO excel) {
SysPost sysPost = new SysPost();
BeanUtil.copyProperties(excel, sysPost);
this.save(sysPost);
}
/**
* 插入excel Post
*/
private void insertExcelPost(PostExcelVO excel) {
SysPost sysPost = new SysPost();
BeanUtil.copyProperties(excel, sysPost);
this.save(sysPost);
}
}
@@ -20,12 +20,12 @@ package com.pig4cloud.pigx.admin.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysPublicParam;
import com.pig4cloud.pigx.admin.mapper.SysPublicParamMapper;
import com.pig4cloud.pigx.admin.service.SysPublicParamService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.enums.DictTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
@@ -46,74 +46,78 @@ import java.util.Map;
@Service
@AllArgsConstructor
public class SysPublicParamServiceImpl extends ServiceImpl<SysPublicParamMapper, SysPublicParam>
implements SysPublicParamService {
implements SysPublicParamService {
@Override
@Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ")
public String getSysPublicParamKeyToValue(String publicKey) {
SysPublicParam sysPublicParam = this.baseMapper
.selectOne(Wrappers.<SysPublicParam>lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey));
@Override
@Cacheable(value = CacheConstants.PARAMS_DETAILS, key = "#publicKey", unless = "#result == null ")
public String getSysPublicParamKeyToValue(String publicKey) {
SysPublicParam sysPublicParam = this.baseMapper
.selectOne(Wrappers.<SysPublicParam>lambdaQuery().eq(SysPublicParam::getPublicKey, publicKey));
if (sysPublicParam != null) {
return sysPublicParam.getPublicValue();
}
return null;
}
if (sysPublicParam != null) {
return sysPublicParam.getPublicValue();
}
return null;
}
/**
* 通过key查询公共参数指定值
* @param keys 参数列表
* @return Map
*/
@Override
public Map<String, Object> getSysPublicParamsKeyToValue(String[] keys) {
List<SysPublicParam> paramList = this.baseMapper
.selectList(Wrappers.<SysPublicParam>lambdaQuery().in(SysPublicParam::getPublicKey, CollUtil.toList(keys)));
Map<String, Object> result = new HashMap<>(8);
paramList.forEach(param -> result.put(param.getPublicKey(), param.getPublicValue()));
return result;
}
/**
* 通过key查询公共参数指定值
*
* @param keys 参数列表
* @return Map
*/
@Override
public Map<String, Object> getSysPublicParamsKeyToValue(String[] keys) {
List<SysPublicParam> paramList = this.baseMapper
.selectList(Wrappers.<SysPublicParam>lambdaQuery().in(SysPublicParam::getPublicKey, CollUtil.toList(keys)));
Map<String, Object> result = new HashMap<>(8);
paramList.forEach(param -> result.put(param.getPublicKey(), param.getPublicValue()));
return result;
}
/**
* 更新参数
* @param sysPublicParam
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey")
public R updateParam(SysPublicParam sysPublicParam) {
SysPublicParam param = this.getById(sysPublicParam.getPublicId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_PARAM_DELETE_SYSTEM));
}
return R.ok(this.updateById(sysPublicParam));
}
/**
* 更新参数
*
* @param sysPublicParam
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, key = "#sysPublicParam.publicKey")
public R updateParam(SysPublicParam sysPublicParam) {
SysPublicParam param = this.getById(sysPublicParam.getPublicId());
// 系统内置
if (DictTypeEnum.SYSTEM.getType().equals(param.getSystemFlag())) {
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_PARAM_DELETE_SYSTEM));
}
return R.ok(this.updateById(sysPublicParam));
}
/**
* 删除参数
* @param publicIds 参数ID列表
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R removeParamByIds(Long[] publicIds) {
List<Long> idList = this.baseMapper.selectByIds(CollUtil.toList(publicIds))
.stream()
.filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除
.map(SysPublicParam::getPublicId)
/**
* 删除参数
*
* @param publicIds 参数ID列表
* @return
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R removeParamByIds(Long[] publicIds) {
List<Long> idList = this.baseMapper.selectByIds(CollUtil.toList(publicIds))
.stream()
.filter(p -> !p.getSystemFlag().equals(DictTypeEnum.SYSTEM.getType()))// 系统内置的跳过不能删除
.map(SysPublicParam::getPublicId)
.toList();
return R.ok(this.removeBatchByIds(idList));
}
return R.ok(this.removeBatchByIds(idList));
}
/**
* 同步缓存
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R syncParamCache() {
return R.ok();
}
/**
* 同步缓存
*
* @return R
*/
@Override
@CacheEvict(value = CacheConstants.PARAMS_DETAILS, allEntries = true)
public R syncParamCache() {
return R.ok();
}
}
@@ -24,6 +24,7 @@ import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ArrayUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.entity.SysRole;
import com.pig4cloud.pigx.admin.api.entity.SysRoleMenu;
import com.pig4cloud.pigx.admin.api.vo.RoleExcelVO;
@@ -32,7 +33,6 @@ import com.pig4cloud.pigx.admin.mapper.SysRoleMapper;
import com.pig4cloud.pigx.admin.service.SysRoleMenuService;
import com.pig4cloud.pigx.admin.service.SysRoleService;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.tenant.TenantContextHolder;
@@ -59,120 +59,125 @@ import java.util.Set;
@AllArgsConstructor
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {
private SysRoleMenuService roleMenuService;
private SysRoleMenuService roleMenuService;
/**
* 通过用户ID查询角色信息
* @param userId 用户ID
* @return 角色信息列表
*/
@Override
public List findRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId, TenantContextHolder.getTenantId());
}
/**
* 通过用户ID查询角色信息
*
* @param userId 用户ID
* @return 角色信息列表
*/
@Override
public List findRolesByUserId(Long userId) {
return baseMapper.listRolesByUserId(userId, TenantContextHolder.getTenantId());
}
/**
* 根据角色ID 查询角色列表,注意缓存删除
* @param roleIdList 角色ID列表
* @param key 缓存key
* @return
*/
@Override
@Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()")
public List<SysRole> findRolesByRoleIds(List<Long> roleIdList, String key) {
return baseMapper.selectByIds(roleIdList);
}
/**
* 根据角色ID 查询角色列表,注意缓存删除
*
* @param roleIdList 角色ID列表
* @param key 缓存key
* @return
*/
@Override
@Cacheable(value = CacheConstants.ROLE_DETAILS, key = "#key", unless = "#result.isEmpty()")
public List<SysRole> findRolesByRoleIds(List<Long> roleIdList, String key) {
return baseMapper.selectByIds(roleIdList);
}
/**
* 通过角色ID,删除角色,并清空角色菜单缓存
* @param ids
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeRoleByIds(Long[] ids) {
roleMenuService
.remove(Wrappers.<SysRoleMenu>update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids)));
return this.removeBatchByIds(CollUtil.toList(ids));
}
/**
* 通过角色ID,删除角色,并清空角色菜单缓存
*
* @param ids
* @return
*/
@Override
@Transactional(rollbackFor = Exception.class)
public Boolean removeRoleByIds(Long[] ids) {
roleMenuService
.remove(Wrappers.<SysRoleMenu>update().lambda().in(SysRoleMenu::getRoleId, CollUtil.toList(ids)));
return this.removeBatchByIds(CollUtil.toList(ids));
}
/**
* 根据角色菜单列表
* @param roleVo 角色&菜单列表
* @return
*/
@Override
public Boolean updateRoleMenus(RoleMenuVO roleVo) {
return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds());
}
/**
* 根据角色菜单列表
*
* @param roleVo 角色&菜单列表
* @return
*/
@Override
public Boolean updateRoleMenus(RoleMenuVO roleVo) {
return roleMenuService.saveRoleMenus(roleVo.getRoleId(), roleVo.getMenuIds());
}
/**
* 导入角色
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
/**
* 导入角色
*
* @param excelVOList 角色列表
* @param bindingResult 错误信息列表
* @return ok fail
*/
@Override
public R importRole(List<RoleExcelVO> excelVOList, BindingResult bindingResult) {
// 通用校验获取失败的数据
List<ErrorMessage> errorMessageList = (List<ErrorMessage>) bindingResult.getTarget();
// 个性化校验逻辑
List<SysRole> roleList = this.list();
// 个性化校验逻辑
List<SysRole> roleList = this.list();
// 执行数据插入操作 组装 RoleDto
for (RoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream()
.anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName())
|| excel.getRoleCode().equals(sysRole.getRoleCode()));
// 执行数据插入操作 组装 RoleDto
for (RoleExcelVO excel : excelVOList) {
Set<String> errorMsg = new HashSet<>();
// 检验角色名称或者角色编码是否存在
boolean existRole = roleList.stream()
.anyMatch(sysRole -> excel.getRoleName().equals(sysRole.getRoleName())
|| excel.getRoleCode().equals(sysRole.getRoleCode()));
if (existRole) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
if (existRole) {
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_ROLE_NAMEORCODE_EXISTING, excel.getRoleName(),
excel.getRoleCode()));
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
}
else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
// 数据合法情况
if (CollUtil.isEmpty(errorMsg)) {
insertExcelRole(excel);
} else {
// 数据不合法情况
errorMessageList.add(new ErrorMessage(excel.getLineNum(), errorMsg));
}
}
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok();
}
/**
* 查询全部的角色
* @return list
*/
@Override
public List<RoleExcelVO> listRole(SysRole sysRole, Long[] ids) {
/**
* 查询全部的角色
*
* @return list
*/
@Override
public List<RoleExcelVO> listRole(SysRole sysRole, Long[] ids) {
List<SysRole> roleList = this.list(
Wrappers.lambdaQuery(sysRole).in(ArrayUtil.isNotEmpty(ids), SysRole::getRoleId, CollUtil.toList(ids)));
// 转换成execl 对象输出
return roleList.stream().map(role -> {
RoleExcelVO roleExcelVO = new RoleExcelVO();
BeanUtil.copyProperties(role, roleExcelVO);
return roleExcelVO;
// 转换成execl 对象输出
return roleList.stream().map(role -> {
RoleExcelVO roleExcelVO = new RoleExcelVO();
BeanUtil.copyProperties(role, roleExcelVO);
return roleExcelVO;
}).toList();
}
}
/**
* 插入excel Role
*/
private void insertExcelRole(RoleExcelVO excel) {
SysRole sysRole = new SysRole();
sysRole.setRoleName(excel.getRoleName());
sysRole.setRoleDesc(excel.getRoleDesc());
sysRole.setRoleCode(excel.getRoleCode());
this.save(sysRole);
}
/**
* 插入excel Role
*/
private void insertExcelRole(RoleExcelVO excel) {
SysRole sysRole = new SysRole();
sysRole.setRoleName(excel.getRoleName());
sysRole.setRoleDesc(excel.getRoleDesc());
sysRole.setRoleCode(excel.getRoleCode());
this.save(sysRole);
}
}
@@ -28,6 +28,7 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pigx.admin.api.constant.UpmsErrorCodes;
import com.pig4cloud.pigx.admin.api.constant.UserStateEnum;
import com.pig4cloud.pigx.admin.api.dto.RegisterUserDTO;
import com.pig4cloud.pigx.admin.api.dto.UserDTO;
@@ -41,7 +42,6 @@ import com.pig4cloud.pigx.common.audit.annotation.Audit;
import com.pig4cloud.pigx.common.core.constant.CacheConstants;
import com.pig4cloud.pigx.common.core.constant.CommonConstants;
import com.pig4cloud.pigx.common.core.constant.enums.LoginTypeEnum;
import com.pig4cloud.pigx.common.core.exception.ErrorCodes;
import com.pig4cloud.pigx.common.core.util.MsgUtils;
import com.pig4cloud.pigx.common.core.util.R;
import com.pig4cloud.pigx.common.data.cache.RedisUtils;
@@ -184,7 +184,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
UserVO dbUser = baseMapper.getUserVo(userDTO);
if (dbUser == null) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERINFO_EMPTY, userDTO.getUsername()));
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERINFO_EMPTY, userDTO.getUsername()));
}
// 设置角色列表 (ID)
@@ -278,7 +278,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
Object codeObj = RedisUtils.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType()
+ StringPool.AT + userDto.getPhone());
if (!StrUtil.equals(userDto.getCode(), codeObj.toString())) {
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_APP_SMS_ERROR));
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_ERROR));
}
}
@@ -444,13 +444,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
.anyMatch(sysUser -> excel.getUsername().equals(sysUser.getUsername()));
if (exsitUserName) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERNAME_EXISTING, excel.getUsername()));
}
// 校验手机号是否存在
boolean exsitPhone = userList.stream().anyMatch(sysUser -> excel.getPhone().equals(sysUser.getPhone()));
if (exsitPhone) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, excel.getPhone()));
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PHONE_EXISTING, excel.getPhone()));
}
// 判断输入的部门名称列表是否合法
@@ -458,7 +458,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
.filter(dept -> excel.getDeptNameList().equals(dept.getName()))
.findFirst();
if (deptOptional.isEmpty()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList()));
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_DEPTNAME_INEXISTENCE, excel.getDeptNameList()));
}
// 判断输入的角色名称列表是否合法
@@ -468,7 +468,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
.toList();
if (roleCollList.size() != roleNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_ROLE_ROLENAME_INEXISTENCE, excel.getRoleNameList()));
}
// 判断输入的部门名称列表是否合法
@@ -478,7 +478,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
.toList();
if (postCollList.size() != postNameList.size()) {
errorMsg.add(MsgUtils.getMessage(ErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
errorMsg.add(MsgUtils.getMessage(UpmsErrorCodes.SYS_POST_POSTNAME_INEXISTENCE, excel.getPostNameList()));
}
// 数据合法情况
@@ -494,7 +494,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
if (CollUtil.isNotEmpty(errorMessageList)) {
return R.failed(errorMessageList);
}
return R.ok(null, MsgUtils.getMessage(ErrorCodes.SYS_USER_IMPORT_SUCCEED));
return R.ok(null, MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_IMPORT_SUCCEED));
}
/**
@@ -537,7 +537,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
boolean usernameExists = TenantBroker
.noneAs(() -> this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getUsername, userDto.getUsername())));
if (usernameExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
String message = MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_USERNAME_EXISTING, userDto.getUsername());
return R.failed(message);
}
@@ -545,7 +545,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
boolean phoneExists = TenantBroker
.noneAs(() -> this.exists(Wrappers.<SysUser>lambdaQuery().eq(SysUser::getPhone, userDto.getPhone())));
if (phoneExists) {
String message = MsgUtils.getMessage(ErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone());
String message = MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PHONE_EXISTING, userDto.getPhone());
return R.failed(message);
}
@@ -585,16 +585,16 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
public R changePassword(UserDTO userDto) {
SysUser user = baseMapper.selectById(SecurityUtils.getUser().getId());
if (StrUtil.isEmpty(userDto.getPassword())) {
return R.failed("原密码不能为空");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_OLD_PASSWORD_EMPTY));
}
if (!ENCODER.matches(userDto.getPassword(), user.getPassword())) {
log.info("原密码错误,修改个人信息失败:{}", userDto.getUsername());
return R.failed(MsgUtils.getMessage(ErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_UPDATE_PASSWORDERROR));
}
if (StrUtil.isEmpty(userDto.getNewpassword1())) {
return R.failed("新密码不能为空");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_NEW_PASSWORD_EMPTY));
}
String password = ENCODER.encode(userDto.getNewpassword1());
@@ -639,7 +639,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
}
if (Objects.isNull(wrapper)) {
return R.failed("解绑账号类型不存在");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_UNBIND_TYPE_NOT_FOUND));
}
this.update(wrapper);
return R.ok();
@@ -660,7 +660,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
if (!ENCODER.matches(password, sysUser.getPassword())) {
log.info("原密码错误");
return R.failed("密码输入错误");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PASSWORD_MISMATCH));
} else {
return R.ok();
}
@@ -683,7 +683,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 新密码校验
if (StrUtil.equals(userDto.getPassword(), userDto.getNewpassword1())) {
return R.failed("新旧密码不能相同");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_USER_PASSWORD_SAME));
}
// 重置密码
@@ -706,13 +706,13 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
@Override
public R<Boolean> forgetUserPassword(RegisterUserDTO userDto, String code) {
if (StrUtil.isBlank(userDto.getPhone())) {
return R.failed("非法参数");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_PARAM_ILLEGAL));
}
String codeObj = RedisUtils
.get(CacheConstants.DEFAULT_CODE_KEY + LoginTypeEnum.SMS.getType() + StringPool.AT + userDto.getPhone());
if (!StrUtil.equals(codeObj, code)) {
return R.failed("验证码错误");
return R.failed(MsgUtils.getMessage(UpmsErrorCodes.SYS_APP_SMS_ERROR));
}
TenantBroker.noneAs(() -> {
@@ -812,7 +812,7 @@ public class SysUserServiceImpl extends ServiceImpl<SysUserMapper, SysUser> impl
// 2. 清除用户缓存,触发权限重新计算
cacheManager.getCache(CacheConstants.USER_DETAILS).evict(username);
return R.ok(true, "部门切换成功");
return R.ok(true, MsgUtils.getMessage(UpmsErrorCodes.SYS_DEPT_SWITCH_SUCCEED));
}
}