Skip to content

Commit

Permalink
v3.6.0 三级等保重磅更新:1、【新增】双因子方式登录;2、【新增】定期修改密码;3、【新增】最大活跃时间;4、【新增】敏感数据脱敏;…
Browse files Browse the repository at this point in the history
…5、【新增】登录锁定配置;6、【新增】密码复杂度配置;7、【新增】三级等保可配置
  • Loading branch information
zhuoda committed Sep 3, 2024
1 parent 50f5324 commit 85c6087
Show file tree
Hide file tree
Showing 160 changed files with 4,091 additions and 1,537 deletions.
45 changes: 37 additions & 8 deletions smart-admin-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<springboot.version>2.7.5</springboot.version>
<springboot.version>2.7.18</springboot.version>
<spring-mock.version>2.0.8</spring-mock.version>
<mybatis-plus.version>3.5.2</mybatis-plus.version>
<mysql-connector-j.version>8.0.33</mysql-connector-j.version>
<p6spy.version>3.9.1</p6spy.version>
<springdoc-openapi-ui.version>1.7.0</springdoc-openapi-ui.version>
<knife4j.version>4.3.0</knife4j.version>
Expand All @@ -42,7 +43,7 @@
<poi.version>5.2.4</poi.version>
<ooxml-schemas.version>1.4</ooxml-schemas.version>
<aws-java-sdk.version>1.11.842</aws-java-sdk.version>
<log4j-spring-boot.version>2.17.2</log4j-spring-boot.version>
<log4j-spring-boot.version>2.23.1</log4j-spring-boot.version>
<hutool.version>5.7.22</hutool.version>
<velocity-engine-core.version>2.3</velocity-engine-core.version>
<jjwt.version>0.9.1</jjwt.version>
Expand All @@ -52,8 +53,12 @@
<ip2region.version>2.7.0</ip2region.version>
<bcprov.version>1.59</bcprov.version>
<jackson-datatype-jsr310.version>2.13.4</jackson-datatype-jsr310.version>
<jackson-dataformat-yaml.version>2.16.1</jackson-dataformat-yaml.version>
<smartdb.version>1.2.0</smartdb.version>
<redisson.version>3.25.0</redisson.version>
<snakeyaml.version>2.2</snakeyaml.version>
<freemarker.version>2.3.33</freemarker.version>
<jsoup.version>1.18.1</jsoup.version>
</properties>

<dependencyManagement>
Expand Down Expand Up @@ -81,6 +86,12 @@
</exclusions>
</dependency>

<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>${mysql-connector-j.version}</version>
</dependency>

<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
Expand Down Expand Up @@ -201,12 +212,6 @@
<version>${commons-text.version}</version>
</dependency>

<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-spring-boot</artifactId>
<version>${log4j-spring-boot.version}</version>
</dependency>

<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
Expand Down Expand Up @@ -309,6 +314,12 @@
<version>${jackson-datatype-jsr310.version}</version>
</dependency>

<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>${jackson-dataformat-yaml.version}</version>
</dependency>

<dependency>
<groupId>net.1024lab</groupId>
<artifactId>smartdb</artifactId>
Expand Down Expand Up @@ -341,6 +352,24 @@
<version>${redisson.version}</version>
</dependency>

<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>${snakeyaml.version}</version>
</dependency>

<dependency>
<groupId>org.jsoup</groupId>
<artifactId>jsoup</artifactId>
<version>${jsoup.version}</version>
</dependency>

<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>

</dependencies>

</dependencyManagement>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,6 @@ public class AdminInterceptor implements HandlerInterceptor {
@Resource
private SystemEnvironment systemEnvironment;

@Value("${sa-token.active-timeout}")
private long tokenActiveTimeout;

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

Expand Down Expand Up @@ -158,11 +155,6 @@ private void checkActiveTimeout(RequestEmployee requestEmployee, boolean debugNu
return;
}

// 小于1 ,也不需要检测
if (tokenActiveTimeout < 1) {
return;
}

StpUtil.checkActiveTimeout();
StpUtil.updateLastActiveToNow();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package net.lab1024.sa.admin.module.business.goods.domain.form;

import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
import net.lab1024.sa.base.common.domain.PageParam;
import net.lab1024.sa.base.common.json.deserializer.DictValueVoDeserializer;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import org.hibernate.validator.constraints.Length;
Expand Down Expand Up @@ -32,6 +34,7 @@ public class GoodsQueryForm extends PageParam {
private Integer goodsStatus;

@Schema(description = "产地")
@JsonDeserialize(using = DictValueVoDeserializer.class)
private String place;

@Schema(description = "上架状态")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ public List<GoodsExcelVO> getAllGoods() {
GoodsExcelVO.builder()
.goodsStatus(SmartEnumUtil.getEnumDescByValue(e.getGoodsStatus(), GoodsStatusEnum.class))
.categoryName(categoryQueryService.queryCategoryName(e.getCategoryId()))
.place(dictCacheService.selectValueNameByValueCode(e.getPlace()))
.place(Arrays.stream(e.getPlace().split(",")).map(code -> dictCacheService.selectValueNameByValueCode(code)).collect(Collectors.joining(",")))
.price(e.getPrice())
.goodsName(e.getGoodsName())
.remark(e.getRemark())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,14 @@ List<NoticeEmployeeVO> queryEmployeeNotViewNotice(Page<?> page,
*/
void updateViewRecord(@Param("noticeId")Long noticeId, @Param("employeeId")Long requestEmployeeId,@Param("ip") String ip, @Param("userAgent")String userAgent);

/**
* 更新 浏览量
*
* @param noticeId 通知 id
* @param pageViewCountIncrement 页面浏览量的增量
* @param userViewCountIncrement 用户浏览量的增量
*/
void updateViewCount(@Param("noticeId")Long noticeId,@Param("pageViewCountIncrement") Integer pageViewCountIncrement, @Param("userViewCountIncrement")Integer userViewCountIncrement);


}
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ public class NoticeEmployeeService {
public ResponseDTO<PageResult<NoticeEmployeeVO>> queryList(Long requestEmployeeId, NoticeEmployeeQueryForm noticeEmployeeQueryForm) {
Page<?> page = SmartPageUtil.convert2PageQuery(noticeEmployeeQueryForm);

//获取请求人的 部门及其子部门
List<Long> employeeDepartmentIdList = Lists.newArrayList();
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity.getDepartmentId() != null) {
// 如果不是管理员 则获取请求人的 部门及其子部门
if (!employeeEntity.getAdministratorFlag() && employeeEntity.getDepartmentId() != null) {
employeeDepartmentIdList = departmentService.selfAndChildrenIdList(employeeEntity.getDepartmentId());
}

Expand Down Expand Up @@ -106,8 +106,15 @@ public ResponseDTO<NoticeDetailVO> view(Long requestEmployeeId, Long noticeId, S
long viewCount = noticeDao.viewRecordCount(noticeId, requestEmployeeId);
if (viewCount == 0) {
noticeDao.insertViewRecord(noticeId, requestEmployeeId, ip, userAgent, 1);
// 该员工对于这个通知是第一次查看 页面浏览量+1 用户浏览量+1
noticeDao.updateViewCount(noticeId, 1, 1);
noticeDetailVO.setPageViewCount(noticeDetailVO.getPageViewCount() + 1);
noticeDetailVO.setUserViewCount(noticeDetailVO.getUserViewCount() + 1);
} else {
noticeDao.updateViewRecord(noticeId, requestEmployeeId, ip, userAgent);
// 该员工对于这个通知不是第一次查看 页面浏览量+1 用户浏览量+0
noticeDao.updateViewCount(noticeId, 1, 0);
noticeDetailVO.setPageViewCount(noticeDetailVO.getPageViewCount() + 1);
}

return ResponseDTO.ok(noticeDetailVO);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,15 @@ public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
return treeVOList;
}

/**
/**
* 构建所有根节点的下级树形结构
*
* 返回值为层序遍历结果
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
*/
private void recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
int nodeSize = nodeList.size();
for (int i = 0; i < nodeSize; i++) {
List<Long> childIdList = new ArrayList<>();
for(int i = 0; i < nodeSize; i++) {
int preIndex = i - 1;
int nextIndex = i + 1;
DepartmentTreeVO node = nodeList.get(i);
Expand All @@ -158,16 +160,34 @@ private void recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<Department
node.setNextId(nodeList.get(nextIndex).getDepartmentId());
}

ArrayList<Long> selfAndAllChildrenIdList = Lists.newArrayList();
selfAndAllChildrenIdList.add(node.getDepartmentId());
node.setSelfAndAllChildrenIdList(selfAndAllChildrenIdList);

List<DepartmentTreeVO> children = getChildren(node.getDepartmentId(), allDepartmentList);

List<Long> tempChildIdList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(children)) {
node.setChildren(children);
this.recursiveBuildTree(children, allDepartmentList);
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
}

if(CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
node.setSelfAndAllChildrenIdList(
new ArrayList<>()
);
}
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());

if(CollectionUtils.isNotEmpty(tempChildIdList)) {
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
childIdList.addAll(tempChildIdList);
}

}

// 保证本层遍历顺序
for(int i = nodeSize - 1; i >= 0; i--) {
childIdList.add(0, nodeList.get(i).getDepartmentId());
}

return childIdList;
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public ResponseDTO<String> deleteDepartment(Long departmentId) {
}

// 是否有未删除员工
int employeeNum = employeeDao.countByDepartmentId(departmentId);
int employeeNum = employeeDao.countByDepartmentId(departmentId, Boolean.FALSE);
if (employeeNum > 0) {
return ResponseDTO.userErrorParam("请先删除部门员工");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartRequestUtil;
import net.lab1024.sa.base.module.support.apiencrypt.annotation.ApiDecrypt;
import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
Expand All @@ -23,7 +25,7 @@
* @Date 2021-12-09 22:57:49
* @Wechat zhuoda1024
* @Email [email protected]
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@RestController
@Tag(name = AdminSwaggerTagConst.System.SYSTEM_EMPLOYEE)
Expand All @@ -32,6 +34,9 @@ public class EmployeeController {
@Resource
private EmployeeService employeeService;

@Resource
private Level3ProtectConfigService level3ProtectConfigService;

@PostMapping("/employee/query")
@Operation(summary = "员工管理查询 @author 卓大")
public ResponseDTO<PageResult<EmployeeVO>> query(@Valid @RequestBody EmployeeQueryForm query) {
Expand Down Expand Up @@ -89,9 +94,17 @@ public ResponseDTO<String> batchUpdateDepartment(@Valid @RequestBody EmployeeBat

@Operation(summary = "修改密码 @author 卓大")
@PostMapping("/employee/update/password")
@ApiDecrypt
public ResponseDTO<String> updatePassword(@Valid @RequestBody EmployeeUpdatePasswordForm updatePasswordForm) {
updatePasswordForm.setEmployeeId(SmartRequestUtil.getRequestUserId());
return employeeService.updatePassword(updatePasswordForm);
return employeeService.updatePassword(SmartRequestUtil.getRequestUser(), updatePasswordForm);
}

@Operation(summary = "获取密码复杂度 @author 卓大")
@GetMapping("/employee/getPasswordComplexityEnabled")
@ApiDecrypt
public ResponseDTO<Boolean> getPasswordComplexityEnabled() {
return ResponseDTO.ok(level3ProtectConfigService.isPasswordComplexityEnabled());
}

@Operation(summary = "重置员工密码 @author 卓大")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ EmployeeEntity getByActualName(@Param("actualName") String actualName,
* 获取某个部门员工数
*
*/
Integer countByDepartmentId(@Param("departmentId") Long departmentId);
Integer countByDepartmentId(@Param("departmentId") Long departmentId, @Param("deletedFlag") Boolean deletedFlag);

/**
* 获取一批员工
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,11 @@ public class EmployeeEntity {
*/
private String phone;

/**
* 邮箱
*/
private String email;

/**
* 部门id
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ public class EmployeeAddForm {
@Pattern(regexp = SmartVerificationUtil.PHONE_REGEXP, message = "手机号格式不正确")
private String phone;

@Schema(description = "邮箱")
private String email;

@Schema(description = "角色列表")
private List<Long> roleIdList;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,9 @@ public class EmployeeUpdatePasswordForm {

@Schema(description = "原密码")
@NotBlank(message = "原密码不能为空哦")
@Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "原密码请输入6-15位(数字|大小写字母|小数点)")
private String oldPassword;

@Schema(description = "新密码")
@NotBlank(message = "新密码不能为空哦")
@Pattern(regexp = SmartVerificationUtil.PWD_REGEXP, message = "新密码请输入6-15位(数字|大小写字母|小数点)")
private String newPassword;
}
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,7 @@ public class EmployeeVO {
@Schema(description = "职务名称")
private String positionName;

@Schema(description = "邮箱")
private String email;

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,14 @@ public void updateEmployee(EmployeeEntity employee, List<Long> roleIdList) {
// 保存员工 获得id
employeeDao.updateById(employee);

if (CollectionUtils.isNotEmpty(roleIdList)) {
List<RoleEmployeeEntity> roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList());
this.updateEmployeeRole(employee.getEmployeeId(), roleEmployeeList);
// 若为空,则删除所有角色
if (CollectionUtils.isEmpty(roleIdList)) {
roleEmployeeDao.deleteByEmployeeId(employee.getEmployeeId());
return;
}

List<RoleEmployeeEntity> roleEmployeeList = roleIdList.stream().map(e -> new RoleEmployeeEntity(e, employee.getEmployeeId())).collect(Collectors.toList());
this.updateEmployeeRole(employee.getEmployeeId(), roleEmployeeList);
}

/**
Expand Down
Loading

0 comments on commit 85c6087

Please sign in to comment.