添加安全规则
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
package xtools.app.sys.api;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleApi</p>
|
||||
* <p>Description : 用户名密码规则 Api</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
public interface SysUserPasswdRuleApi {
|
||||
|
||||
}
|
||||
@@ -109,6 +109,23 @@ public class SysUserController {
|
||||
return sysUserService.delById(req.getIdList());
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*
|
||||
* @param id 用户ID
|
||||
* @return 重置密码结果
|
||||
*/
|
||||
@Operation(summary = "重置密码")
|
||||
@PostMapping("reset-passwd/{id}")
|
||||
public Result<Boolean> resetPasswd(
|
||||
@Schema(description = "ID", example = "1")
|
||||
@Min(value = 1L, message = "不能小于1")
|
||||
@NotNull(message = "不能为空")
|
||||
@PathVariable Long id
|
||||
) {
|
||||
return sysUserService.resetPasswd(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 集合查询
|
||||
*
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
package xtools.app.sys.controller;
|
||||
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.validation.Valid;
|
||||
import jakarta.validation.constraints.Min;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import xtools.app.sys.api.SysUserPasswdRuleApi;
|
||||
import xtools.app.sys.model.dto.excel.SysUserPasswdRuleExcel;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleAddReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRulePageReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleUpdateReq;
|
||||
import xtools.app.sys.model.dto.resp.SysUserPasswdRuleResp;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
import xtools.boot.api.model.dto.page.PageReq;
|
||||
import xtools.boot.api.model.dto.page.PageResp;
|
||||
import xtools.boot.api.model.dto.req.IdListReq;
|
||||
import xtools.core.CollectionUtils;
|
||||
import xtools.extend.office.FesodUtils;
|
||||
import xtools.web.HttpServletUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleController</p>
|
||||
* <p>Description : 用户名密码规则 Controller</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@RequiredArgsConstructor
|
||||
@Tag(name = "用户名密码规则")
|
||||
@RestController
|
||||
@RequestMapping("/sys/user-passwd-rule")
|
||||
public class SysUserPasswdRuleController implements SysUserPasswdRuleApi {
|
||||
|
||||
private final SysUserPasswdRuleService sysUserPasswdRuleService;
|
||||
|
||||
@Operation(summary = "分页请求")
|
||||
@PostMapping("page")
|
||||
public Result<PageResp<SysUserPasswdRuleResp>> page(@RequestBody @Valid PageReq<SysUserPasswdRulePageReq> pageReq) {
|
||||
return sysUserPasswdRuleService.page(pageReq);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取数据")
|
||||
@GetMapping("base/{id}")
|
||||
public Result<SysUserPasswdRuleResp> getById(
|
||||
@Schema(description = "ID", example = "1")
|
||||
@Min(value = 1L, message = "不能小于1")
|
||||
@NotNull(message = "不能为空")
|
||||
@PathVariable Long id
|
||||
) {
|
||||
return sysUserPasswdRuleService.getById(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "添加数据")
|
||||
@PostMapping("base")
|
||||
public Result<Boolean> add(@RequestBody @Valid SysUserPasswdRuleAddReq req) {
|
||||
return sysUserPasswdRuleService.add(req);
|
||||
}
|
||||
|
||||
@Operation(summary = "更新数据")
|
||||
@PutMapping("base")
|
||||
public Result<Boolean> update(@RequestBody @Valid SysUserPasswdRuleUpdateReq req) {
|
||||
return sysUserPasswdRuleService.update(req);
|
||||
}
|
||||
|
||||
@Operation(summary = "删除数据")
|
||||
@DeleteMapping("base")
|
||||
public Result<Boolean> delById(@RequestBody @Valid IdListReq req) {
|
||||
return sysUserPasswdRuleService.delById(req);
|
||||
}
|
||||
|
||||
@Operation(summary = "设置默认")
|
||||
@PostMapping("set-def/{id}")
|
||||
public Result<Boolean> setDef(
|
||||
@Schema(description = "ID", example = "1")
|
||||
@Min(value = 1L, message = "不能小于1")
|
||||
@NotNull(message = "不能为空")
|
||||
@PathVariable Long id
|
||||
) {
|
||||
return sysUserPasswdRuleService.setDef(id);
|
||||
}
|
||||
|
||||
@Operation(summary = "导出Excel")
|
||||
@PostMapping("export")
|
||||
public void exportExcel(@RequestBody @Valid SysUserPasswdRulePageReq req, HttpServletResponse response) {
|
||||
String sheetName = "用户名密码规则";
|
||||
String filename = sheetName + ".xlsx";
|
||||
List<SysUserPasswdRuleExcel> dataList = sysUserPasswdRuleService.exportExcel(req);
|
||||
try {
|
||||
FesodUtils.write(response.getOutputStream(), SysUserPasswdRuleExcel.class, sheetName, dataList);
|
||||
} catch (IOException e) {
|
||||
throw new BizError("导出Excel失败");
|
||||
}
|
||||
// 设置 header 和 contentType.写在最后的原因是,避免报错时,响应 contentType 已经被修改
|
||||
HttpServletUtils.addDownloadHeader(response, filename);
|
||||
}
|
||||
|
||||
@Operation(summary = "导入Excel")
|
||||
@PostMapping("import")
|
||||
public Result<Boolean> importExcel(@RequestParam("file") MultipartFile file) {
|
||||
List<SysUserPasswdRuleExcel> dataList;
|
||||
try {
|
||||
dataList = FesodUtils.read(file.getInputStream(), SysUserPasswdRuleExcel.class);
|
||||
} catch (IOException e) {
|
||||
throw new BizError("导入Excel失败");
|
||||
}
|
||||
if (CollectionUtils.isEmpty(dataList)) {
|
||||
throw new BizWarning("导入Excel没有包含有效数据");
|
||||
}
|
||||
sysUserPasswdRuleService.importExcel(dataList);
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package xtools.app.sys.convert;
|
||||
|
||||
import org.mapstruct.Mapper;
|
||||
import xtools.app.sys.model.dto.excel.SysUserPasswdRuleExcel;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleAddReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleUpdateReq;
|
||||
import xtools.app.sys.model.dto.resp.SysUserPasswdRuleResp;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleConvert</p>
|
||||
* <p>Description : 用户名密码规则 Convert</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Mapper(componentModel = "spring")
|
||||
public interface SysUserPasswdRuleConvert {
|
||||
|
||||
/**
|
||||
* 添加请求转实体
|
||||
*
|
||||
* @param req 添加请求
|
||||
* @return 实体
|
||||
*/
|
||||
SysUserPasswdRule addReqToEntity(SysUserPasswdRuleAddReq req);
|
||||
|
||||
/**
|
||||
* 修改请求转实体
|
||||
*
|
||||
* @param req 修改请求
|
||||
* @return 实体
|
||||
*/
|
||||
SysUserPasswdRule updateReqToEntity(SysUserPasswdRuleUpdateReq req);
|
||||
|
||||
/**
|
||||
* 实体转响应
|
||||
*
|
||||
* @param data 实体
|
||||
* @return 响应
|
||||
*/
|
||||
SysUserPasswdRuleResp entityToResp(SysUserPasswdRule data);
|
||||
|
||||
/**
|
||||
* 批量实体转响应
|
||||
*
|
||||
* @param dataList 批量实体
|
||||
* @return 响应
|
||||
*/
|
||||
List<SysUserPasswdRuleResp> entityToRespList(List<SysUserPasswdRule> dataList);
|
||||
|
||||
/**
|
||||
* 实体转Excel
|
||||
*
|
||||
* @param data 实体
|
||||
* @return Excel
|
||||
*/
|
||||
SysUserPasswdRuleExcel entityToExcel(SysUserPasswdRule data);
|
||||
|
||||
/**
|
||||
* Excel转实体
|
||||
*
|
||||
* @param data Excel
|
||||
* @return 实体
|
||||
*/
|
||||
SysUserPasswdRule excelToEntity(SysUserPasswdRuleExcel data);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package xtools.app.sys.job;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
import xtools.app.common.job.base.BaseJob;
|
||||
import xtools.app.sys.service.SysUserService;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserJob</p>
|
||||
* <p>Description : SysUserJob</p>
|
||||
* <p>DevelopTools : Idea_x64_v2026.1</p>
|
||||
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : XuJun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026/3/17 21:24
|
||||
*/
|
||||
@Slf4j
|
||||
@Component
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserJob extends BaseJob {
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
|
||||
/**
|
||||
* 运行作业
|
||||
*/
|
||||
@Override
|
||||
public void runJob() {
|
||||
sysUserService.cleanSysUserJob();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
package xtools.app.sys.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleMapper</p>
|
||||
* <p>Description : 用户名密码规则 Mapper 接口</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Mapper
|
||||
public interface SysUserPasswdRuleMapper extends BaseMapper<SysUserPasswdRule> {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
package xtools.app.sys.model.dto.excel;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import org.apache.fesod.sheet.annotation.ExcelProperty;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleExcel</p>
|
||||
* <p>Description : 用户名密码规则Excel对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserPasswdRuleExcel implements Serializable {
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@ExcelProperty("规则名称")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@ExcelProperty("规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@ExcelProperty("规则编码")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@ExcelProperty("最小密码长度")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@ExcelProperty("最大密码长度")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@ExcelProperty("最少数字字符个数")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@ExcelProperty("最少特殊字符个数")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@ExcelProperty("最少小写字母个数")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@ExcelProperty("最少大写字母个数")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@ExcelProperty("禁止使用历史最近多少次口令")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@ExcelProperty("禁止使用键盘连续3个字符")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@ExcelProperty("禁止使用弱口令字典中的口令")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@ExcelProperty("禁止账号名在密码中所占长度超过一半")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@ExcelProperty("密码有效期天数")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@ExcelProperty("密码修改后剩余多少天进行提示")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@ExcelProperty("账号锁定后多久没启用进行账号注销")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@ExcelProperty("密码错误时间窗口")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@ExcelProperty("错误密码次数")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@ExcelProperty("账号锁定分钟数")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@ExcelProperty("账号有效期")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@ExcelProperty("账号有效期剩余天数提示")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@ExcelProperty("备注")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserAddReq</p>
|
||||
@@ -69,6 +70,12 @@ public class SysUserAddReq implements Serializable {
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 账号失效时间,空则不失效
|
||||
*/
|
||||
@Schema(description = "账号失效时间,空则不失效")
|
||||
private Instant accountExpirationTime;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
package xtools.app.sys.model.dto.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleAddReq</p>
|
||||
* <p>Description : 用户名密码规则添加请求对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserPasswdRuleAddReq implements Serializable {
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@Schema(description = "规则名称")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@Schema(description = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@Schema(description = "规则编码")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 默认规则
|
||||
*/
|
||||
@Schema(description = "默认规则")
|
||||
private Integer ruleDefault;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@Schema(description = "最小密码长度")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@Schema(description = "最大密码长度")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@Schema(description = "最少数字字符个数")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@Schema(description = "最少特殊字符个数")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@Schema(description = "最少小写字母个数")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@Schema(description = "最少大写字母个数")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@Schema(description = "禁止使用历史最近多少次口令")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@Schema(description = "禁止使用键盘连续3个字符")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@Schema(description = "禁止使用弱口令字典中的口令")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@Schema(description = "禁止账号名在密码中所占长度超过一半")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@Schema(description = "密码有效期天数")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@Schema(description = "密码修改后剩余多少天进行提示")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@Schema(description = "账号锁定后多久没启用进行账号注销")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@Schema(description = "密码错误时间窗口")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@Schema(description = "错误密码次数")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@Schema(description = "账号锁定分钟数")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@Schema(description = "账号有效期,默认值为90天")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@Schema(description = "账号有效期剩余天数提示,默认值为15天")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@Schema(description = "创建人 ID")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
package xtools.app.sys.model.dto.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRulePageReq</p>
|
||||
* <p>Description : 用户名密码规则分页请求对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserPasswdRulePageReq implements Serializable {
|
||||
|
||||
/**
|
||||
* 规则主键id
|
||||
*/
|
||||
@Schema(description = "规则主键id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@Schema(description = "规则名称")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@Schema(description = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@Schema(description = "规则编码")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 默认规则
|
||||
*/
|
||||
@Schema(description = "默认规则")
|
||||
private Integer ruleDefault;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@Schema(description = "最小密码长度")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@Schema(description = "最大密码长度")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@Schema(description = "最少数字字符个数")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@Schema(description = "最少特殊字符个数")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@Schema(description = "最少小写字母个数")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@Schema(description = "最少大写字母个数")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@Schema(description = "禁止使用历史最近多少次口令")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@Schema(description = "禁止使用键盘连续3个字符")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@Schema(description = "禁止使用弱口令字典中的口令")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@Schema(description = "禁止账号名在密码中所占长度超过一半")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@Schema(description = "密码有效期天数")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@Schema(description = "密码修改后剩余多少天进行提示")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@Schema(description = "账号锁定后多久没启用进行账号注销")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@Schema(description = "密码错误时间窗口")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@Schema(description = "错误密码次数")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@Schema(description = "账号锁定分钟数")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@Schema(description = "账号有效期,默认值为90天")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@Schema(description = "账号有效期剩余天数提示,默认值为15天")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@Schema(description = "创建人 ID")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String memo;
|
||||
|
||||
/**
|
||||
* 创建时间(范围)
|
||||
*/
|
||||
@Schema(description = "创建时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']")
|
||||
private Instant[] gmtCreateRange;
|
||||
|
||||
/**
|
||||
* 更新时间(范围)
|
||||
*/
|
||||
@Schema(description = "更新时间(范围)", example = "['2026-01-01 00:00:00', '2026-01-01 12:00:00']")
|
||||
private Instant[] gmtModifiedRange;
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
package xtools.app.sys.model.dto.req;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleUpdateReq</p>
|
||||
* <p>Description : 用户名密码规则更新请求对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class SysUserPasswdRuleUpdateReq implements Serializable {
|
||||
|
||||
/**
|
||||
* 规则主键id
|
||||
*/
|
||||
@Schema(description = "规则主键id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@Schema(description = "规则名称")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@Schema(description = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@Schema(description = "规则编码")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 默认规则
|
||||
*/
|
||||
@Schema(description = "默认规则")
|
||||
private Integer ruleDefault;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@Schema(description = "最小密码长度")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@Schema(description = "最大密码长度")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@Schema(description = "最少数字字符个数")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@Schema(description = "最少特殊字符个数")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@Schema(description = "最少小写字母个数")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@Schema(description = "最少大写字母个数")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@Schema(description = "禁止使用历史最近多少次口令")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@Schema(description = "禁止使用键盘连续3个字符")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@Schema(description = "禁止使用弱口令字典中的口令")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@Schema(description = "禁止账号名在密码中所占长度超过一半")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@Schema(description = "密码有效期天数")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@Schema(description = "密码修改后剩余多少天进行提示")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@Schema(description = "账号锁定后多久没启用进行账号注销")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@Schema(description = "密码错误时间窗口")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@Schema(description = "错误密码次数")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@Schema(description = "账号锁定分钟数")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@Schema(description = "账号有效期,默认值为90天")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@Schema(description = "账号有效期剩余天数提示,默认值为15天")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@Schema(description = "创建人 ID")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserUpdateReq</p>
|
||||
@@ -75,6 +76,12 @@ public class SysUserUpdateReq implements Serializable {
|
||||
@Schema(description = "状态", example = "1")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 账号失效时间,空则不失效
|
||||
*/
|
||||
@Schema(description = "账号失效时间,空则不失效")
|
||||
private Instant accountExpirationTime;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
|
||||
@@ -47,4 +47,10 @@ public class SysBaseUserInfoResp implements Serializable {
|
||||
*/
|
||||
@Schema(description = "按钮权限")
|
||||
private List<String> btnPerms;
|
||||
|
||||
/**
|
||||
* 提示信息
|
||||
*/
|
||||
@Schema(description = "提示信息")
|
||||
private List<String> tips;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,181 @@
|
||||
package xtools.app.sys.model.dto.resp;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import xtools.boot.api.model.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleResp</p>
|
||||
* <p>Description : 用户名密码规则响应对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class SysUserPasswdRuleResp extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 规则主键id
|
||||
*/
|
||||
@Schema(description = "规则主键id")
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@Schema(description = "规则名称")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@Schema(description = "规则描述")
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@Schema(description = "规则编码")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 默认规则
|
||||
*/
|
||||
@Schema(description = "默认规则")
|
||||
private Integer ruleDefault;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@Schema(description = "最小密码长度")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@Schema(description = "最大密码长度")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@Schema(description = "最少数字字符个数")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@Schema(description = "最少特殊字符个数")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@Schema(description = "最少小写字母个数")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@Schema(description = "最少大写字母个数")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@Schema(description = "禁止使用历史最近多少次口令")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@Schema(description = "禁止使用键盘连续3个字符")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@Schema(description = "禁止使用弱口令字典中的口令")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@Schema(description = "禁止账号名在密码中所占长度超过一半")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@Schema(description = "密码有效期天数")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@Schema(description = "密码修改后剩余多少天进行提示")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@Schema(description = "账号锁定后多久没启用进行账号注销")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@Schema(description = "密码错误时间窗口")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@Schema(description = "错误密码次数")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@Schema(description = "账号锁定分钟数")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@Schema(description = "账号有效期,默认值为90天")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@Schema(description = "账号有效期剩余天数提示,默认值为15天")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@Schema(description = "创建人 ID")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import xtools.boot.api.model.entity.BaseEntity;
|
||||
import xtools.boot.mask.anntation.Mask;
|
||||
import xtools.boot.mask.enums.MaskType;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -62,7 +63,7 @@ public class SysUserResp extends BaseEntity {
|
||||
* 手机号
|
||||
*/
|
||||
@Schema(description = "手机号", example = "13800138000")
|
||||
@Mask(value = MaskType.MOBILE_PHONE, always = true)
|
||||
@Mask(value = MaskType.MOBILE_PHONE)
|
||||
private String mobile;
|
||||
|
||||
/**
|
||||
@@ -78,13 +79,6 @@ public class SysUserResp extends BaseEntity {
|
||||
@Schema(description = "性别", example = "1")
|
||||
private Integer sex;
|
||||
|
||||
/**
|
||||
* 密码
|
||||
*/
|
||||
@Schema(description = "密码", example = "******")
|
||||
@Mask(MaskType.PASSWORD)
|
||||
private String passwd;
|
||||
|
||||
/**
|
||||
* 状态
|
||||
*/
|
||||
@@ -92,16 +86,10 @@ public class SysUserResp extends BaseEntity {
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
* 账号失效时间,空则不失效
|
||||
*/
|
||||
@Schema(description = "创建人 ID", example = "1")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID", example = "1")
|
||||
private Long updateBy;
|
||||
@Schema(description = "账号失效时间,空则不失效")
|
||||
private Instant accountExpirationTime;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -80,7 +81,7 @@ public class SysAddress extends BaseEntity {
|
||||
* 公用地址-备注
|
||||
*/
|
||||
@Schema(description = "公用地址-备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -94,6 +95,6 @@ public class SysDept extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -73,6 +74,6 @@ public class SysDict extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -94,6 +95,6 @@ public class SysDictItem extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -152,7 +153,7 @@ public class SysFile extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -157,6 +158,6 @@ public class SysLog extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -164,6 +165,6 @@ public class SysMenu extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -131,7 +132,7 @@ public class SysNotice extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -94,7 +95,7 @@ public class SysOptLog implements Serializable {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -73,7 +74,7 @@ public class SysParam extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -73,7 +74,7 @@ public class SysRisk extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -87,6 +88,6 @@ public class SysRole extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -52,6 +53,6 @@ public class SysRoleMenu extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -89,6 +90,6 @@ public class SysTask extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -66,6 +67,6 @@ public class SysUpdateHistory extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -11,6 +12,8 @@ import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import xtools.boot.api.model.entity.BaseEntity;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUser</p>
|
||||
* <p>Description : 系统用户表实体对象</p>
|
||||
@@ -97,6 +100,34 @@ public class SysUser extends BaseEntity {
|
||||
@TableField(value = "status")
|
||||
private Integer status;
|
||||
|
||||
/**
|
||||
* 历史密码
|
||||
*/
|
||||
@Schema(description = "历史密码")
|
||||
@TableField(value = "history_passwd")
|
||||
private String historyPasswd;
|
||||
|
||||
/**
|
||||
* 密码修改时间
|
||||
*/
|
||||
@Schema(description = "密码修改时间")
|
||||
@TableField(value = "passwd_gmt_modified")
|
||||
private Instant passwdGmtModified;
|
||||
|
||||
/**
|
||||
* 账号失效时间,空则不失效
|
||||
*/
|
||||
@Schema(description = "账号失效时间,空则不失效")
|
||||
@TableField(value = "account_expiration_time", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private Instant accountExpirationTime;
|
||||
|
||||
/**
|
||||
* 账号禁用时间
|
||||
*/
|
||||
@Schema(description = "账号禁用时间")
|
||||
@TableField(value = "account_disabled_time", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private Instant accountDisabledTime;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@@ -115,6 +146,6 @@ public class SysUser extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -75,7 +76,7 @@ public class SysUserNotice extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
import lombok.NoArgsConstructor;
|
||||
import xtools.boot.api.model.entity.BaseEntity;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRule</p>
|
||||
* <p>Description : 用户名密码规则实体对象</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@TableName("sys_user_passwd_rule")
|
||||
public class SysUserPasswdRule extends BaseEntity {
|
||||
|
||||
/**
|
||||
* 规则主键id
|
||||
*/
|
||||
@Schema(description = "规则主键id")
|
||||
@TableId(value = "id", type = IdType.ASSIGN_ID)
|
||||
private Long id;
|
||||
|
||||
/**
|
||||
* 规则名称
|
||||
*/
|
||||
@Schema(description = "规则名称")
|
||||
@TableField(value = "rule_name")
|
||||
private String ruleName;
|
||||
|
||||
/**
|
||||
* 规则描述
|
||||
*/
|
||||
@Schema(description = "规则描述")
|
||||
@TableField(value = "rule_desc", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String ruleDesc;
|
||||
|
||||
/**
|
||||
* 规则编码
|
||||
*/
|
||||
@Schema(description = "规则编码")
|
||||
@TableField(value = "rule_code")
|
||||
private String ruleCode;
|
||||
|
||||
/**
|
||||
* 默认规则
|
||||
*/
|
||||
@Schema(description = "默认规则")
|
||||
@TableField(value = "rule_default")
|
||||
private Integer ruleDefault;
|
||||
|
||||
/**
|
||||
* 最小密码长度
|
||||
*/
|
||||
@Schema(description = "最小密码长度")
|
||||
@TableField(value = "passwd_min_length")
|
||||
private Integer passwdMinLength;
|
||||
|
||||
/**
|
||||
* 最大密码长度
|
||||
*/
|
||||
@Schema(description = "最大密码长度")
|
||||
@TableField(value = "passwd_max_length")
|
||||
private Integer passwdMaxLength;
|
||||
|
||||
/**
|
||||
* 最少数字字符个数
|
||||
*/
|
||||
@Schema(description = "最少数字字符个数")
|
||||
@TableField(value = "min_num_count")
|
||||
private Integer minNumCount;
|
||||
|
||||
/**
|
||||
* 最少特殊字符个数
|
||||
*/
|
||||
@Schema(description = "最少特殊字符个数")
|
||||
@TableField(value = "min_spec_count")
|
||||
private Integer minSpecCount;
|
||||
|
||||
/**
|
||||
* 最少小写字母个数
|
||||
*/
|
||||
@Schema(description = "最少小写字母个数")
|
||||
@TableField(value = "min_lower_count")
|
||||
private Integer minLowerCount;
|
||||
|
||||
/**
|
||||
* 最少大写字母个数
|
||||
*/
|
||||
@Schema(description = "最少大写字母个数")
|
||||
@TableField(value = "min_upper_count")
|
||||
private Integer minUpperCount;
|
||||
|
||||
/**
|
||||
* 禁止使用历史最近多少次口令
|
||||
*/
|
||||
@Schema(description = "禁止使用历史最近多少次口令")
|
||||
@TableField(value = "his_passwd_count")
|
||||
private Integer hisPasswdCount;
|
||||
|
||||
/**
|
||||
* 禁止使用键盘连续3个字符
|
||||
*/
|
||||
@Schema(description = "禁止使用键盘连续3个字符")
|
||||
@TableField(value = "continuous_check")
|
||||
private Integer continuousCheck;
|
||||
|
||||
/**
|
||||
* 禁止使用弱口令字典中的口令
|
||||
*/
|
||||
@Schema(description = "禁止使用弱口令字典中的口令")
|
||||
@TableField(value = "invalid_check")
|
||||
private Integer invalidCheck;
|
||||
|
||||
/**
|
||||
* 禁止账号名在密码中所占长度超过一半
|
||||
*/
|
||||
@Schema(description = "禁止账号名在密码中所占长度超过一半")
|
||||
@TableField(value = "cover_half_check")
|
||||
private Integer coverHalfCheck;
|
||||
|
||||
/**
|
||||
* 密码有效期天数
|
||||
*/
|
||||
@Schema(description = "密码有效期天数")
|
||||
@TableField(value = "validity_days")
|
||||
private Integer validityDays;
|
||||
|
||||
/**
|
||||
* 密码修改后剩余多少天进行提示
|
||||
*/
|
||||
@Schema(description = "密码修改后剩余多少天进行提示")
|
||||
@TableField(value = "residue_tips_days")
|
||||
private Integer residueTipsDays;
|
||||
|
||||
/**
|
||||
* 账号锁定后多久没启用进行账号注销
|
||||
*/
|
||||
@Schema(description = "账号锁定后多久没启用进行账号注销")
|
||||
@TableField(value = "lock_cancel_days")
|
||||
private Integer lockCancelDays;
|
||||
|
||||
/**
|
||||
* 密码错误时间窗口
|
||||
*/
|
||||
@Schema(description = "密码错误时间窗口")
|
||||
@TableField(value = "error_passwd_window_minutes")
|
||||
private Integer errorPasswdWindowMinutes;
|
||||
|
||||
/**
|
||||
* 错误密码次数
|
||||
*/
|
||||
@Schema(description = "错误密码次数")
|
||||
@TableField(value = "error_passwd_count")
|
||||
private Integer errorPasswdCount;
|
||||
|
||||
/**
|
||||
* 账号锁定分钟数
|
||||
*/
|
||||
@Schema(description = "账号锁定分钟数")
|
||||
@TableField(value = "error_passwd_lock_minutes")
|
||||
private Integer errorPasswdLockMinutes;
|
||||
|
||||
/**
|
||||
* 账号有效期,默认值为90天
|
||||
*/
|
||||
@Schema(description = "账号有效期,默认值为90天")
|
||||
@TableField(value = "account_validity_days")
|
||||
private Integer accountValidityDays;
|
||||
|
||||
/**
|
||||
* 账号有效期剩余天数提示,默认值为15天
|
||||
*/
|
||||
@Schema(description = "账号有效期剩余天数提示,默认值为15天")
|
||||
@TableField(value = "account_tips_days")
|
||||
private Integer accountTipsDays;
|
||||
|
||||
/**
|
||||
* 创建人 ID
|
||||
*/
|
||||
@Schema(description = "创建人 ID")
|
||||
@TableField(value = "create_by")
|
||||
private Long createBy;
|
||||
|
||||
/**
|
||||
* 修改人 ID
|
||||
*/
|
||||
@Schema(description = "修改人 ID")
|
||||
@TableField(value = "update_by")
|
||||
private Long updateBy;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.FieldStrategy;
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
@@ -52,6 +53,6 @@ public class SysUserRole extends BaseEntity {
|
||||
* 备注
|
||||
*/
|
||||
@Schema(description = "备注")
|
||||
@TableField(value = "memo")
|
||||
@TableField(value = "memo", updateStrategy = FieldStrategy.ALWAYS)
|
||||
private String memo;
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package xtools.app.sys.service;
|
||||
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
|
||||
/**
|
||||
* <p>Title : SysPasswdService</p>
|
||||
* <p>Description : SysPasswdService</p>
|
||||
* <p>DevelopTools : Idea_x64_v2026.1</p>
|
||||
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : XuJun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026/6/4 09:32
|
||||
*/
|
||||
public interface SysPasswdService {
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
*/
|
||||
void checkPasswd(String passwd, String account);
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
* @param ruleCode 规则码
|
||||
*/
|
||||
void checkPasswd(String passwd, String account, String ruleCode);
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
* @param rule 规则
|
||||
*/
|
||||
void checkPasswd(String passwd, String account, SysUserPasswdRule rule);
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
package xtools.app.sys.service;
|
||||
|
||||
import xtools.app.sys.api.SysUserPasswdRuleApi;
|
||||
import xtools.app.sys.model.dto.excel.SysUserPasswdRuleExcel;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleAddReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRulePageReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleUpdateReq;
|
||||
import xtools.app.sys.model.dto.resp.SysUserPasswdRuleResp;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
import xtools.boot.api.model.dto.page.PageReq;
|
||||
import xtools.boot.api.model.dto.page.PageResp;
|
||||
import xtools.boot.api.model.dto.req.IdListReq;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleService</p>
|
||||
* <p>Description : 用户名密码规则 Service</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
public interface SysUserPasswdRuleService extends SysUserPasswdRuleApi {
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param pageReq 分页请求
|
||||
* @return 分页结果
|
||||
*/
|
||||
Result<PageResp<SysUserPasswdRuleResp>> page(PageReq<SysUserPasswdRulePageReq> pageReq);
|
||||
|
||||
/**
|
||||
* 根据 ID 查询
|
||||
*
|
||||
* @param id ID
|
||||
* @return 结果
|
||||
*/
|
||||
Result<SysUserPasswdRuleResp> getById(Long id);
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param req 添加请求
|
||||
* @return 添加结果
|
||||
*/
|
||||
Result<Boolean> add(SysUserPasswdRuleAddReq req);
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param req 修改请求
|
||||
* @return 修改结果
|
||||
*/
|
||||
Result<Boolean> update(SysUserPasswdRuleUpdateReq req);
|
||||
|
||||
/**
|
||||
* 根据 ID 删除
|
||||
*
|
||||
* @param req ID 集合
|
||||
* @return 删除结果
|
||||
*/
|
||||
Result<Boolean> delById(IdListReq req);
|
||||
|
||||
/**
|
||||
* 设置默认
|
||||
*
|
||||
* @param id ID
|
||||
* @return 设置结果
|
||||
*/
|
||||
Result<Boolean> setDef(Long id);
|
||||
|
||||
/**
|
||||
* 根据规则code获取数据,code为空则获取默认规则
|
||||
*
|
||||
* @param code code
|
||||
* @return 规则
|
||||
*/
|
||||
SysUserPasswdRule getByCode(String code);
|
||||
|
||||
/**
|
||||
* 导出 Excel
|
||||
*
|
||||
* @param req 请求参数
|
||||
* @return Excel 数据
|
||||
*/
|
||||
List<SysUserPasswdRuleExcel> exportExcel(SysUserPasswdRulePageReq req);
|
||||
|
||||
/**
|
||||
* 导入 Excel
|
||||
*
|
||||
* @param dataList Excel 数据
|
||||
*/
|
||||
void importExcel(List<SysUserPasswdRuleExcel> dataList);
|
||||
|
||||
}
|
||||
@@ -63,6 +63,14 @@ public interface SysUserService {
|
||||
*/
|
||||
Result<Boolean> delById(List<Long> idList);
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*
|
||||
* @param id ID
|
||||
* @return 重置密码结果
|
||||
*/
|
||||
Result<Boolean> resetPasswd(Long id);
|
||||
|
||||
/**
|
||||
* 根据 ID 集合查询
|
||||
*
|
||||
@@ -87,4 +95,9 @@ public interface SysUserService {
|
||||
*/
|
||||
boolean saveSysUser(UserInfoEditReq req);
|
||||
|
||||
/**
|
||||
* 清理禁用账号Job
|
||||
*/
|
||||
void cleanSysUserJob();
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package xtools.app.sys.service.base;
|
||||
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import xtools.app.sys.mapper.SysUserPasswdRuleMapper;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleBaseService</p>
|
||||
* <p>Description : 用户名密码规则 BaseService</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Component
|
||||
public class SysUserPasswdRuleBaseService extends ServiceImpl<SysUserPasswdRuleMapper, SysUserPasswdRule> {
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package xtools.app.sys.service.impl;
|
||||
|
||||
import com.alibaba.fastjson2.JSONArray;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
@@ -7,6 +8,7 @@ import org.springframework.transaction.annotation.Transactional;
|
||||
import xtools.app.sys.auth.model.dto.LoginUserDto;
|
||||
import xtools.app.sys.auth.utils.AuthUtils;
|
||||
import xtools.app.sys.convert.SysBaseConvert;
|
||||
import xtools.app.sys.convert.SysUserConvert;
|
||||
import xtools.app.sys.model.dto.Sm2KeyDto;
|
||||
import xtools.app.sys.model.dto.req.IgnoreMaskReq;
|
||||
import xtools.app.sys.model.dto.req.UserInfoEditReq;
|
||||
@@ -15,19 +17,28 @@ import xtools.app.sys.model.dto.resp.SysBaseUserInfoResp;
|
||||
import xtools.app.sys.model.dto.resp.SysIpAddrResp;
|
||||
import xtools.app.sys.model.entity.SysMenu;
|
||||
import xtools.app.sys.model.entity.SysUser;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.app.sys.service.SysBaseService;
|
||||
import xtools.app.sys.service.SysCommonService;
|
||||
import xtools.app.sys.service.SysMenuService;
|
||||
import xtools.app.sys.service.SysPasswdService;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.app.sys.service.SysUserService;
|
||||
import xtools.app.sys.service.base.SysUserBaseService;
|
||||
import xtools.app.sys.utils.PasswdUtils;
|
||||
import xtools.base.config.BaseParams;
|
||||
import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
import xtools.boot.ip.utils.IpUtils;
|
||||
import xtools.core.CollectionUtils;
|
||||
import xtools.core.StringUtils;
|
||||
import xtools.core.time.InstantUtils;
|
||||
import xtools.extend.dto.IpAddrDto;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -49,6 +60,10 @@ public class SysBaseServiceImpl implements SysBaseService, BaseParams {
|
||||
|
||||
private final SysCommonService sysCommonService;
|
||||
|
||||
private final SysUserPasswdRuleService sysUserPasswdRuleService;
|
||||
|
||||
private final SysPasswdService sysPasswdService;
|
||||
|
||||
private final SysMenuService sysMenuService;
|
||||
|
||||
private final SysUserService sysUserService;
|
||||
@@ -57,6 +72,8 @@ public class SysBaseServiceImpl implements SysBaseService, BaseParams {
|
||||
|
||||
private final SysBaseConvert sysBaseConvert;
|
||||
|
||||
private final SysUserConvert sysUserConvert;
|
||||
|
||||
/**
|
||||
* 获取用户信息
|
||||
*
|
||||
@@ -64,15 +81,18 @@ public class SysBaseServiceImpl implements SysBaseService, BaseParams {
|
||||
*/
|
||||
@Override
|
||||
public Result<SysBaseUserInfoResp> getUserInfo() {
|
||||
// 用户信息响应
|
||||
SysBaseUserInfoResp resp = new SysBaseUserInfoResp();
|
||||
|
||||
// 获取登录用户信息
|
||||
LoginUserDto loginUser = AuthUtils.get();
|
||||
SysUser sysUser = sysUserBaseService.getById(loginUser.getId());
|
||||
if (Objects.isNull(sysUser)) {
|
||||
throw new BizWarning("用户不存在");
|
||||
}
|
||||
|
||||
// 用户信息响应
|
||||
SysBaseUserInfoResp resp = new SysBaseUserInfoResp();
|
||||
// 设置用户信息
|
||||
resp.setSysUser(sysUserService.getUserInfo(loginUser.getId()));
|
||||
|
||||
resp.setSysUser(sysUserConvert.entityToResp(sysUser));
|
||||
resp.setTips(checkUser(sysUser));
|
||||
// 获取用户角色信息
|
||||
List<Long> roleIds = loginUser.getRoleIds();
|
||||
if (CollectionUtils.isNotEmpty(roleIds)) {
|
||||
@@ -85,6 +105,35 @@ public class SysBaseServiceImpl implements SysBaseService, BaseParams {
|
||||
return Result.ok(resp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查用户信息
|
||||
*
|
||||
* @param sysUser 用户信息
|
||||
* @return 检查结果
|
||||
*/
|
||||
private List<String> checkUser(SysUser sysUser) {
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(null);
|
||||
if (Objects.isNull(rule)) {
|
||||
throw new BizError("安全规则不存在");
|
||||
}
|
||||
List<String> tips = new ArrayList<>();
|
||||
// 密码过期提醒
|
||||
Integer validityDays = rule.getValidityDays();
|
||||
if (validityDays > CP_NUM0) {
|
||||
Instant passwdGmtModified = sysUser.getPasswdGmtModified();
|
||||
if (Objects.nonNull(passwdGmtModified) && Instant.now().isAfter(passwdGmtModified.plus(validityDays - rule.getResidueTipsDays(), ChronoUnit.DAYS))) {
|
||||
Instant expirationTime = passwdGmtModified.plus(validityDays, ChronoUnit.DAYS);
|
||||
tips.add("密码将于[" + InstantUtils.format(expirationTime) + "]过期,请及时修改密码,届时将无法登录");
|
||||
}
|
||||
}
|
||||
// 账号过期提醒
|
||||
Instant accountExpirationTime = sysUser.getAccountExpirationTime();
|
||||
if (Objects.nonNull(accountExpirationTime) && Instant.now().isAfter(accountExpirationTime.plus(-rule.getAccountTipsDays(), ChronoUnit.DAYS))) {
|
||||
tips.add("账户将于[" + InstantUtils.format(accountExpirationTime) + "]过期,请联系管理员,届时将无法登录");
|
||||
}
|
||||
return tips;
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改用户信息
|
||||
*
|
||||
@@ -115,15 +164,50 @@ public class SysBaseServiceImpl implements SysBaseService, BaseParams {
|
||||
Long userId = AuthUtils.get().getId();
|
||||
SysUser sysUser = sysUserBaseService.getById(userId);
|
||||
if (Objects.isNull(sysUser)) {
|
||||
throw new BizError("用户不存在");
|
||||
throw new BizWarning("用户不存在");
|
||||
}
|
||||
if (!PasswdUtils.check(oldPasswd, sysUser.getPasswd())) {
|
||||
throw new BizError("原密码错误");
|
||||
throw new BizWarning("原密码错误");
|
||||
}
|
||||
// 获取安全规则
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(null);
|
||||
if (Objects.isNull(rule)) {
|
||||
throw new BizError("安全规则不存在");
|
||||
}
|
||||
// 检查密码
|
||||
sysPasswdService.checkPasswd(passwd, sysUser.getAccount(), rule);
|
||||
// 加密密码
|
||||
String encryptPasswd = PasswdUtils.encrypt(passwd);
|
||||
// 历史密码
|
||||
final Integer hisPasswdCount = rule.getHisPasswdCount();
|
||||
String historyPasswd = sysUser.getHistoryPasswd();
|
||||
JSONArray historyPasswdArr;
|
||||
if (StringUtils.isBlank(historyPasswd)) {
|
||||
historyPasswdArr = new JSONArray();
|
||||
} else {
|
||||
historyPasswdArr = JSONArray.parseArray(historyPasswd);
|
||||
}
|
||||
// 检查历史密码
|
||||
int size = historyPasswdArr.size();
|
||||
if (hisPasswdCount > CP_NUM0 && historyPasswdArr.contains(encryptPasswd)) {
|
||||
for (int i = size - CP_NUM1; i > size - hisPasswdCount; i--) {
|
||||
if (historyPasswdArr.getString(i).equals(encryptPasswd)) {
|
||||
throw new BizWarning("密码不能与近" + hisPasswdCount + "次的历史密码相同");
|
||||
}
|
||||
}
|
||||
}
|
||||
// 保存最近20次的历史密码
|
||||
if (size >= CP_NUM20) {
|
||||
historyPasswdArr.removeFirst();
|
||||
}
|
||||
historyPasswdArr.add(sysUser.getPasswd());
|
||||
|
||||
// 修改密码
|
||||
SysUser update = new SysUser();
|
||||
update.setId(userId);
|
||||
update.setPasswd(PasswdUtils.encrypt(passwd));
|
||||
update.setHistoryPasswd(historyPasswdArr.toJSONString());
|
||||
update.setPasswdGmtModified(Instant.now());
|
||||
return Result.ok(sysUserBaseService.updateById(update));
|
||||
}
|
||||
|
||||
|
||||
@@ -15,8 +15,10 @@ import xtools.app.sys.convert.SysLoginConvert;
|
||||
import xtools.app.sys.model.dto.Sm2KeyDto;
|
||||
import xtools.app.sys.model.dto.req.SysLoginReq;
|
||||
import xtools.app.sys.model.entity.SysUser;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.app.sys.service.SysCommonService;
|
||||
import xtools.app.sys.service.SysLoginService;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.app.sys.service.base.SysUserBaseService;
|
||||
import xtools.app.sys.service.base.SysUserRoleBaseService;
|
||||
import xtools.app.sys.utils.PasswdUtils;
|
||||
@@ -25,6 +27,7 @@ import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
import xtools.boot.cache.redis.base.RedisService;
|
||||
import xtools.core.BytesUtils;
|
||||
import xtools.core.StringUtils;
|
||||
import xtools.core.dto.ArithmeticDto;
|
||||
import xtools.core.encrypt.Base64Utils;
|
||||
@@ -34,6 +37,8 @@ import xtools.core.img.ImgUtils;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@@ -54,9 +59,15 @@ import java.util.Objects;
|
||||
public class SysLoginServiceImpl implements SysLoginService, BaseParams {
|
||||
|
||||
private final SysCommonService sysCommonService;
|
||||
|
||||
private final SysUserPasswdRuleService sysUserPasswdRuleService;
|
||||
|
||||
private final SysUserRoleBaseService sysUserRoleBaseService;
|
||||
|
||||
private final SysUserBaseService sysUserBaseService;
|
||||
|
||||
private final SysLoginConvert sysLoginConvert;
|
||||
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
@@ -123,7 +134,7 @@ public class SysLoginServiceImpl implements SysLoginService, BaseParams {
|
||||
ArithmeticDto arithmeticDto = ArithmeticUtils.create();
|
||||
// 根据随机验证码生成图片验证码
|
||||
byte[] imgCode = ImgUtils.getBytesImgCode(128, 36, arithmeticDto.getArithmetic());
|
||||
if (imgCode == null) {
|
||||
if (BytesUtils.isEmpty(imgCode)) {
|
||||
throw new BizError("验证码生成失败");
|
||||
}
|
||||
AppCache cacheParam = AppCache.UID_CAPTCHA;
|
||||
@@ -168,10 +179,26 @@ public class SysLoginServiceImpl implements SysLoginService, BaseParams {
|
||||
throw new BizWarning("账户不存在");
|
||||
}
|
||||
SysUser user = userList.get(CP_NUM0);
|
||||
checkLock(user.getId());
|
||||
if (!Objects.equals(user.getStatus(), CP_NUM1)) {
|
||||
throw new BizWarning("账户被禁用");
|
||||
}
|
||||
Instant accountExpirationTime = user.getAccountExpirationTime();
|
||||
if (Objects.nonNull(accountExpirationTime) && Instant.now().isAfter(accountExpirationTime)) {
|
||||
throw new BizWarning("账户已过期,请联系管理员");
|
||||
}
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(null);
|
||||
if (Objects.isNull(rule)) {
|
||||
throw new BizError("安全规则不存在");
|
||||
}
|
||||
if (rule.getValidityDays() > CP_NUM0) {
|
||||
Instant passwdGmtModified = user.getPasswdGmtModified();
|
||||
if (Objects.nonNull(passwdGmtModified) && Instant.now().isAfter(passwdGmtModified.plus(rule.getValidityDays(), ChronoUnit.DAYS))) {
|
||||
throw new BizWarning("密码已过期,请联系管理员");
|
||||
}
|
||||
}
|
||||
if (!PasswdUtils.check(passwd, user.getPasswd())) {
|
||||
passwdError(user.getId(), rule);
|
||||
throw new BizWarning("密码错误");
|
||||
}
|
||||
LoginUserDto loginUserDto = sysLoginConvert.entityToCacheDto(user);
|
||||
@@ -179,4 +206,51 @@ public class SysLoginServiceImpl implements SysLoginService, BaseParams {
|
||||
redisService.del(captchaKey);
|
||||
return Result.ok(AuthUtils.createToken(loginUserDto));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 校验账号是否被锁定
|
||||
*
|
||||
* @param id 用户id
|
||||
*/
|
||||
private void checkLock(Long id) {
|
||||
String lockKey = getLockKey(id);
|
||||
Long lock = redisService.get(lockKey, Long.class);
|
||||
if (Objects.nonNull(lock)) {
|
||||
Long time = redisService.getExpire(lockKey);
|
||||
throw new BizWarning("账户已锁定,请" + Math.round(time / 60.0) + "分钟后解锁");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 密码错误
|
||||
*
|
||||
* @param id 用户id
|
||||
* @param rule 规则
|
||||
*/
|
||||
private void passwdError(Long id, SysUserPasswdRule rule) {
|
||||
String key = AppCache.COUNT_SYS_USER_PASSWD_ERR.key() + id;
|
||||
// 获取密码错误次数
|
||||
Long count = redisService.incr(key);
|
||||
if (count >= rule.getErrorPasswdCount()) {
|
||||
// 大于阈值锁定
|
||||
redisService.set(getLockKey(id), CP_NUM1, (long) rule.getErrorPasswdLockMinutes() * BaseParams.CP_NUM60);
|
||||
redisService.del(key);
|
||||
throw new BizWarning("密码错误次数超过" + rule.getErrorPasswdCount() + "次,账户已锁定" + rule.getErrorPasswdLockMinutes() + "分钟");
|
||||
} else {
|
||||
// 更新密码错误时间窗口
|
||||
redisService.expire(key, (long) rule.getErrorPasswdWindowMinutes() * BaseParams.CP_NUM60);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取锁定key
|
||||
*
|
||||
* @param id 用户id
|
||||
* @return 锁定key
|
||||
*/
|
||||
private String getLockKey(Long id) {
|
||||
return AppCache.LOCK_SYS_USER.key() + id;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
package xtools.app.sys.service.impl;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.app.sys.service.SysPasswdService;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.base.config.BaseParams;
|
||||
import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.core.StringUtils;
|
||||
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* <p>Title : SysPasswdServiceImpl</p>
|
||||
* <p>Description : SysPasswdServiceImpl</p>
|
||||
* <p>DevelopTools : Idea_x64_v2026.1</p>
|
||||
* <p>DevelopSystem : macOS Sequoia 15.7.5</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : XuJun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026/6/4 09:32
|
||||
*/
|
||||
@Primary
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysPasswdServiceImpl implements SysPasswdService, BaseParams {
|
||||
|
||||
/**
|
||||
* 键盘连续字符序列
|
||||
*/
|
||||
private static final String[] KEYBOARD_SEQUENCES = {
|
||||
"1234567890",
|
||||
"qwertyuiop",
|
||||
"asdfghjkl",
|
||||
"zxcvbnm",
|
||||
"qwerty",
|
||||
"asdfgh",
|
||||
"zxcvbn",
|
||||
"qazwsx",
|
||||
"edcrfv",
|
||||
"tgbyhn",
|
||||
"ujmik,"
|
||||
};
|
||||
/**
|
||||
* 常见弱口令列表
|
||||
*/
|
||||
private static final Set<String> WEAK_PASSWORDS = Set.of(
|
||||
"111111",
|
||||
"123456",
|
||||
"1234567",
|
||||
"12345678",
|
||||
"123456789",
|
||||
"1234567890",
|
||||
"abc123",
|
||||
"admin",
|
||||
"root",
|
||||
"password",
|
||||
"qwerty",
|
||||
"welcome",
|
||||
"monkey",
|
||||
"login",
|
||||
"princess",
|
||||
"dragon",
|
||||
"master",
|
||||
"qwertyuiop"
|
||||
);
|
||||
|
||||
private final SysUserPasswdRuleService sysUserPasswdRuleService;
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
*/
|
||||
@Override
|
||||
public void checkPasswd(String passwd, String account) {
|
||||
checkPasswd(passwd, account, CP_EMPTY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
* @param ruleCode 规则码
|
||||
*/
|
||||
@Override
|
||||
public void checkPasswd(String passwd, String account, String ruleCode) {
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(ruleCode);
|
||||
if (Objects.isNull(rule)) {
|
||||
throw new BizError("安全规则不存在");
|
||||
}
|
||||
checkPasswd(passwd, account, rule);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查密码
|
||||
*
|
||||
* @param passwd 密码
|
||||
* @param account 账号
|
||||
* @param rule 规则
|
||||
*/
|
||||
@Override
|
||||
public void checkPasswd(String passwd, String account, SysUserPasswdRule rule) {
|
||||
if (StringUtils.isBlank(passwd)) {
|
||||
throw new BizError("密码不能为空");
|
||||
}
|
||||
|
||||
// 校验最小密码长度
|
||||
if (Objects.nonNull(rule.getPasswdMinLength()) && passwd.length() < rule.getPasswdMinLength()) {
|
||||
throw new BizWarning("密码长度不能少于" + rule.getPasswdMinLength() + "个字符");
|
||||
}
|
||||
|
||||
// 校验最大密码长度
|
||||
if (Objects.nonNull(rule.getPasswdMaxLength()) && passwd.length() > rule.getPasswdMaxLength()) {
|
||||
throw new BizWarning("密码长度不能超过" + rule.getPasswdMaxLength() + "个字符");
|
||||
}
|
||||
|
||||
// 校验最少数字字符个数
|
||||
if (Objects.nonNull(rule.getMinNumCount()) && rule.getMinNumCount() > CP_NUM0) {
|
||||
int numCount = countMatches(passwd, "\\d");
|
||||
if (numCount < rule.getMinNumCount()) {
|
||||
throw new BizWarning("密码中至少需要包含" + rule.getMinNumCount() + "个数字");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验最少特殊字符个数
|
||||
if (Objects.nonNull(rule.getMinSpecCount()) && rule.getMinSpecCount() > CP_NUM0) {
|
||||
int specCount = countMatches(passwd, "[^a-zA-Z0-9]");
|
||||
if (specCount < rule.getMinSpecCount()) {
|
||||
throw new BizWarning("密码中至少需要包含" + rule.getMinSpecCount() + "个特殊字符");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验最少小写字母个数
|
||||
if (Objects.nonNull(rule.getMinLowerCount()) && rule.getMinLowerCount() > CP_NUM0) {
|
||||
int lowerCount = countMatches(passwd, "[a-z]");
|
||||
if (lowerCount < rule.getMinLowerCount()) {
|
||||
throw new BizWarning("密码中至少需要包含" + rule.getMinLowerCount() + "个小写字母");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验最少大写字母个数
|
||||
if (Objects.nonNull(rule.getMinUpperCount()) && rule.getMinUpperCount() > CP_NUM0) {
|
||||
int upperCount = countMatches(passwd, "[A-Z]");
|
||||
if (upperCount < rule.getMinUpperCount()) {
|
||||
throw new BizWarning("密码中至少需要包含" + rule.getMinUpperCount() + "个大写字母");
|
||||
}
|
||||
}
|
||||
|
||||
// 校验键盘连续字符
|
||||
if (Objects.nonNull(rule.getContinuousCheck()) && rule.getContinuousCheck() > CP_NUM0) {
|
||||
checkKeyboardSequence(passwd);
|
||||
}
|
||||
|
||||
// 校验弱口令字典
|
||||
if (Objects.nonNull(rule.getInvalidCheck()) && rule.getInvalidCheck() > CP_NUM0) {
|
||||
checkWeakPassword(passwd);
|
||||
}
|
||||
|
||||
// 校验账号名在密码中占比
|
||||
if (Objects.nonNull(rule.getCoverHalfCheck()) && rule.getCoverHalfCheck() > CP_NUM0) {
|
||||
checkAccountInPassword(passwd, account);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 统计正则匹配的次数
|
||||
*
|
||||
* @param password 密码
|
||||
* @param regex 正则表达式
|
||||
* @return 匹配次数
|
||||
*/
|
||||
private int countMatches(String password, String regex) {
|
||||
Pattern pattern = Pattern.compile(regex);
|
||||
Matcher matcher = pattern.matcher(password);
|
||||
int count = CP_NUM0;
|
||||
while (matcher.find()) {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查键盘连续字符
|
||||
*
|
||||
* @param password 密码
|
||||
*/
|
||||
private void checkKeyboardSequence(String password) {
|
||||
int length = CP_NUM3;
|
||||
String lowerPassword = password.toLowerCase();
|
||||
for (String sequence : KEYBOARD_SEQUENCES) {
|
||||
for (int i = CP_NUM0; i <= sequence.length() - length; i++) {
|
||||
String subSequence = sequence.substring(i, i + length);
|
||||
if (lowerPassword.contains(subSequence)) {
|
||||
throw new BizWarning("密码不能包含键盘连续字符");
|
||||
}
|
||||
// 检查反向序列
|
||||
String reversedSequence = new StringBuilder(subSequence).reverse().toString();
|
||||
if (lowerPassword.contains(reversedSequence)) {
|
||||
throw new BizWarning("密码不能包含键盘连续字符");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查弱口令
|
||||
*
|
||||
* @param password 密码
|
||||
*/
|
||||
private void checkWeakPassword(String password) {
|
||||
if (WEAK_PASSWORDS.contains(password.toLowerCase())) {
|
||||
throw new BizWarning("密码过于简单,请使用更复杂的密码");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查账号名在密码中的占比
|
||||
*
|
||||
* @param password 密码
|
||||
* @param account 账号名
|
||||
*/
|
||||
private void checkAccountInPassword(String password, String account) {
|
||||
if (StringUtils.isBlank(account)) {
|
||||
return;
|
||||
}
|
||||
String lowerPassword = password.toLowerCase();
|
||||
String lowerAccount = account.toLowerCase();
|
||||
// 检查账号名是否出现在密码中
|
||||
if (lowerPassword.contains(lowerAccount)) {
|
||||
// 计算账号名在密码中的占比
|
||||
double ratio = (double) account.length() / password.length();
|
||||
if (ratio > 0.5) {
|
||||
throw new BizWarning("账号名在密码中所占长度不能超过一半");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,377 @@
|
||||
package xtools.app.sys.service.impl;
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import xtools.app.common.cache.enums.AppCache;
|
||||
import xtools.app.sys.auth.model.dto.LoginUserDto;
|
||||
import xtools.app.sys.auth.utils.AuthUtils;
|
||||
import xtools.app.sys.convert.SysUserPasswdRuleConvert;
|
||||
import xtools.app.sys.model.dto.excel.SysUserPasswdRuleExcel;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleAddReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRulePageReq;
|
||||
import xtools.app.sys.model.dto.req.SysUserPasswdRuleUpdateReq;
|
||||
import xtools.app.sys.model.dto.resp.SysUserPasswdRuleResp;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.app.sys.service.base.SysUserPasswdRuleBaseService;
|
||||
import xtools.base.config.BaseParams;
|
||||
import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
import xtools.boot.api.model.dto.page.PageReq;
|
||||
import xtools.boot.api.model.dto.page.PageResp;
|
||||
import xtools.boot.api.model.dto.req.IdListReq;
|
||||
import xtools.boot.cache.redis.base.RedisService;
|
||||
import xtools.boot.db.mybatisplus.utils.QueryUtils;
|
||||
import xtools.core.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleServiceImpl</p>
|
||||
* <p>Description : 用户名密码规则 ServiceImpl</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@Primary
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserPasswdRuleServiceImpl implements SysUserPasswdRuleService, BaseParams {
|
||||
|
||||
private final static AppCache CACHE_PARAM = AppCache.SYS_CACHE_AP_RULE;
|
||||
private final SysUserPasswdRuleBaseService sysUserPasswdRuleBaseService;
|
||||
private final SysUserPasswdRuleConvert sysUserPasswdRuleConvert;
|
||||
@Resource
|
||||
private RedisService redisService;
|
||||
|
||||
/**
|
||||
* 分页查询
|
||||
*
|
||||
* @param pageReq 分页请求
|
||||
* @return 分页结果
|
||||
*/
|
||||
@Override
|
||||
public Result<PageResp<SysUserPasswdRuleResp>> page(PageReq<SysUserPasswdRulePageReq> pageReq) {
|
||||
// 分页查询
|
||||
Page<SysUserPasswdRule> page = getPageData(pageReq.getCurrentPage(), pageReq.getPageSize(), pageReq.getQuery());
|
||||
// 分装结果
|
||||
PageResp<SysUserPasswdRuleResp> pageResp = new PageResp<>(pageReq, page.getTotal(), sysUserPasswdRuleConvert.entityToRespList(page.getRecords()));
|
||||
return Result.ok(pageResp);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 查询
|
||||
*
|
||||
* @param id ID
|
||||
* @return 结果
|
||||
*/
|
||||
@Override
|
||||
public Result<SysUserPasswdRuleResp> getById(Long id) {
|
||||
SysUserPasswdRule data = sysUserPasswdRuleBaseService.getById(id);
|
||||
return Result.ok(sysUserPasswdRuleConvert.entityToResp(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加
|
||||
*
|
||||
* @param req 添加请求
|
||||
* @return 添加结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> add(SysUserPasswdRuleAddReq req) {
|
||||
SysUserPasswdRule entity = sysUserPasswdRuleConvert.addReqToEntity(req);
|
||||
if (Objects.nonNull(existsEntity(entity))) {
|
||||
throw new BizWarning("数据已存在");
|
||||
}
|
||||
LoginUserDto loginUser = AuthUtils.get();
|
||||
entity.setCreateBy(loginUser.getId());
|
||||
entity.setUpdateBy(loginUser.getId());
|
||||
return Result.ok(sysUserPasswdRuleBaseService.save(entity));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改
|
||||
*
|
||||
* @param req 修改请求
|
||||
* @return 修改结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> update(SysUserPasswdRuleUpdateReq req) {
|
||||
SysUserPasswdRule entity = sysUserPasswdRuleConvert.updateReqToEntity(req);
|
||||
if (Objects.nonNull(existsEntity(entity))) {
|
||||
throw new BizWarning("数据已存在");
|
||||
}
|
||||
LoginUserDto loginUser = AuthUtils.get();
|
||||
entity.setUpdateBy(loginUser.getId());
|
||||
boolean updated = sysUserPasswdRuleBaseService.updateById(entity);
|
||||
if (!updated) {
|
||||
throw new BizError("修改失败");
|
||||
}
|
||||
delCache();
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 删除
|
||||
*
|
||||
* @param req ID 集合
|
||||
* @return 删除结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> delById(IdListReq req) {
|
||||
boolean removed = sysUserPasswdRuleBaseService.removeByIds(req.getIdList());
|
||||
if (!removed) {
|
||||
throw new BizError("删除失败");
|
||||
}
|
||||
delCache();
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置默认
|
||||
*
|
||||
* @param id ID
|
||||
* @return 设置结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> setDef(Long id) {
|
||||
SysUserPasswdRule entity = new SysUserPasswdRule();
|
||||
entity.setRuleDefault(CP_NUM0);
|
||||
sysUserPasswdRuleBaseService.update(entity, null);
|
||||
|
||||
entity.setId(id);
|
||||
entity.setRuleDefault(CP_NUM1);
|
||||
sysUserPasswdRuleBaseService.updateById(entity);
|
||||
|
||||
delCache();
|
||||
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据规则code获取数据,code为空则获取默认规则
|
||||
*
|
||||
* @param code code
|
||||
* @return 规则
|
||||
*/
|
||||
@Override
|
||||
public SysUserPasswdRule getByCode(String code) {
|
||||
// 默认规则code
|
||||
String defaultCode = "default";
|
||||
|
||||
// 从缓存获取规则
|
||||
String cacheKey = StringUtils.isBlank(code) ? defaultCode : code;
|
||||
SysUserPasswdRule rule = redisService.hashGet(CACHE_PARAM.key(), cacheKey, SysUserPasswdRule.class);
|
||||
if (Objects.nonNull(rule)) {
|
||||
return rule;
|
||||
}
|
||||
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<SysUserPasswdRule> query = new LambdaQueryWrapper<>();
|
||||
if (StringUtils.isBlank(code)) {
|
||||
query.eq(SysUserPasswdRule::getRuleDefault, CP_NUM1);
|
||||
} else {
|
||||
query.eq(SysUserPasswdRule::getRuleCode, code);
|
||||
}
|
||||
rule = sysUserPasswdRuleBaseService.getOne(query);
|
||||
if (Objects.isNull(rule)) {
|
||||
return null;
|
||||
}
|
||||
redisService.hashPut(CACHE_PARAM.key(), cacheKey, rule);
|
||||
return rule;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
*/
|
||||
private void delCache() {
|
||||
redisService.del(CACHE_PARAM.key());
|
||||
}
|
||||
|
||||
/**
|
||||
* 导出 Excel
|
||||
*
|
||||
* @param req 请求参数
|
||||
* @return Excel 数据
|
||||
*/
|
||||
@Override
|
||||
public List<SysUserPasswdRuleExcel> exportExcel(SysUserPasswdRulePageReq req) {
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<SysUserPasswdRule> query = new LambdaQueryWrapper<>();
|
||||
// 查询字段
|
||||
query.select(
|
||||
SysUserPasswdRule::getRuleName
|
||||
, SysUserPasswdRule::getRuleDesc
|
||||
, SysUserPasswdRule::getRuleCode
|
||||
, SysUserPasswdRule::getPasswdMinLength
|
||||
, SysUserPasswdRule::getPasswdMaxLength
|
||||
, SysUserPasswdRule::getMinNumCount
|
||||
, SysUserPasswdRule::getMinSpecCount
|
||||
, SysUserPasswdRule::getMinLowerCount
|
||||
, SysUserPasswdRule::getMinUpperCount
|
||||
, SysUserPasswdRule::getHisPasswdCount
|
||||
, SysUserPasswdRule::getContinuousCheck
|
||||
, SysUserPasswdRule::getInvalidCheck
|
||||
, SysUserPasswdRule::getCoverHalfCheck
|
||||
, SysUserPasswdRule::getValidityDays
|
||||
, SysUserPasswdRule::getResidueTipsDays
|
||||
, SysUserPasswdRule::getLockCancelDays
|
||||
, SysUserPasswdRule::getErrorPasswdWindowMinutes
|
||||
, SysUserPasswdRule::getErrorPasswdCount
|
||||
, SysUserPasswdRule::getErrorPasswdLockMinutes
|
||||
, SysUserPasswdRule::getAccountValidityDays
|
||||
, SysUserPasswdRule::getAccountTipsDays
|
||||
, SysUserPasswdRule::getMemo
|
||||
);
|
||||
// 设置查询条件
|
||||
setQueryWrapper(query, req);
|
||||
// 排序
|
||||
query.orderByDesc(SysUserPasswdRule::getGmtCreate);
|
||||
List<SysUserPasswdRule> dataList = sysUserPasswdRuleBaseService.list(query);
|
||||
return dataList.stream().map(sysUserPasswdRuleConvert::entityToExcel).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 导入 Excel
|
||||
*
|
||||
* @param dataList Excel 数据
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void importExcel(List<SysUserPasswdRuleExcel> dataList) {
|
||||
for (SysUserPasswdRuleExcel excel : dataList) {
|
||||
SysUserPasswdRule item = sysUserPasswdRuleConvert.excelToEntity(excel);
|
||||
SysUserPasswdRule dbItem = existsEntity(item);
|
||||
if (Objects.isNull(dbItem)) {
|
||||
// 新增
|
||||
sysUserPasswdRuleBaseService.save(item);
|
||||
} else {
|
||||
// 修改
|
||||
item.setId(dbItem.getId());
|
||||
sysUserPasswdRuleBaseService.updateById(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取分页数据
|
||||
*
|
||||
* @param currentPage 当前页
|
||||
* @param pageSize 每页数量
|
||||
* @param req 请求参数
|
||||
* @return 分页数据
|
||||
*/
|
||||
private Page<SysUserPasswdRule> getPageData(Integer currentPage, Integer pageSize, SysUserPasswdRulePageReq req) {
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<SysUserPasswdRule> query = new LambdaQueryWrapper<>();
|
||||
// 查询字段
|
||||
query.select(
|
||||
SysUserPasswdRule::getId
|
||||
, SysUserPasswdRule::getRuleName
|
||||
, SysUserPasswdRule::getRuleDesc
|
||||
, SysUserPasswdRule::getRuleCode
|
||||
, SysUserPasswdRule::getRuleDefault
|
||||
, SysUserPasswdRule::getPasswdMinLength
|
||||
, SysUserPasswdRule::getPasswdMaxLength
|
||||
, SysUserPasswdRule::getMinNumCount
|
||||
, SysUserPasswdRule::getMinSpecCount
|
||||
, SysUserPasswdRule::getMinLowerCount
|
||||
, SysUserPasswdRule::getMinUpperCount
|
||||
, SysUserPasswdRule::getHisPasswdCount
|
||||
, SysUserPasswdRule::getContinuousCheck
|
||||
, SysUserPasswdRule::getInvalidCheck
|
||||
, SysUserPasswdRule::getCoverHalfCheck
|
||||
, SysUserPasswdRule::getValidityDays
|
||||
, SysUserPasswdRule::getResidueTipsDays
|
||||
, SysUserPasswdRule::getLockCancelDays
|
||||
, SysUserPasswdRule::getErrorPasswdWindowMinutes
|
||||
, SysUserPasswdRule::getErrorPasswdCount
|
||||
, SysUserPasswdRule::getErrorPasswdLockMinutes
|
||||
, SysUserPasswdRule::getAccountValidityDays
|
||||
, SysUserPasswdRule::getAccountTipsDays
|
||||
, SysUserPasswdRule::getCreateBy
|
||||
, SysUserPasswdRule::getUpdateBy
|
||||
, SysUserPasswdRule::getMemo
|
||||
, SysUserPasswdRule::getGmtCreate
|
||||
, SysUserPasswdRule::getGmtModified
|
||||
);
|
||||
// 设置查询条件
|
||||
setQueryWrapper(query, req);
|
||||
// 排序
|
||||
query.orderByDesc(SysUserPasswdRule::getGmtCreate);
|
||||
return sysUserPasswdRuleBaseService.page(QueryUtils.getPage(currentPage, pageSize), query);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置查询条件
|
||||
*
|
||||
* @param query 查询条件
|
||||
* @param req 请求参数
|
||||
*/
|
||||
private void setQueryWrapper(LambdaQueryWrapper<SysUserPasswdRule> query, SysUserPasswdRulePageReq req) {
|
||||
if (Objects.isNull(req)) {
|
||||
return;
|
||||
}
|
||||
// 查询条件
|
||||
query.eq(Objects.nonNull(req.getId()), SysUserPasswdRule::getId, req.getId());
|
||||
query.like(StringUtils.isNotBlank(req.getRuleName()), SysUserPasswdRule::getRuleName, req.getRuleName());
|
||||
query.like(StringUtils.isNotBlank(req.getRuleDesc()), SysUserPasswdRule::getRuleDesc, req.getRuleDesc());
|
||||
query.like(StringUtils.isNotBlank(req.getRuleCode()), SysUserPasswdRule::getRuleCode, req.getRuleCode());
|
||||
query.eq(Objects.nonNull(req.getRuleDefault()), SysUserPasswdRule::getRuleDefault, req.getRuleDefault());
|
||||
query.eq(Objects.nonNull(req.getPasswdMinLength()), SysUserPasswdRule::getPasswdMinLength, req.getPasswdMinLength());
|
||||
query.eq(Objects.nonNull(req.getPasswdMaxLength()), SysUserPasswdRule::getPasswdMaxLength, req.getPasswdMaxLength());
|
||||
query.eq(Objects.nonNull(req.getMinNumCount()), SysUserPasswdRule::getMinNumCount, req.getMinNumCount());
|
||||
query.eq(Objects.nonNull(req.getMinSpecCount()), SysUserPasswdRule::getMinSpecCount, req.getMinSpecCount());
|
||||
query.eq(Objects.nonNull(req.getMinLowerCount()), SysUserPasswdRule::getMinLowerCount, req.getMinLowerCount());
|
||||
query.eq(Objects.nonNull(req.getMinUpperCount()), SysUserPasswdRule::getMinUpperCount, req.getMinUpperCount());
|
||||
query.eq(Objects.nonNull(req.getHisPasswdCount()), SysUserPasswdRule::getHisPasswdCount, req.getHisPasswdCount());
|
||||
query.eq(Objects.nonNull(req.getContinuousCheck()), SysUserPasswdRule::getContinuousCheck, req.getContinuousCheck());
|
||||
query.eq(Objects.nonNull(req.getInvalidCheck()), SysUserPasswdRule::getInvalidCheck, req.getInvalidCheck());
|
||||
query.eq(Objects.nonNull(req.getCoverHalfCheck()), SysUserPasswdRule::getCoverHalfCheck, req.getCoverHalfCheck());
|
||||
query.eq(Objects.nonNull(req.getValidityDays()), SysUserPasswdRule::getValidityDays, req.getValidityDays());
|
||||
query.eq(Objects.nonNull(req.getResidueTipsDays()), SysUserPasswdRule::getResidueTipsDays, req.getResidueTipsDays());
|
||||
query.eq(Objects.nonNull(req.getLockCancelDays()), SysUserPasswdRule::getLockCancelDays, req.getLockCancelDays());
|
||||
query.eq(Objects.nonNull(req.getErrorPasswdWindowMinutes()), SysUserPasswdRule::getErrorPasswdWindowMinutes, req.getErrorPasswdWindowMinutes());
|
||||
query.eq(Objects.nonNull(req.getErrorPasswdCount()), SysUserPasswdRule::getErrorPasswdCount, req.getErrorPasswdCount());
|
||||
query.eq(Objects.nonNull(req.getErrorPasswdLockMinutes()), SysUserPasswdRule::getErrorPasswdLockMinutes, req.getErrorPasswdLockMinutes());
|
||||
query.eq(Objects.nonNull(req.getAccountValidityDays()), SysUserPasswdRule::getAccountValidityDays, req.getAccountValidityDays());
|
||||
query.eq(Objects.nonNull(req.getAccountTipsDays()), SysUserPasswdRule::getAccountTipsDays, req.getAccountTipsDays());
|
||||
query.eq(Objects.nonNull(req.getCreateBy()), SysUserPasswdRule::getCreateBy, req.getCreateBy());
|
||||
query.eq(Objects.nonNull(req.getUpdateBy()), SysUserPasswdRule::getUpdateBy, req.getUpdateBy());
|
||||
query.like(StringUtils.isNotBlank(req.getMemo()), SysUserPasswdRule::getMemo, req.getMemo());
|
||||
QueryUtils.addTimeRange(query, req.getGmtCreateRange(), SysUserPasswdRule::getGmtCreate);
|
||||
QueryUtils.addTimeRange(query, req.getGmtModifiedRange(), SysUserPasswdRule::getGmtModified);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断实体是否存在
|
||||
*
|
||||
* @param entity 实体
|
||||
* @return 是否存在
|
||||
*/
|
||||
private SysUserPasswdRule existsEntity(SysUserPasswdRule entity) {
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<SysUserPasswdRule> query = new LambdaQueryWrapper<>();
|
||||
// 查询字段
|
||||
query.select(SysUserPasswdRule::getId);
|
||||
// 排除当前数据
|
||||
query.ne(Objects.nonNull(entity.getId()), SysUserPasswdRule::getId, entity.getId());
|
||||
query.eq(StringUtils.isNotBlank(entity.getRuleCode()), SysUserPasswdRule::getRuleCode, entity.getRuleCode());
|
||||
// 校验数据时候存在的条件
|
||||
return sysUserPasswdRuleBaseService.getOne(query);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import xtools.app.common.task.enums.TaskType;
|
||||
import xtools.app.sys.auth.utils.AuthUtils;
|
||||
import xtools.app.sys.config.SysConfig;
|
||||
import xtools.app.sys.convert.SysUserConvert;
|
||||
@@ -15,11 +16,14 @@ import xtools.app.sys.model.dto.req.SysUserUpdateReq;
|
||||
import xtools.app.sys.model.dto.req.UserInfoEditReq;
|
||||
import xtools.app.sys.model.dto.resp.SysUserResp;
|
||||
import xtools.app.sys.model.entity.SysUser;
|
||||
import xtools.app.sys.model.entity.SysUserPasswdRule;
|
||||
import xtools.app.sys.service.SysUserPasswdRuleService;
|
||||
import xtools.app.sys.service.SysUserService;
|
||||
import xtools.app.sys.service.base.SysDeptBaseService;
|
||||
import xtools.app.sys.service.base.SysUserBaseService;
|
||||
import xtools.app.sys.service.base.SysUserRoleBaseService;
|
||||
import xtools.app.sys.utils.PasswdUtils;
|
||||
import xtools.base.config.BaseParams;
|
||||
import xtools.boot.api.exection.BizError;
|
||||
import xtools.boot.api.exection.BizWarning;
|
||||
import xtools.boot.api.model.dto.Result;
|
||||
@@ -27,9 +31,17 @@ import xtools.boot.api.model.dto.page.PageReq;
|
||||
import xtools.boot.api.model.dto.page.PageResp;
|
||||
import xtools.boot.api.model.dto.req.IdListReq;
|
||||
import xtools.boot.db.mybatisplus.utils.QueryUtils;
|
||||
import xtools.boot.log.LogBus;
|
||||
import xtools.boot.log.enums.LogBusBaseType;
|
||||
import xtools.boot.task.TaskBus;
|
||||
import xtools.boot.task.enums.TaskStatus;
|
||||
import xtools.core.StringUtils;
|
||||
import xtools.core.UuidUtils;
|
||||
import xtools.core.enums.LogLevel;
|
||||
import xtools.core.extend.CheckUtils;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
@@ -46,12 +58,14 @@ import java.util.Objects;
|
||||
@Primary
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class SysUserServiceImpl implements SysUserService {
|
||||
public class SysUserServiceImpl implements SysUserService, BaseParams {
|
||||
|
||||
private final SysConfig sysConfig;
|
||||
|
||||
private final SysDeptBaseService sysDeptBaseService;
|
||||
|
||||
private final SysUserPasswdRuleService sysUserPasswdRuleService;
|
||||
|
||||
private final SysUserRoleBaseService sysUserRoleBaseService;
|
||||
|
||||
private final SysUserBaseService sysUserBaseService;
|
||||
@@ -89,7 +103,6 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
SysUser data = sysUserBaseService.getById(id);
|
||||
SysUserResp sysUserResp = sysUserConvert.entityToResp(data);
|
||||
sysUserResp.setRoleIds(sysUserRoleBaseService.getUserRole(sysUserResp.getId()));
|
||||
sysUserResp.setPasswd(null);
|
||||
return Result.ok(sysUserResp);
|
||||
}
|
||||
|
||||
@@ -107,6 +120,13 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
throw new BizWarning("数据已存在");
|
||||
}
|
||||
entity.setPasswd(PasswdUtils.encrypt(sysConfig.getUser().getPasswd()));
|
||||
if (Objects.isNull(entity.getAccountExpirationTime())) {
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(null);
|
||||
Integer validityDays = rule.getAccountValidityDays();
|
||||
if (validityDays > CP_NUM0) {
|
||||
entity.setAccountExpirationTime(Instant.now().plus(validityDays, ChronoUnit.DAYS));
|
||||
}
|
||||
}
|
||||
boolean saved = sysUserBaseService.save(entity);
|
||||
if (!saved) {
|
||||
throw new BizError("添加失败");
|
||||
@@ -130,6 +150,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
throw new BizWarning("数据已存在");
|
||||
}
|
||||
entity.setPasswd(null);
|
||||
entity.setAccountDisabledTime(Objects.equals(entity.getStatus(), CP_NUM0) ? Instant.now() : null);
|
||||
boolean updated = sysUserBaseService.updateById(entity);
|
||||
if (!updated) {
|
||||
throw new BizError("修改失败");
|
||||
@@ -157,6 +178,30 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置密码
|
||||
*
|
||||
* @param id ID
|
||||
* @return 重置密码结果
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public Result<Boolean> resetPasswd(Long id) {
|
||||
SysUser entity = sysUserBaseService.getById(id);
|
||||
if (Objects.isNull(entity)) {
|
||||
throw new BizError("用户不存在");
|
||||
}
|
||||
SysUser update = new SysUser();
|
||||
update.setId(id);
|
||||
update.setPasswd(PasswdUtils.encrypt(sysConfig.getUser().getPasswd()));
|
||||
update.setPasswdGmtModified(Instant.now());
|
||||
boolean updated = sysUserBaseService.updateById(update);
|
||||
if (!updated) {
|
||||
throw new BizError("重置密码失败");
|
||||
}
|
||||
return Result.ok(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据 ID 集合查询
|
||||
*
|
||||
@@ -208,6 +253,7 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
SysUser::getEmail,
|
||||
SysUser::getSex,
|
||||
SysUser::getStatus,
|
||||
SysUser::getAccountExpirationTime,
|
||||
SysUser::getMemo,
|
||||
SysUser::getGmtCreate,
|
||||
SysUser::getGmtModified
|
||||
@@ -303,4 +349,60 @@ public class SysUserServiceImpl implements SysUserService {
|
||||
return sysUserBaseService.updateById(entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理禁用账号Job
|
||||
*/
|
||||
@Override
|
||||
public void cleanSysUserJob() {
|
||||
// 任务日志code
|
||||
String code = UuidUtils.get();
|
||||
// 任务类型
|
||||
TaskType taskType = TaskType.DEL_DISABLE_SYS_USER;
|
||||
|
||||
// 任务信息
|
||||
String info = "开始清理禁用账号,请稍候...";
|
||||
// 保存任务
|
||||
TaskBus.init(code, taskType, TaskStatus.ING).info(info).save();
|
||||
// 异常
|
||||
Exception ex = null;
|
||||
try {
|
||||
info = cleanSysUser();
|
||||
} catch (Exception e) {
|
||||
ex = e;
|
||||
info = "执行失败";
|
||||
throw e;
|
||||
} finally {
|
||||
// 保存任务
|
||||
TaskStatus status = Objects.isNull(ex) ? TaskStatus.SUCCESS : TaskStatus.ERROR;
|
||||
TaskBus.init(code, taskType, status).info(info).save();
|
||||
if (Objects.nonNull(ex)) {
|
||||
// 保存异常日志
|
||||
LogBus.init(LogLevel.ERROR, LogBusBaseType.TASK).error(ex).save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 清理禁用账号
|
||||
*
|
||||
* @return 清理结果
|
||||
*/
|
||||
private String cleanSysUser() {
|
||||
SysUserPasswdRule rule = sysUserPasswdRuleService.getByCode(null);
|
||||
if (Objects.isNull(rule)) {
|
||||
return "安全规则不存在";
|
||||
}
|
||||
Integer lockCancelDays = rule.getLockCancelDays();
|
||||
if (lockCancelDays <= CP_NUM0) {
|
||||
return "清理时间为0,则不清理禁用账号";
|
||||
}
|
||||
Instant time = Instant.now().plus(-lockCancelDays, ChronoUnit.DAYS);
|
||||
// 创建查询条件
|
||||
LambdaQueryWrapper<SysUser> query = new LambdaQueryWrapper<>();
|
||||
query.eq(SysUser::getStatus, CP_NUM0);
|
||||
query.le(SysUser::getAccountDisabledTime, time);
|
||||
boolean remove = sysUserBaseService.remove(query);
|
||||
return remove ? "清理成功" : "清理失败";
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package xtools.app.sys.call;
|
||||
|
||||
import org.springframework.web.service.annotation.HttpExchange;
|
||||
import xtools.app.sys.api.SysUserPasswdRuleApi;
|
||||
|
||||
/**
|
||||
* <p>Title : SysUserPasswdRuleCall</p>
|
||||
* <p>Description : 用户名密码规则 Call</p>
|
||||
* <p>Company : org.xujun</p>
|
||||
*
|
||||
* @author : xujun
|
||||
* @version : 1.0.0
|
||||
* @date : 2026-06-03 16:26:10
|
||||
*/
|
||||
@HttpExchange("/sys/user-passwd-rule")
|
||||
public interface SysUserPasswdRuleCall extends SysUserPasswdRuleApi {
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user