20 Commits
v3.19 ... v3.21

Author SHA1 Message Date
zhuoda
4d2be37e0e v3.21.0 【新增】修改部门名称字段;【新增】修改系统版本version字段;【新增】优化代码生成前端代码;【优化】SQL 2025-05-13 20:06:41 +08:00
zhuoda
d5abf42014 Merge branch 'master' of https://gitee.com/lab1024/smart-admin 2025-05-13 20:04:29 +08:00
zhuoda
8d2d8f2846 v3.21.0 【新增】修改部门名称字段;【新增】修改系统版本version字段;【新增】优化代码生成前端代码;【优化】SQL 2025-05-13 20:04:12 +08:00
1024创新实验室
0e06f36787 !74 【修复】数据变更记录getChangeContent解析列表返回空
Merge pull request !74 from 憨涛子/master
2025-05-10 15:28:19 +00:00
SillyBoy
012096a3ee 【修复】数据变更记录getChangeContent解析列表返回空 2025-05-10 10:43:33 +08:00
zhuoda
3fb4dfad09 v3.20.0 【新增】优化登录使用spring cache;【新增】优化部门cache;【新增】代码生成枚举;【优化】三级等保Label显示宽度 2025-05-03 21:31:28 +08:00
1024创新实验室
f198a949c9 !71 Fix: 修复三级等保配置页面部分Label被遮盖问题,优化 OA 模块代码结构
Merge pull request !71 from Engineer/master
2025-05-01 15:30:37 +00:00
钟家兴
41fad5b831 feat(sa-base): 实现主从数据源动态切换
- 新增 DataSource 注解用于切换数据源
- 实现 DynamicDataSourceHandler 动态数据源处理器
- 添加 DruidConfig 配置多数据源
- 更新 sa-base.yaml 配置文件,支持主从数据源
2025-05-01 23:26:22 +08:00
钟家兴
696db3835a fix(smart-admin-web-typescript): 三级等保配置页面部分Label被遮盖问题 2025-05-01 01:18:19 +08:00
钟家兴
40edf452ac fix(smart-admin-web-javascript): 三级等保配置页面部分Label被遮盖问题 2025-05-01 01:15:03 +08:00
钟家兴
c93616bec2 refactor(oa): 优化 OA 模块代码结构 Java8版本
- 银行相关代码:将 BankController、BankDao、BankService移至合适的包结构
- 数据范围控制器:将 DataScopeController移至 controller 包
- 企业相关代码:将 EnterpriseController、EnterpriseEmployeeManager、EnterpriseService 移至合适的包结构
- 发票相关代码:将 InvoiceController、InvoiceDao、InvoiceService 移至合适的包结构
- 更新相关 XML映射文件的命名空间
2025-05-01 00:20:05 +08:00
钟家兴
61c49b5798 refactor(oa): 优化 OA 模块代码结构
- 银行管理:将 BankController、BankDao、BankService 移至各自独立的包中
- 数据范围:将 DataScopeController移至独立包中
- 企业信息:将 EnterpriseController、EnterpriseEmployeeManager、EnterpriseService 移至各自独立的包中
- 发票管理:将 InvoiceController、InvoiceDao、InvoiceService 移至各自独立的包中
- 更新相关 XML 文件中的命名空间
2025-05-01 00:17:08 +08:00
1024创新实验室
54ad0e5893 !68 refactor(sa-base): 修正邮件服务类中的注释
Merge pull request !68 from Engineer/master
2025-04-27 07:29:55 +00:00
1024创新实验室
fa5b5c7def !67 优化代码生成模块的前端枚举
Merge pull request !67 from 大熊/code-generator
2025-04-27 07:29:28 +00:00
1024创新实验室
57270a7130 !66 在goods-list.vue页面销毁时移除 resize 事件监听器
Merge pull request !66 from luoyangxin/master
2025-04-27 07:29:12 +00:00
zhuoda
6c4cf9cc34 v3.19.1 ts引入错误 2025-04-27 15:13:20 +08:00
钟家兴
c49c1bbbfe refactor(sa-base): 修正邮件服务类中的注释
- 将"发生邮件"修改为"发送邮件",纠正了拼写错误
- 优化了代码注释的准确性,提高了代码可读性
2025-04-26 23:54:49 +08:00
钟家兴
47d41f0379 refactor(sa-base): 修正邮件服务类文档错别字
- 将"发生邮件"修改为"发送邮件",纠正了文档中的错别字
- 优化了代码注释,提高了代码可读性
2025-04-26 23:53:19 +08:00
zhoumingfa
3c3e3b4e32 优化代码生成模块的前端枚举 2025-04-18 16:49:14 +08:00
luoyangxin
7bad13fc23 在goods-list.vue页面销毁时移除 resize 事件监听器
Signed-off-by: luoyangxin <835168276@qq.com>
2025-04-14 02:23:17 +00:00
184 changed files with 1054 additions and 912 deletions

View File

@@ -20,11 +20,6 @@ public class AdminCacheConst extends CacheKeyConst {
*/
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
/**
* 部门map
*/
public static final String DEPARTMENT_MAP_CACHE = "department_map_cache";
/**
* 部门树
*/
@@ -54,4 +49,20 @@ public class AdminCacheConst extends CacheKeyConst {
public static final String CATEGORY_TREE = "category_tree_cache";
}
/**
* 登录相关
*/
public static class Login {
/**
* 请求用户信息
*/
public static final String REQUEST_EMPLOYEE = "login_request_employee";
/**
* 请求用户信息权限
*/
public static final String USER_PERMISSION = "login_user_permission";
}
}

View File

@@ -17,7 +17,7 @@ import org.hibernate.validator.constraints.Length;
* @Date 2021-10-25 20:26:54
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Data
public class GoodsQueryForm extends PageParam {

View File

@@ -1,6 +1,5 @@
package net.lab1024.sa.admin.module.business.goods.domain.vo;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
@@ -6,6 +6,7 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.bank.service.BankService;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,7 +7,6 @@ import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;

View File

@@ -1,8 +1,9 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.bank.dao.BankDao;
import net.lab1024.sa.admin.module.business.oa.bank.domain.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
@@ -7,6 +7,7 @@ import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.invoice.service.InvoiceService;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,7 +7,6 @@ import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;

View File

@@ -1,10 +1,11 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.enterprise.EnterpriseService;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.*;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;

View File

@@ -230,7 +230,7 @@ public class NoticeService {
noticeVisibleRange.setDataName(employeeEntity == null ? StringConst.EMPTY : employeeEntity.getActualName());
} else {
DepartmentVO departmentVO = departmentService.getDepartmentById(noticeVisibleRange.getDataId());
noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getName());
noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getDepartmentName());
}
}
updateFormVO.setVisibleRangeList(noticeVisibleRangeList);

View File

@@ -5,7 +5,6 @@ import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEnt
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -32,4 +31,5 @@ public interface DepartmentDao extends BaseMapper<DepartmentEntity> {
*/
List<DepartmentVO> listAll();
DepartmentVO selectDepartmentVO(@Param("departmentId")Long departmentId);
}

View File

@@ -31,7 +31,7 @@ public class DepartmentEntity {
/**
* 部门名称
*/
private String name;
private String departmentName;
/**
* 负责人员工 id

View File

@@ -20,7 +20,7 @@ public class DepartmentAddForm {
@Schema(description = "部门名称")
@Length(min = 1, max = 50, message = "请输入正确的部门名称(1-50个字符)")
@NotNull(message = "请输入正确的部门名称(1-50个字符)")
private String name;
private String departmentName;
@Schema(description = "排序")
@NotNull(message = "排序值")

View File

@@ -24,7 +24,7 @@ public class DepartmentVO implements Serializable {
private Long departmentId;
@Schema(description = "部门名称")
private String name;
private String departmentName;
@Schema(description = "部门负责人姓名")
private String managerName;

View File

@@ -29,7 +29,7 @@ import java.util.stream.Collectors;
* @Date 2022-01-12 20:37:48
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Service
@@ -42,7 +42,7 @@ public class DepartmentCacheManager {
log.info("clear " + cache);
}
@CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_MAP_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true)
@CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true)
public void clearCache() {
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
}
@@ -56,19 +56,8 @@ public class DepartmentCacheManager {
return departmentDao.listAll();
}
/**
* 部门map
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_MAP_CACHE)
public Map<Long, DepartmentVO> getDepartmentMap() {
return departmentDao.listAll().stream().collect(Collectors.toMap(DepartmentVO::getDepartmentId, Function.identity()));
}
/**
* 缓存部门树结构
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE)
public List<DepartmentTreeVO> getDepartmentTree() {
@@ -78,7 +67,6 @@ public class DepartmentCacheManager {
/**
* 缓存某个部门的下级id列表
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
@@ -89,7 +77,6 @@ public class DepartmentCacheManager {
/**
* 部门的路径名称
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
public Map<Long, String> getDepartmentPathMap() {
@@ -110,22 +97,21 @@ public class DepartmentCacheManager {
*/
private String buildDepartmentPath(DepartmentVO departmentVO, Map<Long, DepartmentVO> departmentMap) {
if (Objects.equals(departmentVO.getParentId(), NumberUtils.LONG_ZERO)) {
return departmentVO.getName();
return departmentVO.getDepartmentName();
}
//父节点
DepartmentVO parentDepartment = departmentMap.get(departmentVO.getParentId());
if (parentDepartment == null) {
return departmentVO.getName();
return departmentVO.getDepartmentName();
}
String pathName = buildDepartmentPath(parentDepartment, departmentMap);
return pathName + "/" + departmentVO.getName();
return pathName + "/" + departmentVO.getDepartmentName();
}
// ---------------------- 构造树的一些方法 ------------------------------
/**
* 构建部门树结构
*
*/
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
if (CollectionUtils.isEmpty(voList)) {
@@ -140,7 +126,7 @@ public class DepartmentCacheManager {
return treeVOList;
}
/**
/**
* 构建所有根节点的下级树形结构
* 返回值为层序遍历结果
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
@@ -148,7 +134,7 @@ public class DepartmentCacheManager {
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
int nodeSize = nodeList.size();
List<Long> childIdList = new ArrayList<>();
for(int i = 0; i < nodeSize; i++) {
for (int i = 0; i < nodeSize; i++) {
int preIndex = i - 1;
int nextIndex = i + 1;
DepartmentTreeVO node = nodeList.get(i);
@@ -167,14 +153,14 @@ public class DepartmentCacheManager {
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
}
if(CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
if (CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
node.setSelfAndAllChildrenIdList(
new ArrayList<>()
);
}
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
if(CollectionUtils.isNotEmpty(tempChildIdList)) {
if (CollectionUtils.isNotEmpty(tempChildIdList)) {
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
childIdList.addAll(tempChildIdList);
}
@@ -182,7 +168,7 @@ public class DepartmentCacheManager {
}
// 保证本层遍历顺序
for(int i = nodeSize - 1; i >= 0; i--) {
for (int i = nodeSize - 1; i >= 0; i--) {
childIdList.add(0, nodeList.get(i).getDepartmentId());
}
@@ -192,7 +178,6 @@ public class DepartmentCacheManager {
/**
* 获取子元素
*
*/
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
@@ -205,7 +190,6 @@ public class DepartmentCacheManager {
/**
* 通过部门id,获取当前以及下属部门
*
*/
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
List<Long> selfAndChildrenIdList = Lists.newArrayList();

View File

@@ -14,10 +14,7 @@ import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 部门 service
@@ -26,7 +23,7 @@ import java.util.Map;
* @Date 2022-01-12 20:37:48
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Service
public class DepartmentService {
@@ -44,7 +41,6 @@ public class DepartmentService {
/**
* 新增添加部门
*
*/
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
@@ -57,7 +53,6 @@ public class DepartmentService {
/**
* 更新部门信息
*
*/
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
if (updateDTO.getParentId() == null) {
@@ -78,7 +73,6 @@ public class DepartmentService {
* 根据id删除部门
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
* 2、需要判断当前部门是否有员工有员工则不能删除
*
*/
public ResponseDTO<String> deleteDepartment(Long departmentId) {
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
@@ -122,7 +116,6 @@ public class DepartmentService {
/**
* 自身以及所有下级的部门id列表
*
*/
public List<Long> selfAndChildrenIdList(Long departmentId) {
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
@@ -131,7 +124,6 @@ public class DepartmentService {
/**
* 获取所有部门
*
*/
public List<DepartmentVO> listAll() {
return departmentCacheManager.getDepartmentList();
@@ -140,10 +132,9 @@ public class DepartmentService {
/**
* 获取部门
*
*/
public DepartmentVO getDepartmentById(Long departmentId) {
return departmentCacheManager.getDepartmentMap().get(departmentId);
return departmentDao.selectDepartmentVO(departmentId);
}
/**
@@ -153,38 +144,4 @@ public class DepartmentService {
return departmentCacheManager.getDepartmentPathMap().get(departmentId);
}
/**
* 查询全部父级部门(不包含自己)
*
*/
public List<DepartmentVO> queryAllParentDepartment(Long departmentId) {
List<DepartmentVO> list = new ArrayList<>();
Map<Long, DepartmentVO> departmentMap = departmentCacheManager.getDepartmentMap();
DepartmentVO departmentVO = departmentMap.get(departmentId);
while (departmentVO != null) {
list.add(departmentVO);
departmentVO = departmentMap.get(departmentVO.getParentId());
}
Collections.reverse(list);
return list;
}
/**
* 查询全部父级部门(不包含自己)
*
*/
public List<Long> queryAllParentDepartmentIdList(Long departmentId) {
List<Long> list = new ArrayList<>();
Map<Long, DepartmentVO> departmentMap = departmentCacheManager.getDepartmentMap();
DepartmentVO departmentVO = departmentMap.get(departmentId);
while (departmentVO != null) {
list.add(departmentVO.getDepartmentId());
departmentVO = departmentMap.get(departmentVO.getParentId());
}
Collections.reverse(list);
return list;
}
}

View File

@@ -2,9 +2,7 @@ package net.lab1024.sa.admin.module.system.employee.domain.form;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import lombok.Data;
import net.lab1024.sa.base.common.util.SmartVerificationUtil;
/**
* 修改密码所需参数

View File

@@ -242,8 +242,6 @@ public class EmployeeService {
/**
* 更新登录人头像
*
* @param employeeUpdateAvatarForm
* @return
*/
public ResponseDTO<String> updateAvatar(EmployeeUpdateAvatarForm employeeUpdateAvatarForm) {
Long employeeId = employeeUpdateAvatarForm.getEmployeeId();
@@ -395,7 +393,7 @@ public class EmployeeService {
List<EmployeeVO> voList = employeeEntityList.stream().map(e -> {
EmployeeVO employeeVO = SmartBeanUtil.copy(e, EmployeeVO.class);
if (department != null) {
employeeVO.setDepartmentName(department.getName());
employeeVO.setDepartmentName(department.getDepartmentName());
}
return employeeVO;
}).collect(Collectors.toList());

View File

@@ -7,6 +7,8 @@ import net.lab1024.sa.base.common.enumeration.GenderEnum;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.io.Serializable;
/**
* 请求员工登录信息
*
@@ -17,7 +19,7 @@ import net.lab1024.sa.base.common.swagger.SchemaEnum;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Data
public class RequestEmployee implements RequestUser {
public class RequestEmployee implements RequestUser, Serializable {
@Schema(description = "员工id")
private Long employeeId;

View File

@@ -0,0 +1,162 @@
package net.lab1024.sa.admin.module.system.login.manager;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
import net.lab1024.sa.admin.module.system.role.service.RoleMenuService;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.UserPermission;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.module.support.file.service.IFileStorageService;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录Manager
*
* @Author 1024创新实验室: 卓大
* @Date 2025-05-03 22:56:34
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Service
public class LoginManager {
@Resource
private DepartmentService departmentService;
@Resource
private IFileStorageService fileStorageService;
@Resource
private EmployeeService employeeService;
@Resource
private RoleEmployeeService roleEmployeeService;
@Resource
private RoleMenuService roleMenuService;
/**
* 获取请求用户信息
*/
@Cacheable(AdminCacheConst.Login.REQUEST_EMPLOYEE)
public RequestEmployee getRequestEmployee(Long requestEmployeeId ) {
if (requestEmployeeId == null) {
return null;
}
// 员工基本信息
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity == null) {
return null;
}
return this.loadLoginInfo(employeeEntity);
}
/**
* 获取登录的用户信息
*/
@CachePut(value = AdminCacheConst.Login.REQUEST_EMPLOYEE, key = "#employeeEntity.employeeId")
public RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
// 基础信息
RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class);
requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE);
// 部门信息
DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId());
requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.getDepartmentName());
// 头像信息
String avatar = employeeEntity.getAvatar();
if (StringUtils.isNotBlank(avatar)) {
ResponseDTO<String> getFileUrl = fileStorageService.getFileUrl(avatar);
if (BooleanUtils.isTrue(getFileUrl.getOk())) {
requestEmployee.setAvatar(getFileUrl.getData());
}
}
return requestEmployee;
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
@Cacheable(AdminCacheConst.Login.USER_PERMISSION)
public UserPermission getUserPermission(Long employeeId) {
if(null == employeeId){
return null;
}
return this.loadUserPermission(employeeId);
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
@CachePut(AdminCacheConst.Login.USER_PERMISSION)
public UserPermission loadUserPermission(Long employeeId) {
UserPermission userPermission = new UserPermission();
userPermission.setPermissionList(new ArrayList<>());
userPermission.setRoleList(new ArrayList<>());
// 角色列表
List<RoleVO> roleList = roleEmployeeService.getRoleIdList(employeeId);
userPermission.getRoleList().addAll(roleList.stream().map(RoleVO::getRoleCode).collect(Collectors.toSet()));
// 前端菜单和功能点清单
EmployeeEntity employeeEntity = employeeService.getById(employeeId);
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), employeeEntity.getAdministratorFlag());
// 权限列表
HashSet<String> permissionSet = new HashSet<>();
for (MenuVO menu : menuAndPointsList) {
if (menu.getPermsType() == null) {
continue;
}
String perms = menu.getApiPerms();
if (StringUtils.isEmpty(perms)) {
continue;
}
//接口权限
String[] split = perms.split(",");
permissionSet.addAll(Arrays.asList(split));
}
userPermission.getPermissionList().addAll(permissionSet);
return userPermission;
}
@CacheEvict(value = {AdminCacheConst.Login.USER_PERMISSION, AdminCacheConst.Login.REQUEST_EMPLOYEE}, allEntries = true)
public void clear(){
}
}

View File

@@ -6,17 +6,16 @@ import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.servlet.JakartaServletUtil;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.LoginForm;
import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.login.manager.LoginManager;
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
@@ -48,21 +47,22 @@ import net.lab1024.sa.base.module.support.mail.MailService;
import net.lab1024.sa.base.module.support.mail.constant.MailTemplateCodeEnum;
import net.lab1024.sa.base.module.support.redis.RedisService;
import net.lab1024.sa.base.module.support.securityprotect.domain.LoginFailEntity;
import net.lab1024.sa.base.module.support.securityprotect.service.*;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService;
import net.lab1024.sa.base.module.support.securityprotect.service.SecurityLoginService;
import net.lab1024.sa.base.module.support.securityprotect.service.SecurityPasswordService;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录
*
* @Author 1024创新实验室: 开云
* @Date 2021-12-01 22:56:34
* @Author 1024创新实验室: 卓大
* @Date 2025-05-03 22:56:34
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
@@ -76,22 +76,6 @@ public class LoginService implements StpInterface {
*/
private static final String SUPER_PASSWORD_LOGIN_ID_PREFIX = "S";
/**
* 最大在线缓存人数
*/
private static final long CACHE_MAX_ONLINE_PERSON_COUNT = 1000L;
/**
* 登录信息二级缓存
*/
private final ConcurrentMap<Long, RequestEmployee> loginEmployeeCache = new ConcurrentLinkedHashMap.Builder<Long, RequestEmployee>().maximumWeightedCapacity(CACHE_MAX_ONLINE_PERSON_COUNT).build();
/**
* 权限 缓存
*/
private final ConcurrentMap<Long, UserPermission> permissionCache = new ConcurrentLinkedHashMap.Builder<Long, UserPermission>().maximumWeightedCapacity(CACHE_MAX_ONLINE_PERSON_COUNT).build();
@Resource
private EmployeeService employeeService;
@@ -134,6 +118,9 @@ public class LoginService implements StpInterface {
@Resource
private RedisService redisService;
@Resource
private LoginManager loginManager;
/**
* 获取验证码
*/
@@ -224,10 +211,7 @@ public class LoginService implements StpInterface {
}
// 获取员工信息
RequestEmployee requestEmployee = loadLoginInfo(employeeEntity);
// 放入缓存
loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee);
RequestEmployee requestEmployee = loginManager.loadLoginInfo(employeeEntity);
// 移除登录失败
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
@@ -242,8 +226,8 @@ public class LoginService implements StpInterface {
// 设置 token
loginResultVO.setToken(token);
// 清除权限缓存
permissionCache.remove(employeeEntity.getEmployeeId());
// 更新用户权限
loginManager.loadUserPermission(employeeEntity.getEmployeeId());
return ResponseDTO.ok(loginResultVO);
}
@@ -262,10 +246,6 @@ public class LoginService implements StpInterface {
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), requestEmployee.getAdministratorFlag());
loginResultVO.setMenuList(menuAndPointsList);
// 更新下后端权限缓存
UserPermission userPermission = getUserPermission(requestEmployee.getUserId());
permissionCache.put(requestEmployee.getUserId(), userPermission);
// 上次登录信息
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS);
if (loginLogVO != null) {
@@ -289,32 +269,6 @@ public class LoginService implements StpInterface {
}
/**
* 获取登录的用户信息
*/
private RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
// 基础信息
RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class);
requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE);
// 部门信息
DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId());
requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.getName());
// 头像信息
String avatar = employeeEntity.getAvatar();
if (StringUtils.isNotBlank(avatar)) {
ResponseDTO<String> getFileUrl = fileStorageService.getFileUrl(avatar);
if (BooleanUtils.isTrue(getFileUrl.getOk())) {
requestEmployee.setAvatar(getFileUrl.getData());
}
}
return requestEmployee;
}
/**
* 根据登陆token 获取员请求工信息
*/
@@ -328,17 +282,7 @@ public class LoginService implements StpInterface {
return null;
}
RequestEmployee requestEmployee = loginEmployeeCache.get(requestEmployeeId);
if (requestEmployee == null) {
// 员工基本信息
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity == null) {
return null;
}
requestEmployee = this.loadLoginInfo(employeeEntity);
loginEmployeeCache.put(requestEmployeeId, requestEmployee);
}
RequestEmployee requestEmployee = loginManager.getRequestEmployee(requestEmployeeId);
// 更新请求ip和user agent
requestEmployee.setUserAgent(JakartaServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
@@ -382,7 +326,7 @@ public class LoginService implements StpInterface {
StpUtil.logout();
// 清空登录信息缓存
loginEmployeeCache.remove(requestUser.getUserId());
loginManager.clear();
//保存登出日志
LoginLogEntity loginEntity = LoginLogEntity.builder()
@@ -400,14 +344,6 @@ public class LoginService implements StpInterface {
return ResponseDTO.ok();
}
/**
* 清除员工登录缓存
*/
public void clearLoginEmployeeCache(Long employeeId) {
// 清空登录信息缓存
loginEmployeeCache.remove(employeeId);
}
/**
* 保存登录日志
*/
@@ -435,12 +371,7 @@ public class LoginService implements StpInterface {
return Collections.emptyList();
}
UserPermission userPermission = permissionCache.get(employeeId);
if (userPermission == null) {
userPermission = getUserPermission(employeeId);
permissionCache.put(employeeId, userPermission);
}
UserPermission userPermission = loginManager.getUserPermission(employeeId);
return userPermission.getPermissionList();
}
@@ -451,51 +382,10 @@ public class LoginService implements StpInterface {
return Collections.emptyList();
}
UserPermission userPermission = permissionCache.get(employeeId);
if (userPermission == null) {
userPermission = getUserPermission(employeeId);
permissionCache.put(employeeId, userPermission);
}
UserPermission userPermission = loginManager.getUserPermission(employeeId);
return userPermission.getRoleList();
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
private UserPermission getUserPermission(Long employeeId) {
UserPermission userPermission = new UserPermission();
userPermission.setPermissionList(new ArrayList<>());
userPermission.setRoleList(new ArrayList<>());
// 角色列表
List<RoleVO> roleList = roleEmployeeService.getRoleIdList(employeeId);
userPermission.getRoleList().addAll(roleList.stream().map(RoleVO::getRoleCode).collect(Collectors.toSet()));
// 前端菜单和功能点清单
EmployeeEntity employeeEntity = employeeService.getById(employeeId);
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), employeeEntity.getAdministratorFlag());
// 权限列表
HashSet<String> permissionSet = new HashSet<>();
for (MenuVO menu : menuAndPointsList) {
if (menu.getPermsType() == null) {
continue;
}
String perms = menu.getApiPerms();
if (StringUtils.isEmpty(perms)) {
continue;
}
//接口权限
String[] split = perms.split(",");
permissionSet.addAll(Arrays.asList(split));
}
userPermission.getPermissionList().addAll(permissionSet);
return userPermission;
}
/**
* 发送 邮箱 验证码
@@ -590,4 +480,8 @@ public class LoginService implements StpInterface {
String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeId);
redisService.delete(redisVerificationCodeKey);
}
public void clearLoginEmployeeCache(Long employeeId) {
loginManager.clear();
}
}

View File

@@ -15,6 +15,7 @@ import net.lab1024.sa.base.common.code.SystemErrorCode;
import net.lab1024.sa.base.common.domain.RequestUrlVO;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -134,6 +135,10 @@ public class MenuService {
* @return true 重复 false 未重复
*/
public <T extends MenuBaseForm> Boolean validateWebPerms(T menuDTO) {
if(SmartStringUtil.isEmpty(menuDTO.getWebPerms())){
return false;
}
MenuEntity menu = menuDao.getByWebPerms(menuDTO.getWebPerms(), Boolean.FALSE);
if (menuDTO instanceof MenuAddForm) {
return menu != null;

View File

@@ -5,7 +5,6 @@ import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import java.util.List;
import java.util.Set;
/**

View File

@@ -3,11 +3,7 @@ package net.lab1024.sa.admin.module.system.role.manager;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.lab1024.sa.admin.module.system.role.dao.RoleEmployeeDao;
import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* 角色员工 manager

View File

@@ -73,7 +73,7 @@ public class RoleEmployeeService {
List<Long> departmentIdList = employeeList.stream().filter(e -> e != null && e.getDepartmentId() != null).map(EmployeeVO::getDepartmentId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(departmentIdList)) {
List<DepartmentEntity> departmentEntities = departmentDao.selectBatchIds(departmentIdList);
Map<Long, String> departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getName));
Map<Long, String> departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getDepartmentName));
employeeList.forEach(e -> {
e.setDepartmentName(departmentIdNameMap.getOrDefault(e.getDepartmentId(), StringConst.EMPTY));
});

View File

@@ -22,7 +22,6 @@ import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
/**
*
* 网络安全
*
* @Author 1024创新实验室-主任:卓大

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.bank.BankDao">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.bank.dao.BankDao">
<update id="deleteBank">
UPDATE t_oa_bank
SET deleted_flag = #{deletedFlag}

View File

@@ -70,7 +70,7 @@
<select id="queryPageEmployeeList"
resultType="net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO">
select
t_oa_enterprise_employee.*,
t_oa_enterprise_employee.enterprise_id,
t_oa_enterprise.enterprise_name,
t_employee.*,
t_employee.actual_name as employeeName

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.invoice.InvoiceDao">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao">
<update id="deleteInvoice">
UPDATE t_oa_invoice
SET deleted_flag = #{deletedFlag}

View File

@@ -219,7 +219,7 @@
<select id="queryNoticeViewRecordList" resultType="net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeViewRecordVO">
select t_notice_view_record.*,
t_employee.actual_name as employeeName,
t_department.name as departmentName
t_department.department_name
from t_notice_view_record
left join t_employee on t_employee.employee_id = t_notice_view_record.employee_id
left join t_department on t_department.department_id = t_employee.department_id

View File

@@ -6,7 +6,7 @@
<select id="listAll" resultType="net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO">
SELECT t_department.*,
t_employee.actual_name as managerName,
parent_department.`name` as parentName
parent_department.department_name as parentName
FROM t_department
left join t_employee on t_department.manager_id = t_employee.employee_id
left join t_department parent_department on t_department.parent_id = parent_department.department_id
@@ -19,5 +19,16 @@
WHERE parent_id = #{departmentId}
</select>
<select id="selectDepartmentVO"
resultType="net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO">
SELECT t_department.*,
t_employee.actual_name as managerName,
parent_department.department_name as parentName
FROM t_department
left join t_employee on t_department.manager_id = t_employee.employee_id
left join t_department parent_department on t_department.parent_id = parent_department.department_id
where t_department.department_id = #{departmentId}
</select>
</mapper>

View File

@@ -5,7 +5,7 @@
<select id="queryEmployee" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT
t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
<where>
@@ -169,7 +169,7 @@
<select id="getEmployeeById" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
where t_employee.employee_id = #{employeeId}
@@ -178,7 +178,7 @@
<select id="selectEmployeeByDisabledAndDeleted" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT
t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
<where>

View File

@@ -3,6 +3,7 @@ package net.lab1024.sa.base.common.controller;
import net.lab1024.sa.base.constant.SwaggerTagConst;
import org.springframework.web.bind.annotation.RequestMapping;
/**
* 支撑类业务路由基类
*

View File

@@ -2,6 +2,7 @@ package net.lab1024.sa.base.common.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
@@ -15,7 +16,7 @@ import java.util.List;
*/
@Data
public class UserPermission {
public class UserPermission implements Serializable {
/**
* 权限列表

View File

@@ -1,11 +1,14 @@
package net.lab1024.sa.base.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import net.lab1024.sa.base.module.support.cache.CacheService;
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.serializer.RedisSerializationContext;
/**
* 缓存配置
@@ -19,6 +22,15 @@ public class CacheConfig {
private static final String REDIS_CACHE = "redis";
private static final String CAFFEINE_CACHE = "caffeine";
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
public RedisCacheConfiguration redisCacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.disableCachingNullValues()
.computePrefixWith(name -> "cache:" + name + ":")
// .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericFastJsonRedisSerializer()));
;
}
@Bean
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)

View File

@@ -1,17 +1,8 @@
package net.lab1024.sa.base.module.support.cache;
import com.google.common.collect.Lists;
import jakarta.annotation.Resource;
import net.lab1024.sa.base.constant.ReloadConst;
import net.lab1024.sa.base.module.support.reload.core.annoation.SmartReload;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.stereotype.Service;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 缓存服务

View File

@@ -28,7 +28,7 @@ public class ChangeLogEntity {
/**
* 版本
*/
private String version;
private String updateVersion;
/**
* 更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]

View File

@@ -23,7 +23,7 @@ public class ChangeLogAddForm {
@Schema(description = "版本", required = true)
@NotBlank(message = "版本 不能为空")
private String version;
private String updateVersion;
@SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]")
@CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true)

View File

@@ -27,7 +27,7 @@ public class ChangeLogUpdateForm {
@Schema(description = "版本", required = true)
@NotBlank(message = "版本 不能为空")
private String version;
private String updateVersion;
@SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]")
@CheckEnum(value = ChangeLogTypeEnum.class, message = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复] 错误", required = true)

View File

@@ -23,7 +23,7 @@ public class ChangeLogVO {
private Long changeLogId;
@Schema(description = "版本")
private String version;
private String updateVersion;
@SchemaEnum(value = ChangeLogTypeEnum.class, desc = "更新类型:[1:特大版本功能更新;2:功能更新;3:bug修复]")
private Integer type;

View File

@@ -44,7 +44,7 @@ public class ChangeLogService {
* 添加
*/
public synchronized ResponseDTO<String> add(ChangeLogAddForm addForm) {
ChangeLogEntity existVersion = changeLogDao.selectByVersion(addForm.getVersion());
ChangeLogEntity existVersion = changeLogDao.selectByVersion(addForm.getUpdateVersion());
if (existVersion != null) {
return ResponseDTO.userErrorParam("此版本已经存在");
}
@@ -58,7 +58,7 @@ public class ChangeLogService {
* 更新
*/
public synchronized ResponseDTO<String> update(ChangeLogUpdateForm updateForm) {
ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getVersion());
ChangeLogEntity existVersion = changeLogDao.selectByVersion(updateForm.getUpdateVersion());
if (existVersion != null && !updateForm.getChangeLogId().equals(existVersion.getChangeLogId())) {
return ResponseDTO.userErrorParam("此版本已经存在");
}

View File

@@ -11,16 +11,6 @@ package net.lab1024.sa.base.module.support.codegenerator.constant;
*/
public class CodeGeneratorConstant {
/**
* 主键
*/
public final static String PRIMARY_KEY = "PRI";
/**
* 自增
*/
public final static String AUTO_INCREMENT = "auto_increment";
/**
* 默认逻辑删除字段名称
*/

View File

@@ -23,20 +23,26 @@ public class TableColumnVO {
@Schema(description = "列描述")
private String columnComment;
@Schema(description = "columnKey")
private String columnKey;
@Schema(description = "extra")
private String extra;
@Schema(description = "是否为空")
private String isNullable;
@Schema(description = "数据类型varchar")
private String dataType;
@Schema(description = "列类型varchar(50)")
private String columnType;
@Schema(description = "是否为空")
private Boolean nullableFlag;
@Schema(description = "是否为主键")
private Boolean primaryKeyFlag;
@Schema(description = "是否递增")
private Boolean autoIncreaseFlag;
// --------------- 临时字段 -------------------
@Schema(hidden = true)
private String columnKey;
@Schema(hidden = true)
private String extra;
@Schema(hidden = true)
private String isNullable;
}

View File

@@ -3,10 +3,8 @@ package net.lab1024.sa.base.module.support.codegenerator.service.variable.backen
import cn.hutool.core.bean.BeanUtil;
import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum;
import net.lab1024.sa.base.module.support.codegenerator.domain.form.CodeGeneratorConfigForm;
import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeInsertAndUpdateField;
import net.lab1024.sa.base.module.support.codegenerator.domain.model.CodeQueryField;
import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService;
import org.apache.commons.collections4.CollectionUtils;
import java.util.ArrayList;
import java.util.HashMap;

View File

@@ -47,7 +47,8 @@ public class ListVariableService extends CodeGenerateBaseVariableService {
CodeField codeField = getCodeFieldByColumnName(queryField.getColumnNameList().get(0), form);
if (CodeQueryFieldQueryTypeEnum.ENUM.equalsValue(queryField.getQueryTypeEnum())) {
objectMap.put("frontEnumName", codeField.getEnumName());
String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName());
objectMap.put("frontEnumName", upperUnderscoreEnum);
frontImportSet.add("import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';");
}
@@ -76,6 +77,12 @@ public class ListVariableService extends CodeGenerateBaseVariableService {
continue;
}
// 是否存在枚举
if (SmartStringUtil.isNotBlank(codeField.getEnumName())) {
String upperUnderscoreEnum = CaseFormat.UPPER_CAMEL.to(CaseFormat.UPPER_UNDERSCORE, codeField.getEnumName());
objectMap.put("frontEnumPlugin", "$smartEnumPlugin.getDescByValue('" + upperUnderscoreEnum + "', text)");
}
// 是否存在字典
if (SmartStringUtil.isNotBlank(codeField.getDict())) {
objectMap.put("dict", codeField.getDict());

View File

@@ -128,6 +128,16 @@ public class DataTracerChangeContentService {
return this.getAddDeleteContent(object);
}
/**
* 解析批量bean的内容
*
* @param objectList 对象列表
* @return 单个内容
*/
public <T> String getChangeContent(List<T> objectList) {
return this.getObjectListContent(objectList);
}
// ---------------------------- 以下 是 私有private 方法 ----------------------------
/**
@@ -160,6 +170,7 @@ public class DataTracerChangeContentService {
return "【原数据】:<br/>" + oldContent + "<br/>" + "【新数据】:<br/>" + newContent;
}
/**
* 获取一个对象的内容信息
*

View File

@@ -43,7 +43,6 @@ public class HelpDocCatalogEntity {
/**
* 排序
*/
@TableField("`sort`")
private Integer sort;

View File

@@ -53,7 +53,6 @@ public class HelpDocEntity {
/**
* 排序
*/
@TableField("`sort`")
private Integer sort;
/**

View File

@@ -1,13 +1,8 @@
package net.lab1024.sa.base.module.support.job.api.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import net.lab1024.sa.base.common.validator.enumeration.CheckEnum;
import net.lab1024.sa.base.module.support.job.constant.SmartJobTriggerTypeEnum;
import org.hibernate.validator.constraints.Length;
/**
* 定时任务 更新

View File

@@ -33,7 +33,7 @@ import java.util.Map;
/**
*
* 发邮件:<br/>
* 发邮件:<br/>
* 1、支持直接发送 <br/>
* 2、支持使用邮件模板发送
*
@@ -47,7 +47,7 @@ import java.util.Map;
@Component
public class MailService {
@Autowired
@Resource
private JavaMailSender javaMailSender;
@Resource

View File

@@ -1,10 +1,13 @@
package net.lab1024.sa.base.module.support.message.domain;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.module.support.message.constant.MessageTemplateEnum;
import java.util.List;
import java.util.Map;
/**
@@ -25,6 +28,10 @@ public class MessageTemplateSendForm {
@NotNull(message = "接收者id不能为空")
private Long receiverUserId;
@Schema(description = "接收者id")
@NotEmpty(message = "接收者id不能为空")
private List<Long> receiverUserIdList;
/**
* 相关业务id | 可选
* 用于跳转具体业务

View File

@@ -11,9 +11,6 @@ import net.lab1024.sa.base.module.support.reload.core.thread.SmartReloadRunnable
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;
import org.springframework.util.ReflectionUtils;

View File

@@ -2,7 +2,6 @@ package net.lab1024.sa.base.module.support.reload.core.thread;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.base.module.support.reload.core.AbstractSmartReloadCommand;
import net.lab1024.sa.base.module.support.reload.core.SmartReloadManager;
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadItem;
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject;
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult;

View File

@@ -13,7 +13,7 @@ import java.lang.annotation.Target;
* @Date 2020-11-25 20:56:58
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)

View File

@@ -2,7 +2,6 @@ package net.lab1024.sa.base.module.support.repeatsubmit.ticket;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

View File

@@ -1,9 +1,7 @@
package net.lab1024.sa.base.module.support.repeatsubmit.ticket;
import net.lab1024.sa.base.module.support.repeatsubmit.annoation.RepeatSubmit;
import org.springframework.data.redis.core.ValueOperations;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/**

View File

@@ -5,6 +5,7 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.Resource;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.module.support.config.ConfigKeyEnum;
@@ -28,17 +29,29 @@ public class Level3ProtectConfigService {
/**
* 开启双因子登录,默认:开启
* -- GETTER --
* 开启双因子登录,默认:开启
*/
@Getter
private boolean twoFactorLoginEnabled = false;
/**
* 连续登录失败次数则锁定,-1表示不受限制可以一直尝试登录
* -- GETTER --
* 连续登录失败次数则锁定,-1表示不受限制可以一直尝试登录
*/
@Getter
private int loginFailMaxTimes = -1;
/**
* 连续登录失败锁定时间(单位:秒),-1表示不锁定建议锁定30分钟
* -- GETTER --
* 连续登录失败锁定时间(单位:秒),-1表示不锁定建议锁定30分钟
*/
@Getter
private int loginFailLockSeconds = 1800;
/**
@@ -48,61 +61,53 @@ public class Level3ProtectConfigService {
/**
* 密码复杂度 是否开启,默认:开启
* -- GETTER --
* 密码复杂度 是否开启,默认:开启
*/
@Getter
private boolean passwordComplexityEnabled = true;
/**
* 定期修改密码时间间隔默认默认建议90天更换密码
* -- GETTER --
* 定期修改密码时间间隔默认默认建议90天更换密码
*/
@Getter
private int regularChangePasswordDays = 90;
/**
* 定期修改密码不允许相同次数默认3次以内密码不能相同
* -- GETTER --
* 定期修改密码不允许相同次数默认3次以内密码不能相同
*/
@Getter
private int regularChangePasswordNotAllowRepeatTimes = 3;
/**
* 文件大小限制,单位 mb (默认50 mb)
* -- GETTER --
* 文件大小限制,单位 mb (默认50 mb)
*/
@Getter
private long maxUploadFileSizeMb = 50;
/**
* 文件检测,默认:不开启
* -- GETTER --
* 文件检测,默认:不开启
*/
@Getter
private boolean fileDetectFlag = false;
@Resource
private ConfigService configService;
/**
* 文件检测,默认:不开启
*/
public boolean isFileDetectFlag() {
return fileDetectFlag;
}
/**
* 文件大小限制,单位 mb (默认50 mb)
*/
public long getMaxUploadFileSizeMb() {
return maxUploadFileSizeMb;
}
/**
* 连续登录失败次数则锁定,-1表示不受限制可以一直尝试登录
*/
public int getLoginFailMaxTimes() {
return loginFailMaxTimes;
}
/**
* 连续登录失败锁定时间(单位:秒),-1表示不锁定建议锁定30分钟
*/
public int getLoginFailLockSeconds() {
return loginFailLockSeconds;
}
/**
* 最低活跃时间(单位:秒),超过此时间没有操作系统就会被冻结,默认-1 代表不限制,永不冻结; 默认 30分钟
*/
@@ -110,34 +115,6 @@ public class Level3ProtectConfigService {
return loginActiveTimeoutSeconds > 0 ? loginActiveTimeoutSeconds : -1;
}
/**
* 定期修改密码时间间隔默认默认建议90天更换密码
*/
public int getRegularChangePasswordDays() {
return regularChangePasswordDays;
}
/**
* 开启双因子登录,默认:开启
*/
public boolean isTwoFactorLoginEnabled() {
return twoFactorLoginEnabled;
}
/**
* 密码复杂度 是否开启,默认:开启
*/
public boolean isPasswordComplexityEnabled() {
return passwordComplexityEnabled;
}
/**
* 定期修改密码不允许相同次数默认3次以内密码不能相同
*/
public int getRegularChangePasswordNotAllowRepeatTimes() {
return regularChangePasswordNotAllowRepeatTimes;
}
@PostConstruct
void init() {
String configValue = configService.getConfigValue(ConfigKeyEnum.LEVEL3_PROTECT_CONFIG);

View File

@@ -6,7 +6,6 @@ import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import net.lab1024.sa.base.module.support.securityprotect.dao.PasswordLogDao;
import net.lab1024.sa.base.module.support.securityprotect.domain.PasswordLogEntity;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.security.crypto.argon2.Argon2PasswordEncoder;
import org.springframework.stereotype.Service;

View File

@@ -11,6 +11,8 @@ import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberDao;
import net.lab1024.sa.base.module.support.serialnumber.dao.SerialNumberRecordDao;
import net.lab1024.sa.base.module.support.serialnumber.domain.*;
import org.apache.commons.lang3.RandomUtils;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDate;
import java.time.LocalDateTime;
@@ -92,6 +94,7 @@ public abstract class SerialNumberBaseService implements SerialNumberService {
public abstract void initLastGenerateData(List<SerialNumberEntity> serialNumberEntityList);
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public String generate(SerialNumberIdEnum serialNumberIdEnum) {
List<String> generateList = this.generate(serialNumberIdEnum, 1);
if (generateList == null || generateList.isEmpty()) {
@@ -101,6 +104,7 @@ public abstract class SerialNumberBaseService implements SerialNumberService {
}
@Override
@Transactional(propagation = Propagation.REQUIRES_NEW)
public List<String> generate(SerialNumberIdEnum serialNumberIdEnum, int count) {
SerialNumberInfoBO serialNumberInfoBO = serialNumberMap.get(serialNumberIdEnum.getSerialNumberId());
if (serialNumberInfoBO == null) {

View File

@@ -60,22 +60,24 @@ public class SerialNumberRedisService extends SerialNumberBaseService {
public List<String> generateSerialNumberList(SerialNumberInfoBO serialNumberInfo, int count) {
SerialNumberGenerateResultBO serialNumberGenerateResult = null;
String lockKey = RedisKeyConst.Support.SERIAL_NUMBER + serialNumberInfo.getSerialNumberId();
try {
boolean lock = false;
for (int i = 0; i < MAX_GET_LOCK_COUNT; i++) {
try {
lock = redisService.getLock(lockKey, 60 * 1000L);
if (lock) {
break;
}
Thread.sleep(SLEEP_MILLISECONDS);
} catch (Throwable e) {
log.error(e.getMessage(), e);
boolean lock = false;
for (int i = 0; i < MAX_GET_LOCK_COUNT; i++) {
try {
lock = redisService.getLock(lockKey, 60 * 1000L);
if (lock) {
break;
}
Thread.sleep(SLEEP_MILLISECONDS);
} catch (Throwable e) {
log.error(e.getMessage(), e);
}
if (!lock) {
throw new BusinessException("SerialNumber 尝试5次未能生成单号");
}
}
if (!lock) {
throw new BusinessException("SerialNumber 尝试5次未能生成单号");
}
try {
// 获取上次的生成结果
SerialNumberLastGenerateBO lastGenerateBO = (SerialNumberLastGenerateBO) redisService.mget(
RedisKeyConst.Support.SERIAL_NUMBER_LAST_INFO,

View File

@@ -18,7 +18,7 @@ public class ${name.upperCamel}Entity {
#foreach ($field in $fields)
/**
* $field.label
* $field.columnComment
*/
#if($field.primaryKeyFlag && $field.autoIncreaseFlag)
@TableId(type = IdType.AUTO)

View File

@@ -89,6 +89,7 @@
<!---------- 表格 begin ----------->
<a-table
size="small"
:scroll="{ y: 800 }"
:dataSource="tableData"
:columns="columns"
rowKey="$!{primaryKeyFieldName}"
@@ -108,6 +109,13 @@
</template>
#end
#end
#foreach ($field in $listFields)
#if($field.frontEnumPlugin)
<template v-if="column.dataIndex === '$!{field.fieldName}'">
<span>{{ $!{field.frontEnumPlugin} }}</span>
</template>
#end
#end
#foreach ($field in $listFields)
#if($field.dict)
<template v-if="column.dataIndex === '$!{field.fieldName}'">

View File

@@ -67,7 +67,7 @@ spring:
# 缓存实现类型
cache:
type: caffeine
type: redis
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
server:

View File

@@ -14,7 +14,7 @@
</if>
<!--关键字-->
<if test="queryForm.keyword != null and queryForm.keyword != ''">
AND ( INSTR(t_change_log.version,#{queryForm.keyword})
AND ( INSTR(t_change_log.update_version,#{queryForm.keyword})
OR INSTR(t_change_log.publish_author,#{queryForm.keyword})
OR INSTR(t_change_log.content,#{queryForm.keyword})
)
@@ -35,12 +35,12 @@
AND t_change_log.link = #{queryForm.link}
</if>
</where>
order by t_change_log.version desc
order by t_change_log.update_version desc
</select>
<select id="selectByVersion"
resultType="net.lab1024.sa.base.module.support.changelog.domain.entity.ChangeLogEntity">
select * from t_change_log where `version` = #{version}
select * from t_change_log where update_version = #{version}
</select>

View File

@@ -13,7 +13,7 @@
<if test="query.userType != null">
AND user_type = #{query.userType}
</if>
<if test="query.ip != null">
<if test="query.ip != null and query.ip != ''">
AND INSTR(login_ip,#{query.ip})
</if>
<if test="query.startDate != null and query.startDate != ''">
@@ -25,9 +25,6 @@
<if test="query.userName != null and query.userName != ''">
AND INSTR(user_name,#{query.userName})
</if>
<if test="query.ip != null">
AND INSTR(login_ip,#{query.ip})
</if>
</where>
order by create_time desc
</select>
@@ -37,9 +34,9 @@
*
from t_login_log
where
user_id = #{userId}
and user_type = #{userType}
and login_result = #{loginLogResult}
user_id = #{userId}
and user_type = #{userType}
and login_result = #{loginLogResult}
order by login_log_id desc
limit 1
</select>

View File

@@ -23,10 +23,10 @@
AND INSTR(operate_user_name,#{query.userName})
</if>
<if test="query.keywords != null and query.keywords != ''">
AND (INSTR(`module`,#{query.keywords}) OR INSTR(content,#{query.keywords}))
AND (INSTR(module,#{query.keywords}) OR INSTR(content,#{query.keywords}))
</if>
<if test="query.requestKeywords != null and query.requestKeywords != ''">
AND (INSTR(`url`,#{query.requestKeywords}) OR INSTR(`method`,#{query.requestKeywords}) OR INSTR(`param`,#{query.requestKeywords}))
AND (INSTR(url,#{query.requestKeywords}) OR INSTR(method,#{query.requestKeywords}) OR INSTR(param,#{query.requestKeywords}))
</if>
<if test="query.successFlag != null">
AND success_flag = #{query.successFlag}

View File

@@ -67,7 +67,7 @@ spring:
# 缓存实现类型
cache:
type: caffeine
type: redis
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
server:
@@ -134,7 +134,7 @@ reload:
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: Authorization
# token 前缀 例如:Bear
# token 前缀 例如:Bearer
token-prefix: Bearer
# token 有效期(单位:秒) 默认30天2592000秒-1 代表永久有效
timeout: 2592000

View File

@@ -34,6 +34,7 @@ spring:
min-idle: 10
max-idle: 50
max-wait: 30000ms
# 邮件置以SSL的方式发送, 这个需要使用这种方式并且端口是465
mail:
host: smtp.163.com
@@ -66,7 +67,7 @@ spring:
# 缓存实现类型
cache:
type: caffeine
type: redis
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
server:
@@ -106,7 +107,7 @@ springdoc:
knife4j:
enable: true
basic:
enable: true
enable: false
username: api # Basic认证用户名
password: 1024 # Basic认证密码
@@ -131,7 +132,7 @@ reload:
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: Authorization
# token 前缀 例如:Bear
# token 前缀 例如:Bearer
token-prefix: Bearer
# token 有效期(单位:秒) 默认30天2592000秒-1 代表永久有效
timeout: 2592000

View File

@@ -67,7 +67,7 @@ spring:
# 缓存实现类型
cache:
type: caffeine
type: redis
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
server:
@@ -134,7 +134,7 @@ reload:
sa-token:
# token 名称(同时也是 cookie 名称)
token-name: Authorization
# token 前缀 例如:Bear
# token 前缀 例如:Bearer
token-prefix: Bearer
# token 有效期(单位:秒) 默认30天2592000秒-1 代表永久有效
timeout: 2592000

View File

@@ -20,11 +20,6 @@ public class AdminCacheConst extends CacheKeyConst {
*/
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
/**
* 部门map
*/
public static final String DEPARTMENT_MAP_CACHE = "department_map_cache";
/**
* 部门树
*/
@@ -54,4 +49,20 @@ public class AdminCacheConst extends CacheKeyConst {
public static final String CATEGORY_TREE = "category_tree_cache";
}
/**
* 登录相关
*/
public static class Login {
/**
* 请求用户信息
*/
public static final String REQUEST_EMPLOYEE = "login_request_employee";
/**
* 请求用户信息权限
*/
public static final String USER_PERMISSION = "login_user_permission";
}
}

View File

@@ -1,9 +1,10 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.bank.service.BankService;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankCreateForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankUpdateForm;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,7 +7,6 @@ import net.lab1024.sa.admin.module.business.oa.bank.domain.BankQueryForm;
import net.lab1024.sa.admin.module.business.oa.bank.domain.BankVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;

View File

@@ -1,7 +1,8 @@
package net.lab1024.sa.admin.module.business.oa.bank;
package net.lab1024.sa.admin.module.business.oa.bank.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.bank.dao.BankDao;
import net.lab1024.sa.admin.module.business.oa.bank.domain.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseDao;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.entity.EnterpriseEntity;

View File

@@ -1,10 +1,11 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
package net.lab1024.sa.admin.module.business.oa.enterprise.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.enterprise.service.EnterpriseService;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.form.*;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
package net.lab1024.sa.admin.module.business.oa.enterprise.manager;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.enterprise;
package net.lab1024.sa.admin.module.business.oa.enterprise.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
@@ -12,6 +12,7 @@ import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEm
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.business.oa.enterprise.manager.EnterpriseEmployeeManager;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.base.common.code.UserErrorCode;
import net.lab1024.sa.base.common.domain.PageResult;

View File

@@ -1,10 +1,11 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
import net.lab1024.sa.admin.module.business.oa.invoice.service.InvoiceService;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceAddForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceUpdateForm;

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.dao;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -7,7 +7,6 @@ import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceQueryForm;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.InvoiceVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;

View File

@@ -1,9 +1,10 @@
package net.lab1024.sa.admin.module.business.oa.invoice;
package net.lab1024.sa.admin.module.business.oa.invoice.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.business.oa.enterprise.EnterpriseService;
import net.lab1024.sa.admin.module.business.oa.enterprise.service.EnterpriseService;
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseVO;
import net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao;
import net.lab1024.sa.admin.module.business.oa.invoice.domain.*;
import net.lab1024.sa.base.common.domain.PageResult;
import net.lab1024.sa.base.common.domain.ResponseDTO;

View File

@@ -230,7 +230,7 @@ public class NoticeService {
noticeVisibleRange.setDataName(employeeEntity == null ? StringConst.EMPTY : employeeEntity.getActualName());
} else {
DepartmentVO departmentVO = departmentService.getDepartmentById(noticeVisibleRange.getDataId());
noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getName());
noticeVisibleRange.setDataName(departmentVO == null ? StringConst.EMPTY : departmentVO.getDepartmentName());
}
}
updateFormVO.setVisibleRangeList(noticeVisibleRangeList);

View File

@@ -1,4 +1,4 @@
package net.lab1024.sa.admin.module.system.datascope;
package net.lab1024.sa.admin.module.system.datascope.controller;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;

View File

@@ -5,7 +5,6 @@ import net.lab1024.sa.admin.module.system.department.domain.entity.DepartmentEnt
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component;
import java.util.List;
@@ -32,4 +31,5 @@ public interface DepartmentDao extends BaseMapper<DepartmentEntity> {
*/
List<DepartmentVO> listAll();
DepartmentVO selectDepartmentVO(@Param("departmentId")Long departmentId);
}

View File

@@ -31,7 +31,7 @@ public class DepartmentEntity {
/**
* 部门名称
*/
private String name;
private String departmentName;
/**
* 负责人员工 id

View File

@@ -21,7 +21,7 @@ public class DepartmentAddForm {
@Schema(description = "部门名称")
@Length(min = 1, max = 50, message = "请输入正确的部门名称(1-50个字符)")
@NotNull(message = "请输入正确的部门名称(1-50个字符)")
private String name;
private String departmentName;
@Schema(description = "排序")
@NotNull(message = "排序值")

View File

@@ -24,7 +24,7 @@ public class DepartmentVO implements Serializable {
private Long departmentId;
@Schema(description = "部门名称")
private String name;
private String departmentName;
@Schema(description = "部门负责人姓名")
private String managerName;

View File

@@ -10,7 +10,6 @@ import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@@ -30,7 +29,7 @@ import java.util.stream.Collectors;
* @Date 2022-01-12 20:37:48
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Service
@@ -43,7 +42,7 @@ public class DepartmentCacheManager {
log.info("clear " + cache);
}
@CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_MAP_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true)
@CacheEvict(value = {AdminCacheConst.Department.DEPARTMENT_LIST_CACHE, AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE, AdminCacheConst.Department.DEPARTMENT_TREE_CACHE, AdminCacheConst.Department.DEPARTMENT_PATH_CACHE,}, allEntries = true)
public void clearCache() {
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
}
@@ -57,19 +56,8 @@ public class DepartmentCacheManager {
return departmentDao.listAll();
}
/**
* 部门map
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_MAP_CACHE)
public Map<Long, DepartmentVO> getDepartmentMap() {
return departmentDao.listAll().stream().collect(Collectors.toMap(DepartmentVO::getDepartmentId, Function.identity()));
}
/**
* 缓存部门树结构
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE)
public List<DepartmentTreeVO> getDepartmentTree() {
@@ -79,7 +67,6 @@ public class DepartmentCacheManager {
/**
* 缓存某个部门的下级id列表
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
@@ -90,7 +77,6 @@ public class DepartmentCacheManager {
/**
* 部门的路径名称
*
*/
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
public Map<Long, String> getDepartmentPathMap() {
@@ -111,22 +97,21 @@ public class DepartmentCacheManager {
*/
private String buildDepartmentPath(DepartmentVO departmentVO, Map<Long, DepartmentVO> departmentMap) {
if (Objects.equals(departmentVO.getParentId(), NumberUtils.LONG_ZERO)) {
return departmentVO.getName();
return departmentVO.getDepartmentName();
}
//父节点
DepartmentVO parentDepartment = departmentMap.get(departmentVO.getParentId());
if (parentDepartment == null) {
return departmentVO.getName();
return departmentVO.getDepartmentName();
}
String pathName = buildDepartmentPath(parentDepartment, departmentMap);
return pathName + "/" + departmentVO.getName();
return pathName + "/" + departmentVO.getDepartmentName();
}
// ---------------------- 构造树的一些方法 ------------------------------
/**
* 构建部门树结构
*
*/
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
if (CollectionUtils.isEmpty(voList)) {
@@ -141,15 +126,15 @@ public class DepartmentCacheManager {
return treeVOList;
}
/**
/**
* 构建所有根节点的下级树形结构
* 返回值为层序遍历结果
* 返回值为层序遍历结果
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
*/
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
int nodeSize = nodeList.size();
List<Long> childIdList = new ArrayList<>();
for(int i = 0; i < nodeSize; i++) {
for (int i = 0; i < nodeSize; i++) {
int preIndex = i - 1;
int nextIndex = i + 1;
DepartmentTreeVO node = nodeList.get(i);
@@ -161,39 +146,38 @@ public class DepartmentCacheManager {
}
List<DepartmentTreeVO> children = getChildren(node.getDepartmentId(), allDepartmentList);
List<Long> tempChildIdList = new ArrayList<>();
if (CollectionUtils.isNotEmpty(children)) {
node.setChildren(children);
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
}
if(CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
if (CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
node.setSelfAndAllChildrenIdList(
new ArrayList<>()
);
}
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
if(CollectionUtils.isNotEmpty(tempChildIdList)) {
if (CollectionUtils.isNotEmpty(tempChildIdList)) {
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
childIdList.addAll(tempChildIdList);
}
}
// 保证本层遍历顺序
for(int i = nodeSize - 1; i >= 0; i--) {
for (int i = nodeSize - 1; i >= 0; i--) {
childIdList.add(0, nodeList.get(i).getDepartmentId());
}
return childIdList;
}
/**
* 获取子元素
*
*/
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
@@ -206,7 +190,6 @@ public class DepartmentCacheManager {
/**
* 通过部门id,获取当前以及下属部门
*
*/
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
List<Long> selfAndChildrenIdList = Lists.newArrayList();

View File

@@ -14,10 +14,7 @@ import net.lab1024.sa.base.common.util.SmartBeanUtil;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* 部门 service
@@ -26,7 +23,7 @@ import java.util.Map;
* @Date 2022-01-12 20:37:48
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Service
public class DepartmentService {
@@ -44,7 +41,6 @@ public class DepartmentService {
/**
* 新增添加部门
*
*/
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
@@ -57,7 +53,6 @@ public class DepartmentService {
/**
* 更新部门信息
*
*/
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
if (updateDTO.getParentId() == null) {
@@ -78,7 +73,6 @@ public class DepartmentService {
* 根据id删除部门
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
* 2、需要判断当前部门是否有员工有员工则不能删除
*
*/
public ResponseDTO<String> deleteDepartment(Long departmentId) {
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
@@ -122,7 +116,6 @@ public class DepartmentService {
/**
* 自身以及所有下级的部门id列表
*
*/
public List<Long> selfAndChildrenIdList(Long departmentId) {
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
@@ -131,7 +124,6 @@ public class DepartmentService {
/**
* 获取所有部门
*
*/
public List<DepartmentVO> listAll() {
return departmentCacheManager.getDepartmentList();
@@ -140,10 +132,9 @@ public class DepartmentService {
/**
* 获取部门
*
*/
public DepartmentVO getDepartmentById(Long departmentId) {
return departmentCacheManager.getDepartmentMap().get(departmentId);
return departmentDao.selectDepartmentVO(departmentId);
}
/**
@@ -153,38 +144,4 @@ public class DepartmentService {
return departmentCacheManager.getDepartmentPathMap().get(departmentId);
}
/**
* 查询全部父级部门(不包含自己)
*
*/
public List<DepartmentVO> queryAllParentDepartment(Long departmentId) {
List<DepartmentVO> list = new ArrayList<>();
Map<Long, DepartmentVO> departmentMap = departmentCacheManager.getDepartmentMap();
DepartmentVO departmentVO = departmentMap.get(departmentId);
while (departmentVO != null) {
list.add(departmentVO);
departmentVO = departmentMap.get(departmentVO.getParentId());
}
Collections.reverse(list);
return list;
}
/**
* 查询全部父级部门(不包含自己)
*
*/
public List<Long> queryAllParentDepartmentIdList(Long departmentId) {
List<Long> list = new ArrayList<>();
Map<Long, DepartmentVO> departmentMap = departmentCacheManager.getDepartmentMap();
DepartmentVO departmentVO = departmentMap.get(departmentId);
while (departmentVO != null) {
list.add(departmentVO.getDepartmentId());
departmentVO = departmentMap.get(departmentVO.getParentId());
}
Collections.reverse(list);
return list;
}
}

View File

@@ -242,8 +242,6 @@ public class EmployeeService {
/**
* 更新登录人头像
*
* @param employeeUpdateAvatarForm
* @return
*/
public ResponseDTO<String> updateAvatar(EmployeeUpdateAvatarForm employeeUpdateAvatarForm) {
Long employeeId = employeeUpdateAvatarForm.getEmployeeId();
@@ -395,7 +393,7 @@ public class EmployeeService {
List<EmployeeVO> voList = employeeEntityList.stream().map(e -> {
EmployeeVO employeeVO = SmartBeanUtil.copy(e, EmployeeVO.class);
if (department != null) {
employeeVO.setDepartmentName(department.getName());
employeeVO.setDepartmentName(department.getDepartmentName());
}
return employeeVO;
}).collect(Collectors.toList());

View File

@@ -7,6 +7,8 @@ import net.lab1024.sa.base.common.enumeration.GenderEnum;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.swagger.SchemaEnum;
import java.io.Serializable;
/**
* 请求员工登录信息
*
@@ -17,7 +19,7 @@ import net.lab1024.sa.base.common.swagger.SchemaEnum;
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Data
public class RequestEmployee implements RequestUser {
public class RequestEmployee implements RequestUser, Serializable {
@Schema(description = "员工id")
private Long employeeId;

View File

@@ -0,0 +1,162 @@
package net.lab1024.sa.admin.module.system.login.manager;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
import net.lab1024.sa.admin.module.system.role.service.RoleMenuService;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.UserPermission;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.module.support.file.service.IFileStorageService;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录Manager
*
* @Author 1024创新实验室: 卓大
* @Date 2025-05-03 22:56:34
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Service
public class LoginManager {
@Resource
private DepartmentService departmentService;
@Resource
private IFileStorageService fileStorageService;
@Resource
private EmployeeService employeeService;
@Resource
private RoleEmployeeService roleEmployeeService;
@Resource
private RoleMenuService roleMenuService;
/**
* 获取请求用户信息
*/
@Cacheable(AdminCacheConst.Login.REQUEST_EMPLOYEE)
public RequestEmployee getRequestEmployee(Long requestEmployeeId ) {
if (requestEmployeeId == null) {
return null;
}
// 员工基本信息
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity == null) {
return null;
}
return this.loadLoginInfo(employeeEntity);
}
/**
* 获取登录的用户信息
*/
@CachePut(value = AdminCacheConst.Login.REQUEST_EMPLOYEE, key = "#employeeEntity.employeeId")
public RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
// 基础信息
RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class);
requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE);
// 部门信息
DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId());
requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.getDepartmentName());
// 头像信息
String avatar = employeeEntity.getAvatar();
if (StringUtils.isNotBlank(avatar)) {
ResponseDTO<String> getFileUrl = fileStorageService.getFileUrl(avatar);
if (BooleanUtils.isTrue(getFileUrl.getOk())) {
requestEmployee.setAvatar(getFileUrl.getData());
}
}
return requestEmployee;
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
@Cacheable(AdminCacheConst.Login.USER_PERMISSION)
public UserPermission getUserPermission(Long employeeId) {
if(null == employeeId){
return null;
}
return this.loadUserPermission(employeeId);
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
@CachePut(AdminCacheConst.Login.USER_PERMISSION)
public UserPermission loadUserPermission(Long employeeId) {
UserPermission userPermission = new UserPermission();
userPermission.setPermissionList(new ArrayList<>());
userPermission.setRoleList(new ArrayList<>());
// 角色列表
List<RoleVO> roleList = roleEmployeeService.getRoleIdList(employeeId);
userPermission.getRoleList().addAll(roleList.stream().map(RoleVO::getRoleCode).collect(Collectors.toSet()));
// 前端菜单和功能点清单
EmployeeEntity employeeEntity = employeeService.getById(employeeId);
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), employeeEntity.getAdministratorFlag());
// 权限列表
HashSet<String> permissionSet = new HashSet<>();
for (MenuVO menu : menuAndPointsList) {
if (menu.getPermsType() == null) {
continue;
}
String perms = menu.getApiPerms();
if (StringUtils.isEmpty(perms)) {
continue;
}
//接口权限
String[] split = perms.split(",");
permissionSet.addAll(Arrays.asList(split));
}
userPermission.getPermissionList().addAll(permissionSet);
return userPermission;
}
@CacheEvict(value = {AdminCacheConst.Login.USER_PERMISSION, AdminCacheConst.Login.REQUEST_EMPLOYEE}, allEntries = true)
public void clear(){
}
}

View File

@@ -6,7 +6,6 @@ import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.extra.servlet.ServletUtil;
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
@@ -15,6 +14,7 @@ import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.LoginForm;
import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.login.manager.LoginManager;
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
@@ -56,15 +56,16 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.ConcurrentMap;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录
*
* @Author 1024创新实验室: 开云
* @Date 2021-12-01 22:56:34
* @Author 1024创新实验室: 卓大
* @Date 2025-05-03 22:56:34
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
@@ -78,22 +79,6 @@ public class LoginService implements StpInterface {
*/
private static final String SUPER_PASSWORD_LOGIN_ID_PREFIX = "S";
/**
* 最大在线缓存人数
*/
private static final long CACHE_MAX_ONLINE_PERSON_COUNT = 1000L;
/**
* 登录信息二级缓存
*/
private final ConcurrentMap<Long, RequestEmployee> loginEmployeeCache = new ConcurrentLinkedHashMap.Builder<Long, RequestEmployee>().maximumWeightedCapacity(CACHE_MAX_ONLINE_PERSON_COUNT).build();
/**
* 权限 缓存
*/
private final ConcurrentMap<Long, UserPermission> permissionCache = new ConcurrentLinkedHashMap.Builder<Long, UserPermission>().maximumWeightedCapacity(CACHE_MAX_ONLINE_PERSON_COUNT).build();
@Resource
private EmployeeService employeeService;
@@ -136,6 +121,9 @@ public class LoginService implements StpInterface {
@Resource
private RedisService redisService;
@Resource
private LoginManager loginManager;
/**
* 获取验证码
*/
@@ -226,10 +214,7 @@ public class LoginService implements StpInterface {
}
// 获取员工信息
RequestEmployee requestEmployee = loadLoginInfo(employeeEntity);
// 放入缓存
loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee);
RequestEmployee requestEmployee = loginManager.loadLoginInfo(employeeEntity);
// 移除登录失败
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
@@ -244,8 +229,8 @@ public class LoginService implements StpInterface {
// 设置 token
loginResultVO.setToken(token);
// 清除权限缓存
permissionCache.remove(employeeEntity.getEmployeeId());
// 更新用户权限
loginManager.loadUserPermission(employeeEntity.getEmployeeId());
return ResponseDTO.ok(loginResultVO);
}
@@ -264,10 +249,6 @@ public class LoginService implements StpInterface {
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), requestEmployee.getAdministratorFlag());
loginResultVO.setMenuList(menuAndPointsList);
// 更新下后端权限缓存
UserPermission userPermission = getUserPermission(requestEmployee.getUserId());
permissionCache.put(requestEmployee.getUserId(), userPermission);
// 上次登录信息
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS);
if (loginLogVO != null) {
@@ -291,32 +272,6 @@ public class LoginService implements StpInterface {
}
/**
* 获取登录的用户信息
*/
private RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
// 基础信息
RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class);
requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE);
// 部门信息
DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId());
requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.getName());
// 头像信息
String avatar = employeeEntity.getAvatar();
if (StringUtils.isNotBlank(avatar)) {
ResponseDTO<String> getFileUrl = fileStorageService.getFileUrl(avatar);
if (BooleanUtils.isTrue(getFileUrl.getOk())) {
requestEmployee.setAvatar(getFileUrl.getData());
}
}
return requestEmployee;
}
/**
* 根据登陆token 获取员请求工信息
*/
@@ -330,17 +285,7 @@ public class LoginService implements StpInterface {
return null;
}
RequestEmployee requestEmployee = loginEmployeeCache.get(requestEmployeeId);
if (requestEmployee == null) {
// 员工基本信息
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity == null) {
return null;
}
requestEmployee = this.loadLoginInfo(employeeEntity);
loginEmployeeCache.put(requestEmployeeId, requestEmployee);
}
RequestEmployee requestEmployee = loginManager.getRequestEmployee(requestEmployeeId);
// 更新请求ip和user agent
requestEmployee.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
@@ -384,7 +329,7 @@ public class LoginService implements StpInterface {
StpUtil.logout();
// 清空登录信息缓存
loginEmployeeCache.remove(requestUser.getUserId());
loginManager.clear();
//保存登出日志
LoginLogEntity loginEntity = LoginLogEntity.builder()
@@ -402,14 +347,6 @@ public class LoginService implements StpInterface {
return ResponseDTO.ok();
}
/**
* 清除员工登录缓存
*/
public void clearLoginEmployeeCache(Long employeeId) {
// 清空登录信息缓存
loginEmployeeCache.remove(employeeId);
}
/**
* 保存登录日志
*/
@@ -437,12 +374,7 @@ public class LoginService implements StpInterface {
return Collections.emptyList();
}
UserPermission userPermission = permissionCache.get(employeeId);
if (userPermission == null) {
userPermission = getUserPermission(employeeId);
permissionCache.put(employeeId, userPermission);
}
UserPermission userPermission = loginManager.getUserPermission(employeeId);
return userPermission.getPermissionList();
}
@@ -453,51 +385,10 @@ public class LoginService implements StpInterface {
return Collections.emptyList();
}
UserPermission userPermission = permissionCache.get(employeeId);
if (userPermission == null) {
userPermission = getUserPermission(employeeId);
permissionCache.put(employeeId, userPermission);
}
UserPermission userPermission = loginManager.getUserPermission(employeeId);
return userPermission.getRoleList();
}
/**
* 获取用户的权限(包含 角色列表、权限列表)
*/
private UserPermission getUserPermission(Long employeeId) {
UserPermission userPermission = new UserPermission();
userPermission.setPermissionList(new ArrayList<>());
userPermission.setRoleList(new ArrayList<>());
// 角色列表
List<RoleVO> roleList = roleEmployeeService.getRoleIdList(employeeId);
userPermission.getRoleList().addAll(roleList.stream().map(RoleVO::getRoleCode).collect(Collectors.toSet()));
// 前端菜单和功能点清单
EmployeeEntity employeeEntity = employeeService.getById(employeeId);
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), employeeEntity.getAdministratorFlag());
// 权限列表
HashSet<String> permissionSet = new HashSet<>();
for (MenuVO menu : menuAndPointsList) {
if (menu.getPermsType() == null) {
continue;
}
String perms = menu.getApiPerms();
if (StringUtils.isEmpty(perms)) {
continue;
}
//接口权限
String[] split = perms.split(",");
permissionSet.addAll(Arrays.asList(split));
}
userPermission.getPermissionList().addAll(permissionSet);
return userPermission;
}
/**
* 发送 邮箱 验证码
@@ -592,4 +483,8 @@ public class LoginService implements StpInterface {
String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeId);
redisService.delete(redisVerificationCodeKey);
}
public void clearLoginEmployeeCache(Long employeeId) {
loginManager.clear();
}
}

View File

@@ -14,6 +14,7 @@ import net.lab1024.sa.base.common.code.SystemErrorCode;
import net.lab1024.sa.base.common.domain.RequestUrlVO;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.common.util.SmartStringUtil;
import org.apache.commons.lang3.math.NumberUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -134,6 +135,10 @@ public class MenuService {
* @return true 重复 false 未重复
*/
public <T extends MenuBaseForm> Boolean validateWebPerms(T menuDTO) {
if(SmartStringUtil.isEmpty(menuDTO.getWebPerms())){
return false;
}
MenuEntity menu = menuDao.getByWebPerms(menuDTO.getWebPerms(), Boolean.FALSE);
if (menuDTO instanceof MenuAddForm) {
return menu != null;

View File

@@ -72,7 +72,7 @@ public class RoleEmployeeService {
List<Long> departmentIdList = employeeList.stream().filter(e -> e != null && e.getDepartmentId() != null).map(EmployeeVO::getDepartmentId).collect(Collectors.toList());
if (CollectionUtils.isNotEmpty(departmentIdList)) {
List<DepartmentEntity> departmentEntities = departmentDao.selectBatchIds(departmentIdList);
Map<Long, String> departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getName));
Map<Long, String> departmentIdNameMap = departmentEntities.stream().collect(Collectors.toMap(DepartmentEntity::getDepartmentId, DepartmentEntity::getDepartmentName));
employeeList.forEach(e -> {
e.setDepartmentName(departmentIdNameMap.getOrDefault(e.getDepartmentId(), StringConst.EMPTY));
});

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.bank.BankDao">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.bank.dao.BankDao">
<update id="deleteBank">
UPDATE t_oa_bank
SET deleted_flag = #{deletedFlag}

View File

@@ -70,7 +70,7 @@
<select id="queryPageEmployeeList"
resultType="net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO">
select
t_oa_enterprise_employee.*,
t_oa_enterprise_employee.enterprise_id,
t_oa_enterprise.enterprise_name,
t_employee.*,
t_employee.actual_name as employeeName

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.invoice.InvoiceDao">
<mapper namespace="net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao">
<update id="deleteInvoice">
UPDATE t_oa_invoice
SET deleted_flag = #{deletedFlag}

View File

@@ -219,7 +219,7 @@
<select id="queryNoticeViewRecordList" resultType="net.lab1024.sa.admin.module.business.oa.notice.domain.vo.NoticeViewRecordVO">
select t_notice_view_record.*,
t_employee.actual_name as employeeName,
t_department.name as departmentName
t_department.department_name
from t_notice_view_record
left join t_employee on t_employee.employee_id = t_notice_view_record.employee_id
left join t_department on t_department.department_id = t_employee.department_id

View File

@@ -6,7 +6,7 @@
<select id="listAll" resultType="net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO">
SELECT t_department.*,
t_employee.actual_name as managerName,
parent_department.`name` as parentName
parent_department.department_name as parentName
FROM t_department
left join t_employee on t_department.manager_id = t_employee.employee_id
left join t_department parent_department on t_department.parent_id = parent_department.department_id
@@ -19,5 +19,16 @@
WHERE parent_id = #{departmentId}
</select>
<select id="selectDepartmentVO"
resultType="net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO">
SELECT t_department.*,
t_employee.actual_name as managerName,
parent_department.department_name as parentName
FROM t_department
left join t_employee on t_department.manager_id = t_employee.employee_id
left join t_department parent_department on t_department.parent_id = parent_department.department_id
where t_department.department_id = #{departmentId}
</select>
</mapper>

View File

@@ -5,7 +5,7 @@
<select id="queryEmployee" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT
t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
<where>
@@ -169,7 +169,7 @@
<select id="getEmployeeById" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
where t_employee.employee_id = #{employeeId}
@@ -178,7 +178,7 @@
<select id="selectEmployeeByDisabledAndDeleted" resultType="net.lab1024.sa.admin.module.system.employee.domain.vo.EmployeeVO">
SELECT
t_employee.*,
t_department.name AS departmentName
t_department.department_name
FROM t_employee
LEFT JOIN t_department ON t_department.department_id = t_employee.department_id
<where>

View File

@@ -2,6 +2,7 @@ package net.lab1024.sa.base.common.domain;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
/**
@@ -15,7 +16,7 @@ import java.util.List;
*/
@Data
public class UserPermission {
public class UserPermission implements Serializable {
/**
* 权限列表

Some files were not shown because too many files have changed in this diff Show More