mirror of
https://gitee.com/lab1024/smart-admin.git
synced 2025-09-23 22:06:39 +08:00
v3.20.0 【新增】优化登录使用spring cache;【新增】优化部门cache;【新增】代码生成枚举;【优化】三级等保Label显示宽度
This commit is contained in:
parent
f198a949c9
commit
3fb4dfad09
@ -20,11 +20,6 @@ public class AdminCacheConst extends CacheKeyConst {
|
|||||||
*/
|
*/
|
||||||
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
|
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 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";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ import org.hibernate.validator.constraints.Length;
|
|||||||
* @Date 2021-10-25 20:26:54
|
* @Date 2021-10-25 20:26:54
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class GoodsQueryForm extends PageParam {
|
public class GoodsQueryForm extends PageParam {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.lab1024.sa.admin.module.business.goods.domain.vo;
|
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 io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
|
import net.lab1024.sa.admin.module.business.goods.constant.GoodsStatusEnum;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.lab1024.sa.admin.module.business.oa.enterprise.controller;
|
package net.lab1024.sa.admin.module.business.oa.enterprise;
|
||||||
|
|
||||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
@ -8,7 +8,6 @@ import jakarta.servlet.http.HttpServletResponse;
|
|||||||
import jakarta.validation.Valid;
|
import jakarta.validation.Valid;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.lab1024.sa.admin.constant.AdminSwaggerTagConst;
|
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.form.*;
|
||||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
|
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseEmployeeVO;
|
||||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
|
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseExcelVO;
|
@ -1,4 +1,4 @@
|
|||||||
package net.lab1024.sa.admin.module.business.oa.enterprise.manager;
|
package net.lab1024.sa.admin.module.business.oa.enterprise;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
|
import net.lab1024.sa.admin.module.business.oa.enterprise.dao.EnterpriseEmployeeDao;
|
@ -1,4 +1,4 @@
|
|||||||
package net.lab1024.sa.admin.module.business.oa.enterprise.service;
|
package net.lab1024.sa.admin.module.business.oa.enterprise;
|
||||||
|
|
||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
@ -13,7 +13,6 @@ 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.EnterpriseExcelVO;
|
||||||
import net.lab1024.sa.admin.module.business.oa.enterprise.domain.vo.EnterpriseListVO;
|
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.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.admin.module.system.department.service.DepartmentService;
|
||||||
import net.lab1024.sa.base.common.code.UserErrorCode;
|
import net.lab1024.sa.base.common.code.UserErrorCode;
|
||||||
import net.lab1024.sa.base.common.domain.PageResult;
|
import net.lab1024.sa.base.common.domain.PageResult;
|
@ -3,7 +3,7 @@ package net.lab1024.sa.admin.module.business.oa.invoice.service;
|
|||||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.lab1024.sa.admin.module.business.oa.enterprise.service.EnterpriseService;
|
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.enterprise.domain.vo.EnterpriseVO;
|
||||||
import net.lab1024.sa.admin.module.business.oa.invoice.dao.InvoiceDao;
|
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.admin.module.business.oa.invoice.domain.*;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package net.lab1024.sa.admin.module.system.datascope.controller;
|
package net.lab1024.sa.admin.module.system.datascope;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
@ -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 net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -32,4 +31,5 @@ public interface DepartmentDao extends BaseMapper<DepartmentEntity> {
|
|||||||
*/
|
*/
|
||||||
List<DepartmentVO> listAll();
|
List<DepartmentVO> listAll();
|
||||||
|
|
||||||
|
DepartmentVO selectDepartmentVO(@Param("departmentId")Long departmentId);
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ import java.util.stream.Collectors;
|
|||||||
* @Date 2022-01-12 20:37:48
|
* @Date 2022-01-12 20:37:48
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -42,7 +42,7 @@ public class DepartmentCacheManager {
|
|||||||
log.info("clear " + cache);
|
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() {
|
public void clearCache() {
|
||||||
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
|
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
|
||||||
}
|
}
|
||||||
@ -56,19 +56,8 @@ public class DepartmentCacheManager {
|
|||||||
return departmentDao.listAll();
|
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)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE)
|
||||||
public List<DepartmentTreeVO> getDepartmentTree() {
|
public List<DepartmentTreeVO> getDepartmentTree() {
|
||||||
@ -78,7 +67,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存某个部门的下级id列表
|
* 缓存某个部门的下级id列表
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
|
||||||
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
|
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
|
||||||
@ -89,7 +77,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门的路径名称
|
* 部门的路径名称
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
|
||||||
public Map<Long, String> getDepartmentPathMap() {
|
public Map<Long, String> getDepartmentPathMap() {
|
||||||
@ -125,7 +112,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建部门树结构
|
* 构建部门树结构
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
|
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
|
||||||
if (CollectionUtils.isEmpty(voList)) {
|
if (CollectionUtils.isEmpty(voList)) {
|
||||||
@ -140,7 +126,7 @@ public class DepartmentCacheManager {
|
|||||||
return treeVOList;
|
return treeVOList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建所有根节点的下级树形结构
|
* 构建所有根节点的下级树形结构
|
||||||
* 返回值为层序遍历结果
|
* 返回值为层序遍历结果
|
||||||
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
|
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
|
||||||
@ -148,7 +134,7 @@ public class DepartmentCacheManager {
|
|||||||
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
|
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
|
||||||
int nodeSize = nodeList.size();
|
int nodeSize = nodeList.size();
|
||||||
List<Long> childIdList = new ArrayList<>();
|
List<Long> childIdList = new ArrayList<>();
|
||||||
for(int i = 0; i < nodeSize; i++) {
|
for (int i = 0; i < nodeSize; i++) {
|
||||||
int preIndex = i - 1;
|
int preIndex = i - 1;
|
||||||
int nextIndex = i + 1;
|
int nextIndex = i + 1;
|
||||||
DepartmentTreeVO node = nodeList.get(i);
|
DepartmentTreeVO node = nodeList.get(i);
|
||||||
@ -167,14 +153,14 @@ public class DepartmentCacheManager {
|
|||||||
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
|
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
|
if (CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
|
||||||
node.setSelfAndAllChildrenIdList(
|
node.setSelfAndAllChildrenIdList(
|
||||||
new ArrayList<>()
|
new ArrayList<>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
|
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
|
||||||
|
|
||||||
if(CollectionUtils.isNotEmpty(tempChildIdList)) {
|
if (CollectionUtils.isNotEmpty(tempChildIdList)) {
|
||||||
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
|
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
|
||||||
childIdList.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());
|
childIdList.add(0, nodeList.get(i).getDepartmentId());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -192,7 +178,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取子元素
|
* 获取子元素
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
|
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
|
||||||
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
|
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
|
||||||
@ -205,7 +190,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过部门id,获取当前以及下属部门
|
* 通过部门id,获取当前以及下属部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
|
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
|
||||||
List<Long> selfAndChildrenIdList = Lists.newArrayList();
|
List<Long> selfAndChildrenIdList = Lists.newArrayList();
|
||||||
|
@ -26,7 +26,7 @@ import java.util.Map;
|
|||||||
* @Date 2022-01-12 20:37:48
|
* @Date 2022-01-12 20:37:48
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class DepartmentService {
|
public class DepartmentService {
|
||||||
@ -44,7 +44,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增添加部门
|
* 新增添加部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
|
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
|
||||||
@ -57,7 +56,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新部门信息
|
* 更新部门信息
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
|
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
|
||||||
if (updateDTO.getParentId() == null) {
|
if (updateDTO.getParentId() == null) {
|
||||||
@ -78,7 +76,6 @@ public class DepartmentService {
|
|||||||
* 根据id删除部门
|
* 根据id删除部门
|
||||||
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
|
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
|
||||||
* 2、需要判断当前部门是否有员工,有员工则不能删除
|
* 2、需要判断当前部门是否有员工,有员工则不能删除
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public ResponseDTO<String> deleteDepartment(Long departmentId) {
|
public ResponseDTO<String> deleteDepartment(Long departmentId) {
|
||||||
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
|
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
|
||||||
@ -122,7 +119,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 自身以及所有下级的部门id列表
|
* 自身以及所有下级的部门id列表
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<Long> selfAndChildrenIdList(Long departmentId) {
|
public List<Long> selfAndChildrenIdList(Long departmentId) {
|
||||||
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
|
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
|
||||||
@ -131,7 +127,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有部门
|
* 获取所有部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<DepartmentVO> listAll() {
|
public List<DepartmentVO> listAll() {
|
||||||
return departmentCacheManager.getDepartmentList();
|
return departmentCacheManager.getDepartmentList();
|
||||||
@ -140,10 +135,9 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取部门
|
* 获取部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public DepartmentVO getDepartmentById(Long departmentId) {
|
public DepartmentVO getDepartmentById(Long departmentId) {
|
||||||
return departmentCacheManager.getDepartmentMap().get(departmentId);
|
return departmentDao.selectDepartmentVO(departmentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -153,38 +147,4 @@ public class DepartmentService {
|
|||||||
return departmentCacheManager.getDepartmentPathMap().get(departmentId);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,7 @@ package net.lab1024.sa.admin.module.system.employee.domain.form;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
import jakarta.validation.constraints.NotBlank;
|
||||||
import jakarta.validation.constraints.Pattern;
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import net.lab1024.sa.base.common.util.SmartVerificationUtil;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改密码所需参数
|
* 修改密码所需参数
|
||||||
|
@ -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.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户的权限(包含 角色列表、权限列表)
|
||||||
|
*/
|
||||||
|
@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(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -6,17 +6,16 @@ import cn.hutool.core.lang.UUID;
|
|||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.hutool.extra.servlet.JakartaServletUtil;
|
import cn.hutool.extra.servlet.JakartaServletUtil;
|
||||||
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
|
|
||||||
import jakarta.annotation.Resource;
|
import jakarta.annotation.Resource;
|
||||||
import jakarta.servlet.http.HttpServletRequest;
|
import jakarta.servlet.http.HttpServletRequest;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
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.department.service.DepartmentService;
|
||||||
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
|
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.employee.service.EmployeeService;
|
||||||
import net.lab1024.sa.admin.module.system.login.domain.LoginForm;
|
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.LoginResultVO;
|
||||||
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
|
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.menu.domain.vo.MenuVO;
|
||||||
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
|
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.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.mail.constant.MailTemplateCodeEnum;
|
||||||
import net.lab1024.sa.base.module.support.redis.RedisService;
|
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.domain.LoginFailEntity;
|
||||||
import net.lab1024.sa.base.module.support.securityprotect.service.*;
|
import net.lab1024.sa.base.module.support.securityprotect.service.Level3ProtectConfigService;
|
||||||
import org.apache.commons.lang3.BooleanUtils;
|
import net.lab1024.sa.base.module.support.securityprotect.service.SecurityLoginService;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import net.lab1024.sa.base.module.support.securityprotect.service.SecurityPasswordService;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
*
|
*
|
||||||
* @Author 1024创新实验室: 开云
|
* @Author 1024创新实验室: 卓大
|
||||||
* @Date 2021-12-01 22:56:34
|
* @Date 2025-05-03 22:56:34
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @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 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
|
@Resource
|
||||||
private EmployeeService employeeService;
|
private EmployeeService employeeService;
|
||||||
|
|
||||||
@ -134,6 +118,9 @@ public class LoginService implements StpInterface {
|
|||||||
@Resource
|
@Resource
|
||||||
private RedisService redisService;
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LoginManager loginManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取验证码
|
* 获取验证码
|
||||||
*/
|
*/
|
||||||
@ -224,10 +211,7 @@ public class LoginService implements StpInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取员工信息
|
// 获取员工信息
|
||||||
RequestEmployee requestEmployee = loadLoginInfo(employeeEntity);
|
RequestEmployee requestEmployee = loginManager.loadLoginInfo(employeeEntity);
|
||||||
|
|
||||||
// 放入缓存
|
|
||||||
loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee);
|
|
||||||
|
|
||||||
// 移除登录失败
|
// 移除登录失败
|
||||||
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
|
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
|
||||||
@ -242,8 +226,8 @@ public class LoginService implements StpInterface {
|
|||||||
// 设置 token
|
// 设置 token
|
||||||
loginResultVO.setToken(token);
|
loginResultVO.setToken(token);
|
||||||
|
|
||||||
// 清除权限缓存
|
// 更新用户权限
|
||||||
permissionCache.remove(employeeEntity.getEmployeeId());
|
loginManager.loadUserPermission(employeeEntity.getEmployeeId());
|
||||||
|
|
||||||
return ResponseDTO.ok(loginResultVO);
|
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());
|
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), requestEmployee.getAdministratorFlag());
|
||||||
loginResultVO.setMenuList(menuAndPointsList);
|
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);
|
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS);
|
||||||
if (loginLogVO != null) {
|
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 获取员请求工信息
|
* 根据登陆token 获取员请求工信息
|
||||||
*/
|
*/
|
||||||
@ -328,17 +282,7 @@ public class LoginService implements StpInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestEmployee requestEmployee = loginEmployeeCache.get(requestEmployeeId);
|
RequestEmployee requestEmployee = loginManager.getRequestEmployee(requestEmployeeId);
|
||||||
if (requestEmployee == null) {
|
|
||||||
// 员工基本信息
|
|
||||||
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
|
|
||||||
if (employeeEntity == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestEmployee = this.loadLoginInfo(employeeEntity);
|
|
||||||
loginEmployeeCache.put(requestEmployeeId, requestEmployee);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新请求ip和user agent
|
// 更新请求ip和user agent
|
||||||
requestEmployee.setUserAgent(JakartaServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
|
requestEmployee.setUserAgent(JakartaServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
|
||||||
@ -382,7 +326,7 @@ public class LoginService implements StpInterface {
|
|||||||
StpUtil.logout();
|
StpUtil.logout();
|
||||||
|
|
||||||
// 清空登录信息缓存
|
// 清空登录信息缓存
|
||||||
loginEmployeeCache.remove(requestUser.getUserId());
|
loginManager.clear();
|
||||||
|
|
||||||
//保存登出日志
|
//保存登出日志
|
||||||
LoginLogEntity loginEntity = LoginLogEntity.builder()
|
LoginLogEntity loginEntity = LoginLogEntity.builder()
|
||||||
@ -400,14 +344,6 @@ public class LoginService implements StpInterface {
|
|||||||
return ResponseDTO.ok();
|
return ResponseDTO.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除员工登录缓存
|
|
||||||
*/
|
|
||||||
public void clearLoginEmployeeCache(Long employeeId) {
|
|
||||||
// 清空登录信息缓存
|
|
||||||
loginEmployeeCache.remove(employeeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存登录日志
|
* 保存登录日志
|
||||||
*/
|
*/
|
||||||
@ -435,12 +371,7 @@ public class LoginService implements StpInterface {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPermission userPermission = permissionCache.get(employeeId);
|
UserPermission userPermission = loginManager.getUserPermission(employeeId);
|
||||||
if (userPermission == null) {
|
|
||||||
userPermission = getUserPermission(employeeId);
|
|
||||||
permissionCache.put(employeeId, userPermission);
|
|
||||||
}
|
|
||||||
|
|
||||||
return userPermission.getPermissionList();
|
return userPermission.getPermissionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -451,51 +382,10 @@ public class LoginService implements StpInterface {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPermission userPermission = permissionCache.get(employeeId);
|
UserPermission userPermission = loginManager.getUserPermission(employeeId);
|
||||||
if (userPermission == null) {
|
|
||||||
userPermission = getUserPermission(employeeId);
|
|
||||||
permissionCache.put(employeeId, userPermission);
|
|
||||||
}
|
|
||||||
return userPermission.getRoleList();
|
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);
|
String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeId);
|
||||||
redisService.delete(redisVerificationCodeKey);
|
redisService.delete(redisVerificationCodeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLoginEmployeeCache(Long employeeId) {
|
||||||
|
loginManager.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,11 +3,7 @@ package net.lab1024.sa.admin.module.system.role.manager;
|
|||||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
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.dao.RoleEmployeeDao;
|
||||||
import net.lab1024.sa.admin.module.system.role.domain.entity.RoleEmployeeEntity;
|
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.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 角色员工 manager
|
* 角色员工 manager
|
||||||
|
@ -19,5 +19,16 @@
|
|||||||
WHERE parent_id = #{departmentId}
|
WHERE parent_id = #{departmentId}
|
||||||
</select>
|
</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.`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>
|
</mapper>
|
@ -1,26 +0,0 @@
|
|||||||
package net.lab1024.sa.base.common.annoation;
|
|
||||||
|
|
||||||
import net.lab1024.sa.base.constant.DataSourceTypeEnum;
|
|
||||||
|
|
||||||
import java.lang.annotation.*;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换数据源名称
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
|
||||||
@Documented
|
|
||||||
@Inherited
|
|
||||||
public @interface DataSource {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 切换数据源名称
|
|
||||||
*/
|
|
||||||
public DataSourceTypeEnum value() default DataSourceTypeEnum.SLAVE;
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
package net.lab1024.sa.base.common.aspect;
|
|
||||||
|
|
||||||
import net.lab1024.sa.base.common.annoation.DataSource;
|
|
||||||
import net.lab1024.sa.base.handler.DynamicDataSourceContextHandler;
|
|
||||||
import org.aspectj.lang.ProceedingJoinPoint;
|
|
||||||
import org.aspectj.lang.annotation.Around;
|
|
||||||
import org.aspectj.lang.annotation.Aspect;
|
|
||||||
import org.aspectj.lang.annotation.Pointcut;
|
|
||||||
import org.aspectj.lang.reflect.MethodSignature;
|
|
||||||
import org.springframework.core.annotation.AnnotationUtils;
|
|
||||||
import org.springframework.core.annotation.Order;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.Objects;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 多数据源处理
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Aspect
|
|
||||||
@Order(1)
|
|
||||||
@Component
|
|
||||||
public class DataSourceAspect {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* aop切点,有相关注解的方法才做增强处理
|
|
||||||
*/
|
|
||||||
@Pointcut("@annotation(net.lab1024.sa.base.common.annoation.DataSource) || @within(net.lab1024.sa.base.common.annoation.DataSource)")
|
|
||||||
public void dsPointCut() {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 环绕通知
|
|
||||||
*/
|
|
||||||
@Around("dsPointCut()")
|
|
||||||
public Object around(ProceedingJoinPoint point) throws Throwable {
|
|
||||||
DataSource dataSource = getDataSource(point);
|
|
||||||
|
|
||||||
if (dataSource != null) {
|
|
||||||
DynamicDataSourceContextHandler.setDataSourceType(dataSource.value().name());
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
return point.proceed();
|
|
||||||
} finally {
|
|
||||||
DynamicDataSourceContextHandler.clearDataSourceType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取需要切换的数据源
|
|
||||||
*/
|
|
||||||
public DataSource getDataSource(ProceedingJoinPoint point) {
|
|
||||||
MethodSignature signature = (MethodSignature) point.getSignature();
|
|
||||||
DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
|
|
||||||
|
|
||||||
// 方法注解为空,则取类注解
|
|
||||||
if (Objects.nonNull(dataSource)) {
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
return AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,6 +2,7 @@ package net.lab1024.sa.base.common.domain;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +16,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UserPermission {
|
public class UserPermission implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限列表
|
* 权限列表
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
package net.lab1024.sa.base.config;
|
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.CacheService;
|
||||||
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
|
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
|
||||||
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
|
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||||
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存配置
|
* 缓存配置
|
||||||
@ -19,6 +22,14 @@ public class CacheConfig {
|
|||||||
private static final String REDIS_CACHE = "redis";
|
private static final String REDIS_CACHE = "redis";
|
||||||
private static final String CAFFEINE_CACHE = "caffeine";
|
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
|
@Bean
|
||||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
||||||
|
@ -0,0 +1,201 @@
|
|||||||
|
package net.lab1024.sa.base.config;
|
||||||
|
|
||||||
|
import com.alibaba.druid.filter.Filter;
|
||||||
|
import com.alibaba.druid.filter.stat.StatFilter;
|
||||||
|
import com.alibaba.druid.pool.DruidDataSource;
|
||||||
|
import com.alibaba.druid.support.jakarta.StatViewServlet;
|
||||||
|
import com.alibaba.druid.support.jakarta.WebStatFilter;
|
||||||
|
import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.annotation.DbType;
|
||||||
|
import com.baomidou.mybatisplus.core.config.GlobalConfig;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
|
||||||
|
import com.baomidou.mybatisplus.extension.spring.MybatisSqlSessionFactoryBean;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
import net.lab1024.sa.base.common.domain.DataScopePlugin;
|
||||||
|
import net.lab1024.sa.base.handler.MybatisPlusFillHandler;
|
||||||
|
import org.apache.ibatis.plugin.Interceptor;
|
||||||
|
import org.apache.ibatis.session.SqlSessionFactory;
|
||||||
|
import org.springframework.aop.support.DefaultPointcutAdvisor;
|
||||||
|
import org.springframework.aop.support.JdkRegexpMethodPointcut;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||||
|
import org.springframework.boot.web.servlet.ServletRegistrationBean;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Conditional;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.annotation.Primary;
|
||||||
|
import org.springframework.core.io.Resource;
|
||||||
|
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据源配置
|
||||||
|
*
|
||||||
|
* @Author 1024创新实验室-主任: 卓大
|
||||||
|
* @Date 2017-11-28 15:21:10
|
||||||
|
* @Wechat zhuoda1024
|
||||||
|
* @Email lab1024@163.com
|
||||||
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
|
*/
|
||||||
|
@Slf4j
|
||||||
|
@Configuration
|
||||||
|
public class DataSourceConfig {
|
||||||
|
|
||||||
|
@Value("${spring.datasource.driver-class-name}")
|
||||||
|
String driver;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.url}")
|
||||||
|
String url;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.username}")
|
||||||
|
String username;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.password}")
|
||||||
|
String password;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.initial-size}")
|
||||||
|
int initialSize;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.min-idle}")
|
||||||
|
int minIdle;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.max-active}")
|
||||||
|
int maxActive;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.max-wait}")
|
||||||
|
long maxWait;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.time-between-eviction-runs-millis}")
|
||||||
|
long timeBetweenEvictionRunsMillis;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.min-evictable-idle-time-millis}")
|
||||||
|
long minEvictableIdleTimeMillis;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.filters}")
|
||||||
|
String filters;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.username}")
|
||||||
|
String druidUserName;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.password}")
|
||||||
|
String druidPassword;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.login.enabled}")
|
||||||
|
boolean druidLoginEnable;
|
||||||
|
|
||||||
|
@Value("${spring.datasource.druid.method.pointcut}")
|
||||||
|
String methodPointcut;
|
||||||
|
|
||||||
|
@jakarta.annotation.Resource
|
||||||
|
private MybatisPlusInterceptor paginationInterceptor;
|
||||||
|
|
||||||
|
@jakarta.annotation.Resource
|
||||||
|
private DataScopePlugin dataScopePlugin;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@Primary
|
||||||
|
public DataSource druidDataSource() {
|
||||||
|
DruidDataSource druidDataSource = new DruidDataSource();
|
||||||
|
druidDataSource.setDbType(DbType.MYSQL.getDb());
|
||||||
|
druidDataSource.setDriverClassName(driver);
|
||||||
|
druidDataSource.setUrl(url);
|
||||||
|
druidDataSource.setUsername(username);
|
||||||
|
druidDataSource.setPassword(password);
|
||||||
|
druidDataSource.setInitialSize(initialSize);
|
||||||
|
druidDataSource.setMinIdle(minIdle);
|
||||||
|
druidDataSource.setMaxActive(maxActive);
|
||||||
|
druidDataSource.setMaxWait(maxWait);
|
||||||
|
druidDataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
||||||
|
druidDataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
|
||||||
|
druidDataSource.setValidationQuery("SELECT 1");
|
||||||
|
try {
|
||||||
|
druidDataSource.setFilters(filters);
|
||||||
|
ArrayList<Filter> arrayList = new ArrayList<>();
|
||||||
|
StatFilter statFilter = new StatFilter();
|
||||||
|
statFilter.setMergeSql(true);
|
||||||
|
statFilter.setSlowSqlMillis(1000);
|
||||||
|
statFilter.setLogSlowSql(true);
|
||||||
|
arrayList.add(statFilter);
|
||||||
|
druidDataSource.setProxyFilters(arrayList);
|
||||||
|
druidDataSource.init();
|
||||||
|
} catch (SQLException e) {
|
||||||
|
log.error("初始化数据源出错", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return druidDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public SqlSessionFactory sqlSessionFactory() throws Exception {
|
||||||
|
MybatisSqlSessionFactoryBean factoryBean = new MybatisSqlSessionFactoryBean();
|
||||||
|
factoryBean.setDataSource(druidDataSource());
|
||||||
|
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
|
||||||
|
Resource[] resources = resolver.getResources("classpath*:/mapper/**/*.xml");
|
||||||
|
factoryBean.setMapperLocations(resources);
|
||||||
|
|
||||||
|
// 设置 MyBatis-Plus 分页插件 注意此处myBatisPlugin一定要放在后面
|
||||||
|
List<Interceptor> pluginsList = new ArrayList<>();
|
||||||
|
pluginsList.add(paginationInterceptor);
|
||||||
|
if (dataScopePlugin != null) {
|
||||||
|
pluginsList.add(dataScopePlugin);
|
||||||
|
}
|
||||||
|
factoryBean.setPlugins(pluginsList.toArray(new Interceptor[0]));
|
||||||
|
// 添加字段自动填充处理
|
||||||
|
factoryBean.setGlobalConfig(new GlobalConfig().setBanner(false).setMetaObjectHandler(new MybatisPlusFillHandler()));
|
||||||
|
|
||||||
|
return factoryBean.getObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 非正式环境 才加载
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@Conditional(SystemEnvironmentConfig.class)
|
||||||
|
@Bean
|
||||||
|
public ServletRegistrationBean<StatViewServlet> druidServlet() {
|
||||||
|
ServletRegistrationBean<StatViewServlet> servletRegistrationBean = new ServletRegistrationBean<>();
|
||||||
|
servletRegistrationBean.setServlet(new StatViewServlet());
|
||||||
|
servletRegistrationBean.addUrlMappings("/druid/*");
|
||||||
|
Map<String, String> initParameters = new HashMap<String, String>();
|
||||||
|
//不设置用户名密码可以直接通过druid/index.html访问
|
||||||
|
if (druidLoginEnable) {
|
||||||
|
initParameters.put("loginUsername", druidUserName);
|
||||||
|
initParameters.put("loginPassword", druidPassword);
|
||||||
|
}
|
||||||
|
initParameters.put("resetEnable", "false");
|
||||||
|
servletRegistrationBean.setInitParameters(initParameters);
|
||||||
|
return servletRegistrationBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FilterRegistrationBean<WebStatFilter> filterRegistrationBean() {
|
||||||
|
FilterRegistrationBean<WebStatFilter> filterRegistrationBean = new FilterRegistrationBean<WebStatFilter>();
|
||||||
|
filterRegistrationBean.setFilter(new WebStatFilter());
|
||||||
|
filterRegistrationBean.addUrlPatterns("/*");
|
||||||
|
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/*");
|
||||||
|
return filterRegistrationBean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public JdkRegexpMethodPointcut jdkRegexpMethodPointcut() {
|
||||||
|
JdkRegexpMethodPointcut jdkRegexpMethodPointcut = new JdkRegexpMethodPointcut();
|
||||||
|
jdkRegexpMethodPointcut.setPatterns(methodPointcut);
|
||||||
|
return jdkRegexpMethodPointcut;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public DefaultPointcutAdvisor defaultPointcutAdvisor() {
|
||||||
|
DefaultPointcutAdvisor pointcutAdvisor = new DefaultPointcutAdvisor();
|
||||||
|
pointcutAdvisor.setPointcut(jdkRegexpMethodPointcut());
|
||||||
|
pointcutAdvisor.setAdvice(new DruidStatInterceptor());
|
||||||
|
return pointcutAdvisor;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,87 +0,0 @@
|
|||||||
package net.lab1024.sa.base.config;
|
|
||||||
|
|
||||||
import com.alibaba.druid.spring.boot3.autoconfigure.DruidDataSourceBuilder;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import net.lab1024.sa.base.constant.DataSourceTypeEnum;
|
|
||||||
import net.lab1024.sa.base.handler.DynamicDataSourceHandler;
|
|
||||||
import net.lab1024.sa.base.properties.DruidProperties;
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Qualifier;
|
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
import org.springframework.context.annotation.Primary;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Druid 配置多数据源
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
@Configuration
|
|
||||||
public class DruidConfig {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 这里以map的方式存储所有的自定义的数据源,其中key是枚举类的字符串值,value是创建好且赋值好的数据源对象
|
|
||||||
*/
|
|
||||||
private static Map<Object, Object> targetDataSources = new HashMap<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* DruidProperties(属性配置对象,见后面6 spring会根据配置文件的值将该对象的属性赋值
|
|
||||||
* 然后调用dataSource()方法将创建好的数据源对象赋值好然后交给spring管理
|
|
||||||
* 这里是配置的主数据源也是默认的数据源
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConfigurationProperties("spring.datasource.druid.master")
|
|
||||||
public DataSource masterDataSource(DruidProperties druidProperties) {
|
|
||||||
DataSource dataSource = druidProperties.dataSource(DruidDataSourceBuilder.create().build());
|
|
||||||
targetDataSources.put(DataSourceTypeEnum.MASTER.name(), dataSource);
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置从数据源,注意从数据源配置“name = "enabled", havingValue = "true"”参数
|
|
||||||
*/
|
|
||||||
@Bean
|
|
||||||
@ConfigurationProperties("spring.datasource.druid.slave")
|
|
||||||
@ConditionalOnProperty(prefix = "spring.datasource.druid.slave", name = "enabled", havingValue = "true")
|
|
||||||
public DataSource slaveDataSource(DruidProperties druidProperties) {
|
|
||||||
DataSource dataSource = druidProperties.dataSource(DruidDataSourceBuilder.create().build());
|
|
||||||
targetDataSources.put(DataSourceTypeEnum.SLAVE.name(), dataSource);
|
|
||||||
return dataSource;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 之后所有需要增加的数据源可以在这里从上到下依次添加
|
|
||||||
* 只需要按照上面的方式(slaveDataSource的方法照葫芦画瓢)注入bean,然后再在配置文件中配置好相关的参数
|
|
||||||
* 最后添加该数据源所对应的枚举类作为该数据源的key即可
|
|
||||||
**/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用 @Qualifier 注解指定将两个数据源作为入参
|
|
||||||
*/
|
|
||||||
@Bean(name = "dynamicDataSource")
|
|
||||||
@Primary
|
|
||||||
public DynamicDataSourceHandler dataSource(@Qualifier("masterDataSource") DataSource masterDataSource, @Autowired(required = false) @Qualifier("slaveDataSource") DataSource slaveDataSource) {
|
|
||||||
Map<Object, Object> targetDataSources = new HashMap<>();
|
|
||||||
targetDataSources.put(DataSourceTypeEnum.MASTER.name(), masterDataSource);
|
|
||||||
log.info("加载动态数据源:{}", DataSourceTypeEnum.MASTER.name());
|
|
||||||
|
|
||||||
// 如果从数据源不为空 则添加到 targetDataSources 中
|
|
||||||
if (slaveDataSource != null) {
|
|
||||||
targetDataSources.put(DataSourceTypeEnum.SLAVE.name(), slaveDataSource);
|
|
||||||
log.info("加载动态数据源:{}", DataSourceTypeEnum.SLAVE.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
return new DynamicDataSourceHandler(masterDataSource, targetDataSources);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,23 +0,0 @@
|
|||||||
package net.lab1024.sa.base.constant;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据源类型
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
public enum DataSourceTypeEnum {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 主库
|
|
||||||
*/
|
|
||||||
MASTER,
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 从库
|
|
||||||
*/
|
|
||||||
SLAVE
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
package net.lab1024.sa.base.handler;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 数据源切换处理
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class DynamicDataSourceContextHandler {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 使用ThreadLocal维护变量,ThreadLocal为每个使用该变量的线程提供独立的变量副本,
|
|
||||||
* 所以每一个线程都可以独立地改变自己的副本,而不会影响其它线程所对应的副本。
|
|
||||||
*/
|
|
||||||
private static final ThreadLocal<String> CONTEXT_HOLDER = new ThreadLocal<>();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 设置数据源的变量
|
|
||||||
*/
|
|
||||||
public static void setDataSourceType(String dsType) {
|
|
||||||
log.info("切换到 {} 数据源", dsType);
|
|
||||||
CONTEXT_HOLDER.set(dsType);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得数据源的变量
|
|
||||||
*/
|
|
||||||
public static String getDataSourceType() {
|
|
||||||
return CONTEXT_HOLDER.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 清空数据源变量
|
|
||||||
*/
|
|
||||||
public static void clearDataSourceType() {
|
|
||||||
CONTEXT_HOLDER.remove();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
package net.lab1024.sa.base.handler;
|
|
||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
|
||||||
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
|
|
||||||
|
|
||||||
import javax.sql.DataSource;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 动态数据源
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Slf4j
|
|
||||||
public class DynamicDataSourceHandler extends AbstractRoutingDataSource {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* targetDataSources:将所有的数据源以Map的形式传入到AbstractRoutingDataSource的实现类中,以供后面进行动态数据源选择
|
|
||||||
*/
|
|
||||||
public DynamicDataSourceHandler(DataSource defaultTargetDataSource, Map<Object, Object> targetDataSources) {
|
|
||||||
super.setDefaultTargetDataSource(defaultTargetDataSource);
|
|
||||||
super.setTargetDataSources(targetDataSources);
|
|
||||||
super.afterPropertiesSet();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 系统每次选择数据源的时候会执行这个方法拿到key,再通过key去内部的数据源targetDataSources Map中找到对应的数据源对象
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
protected Object determineCurrentLookupKey() {
|
|
||||||
return DynamicDataSourceContextHandler.getDataSourceType();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,17 +1,8 @@
|
|||||||
package net.lab1024.sa.base.module.support.cache;
|
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 org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存服务
|
* 缓存服务
|
||||||
|
@ -3,10 +3,8 @@ package net.lab1024.sa.base.module.support.codegenerator.service.variable.backen
|
|||||||
import cn.hutool.core.bean.BeanUtil;
|
import cn.hutool.core.bean.BeanUtil;
|
||||||
import net.lab1024.sa.base.module.support.codegenerator.constant.CodeQueryFieldQueryTypeEnum;
|
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.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.domain.model.CodeQueryField;
|
||||||
import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService;
|
import net.lab1024.sa.base.module.support.codegenerator.service.variable.CodeGenerateBaseVariableService;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
@ -1,13 +1,8 @@
|
|||||||
package net.lab1024.sa.base.module.support.job.api.domain;
|
package net.lab1024.sa.base.module.support.job.api.domain;
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.NotBlank;
|
|
||||||
import jakarta.validation.constraints.NotNull;
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
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;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时任务 更新
|
* 定时任务 更新
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
package net.lab1024.sa.base.module.support.message.domain;
|
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 jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
|
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
|
||||||
import net.lab1024.sa.base.module.support.message.constant.MessageTemplateEnum;
|
import net.lab1024.sa.base.module.support.message.constant.MessageTemplateEnum;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,6 +28,10 @@ public class MessageTemplateSendForm {
|
|||||||
@NotNull(message = "接收者id不能为空")
|
@NotNull(message = "接收者id不能为空")
|
||||||
private Long receiverUserId;
|
private Long receiverUserId;
|
||||||
|
|
||||||
|
@Schema(description = "接收者id")
|
||||||
|
@NotEmpty(message = "接收者id不能为空")
|
||||||
|
private List<Long> receiverUserIdList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 相关业务id | 可选
|
* 相关业务id | 可选
|
||||||
* 用于跳转具体业务
|
* 用于跳转具体业务
|
||||||
|
@ -11,9 +11,6 @@ import net.lab1024.sa.base.module.support.reload.core.thread.SmartReloadRunnable
|
|||||||
import org.springframework.beans.BeansException;
|
import org.springframework.beans.BeansException;
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
import org.springframework.beans.factory.config.BeanPostProcessor;
|
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.stereotype.Service;
|
||||||
import org.springframework.util.ReflectionUtils;
|
import org.springframework.util.ReflectionUtils;
|
||||||
|
|
||||||
|
@ -2,7 +2,6 @@ package net.lab1024.sa.base.module.support.reload.core.thread;
|
|||||||
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.lab1024.sa.base.module.support.reload.core.AbstractSmartReloadCommand;
|
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.SmartReloadItem;
|
||||||
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject;
|
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadObject;
|
||||||
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult;
|
import net.lab1024.sa.base.module.support.reload.core.domain.SmartReloadResult;
|
||||||
|
@ -13,7 +13,7 @@ import java.lang.annotation.Target;
|
|||||||
* @Date 2020-11-25 20:56:58
|
* @Date 2020-11-25 20:56:58
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
|
@ -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.Cache;
|
||||||
import com.github.benmanes.caffeine.cache.Caffeine;
|
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.concurrent.TimeUnit;
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
@ -1,9 +1,7 @@
|
|||||||
package net.lab1024.sa.base.module.support.repeatsubmit.ticket;
|
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 org.springframework.data.redis.core.ValueOperations;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,73 +0,0 @@
|
|||||||
package net.lab1024.sa.base.properties;
|
|
||||||
|
|
||||||
import com.alibaba.druid.pool.DruidDataSource;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.context.annotation.Configuration;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Druid 配置属性
|
|
||||||
*
|
|
||||||
* @Author 钟家兴
|
|
||||||
* @Date 2025-05-01 14:49
|
|
||||||
* @Wechat JavaerEngineer
|
|
||||||
* @Email lab1024@163.com
|
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
|
||||||
*/
|
|
||||||
@Configuration
|
|
||||||
public class DruidProperties {
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.initial-size}")
|
|
||||||
private int initialSize;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.min-idle}")
|
|
||||||
private int minIdle;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.max-active}")
|
|
||||||
private int maxActive;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.max-wait}")
|
|
||||||
private int maxWait;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.connect-timeout}")
|
|
||||||
private int connectTimeout;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.socket-timeout}")
|
|
||||||
private int socketTimeout;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
|
|
||||||
private int timeBetweenEvictionRunsMillis;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
|
|
||||||
private int minEvictableIdleTimeMillis;
|
|
||||||
|
|
||||||
@Value("${spring.datasource.druid.max-evictable-idle-time-millis}")
|
|
||||||
private int maxEvictableIdleTimeMillis;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建datasource
|
|
||||||
*/
|
|
||||||
public DruidDataSource dataSource(DruidDataSource datasource)
|
|
||||||
{
|
|
||||||
// 配置初始化大小、最小、最大
|
|
||||||
datasource.setInitialSize(initialSize);
|
|
||||||
datasource.setMaxActive(maxActive);
|
|
||||||
datasource.setMinIdle(minIdle);
|
|
||||||
|
|
||||||
// 配置获取连接等待超时的时间
|
|
||||||
datasource.setMaxWait(maxWait);
|
|
||||||
|
|
||||||
// 配置驱动连接超时时间,检测数据库建立连接的超时时间,单位是毫秒
|
|
||||||
datasource.setConnectTimeout(connectTimeout);
|
|
||||||
|
|
||||||
// 配置网络超时时间,等待数据库操作完成的网络超时时间,单位是毫秒
|
|
||||||
datasource.setSocketTimeout(socketTimeout);
|
|
||||||
|
|
||||||
// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
|
|
||||||
datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
|
|
||||||
|
|
||||||
// 配置一个连接在池中最小、最大生存的时间,单位是毫秒
|
|
||||||
datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
|
|
||||||
datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis);
|
|
||||||
return datasource;
|
|
||||||
}
|
|
||||||
}
|
|
@ -22,12 +22,12 @@
|
|||||||
#end
|
#end
|
||||||
#if($field.queryTypeEnum == "Dict")
|
#if($field.queryTypeEnum == "Dict")
|
||||||
<a-form-item label="${field.label}" class="smart-query-form-item">
|
<a-form-item label="${field.label}" class="smart-query-form-item">
|
||||||
<DictSelect dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
|
<DictSelect dict-code="DICT_CODE_ENUM.$!{field.dict} || '$!{field.dict}'" placeholder="${field.label}" v-model:value="queryForm.${field.fieldName}" width="${field.width}" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
#end
|
#end
|
||||||
#if($field.queryTypeEnum == "Enum")
|
#if($field.queryTypeEnum == "Enum")
|
||||||
<a-form-item label="$codeGeneratorTool.removeEnumDesc(${field.label})" class="smart-query-form-item">
|
<a-form-item label="$codeGeneratorTool.removeEnumDesc(${field.label})" class="smart-query-form-item">
|
||||||
<SmartEnumSelect width="${field.width}" v-model:value="queryForm.${field.fieldName}" enum-name="$!{field.frontEnumName}" placeholder="$codeGeneratorTool.removeEnumDesc(${field.label})"/>
|
<SmartEnumSelect width="${field.width}" v-model:value="queryForm.${field.fieldName}" enum-name="$!{field.frontEnumName}" placeholder="$codeGeneratorTool.removeEnumDesc(${field.label})"/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
#end
|
#end
|
||||||
#if($field.queryTypeEnum == "Date")
|
#if($field.queryTypeEnum == "Date")
|
||||||
|
@ -1,28 +1,18 @@
|
|||||||
spring:
|
spring:
|
||||||
# 数据库连接信息
|
# 数据库连接信息
|
||||||
datasource:
|
datasource:
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
||||||
|
username: root
|
||||||
|
password: SmartAdmin666
|
||||||
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
|
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
|
||||||
|
initial-size: 2
|
||||||
|
min-idle: 2
|
||||||
|
max-active: 10
|
||||||
|
max-wait: 60000
|
||||||
|
time-between-eviction-runs-millis: 60000
|
||||||
|
min-evictable-idle-time-millis: 300000
|
||||||
|
filters: stat
|
||||||
druid:
|
druid:
|
||||||
master:
|
|
||||||
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
|
||||||
username: root
|
|
||||||
password: SmartAdmin666
|
|
||||||
slave:
|
|
||||||
enabled: true
|
|
||||||
url: jdbc:p6spy:mysql://127.0.0.1:3306/smart_admin_v3_slave?autoReconnect=true&useServerPreparedStmts=false&rewriteBatchedStatements=true&characterEncoding=UTF-8&useSSL=false&allowMultiQueries=true&serverTimezone=Asia/Shanghai
|
|
||||||
username: root
|
|
||||||
password: SmartAdmin666
|
|
||||||
initial-size: 2
|
|
||||||
min-idle: 2
|
|
||||||
max-active: 10
|
|
||||||
max-wait: 60000
|
|
||||||
connect-timeout: 30000
|
|
||||||
socket-timeout: 30000
|
|
||||||
time-between-eviction-runs-millis: 60000
|
|
||||||
min-evictable-idle-time-millis: 300000
|
|
||||||
max-evictable-idle-time-millis: 300000
|
|
||||||
filters: stat
|
|
||||||
username: druid
|
username: druid
|
||||||
password: 1024
|
password: 1024
|
||||||
login:
|
login:
|
||||||
@ -36,7 +26,7 @@ spring:
|
|||||||
database: 1
|
database: 1
|
||||||
host: 127.0.0.1
|
host: 127.0.0.1
|
||||||
port: 6379
|
port: 6379
|
||||||
password: 123456
|
password:
|
||||||
timeout: 10000ms
|
timeout: 10000ms
|
||||||
lettuce:
|
lettuce:
|
||||||
pool:
|
pool:
|
||||||
|
@ -67,7 +67,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
@ -66,7 +66,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
@ -67,7 +67,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
@ -20,11 +20,6 @@ public class AdminCacheConst extends CacheKeyConst {
|
|||||||
*/
|
*/
|
||||||
public static final String DEPARTMENT_LIST_CACHE = "department_list_cache";
|
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 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";
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
import org.apache.ibatis.annotations.Param;
|
import org.apache.ibatis.annotations.Param;
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -32,4 +31,5 @@ public interface DepartmentDao extends BaseMapper<DepartmentEntity> {
|
|||||||
*/
|
*/
|
||||||
List<DepartmentVO> listAll();
|
List<DepartmentVO> listAll();
|
||||||
|
|
||||||
|
DepartmentVO selectDepartmentVO(@Param("departmentId")Long departmentId);
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
|
|||||||
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.math.NumberUtils;
|
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.CacheEvict;
|
||||||
import org.springframework.cache.annotation.Cacheable;
|
import org.springframework.cache.annotation.Cacheable;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -30,7 +29,7 @@ import java.util.stream.Collectors;
|
|||||||
* @Date 2022-01-12 20:37:48
|
* @Date 2022-01-12 20:37:48
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
@ -43,7 +42,7 @@ public class DepartmentCacheManager {
|
|||||||
log.info("clear " + cache);
|
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() {
|
public void clearCache() {
|
||||||
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
|
logClearInfo(AdminCacheConst.Department.DEPARTMENT_LIST_CACHE);
|
||||||
}
|
}
|
||||||
@ -57,19 +56,8 @@ public class DepartmentCacheManager {
|
|||||||
return departmentDao.listAll();
|
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)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_TREE_CACHE)
|
||||||
public List<DepartmentTreeVO> getDepartmentTree() {
|
public List<DepartmentTreeVO> getDepartmentTree() {
|
||||||
@ -79,7 +67,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存某个部门的下级id列表
|
* 缓存某个部门的下级id列表
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_SELF_CHILDREN_CACHE)
|
||||||
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
|
public List<Long> getDepartmentSelfAndChildren(Long departmentId) {
|
||||||
@ -90,7 +77,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门的路径名称
|
* 部门的路径名称
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
|
@Cacheable(AdminCacheConst.Department.DEPARTMENT_PATH_CACHE)
|
||||||
public Map<Long, String> getDepartmentPathMap() {
|
public Map<Long, String> getDepartmentPathMap() {
|
||||||
@ -126,7 +112,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建部门树结构
|
* 构建部门树结构
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
|
public List<DepartmentTreeVO> buildTree(List<DepartmentVO> voList) {
|
||||||
if (CollectionUtils.isEmpty(voList)) {
|
if (CollectionUtils.isEmpty(voList)) {
|
||||||
@ -141,15 +126,15 @@ public class DepartmentCacheManager {
|
|||||||
return treeVOList;
|
return treeVOList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 构建所有根节点的下级树形结构
|
* 构建所有根节点的下级树形结构
|
||||||
* 返回值为层序遍历结果
|
* 返回值为层序遍历结果
|
||||||
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
|
* [由于departmentDao中listAll给出数据根据Sort降序 所以同一层中Sort值较大的优先遍历]
|
||||||
*/
|
*/
|
||||||
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
|
private List<Long> recursiveBuildTree(List<DepartmentTreeVO> nodeList, List<DepartmentVO> allDepartmentList) {
|
||||||
int nodeSize = nodeList.size();
|
int nodeSize = nodeList.size();
|
||||||
List<Long> childIdList = new ArrayList<>();
|
List<Long> childIdList = new ArrayList<>();
|
||||||
for(int i = 0; i < nodeSize; i++) {
|
for (int i = 0; i < nodeSize; i++) {
|
||||||
int preIndex = i - 1;
|
int preIndex = i - 1;
|
||||||
int nextIndex = i + 1;
|
int nextIndex = i + 1;
|
||||||
DepartmentTreeVO node = nodeList.get(i);
|
DepartmentTreeVO node = nodeList.get(i);
|
||||||
@ -161,39 +146,38 @@ public class DepartmentCacheManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
List<DepartmentTreeVO> children = getChildren(node.getDepartmentId(), allDepartmentList);
|
List<DepartmentTreeVO> children = getChildren(node.getDepartmentId(), allDepartmentList);
|
||||||
|
|
||||||
List<Long> tempChildIdList = new ArrayList<>();
|
List<Long> tempChildIdList = new ArrayList<>();
|
||||||
if (CollectionUtils.isNotEmpty(children)) {
|
if (CollectionUtils.isNotEmpty(children)) {
|
||||||
node.setChildren(children);
|
node.setChildren(children);
|
||||||
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
|
tempChildIdList = this.recursiveBuildTree(children, allDepartmentList);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
|
if (CollectionUtils.isEmpty(node.getSelfAndAllChildrenIdList())) {
|
||||||
node.setSelfAndAllChildrenIdList(
|
node.setSelfAndAllChildrenIdList(
|
||||||
new ArrayList<>()
|
new ArrayList<>()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
|
node.getSelfAndAllChildrenIdList().add(node.getDepartmentId());
|
||||||
|
|
||||||
if(CollectionUtils.isNotEmpty(tempChildIdList)) {
|
if (CollectionUtils.isNotEmpty(tempChildIdList)) {
|
||||||
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
|
node.getSelfAndAllChildrenIdList().addAll(tempChildIdList);
|
||||||
childIdList.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());
|
childIdList.add(0, nodeList.get(i).getDepartmentId());
|
||||||
}
|
}
|
||||||
|
|
||||||
return childIdList;
|
return childIdList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取子元素
|
* 获取子元素
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
|
private List<DepartmentTreeVO> getChildren(Long departmentId, List<DepartmentVO> voList) {
|
||||||
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
|
List<DepartmentVO> childrenEntityList = voList.stream().filter(e -> departmentId.equals(e.getParentId())).collect(Collectors.toList());
|
||||||
@ -206,7 +190,6 @@ public class DepartmentCacheManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 通过部门id,获取当前以及下属部门
|
* 通过部门id,获取当前以及下属部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
|
public List<Long> selfAndChildrenIdList(Long departmentId, List<DepartmentVO> voList) {
|
||||||
List<Long> selfAndChildrenIdList = Lists.newArrayList();
|
List<Long> selfAndChildrenIdList = Lists.newArrayList();
|
||||||
|
@ -14,10 +14,7 @@ import net.lab1024.sa.base.common.util.SmartBeanUtil;
|
|||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 部门 service
|
* 部门 service
|
||||||
@ -26,7 +23,7 @@ import java.util.Map;
|
|||||||
* @Date 2022-01-12 20:37:48
|
* @Date 2022-01-12 20:37:48
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Service
|
@Service
|
||||||
public class DepartmentService {
|
public class DepartmentService {
|
||||||
@ -44,7 +41,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增添加部门
|
* 新增添加部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
|
public ResponseDTO<String> addDepartment(DepartmentAddForm departmentAddForm) {
|
||||||
@ -57,7 +53,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 更新部门信息
|
* 更新部门信息
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
|
public ResponseDTO<String> updateDepartment(DepartmentUpdateForm updateDTO) {
|
||||||
if (updateDTO.getParentId() == null) {
|
if (updateDTO.getParentId() == null) {
|
||||||
@ -78,7 +73,6 @@ public class DepartmentService {
|
|||||||
* 根据id删除部门
|
* 根据id删除部门
|
||||||
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
|
* 1、需要判断当前部门是否有子部门,有子部门则不允许删除
|
||||||
* 2、需要判断当前部门是否有员工,有员工则不能删除
|
* 2、需要判断当前部门是否有员工,有员工则不能删除
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public ResponseDTO<String> deleteDepartment(Long departmentId) {
|
public ResponseDTO<String> deleteDepartment(Long departmentId) {
|
||||||
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
|
DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
|
||||||
@ -122,7 +116,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 自身以及所有下级的部门id列表
|
* 自身以及所有下级的部门id列表
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<Long> selfAndChildrenIdList(Long departmentId) {
|
public List<Long> selfAndChildrenIdList(Long departmentId) {
|
||||||
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
|
return departmentCacheManager.getDepartmentSelfAndChildren(departmentId);
|
||||||
@ -131,7 +124,6 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取所有部门
|
* 获取所有部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public List<DepartmentVO> listAll() {
|
public List<DepartmentVO> listAll() {
|
||||||
return departmentCacheManager.getDepartmentList();
|
return departmentCacheManager.getDepartmentList();
|
||||||
@ -140,10 +132,9 @@ public class DepartmentService {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取部门
|
* 获取部门
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
public DepartmentVO getDepartmentById(Long departmentId) {
|
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);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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.enumeration.UserTypeEnum;
|
||||||
import net.lab1024.sa.base.common.swagger.SchemaEnum;
|
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>
|
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class RequestEmployee implements RequestUser {
|
public class RequestEmployee implements RequestUser, Serializable {
|
||||||
|
|
||||||
@Schema(description = "员工id")
|
@Schema(description = "员工id")
|
||||||
private Long employeeId;
|
private Long employeeId;
|
||||||
|
@ -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.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取用户的权限(包含 角色列表、权限列表)
|
||||||
|
*/
|
||||||
|
@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(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -6,7 +6,6 @@ import cn.hutool.core.lang.UUID;
|
|||||||
import cn.hutool.core.util.NumberUtil;
|
import cn.hutool.core.util.NumberUtil;
|
||||||
import cn.hutool.core.util.RandomUtil;
|
import cn.hutool.core.util.RandomUtil;
|
||||||
import cn.hutool.extra.servlet.ServletUtil;
|
import cn.hutool.extra.servlet.ServletUtil;
|
||||||
import com.googlecode.concurrentlinkedhashmap.ConcurrentLinkedHashMap;
|
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
|
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.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.LoginForm;
|
||||||
import net.lab1024.sa.admin.module.system.login.domain.LoginResultVO;
|
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.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.menu.domain.vo.MenuVO;
|
||||||
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
|
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.RoleEmployeeService;
|
||||||
@ -56,15 +56,16 @@ import org.springframework.stereotype.Service;
|
|||||||
import javax.annotation.Resource;
|
import javax.annotation.Resource;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
import javax.servlet.http.HttpServletRequest;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import java.util.*;
|
import java.util.Collections;
|
||||||
import java.util.concurrent.ConcurrentMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 登录
|
* 登录
|
||||||
*
|
*
|
||||||
* @Author 1024创新实验室: 开云
|
* @Author 1024创新实验室: 卓大
|
||||||
* @Date 2021-12-01 22:56:34
|
* @Date 2025-05-03 22:56:34
|
||||||
* @Wechat zhuoda1024
|
* @Wechat zhuoda1024
|
||||||
* @Email lab1024@163.com
|
* @Email lab1024@163.com
|
||||||
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
|
* @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 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
|
@Resource
|
||||||
private EmployeeService employeeService;
|
private EmployeeService employeeService;
|
||||||
|
|
||||||
@ -136,6 +121,9 @@ public class LoginService implements StpInterface {
|
|||||||
@Resource
|
@Resource
|
||||||
private RedisService redisService;
|
private RedisService redisService;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private LoginManager loginManager;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取验证码
|
* 获取验证码
|
||||||
*/
|
*/
|
||||||
@ -226,10 +214,7 @@ public class LoginService implements StpInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取员工信息
|
// 获取员工信息
|
||||||
RequestEmployee requestEmployee = loadLoginInfo(employeeEntity);
|
RequestEmployee requestEmployee = loginManager.loadLoginInfo(employeeEntity);
|
||||||
|
|
||||||
// 放入缓存
|
|
||||||
loginEmployeeCache.put(employeeEntity.getEmployeeId(), requestEmployee);
|
|
||||||
|
|
||||||
// 移除登录失败
|
// 移除登录失败
|
||||||
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
|
securityLoginService.removeLoginFail(employeeEntity.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE);
|
||||||
@ -244,8 +229,8 @@ public class LoginService implements StpInterface {
|
|||||||
// 设置 token
|
// 设置 token
|
||||||
loginResultVO.setToken(token);
|
loginResultVO.setToken(token);
|
||||||
|
|
||||||
// 清除权限缓存
|
// 更新用户权限
|
||||||
permissionCache.remove(employeeEntity.getEmployeeId());
|
loginManager.loadUserPermission(employeeEntity.getEmployeeId());
|
||||||
|
|
||||||
return ResponseDTO.ok(loginResultVO);
|
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());
|
List<MenuVO> menuAndPointsList = roleMenuService.getMenuList(roleList.stream().map(RoleVO::getRoleId).collect(Collectors.toList()), requestEmployee.getAdministratorFlag());
|
||||||
loginResultVO.setMenuList(menuAndPointsList);
|
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);
|
LoginLogVO loginLogVO = loginLogService.queryLastByUserId(requestEmployee.getEmployeeId(), UserTypeEnum.ADMIN_EMPLOYEE, LoginLogResultEnum.LOGIN_SUCCESS);
|
||||||
if (loginLogVO != null) {
|
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 获取员请求工信息
|
* 根据登陆token 获取员请求工信息
|
||||||
*/
|
*/
|
||||||
@ -330,17 +285,7 @@ public class LoginService implements StpInterface {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
RequestEmployee requestEmployee = loginEmployeeCache.get(requestEmployeeId);
|
RequestEmployee requestEmployee = loginManager.getRequestEmployee(requestEmployeeId);
|
||||||
if (requestEmployee == null) {
|
|
||||||
// 员工基本信息
|
|
||||||
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
|
|
||||||
if (employeeEntity == null) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
requestEmployee = this.loadLoginInfo(employeeEntity);
|
|
||||||
loginEmployeeCache.put(requestEmployeeId, requestEmployee);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新请求ip和user agent
|
// 更新请求ip和user agent
|
||||||
requestEmployee.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
|
requestEmployee.setUserAgent(ServletUtil.getHeaderIgnoreCase(request, RequestHeaderConst.USER_AGENT));
|
||||||
@ -384,7 +329,7 @@ public class LoginService implements StpInterface {
|
|||||||
StpUtil.logout();
|
StpUtil.logout();
|
||||||
|
|
||||||
// 清空登录信息缓存
|
// 清空登录信息缓存
|
||||||
loginEmployeeCache.remove(requestUser.getUserId());
|
loginManager.clear();
|
||||||
|
|
||||||
//保存登出日志
|
//保存登出日志
|
||||||
LoginLogEntity loginEntity = LoginLogEntity.builder()
|
LoginLogEntity loginEntity = LoginLogEntity.builder()
|
||||||
@ -402,14 +347,6 @@ public class LoginService implements StpInterface {
|
|||||||
return ResponseDTO.ok();
|
return ResponseDTO.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 清除员工登录缓存
|
|
||||||
*/
|
|
||||||
public void clearLoginEmployeeCache(Long employeeId) {
|
|
||||||
// 清空登录信息缓存
|
|
||||||
loginEmployeeCache.remove(employeeId);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 保存登录日志
|
* 保存登录日志
|
||||||
*/
|
*/
|
||||||
@ -437,12 +374,7 @@ public class LoginService implements StpInterface {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPermission userPermission = permissionCache.get(employeeId);
|
UserPermission userPermission = loginManager.getUserPermission(employeeId);
|
||||||
if (userPermission == null) {
|
|
||||||
userPermission = getUserPermission(employeeId);
|
|
||||||
permissionCache.put(employeeId, userPermission);
|
|
||||||
}
|
|
||||||
|
|
||||||
return userPermission.getPermissionList();
|
return userPermission.getPermissionList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -453,51 +385,10 @@ public class LoginService implements StpInterface {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserPermission userPermission = permissionCache.get(employeeId);
|
UserPermission userPermission = loginManager.getUserPermission(employeeId);
|
||||||
if (userPermission == null) {
|
|
||||||
userPermission = getUserPermission(employeeId);
|
|
||||||
permissionCache.put(employeeId, userPermission);
|
|
||||||
}
|
|
||||||
return userPermission.getRoleList();
|
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);
|
String redisVerificationCodeKey = redisService.generateRedisKey(RedisKeyConst.Support.LOGIN_VERIFICATION_CODE, UserTypeEnum.ADMIN_EMPLOYEE.getValue() + RedisKeyConst.SEPARATOR + employeeId);
|
||||||
redisService.delete(redisVerificationCodeKey);
|
redisService.delete(redisVerificationCodeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clearLoginEmployeeCache(Long employeeId) {
|
||||||
|
loginManager.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,5 +19,16 @@
|
|||||||
WHERE parent_id = #{departmentId}
|
WHERE parent_id = #{departmentId}
|
||||||
</select>
|
</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.`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>
|
</mapper>
|
@ -2,6 +2,7 @@ package net.lab1024.sa.base.common.domain;
|
|||||||
|
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -15,7 +16,7 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
@Data
|
@Data
|
||||||
public class UserPermission {
|
public class UserPermission implements Serializable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 权限列表
|
* 权限列表
|
||||||
|
@ -1,11 +1,17 @@
|
|||||||
package net.lab1024.sa.base.config;
|
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.CacheService;
|
||||||
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
|
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
|
||||||
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
|
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.context.annotation.Bean;
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.data.redis.cache.RedisCacheConfiguration;
|
||||||
|
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||||
|
import org.springframework.data.redis.serializer.RedisSerializationContext;
|
||||||
|
|
||||||
|
import javax.annotation.Resource;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 缓存配置
|
* 缓存配置
|
||||||
@ -20,6 +26,18 @@ public class CacheConfig {
|
|||||||
private static final String CAFFEINE_CACHE = "caffeine";
|
private static final String CAFFEINE_CACHE = "caffeine";
|
||||||
|
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private RedisConnectionFactory factory;
|
||||||
|
|
||||||
|
@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
|
@Bean
|
||||||
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
|
||||||
public CacheService redisCacheService() {
|
public CacheService redisCacheService() {
|
||||||
|
@ -66,7 +66,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
@ -88,8 +88,8 @@ file:
|
|||||||
region: oss-cn-hangzhou
|
region: oss-cn-hangzhou
|
||||||
endpoint: oss-cn-hangzhou.aliyuncs.com
|
endpoint: oss-cn-hangzhou.aliyuncs.com
|
||||||
bucket-name: 1024lab-smart-admin
|
bucket-name: 1024lab-smart-admin
|
||||||
access-key:
|
access-key:
|
||||||
secret-key:
|
secret-key:
|
||||||
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
|
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
|
||||||
private-url-expire-seconds: 3600
|
private-url-expire-seconds: 3600
|
||||||
|
|
||||||
|
@ -66,7 +66,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
@ -65,7 +65,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
@ -66,7 +66,7 @@ spring:
|
|||||||
|
|
||||||
# 缓存实现类型
|
# 缓存实现类型
|
||||||
cache:
|
cache:
|
||||||
type: caffeine
|
type: redis
|
||||||
|
|
||||||
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
|
||||||
server:
|
server:
|
||||||
|
BIN
smart-admin-web-javascript/src/assets/images/login/login-min.gif
Normal file
BIN
smart-admin-web-javascript/src/assets/images/login/login-min.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dictCode: String,
|
dictCode: String,
|
||||||
dataValue: String,
|
dataValue: [String, Number],
|
||||||
});
|
});
|
||||||
const dataLabels = computed(() => {
|
const dataLabels = computed(() => {
|
||||||
return useDictStore().getDataLabels(props.dictCode, props.dataValue);
|
return useDictStore().getDataLabels(props.dictCode, props.dataValue);
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { dictApi } from '/@/api/support/dict-api';
|
|
||||||
import { smartSentry } from '/@/lib/smart-sentry';
|
|
||||||
import { DICT_SPLIT } from '/@/constants/support/dict-const.js';
|
import { DICT_SPLIT } from '/@/constants/support/dict-const.js';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
@ -23,14 +21,21 @@ export const useDictStore = defineStore({
|
|||||||
|
|
||||||
// 获取字典的值名称
|
// 获取字典的值名称
|
||||||
getDataLabels(dictCode, dataValue) {
|
getDataLabels(dictCode, dataValue) {
|
||||||
if (!dataValue) {
|
if (_.isNil(dataValue) || _.isNaN(dataValue)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let dict = this.getDictData(dictCode);
|
let dict = this.getDictData(dictCode);
|
||||||
if (dict.length === 0) {
|
if (dict.length === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是数字的话,需要特殊处理
|
||||||
|
if(_.isNumber(dataValue)){
|
||||||
|
let target = _.find(dict, { dataValue: dataValue });
|
||||||
|
return target ? target.dataLabel : '';
|
||||||
|
}
|
||||||
|
|
||||||
let valueArray = dataValue.split(DICT_SPLIT);
|
let valueArray = dataValue.split(DICT_SPLIT);
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let item of valueArray) {
|
for (let item of valueArray) {
|
||||||
@ -42,7 +47,7 @@ export const useDictStore = defineStore({
|
|||||||
return result.join(DICT_SPLIT);
|
return result.join(DICT_SPLIT);
|
||||||
},
|
},
|
||||||
// 初始化字典
|
// 初始化字典
|
||||||
initData(dictDataList){
|
initData(dictDataList) {
|
||||||
this.dictMap.clear();
|
this.dictMap.clear();
|
||||||
for (let data of dictDataList) {
|
for (let data of dictDataList) {
|
||||||
let dataArray = this.dictMap.get(data.dictCode);
|
let dataArray = this.dictMap.get(data.dictCode);
|
||||||
|
@ -495,40 +495,32 @@
|
|||||||
function camelToUnderscore(str) {
|
function camelToUnderscore(str) {
|
||||||
return str.replace(/([A-Z])/g, '_$1').toLowerCase();
|
return str.replace(/([A-Z])/g, '_$1').toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 动态设置表格高度
|
// 动态设置表格高度
|
||||||
const yHeight = ref(0);
|
const yHeight = ref(0);
|
||||||
|
onMounted(() => {
|
||||||
|
resetGetHeight();
|
||||||
|
});
|
||||||
function resetGetHeight() {
|
function resetGetHeight() {
|
||||||
// 搜索部分高度
|
// 搜索部分高度
|
||||||
let doc = document.querySelector('.ant-form');
|
let doc = document.querySelector('.ant-form');
|
||||||
// 按钮部分高度
|
// 按钮部分高度
|
||||||
let btn = document.querySelector('.smart-table-btn-block');
|
let btn = document.querySelector('.smart-table-btn-block');
|
||||||
// 表格头高度
|
// 表格头高度
|
||||||
let tableCell = document.querySelector('.ant-table-cell');
|
let tableCell = document.querySelector('.ant-table-cell');
|
||||||
// 分页高度
|
// 分页高度
|
||||||
let page = document.querySelector('.smart-query-table-page');
|
let page = document.querySelector('.smart-query-table-page');
|
||||||
// 内容区总高度
|
// 内容区总高度
|
||||||
let box = document.querySelector('.admin-content');
|
let box = document.querySelector('.admin-content');
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let dueHeight = doc.offsetHeight + 10 + 24 + btn.offsetHeight + 15 + tableCell.offsetHeight + page.offsetHeight + 20;
|
let dueHeight = doc.offsetHeight + 10 + 24 + btn.offsetHeight + 15 + tableCell.offsetHeight + page.offsetHeight + 20;
|
||||||
yHeight.value = box.offsetHeight - dueHeight;
|
yHeight.value = box.offsetHeight - dueHeight;
|
||||||
}, 100);
|
}, 100);
|
||||||
}
|
}
|
||||||
|
window.addEventListener(
|
||||||
// 定义一个变量来存储节流后的回调函数
|
'resize',
|
||||||
let throttledResizeHandler;
|
_.throttle(() => {
|
||||||
onMounted(() => {
|
resetGetHeight();
|
||||||
resetGetHeight();
|
}, 1000)
|
||||||
throttledResizeHandler = _.throttle(() => {
|
);
|
||||||
resetGetHeight();
|
|
||||||
}, 1000);
|
|
||||||
|
|
||||||
window.addEventListener('resize', throttledResizeHandler);
|
|
||||||
});
|
|
||||||
|
|
||||||
// 在组件销毁时移除 resize 事件监听器
|
|
||||||
onUnmounted(() => {
|
|
||||||
window.removeEventListener('resize', throttledResizeHandler);
|
|
||||||
});
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<a-table
|
<a-table
|
||||||
size="small"
|
size="small"
|
||||||
:scroll="{ y: 800 }"
|
:scroll="{ x: 1000 }"
|
||||||
:loading="tableLoading"
|
:loading="tableLoading"
|
||||||
bordered
|
bordered
|
||||||
:dataSource="tableData"
|
:dataSource="tableData"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:open="visible" title="推送人" width="1100px" ok-text="确定" cancel-text="取消" @ok="onSubmit" @cancel="onClose" :zIndex="9999">
|
<a-modal v-model:open="visible" title="推送人" width="1100px" ok-text="确定" cancel-text="取消" @ok="onSubmit" @cancel="onClose" :zIndex="9999">
|
||||||
<a-form class="smart-query-form">
|
<a-form class="smart-query-form">
|
||||||
<a-row class="smart-query-form-row">
|
<a-row class="smart-query-form-row">
|
||||||
<a-form-item label="关键词搜索" class="smart-query-form-item">
|
<a-form-item label="关键词搜索" class="smart-query-form-item">
|
||||||
@ -56,11 +56,9 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
|
||||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||||
import { smartSentry } from '/@/lib/smart-sentry';
|
import { smartSentry } from '/@/lib/smart-sentry';
|
||||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
|
||||||
import { employeeApi } from '/@/api/system/employee-api';
|
import { employeeApi } from '/@/api/system/employee-api';
|
||||||
// ---------------查询条件----------------
|
// ---------------查询条件----------------
|
||||||
const queryParamState = {
|
const queryParamState = {
|
||||||
|
@ -54,11 +54,11 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<!--待办、已办-->
|
<!--待办、已办-->
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<ToBeDoneCard />
|
<ChangelogCard />
|
||||||
</a-col>
|
</a-col>
|
||||||
<!--更新日志-->
|
<!--更新日志-->
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<ChangelogCard />
|
<ToBeDoneCard />
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -80,8 +80,7 @@
|
|||||||
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
||||||
import { useUserStore } from '/@/store/modules/system/user';
|
import { useUserStore } from '/@/store/modules/system/user';
|
||||||
import loginQR from '/@/assets/images/login/login-qr.png';
|
import loginQR from '/@/assets/images/login/login-qr.png';
|
||||||
import leftBg2 from '/@/assets/images/login/left-bg2.png';
|
import loginGif from '/@/assets/images/login/login-min.gif';
|
||||||
import loginGif from '/@/assets/images/login/login.gif';
|
|
||||||
import wechatIcon from '/@/assets/images/login/wechat-icon.png';
|
import wechatIcon from '/@/assets/images/login/wechat-icon.png';
|
||||||
import aliIcon from '/@/assets/images/login/ali-icon.png';
|
import aliIcon from '/@/assets/images/login/ali-icon.png';
|
||||||
import douyinIcon from '/@/assets/images/login/douyin-icon.png';
|
import douyinIcon from '/@/assets/images/login/douyin-icon.png';
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
<li v-for="module in props.tree" :key="module.menuId">
|
<li v-for="module in props.tree" :key="module.menuId">
|
||||||
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
|
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
|
||||||
<a-checkbox @change="selectCheckbox(module)" class="checked-box-label" :value="module.menuId">{{ module.menuName }} </a-checkbox>
|
<a-checkbox @change="selectCheckbox(module)" class="checked-box-label" :value="module.menuId">{{ module.menuName }} </a-checkbox>
|
||||||
<div v-if="module.children && module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
|
<div v-if="module.children && module.children.some((e) => e.menuType === MENU_TYPE_ENUM.POINTS.value)">
|
||||||
<RoleTreePoint :tree="module.children" @selectCheckbox="selectCheckbox" />
|
<RoleTreePoint :tree="module.children" @selectCheckbox="selectCheckbox" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="module.children && !module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
|
<template v-if="module.children && !module.children.some((e) => e.menuType === MENU_TYPE_ENUM.POINTS.value)">
|
||||||
<RoleTreeMenu :tree="module.children" :index="props.index + 1" />
|
<RoleTreeMenu :tree="module.children" :index="props.index + 1" />
|
||||||
</template>
|
</template>
|
||||||
</li>
|
</li>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
let checkedData = roleStore.checkedData;
|
let checkedData = roleStore.checkedData;
|
||||||
let findIndex = checkedData.indexOf(module.menuId);
|
let findIndex = checkedData.indexOf(module.menuId);
|
||||||
// 选中
|
// 选中
|
||||||
if (findIndex == -1) {
|
if (findIndex === -1) {
|
||||||
// 选中本级以及子级
|
// 选中本级以及子级
|
||||||
roleStore.addCheckedDataAndChildren(module);
|
roleStore.addCheckedDataAndChildren(module);
|
||||||
// 选中上级
|
// 选中上级
|
||||||
|
@ -43,18 +43,15 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import dayjs from 'dayjs';
|
import dayjs from 'dayjs';
|
||||||
import { computed, h, useSlots } from 'vue';
|
import {computed, h} from 'vue';
|
||||||
import { messages } from '/@/i18n';
|
import {messages} from '/@/i18n';
|
||||||
import { useAppConfigStore } from '/@/store/modules/system/app-config';
|
import {useAppConfigStore} from '/@/store/modules/system/app-config';
|
||||||
import { useSpinStore } from '/@/store/modules/system/spin';
|
import {useSpinStore} from '/@/store/modules/system/spin';
|
||||||
import { theme } from 'ant-design-vue';
|
import {Popover, theme} from 'ant-design-vue';
|
||||||
import { themeColors } from '/@/theme/color.js';
|
import {themeColors} from '/@/theme/color.js';
|
||||||
import { Popover } from 'ant-design-vue';
|
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
|
||||||
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
|
|
||||||
import _ from 'lodash';
|
|
||||||
|
|
||||||
const slots = useSlots();
|
|
||||||
const antdLocale = computed(() => messages[useAppConfigStore().language].antdLocale);
|
const antdLocale = computed(() => messages[useAppConfigStore().language].antdLocale);
|
||||||
const dayjsLocale = computed(() => messages[useAppConfigStore().language].dayjsLocale);
|
const dayjsLocale = computed(() => messages[useAppConfigStore().language].dayjsLocale);
|
||||||
dayjs.locale(dayjsLocale);
|
dayjs.locale(dayjsLocale);
|
||||||
@ -91,6 +88,7 @@
|
|||||||
return text;
|
return text;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
:deep(.ant-table-column-sorters) {
|
:deep(.ant-table-column-sorters) {
|
||||||
|
BIN
smart-admin-web-typescript/src/assets/images/login/login-min.gif
Normal file
BIN
smart-admin-web-typescript/src/assets/images/login/login-min.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
@ -26,7 +26,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, watch, onMounted, getCurrentInstance} from 'vue';
|
import { ref, watch, onMounted, getCurrentInstance } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
enumName: String,
|
enumName: String,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
dictCode: String,
|
dictCode: String,
|
||||||
dataValue: String,
|
dataValue: [String, Number],
|
||||||
});
|
});
|
||||||
const dataLabels = computed(() => {
|
const dataLabels = computed(() => {
|
||||||
return useDictStore().getDataLabels(props.dictCode, props.dataValue);
|
return useDictStore().getDataLabels(props.dictCode, props.dataValue);
|
||||||
|
@ -7,13 +7,7 @@
|
|||||||
* @Email: lab1024@163.com
|
* @Email: lab1024@163.com
|
||||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||||
*/
|
*/
|
||||||
import { AppConfig } from '/@/types/config';
|
export const appDefaultConfig = {
|
||||||
|
|
||||||
/**
|
|
||||||
* 应用默认配置
|
|
||||||
*/
|
|
||||||
|
|
||||||
export const appDefaultConfig: AppConfig = {
|
|
||||||
// i18n 语言选择
|
// i18n 语言选择
|
||||||
language: 'zh_CN',
|
language: 'zh_CN',
|
||||||
// 布局: side 或者 side-expand 或者 top
|
// 布局: side 或者 side-expand 或者 top
|
||||||
|
@ -208,9 +208,9 @@
|
|||||||
// 页面圆角
|
// 页面圆角
|
||||||
borderRadius: appConfigStore.borderRadius,
|
borderRadius: appConfigStore.borderRadius,
|
||||||
// 标签页
|
// 标签页
|
||||||
flatPattern: appConfigStore.flatPattern,
|
|
||||||
// 标签页
|
|
||||||
pageTagFlag: appConfigStore.pageTagFlag,
|
pageTagFlag: appConfigStore.pageTagFlag,
|
||||||
|
// 标签页
|
||||||
|
flatPattern: appConfigStore.flatPattern,
|
||||||
// 标签页 样式
|
// 标签页 样式
|
||||||
pageTagStyle: appConfigStore.pageTagStyle,
|
pageTagStyle: appConfigStore.pageTagStyle,
|
||||||
// 面包屑
|
// 面包屑
|
||||||
@ -251,7 +251,7 @@
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function changePageTagLocation(e: any) {
|
function changePageTagLocation(e) {
|
||||||
appConfigStore.$patch({
|
appConfigStore.$patch({
|
||||||
pageTagLocation: e.target.value,
|
pageTagLocation: e.target.value,
|
||||||
});
|
});
|
||||||
|
@ -48,6 +48,7 @@
|
|||||||
const menuTree = computed(() => useUserStore().getMenuTree || []);
|
const menuTree = computed(() => useUserStore().getMenuTree || []);
|
||||||
const rootSubmenuKeys = computed(()=>menuTree.value.map(item=>item.menuId));
|
const rootSubmenuKeys = computed(()=>menuTree.value.map(item=>item.menuId));
|
||||||
|
|
||||||
|
|
||||||
//展开的菜单
|
//展开的菜单
|
||||||
let currentRoute = useRoute();
|
let currentRoute = useRoute();
|
||||||
const selectedKeys = ref([]);
|
const selectedKeys = ref([]);
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { defineStore } from 'pinia';
|
import { defineStore } from 'pinia';
|
||||||
import { dictApi } from '/@/api/support/dict-api';
|
|
||||||
import { smartSentry } from '/@/lib/smart-sentry';
|
|
||||||
import { DICT_SPLIT } from '/@/constants/support/dict-const.js';
|
import { DICT_SPLIT } from '/@/constants/support/dict-const.js';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
|
|
||||||
@ -23,14 +21,21 @@ export const useDictStore = defineStore({
|
|||||||
|
|
||||||
// 获取字典的值名称
|
// 获取字典的值名称
|
||||||
getDataLabels(dictCode, dataValue) {
|
getDataLabels(dictCode, dataValue) {
|
||||||
if (!dataValue) {
|
if (_.isNil(dataValue) || _.isNaN(dataValue)) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
let dict = this.getDictData(dictCode);
|
let dict = this.getDictData(dictCode);
|
||||||
if (dict.length === 0) {
|
if (dict.length === 0) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 是数字的话,需要特殊处理
|
||||||
|
if(_.isNumber(dataValue)){
|
||||||
|
let target = _.find(dict, { dataValue: dataValue });
|
||||||
|
return target ? target.dataLabel : '';
|
||||||
|
}
|
||||||
|
|
||||||
let valueArray = dataValue.split(DICT_SPLIT);
|
let valueArray = dataValue.split(DICT_SPLIT);
|
||||||
let result = [];
|
let result = [];
|
||||||
for (let item of valueArray) {
|
for (let item of valueArray) {
|
||||||
@ -42,7 +47,7 @@ export const useDictStore = defineStore({
|
|||||||
return result.join(DICT_SPLIT);
|
return result.join(DICT_SPLIT);
|
||||||
},
|
},
|
||||||
// 初始化字典
|
// 初始化字典
|
||||||
initData(dictDataList){
|
initData(dictDataList) {
|
||||||
this.dictMap.clear();
|
this.dictMap.clear();
|
||||||
for (let data of dictDataList) {
|
for (let data of dictDataList) {
|
||||||
let dataArray = this.dictMap.get(data.dictCode);
|
let dataArray = this.dictMap.get(data.dictCode);
|
||||||
|
@ -36,7 +36,7 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</a-button-group>
|
</a-button-group>
|
||||||
|
|
||||||
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20" v-if="$privilege('oa:bank:add')">
|
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20">
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusOutlined />
|
<PlusOutlined />
|
||||||
</template>
|
</template>
|
||||||
@ -60,8 +60,8 @@
|
|||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.dataIndex === 'action'">
|
<template v-else-if="column.dataIndex === 'action'">
|
||||||
<div class="smart-table-operate">
|
<div class="smart-table-operate">
|
||||||
<a-button @click="addOrUpdate(record)" type="link" v-if="$privilege('oa:bank:update')">编辑</a-button>
|
<a-button @click="addOrUpdate(record)" type="link">编辑</a-button>
|
||||||
<a-button @click="confirmDelete(record.bankId)" danger type="link" v-if="$privilege('oa:bank:delete')">删除</a-button>
|
<a-button @click="confirmDelete(record.bankId)" danger type="link">删除</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-modal :open="visible" :title="form.bankId ? '编辑' : '添加'" :width="700" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
<a-modal :open="visible" :title="form.bankId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 19 }">
|
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
|
||||||
<a-form-item label="开户银行" name="bankName">
|
<a-form-item label="开户银行" name="bankName">
|
||||||
<a-input v-model:value="form.bankName" placeholder="请输入开户银行" />
|
<a-input v-model:value="form.bankName" placeholder="请输入开户银行" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -16,59 +16,50 @@
|
|||||||
<a-button class="button-style" type="primary" @click="onSearch">搜索</a-button>
|
<a-button class="button-style" type="primary" @click="onSearch">搜索</a-button>
|
||||||
<a-button class="button-style" type="default" @click="resetQueryEmployee">重置</a-button>
|
<a-button class="button-style" type="default" @click="resetQueryEmployee">重置</a-button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<a-button class="button-style" type="primary" @click="addEmployee" v-privilege="'oa:enterprise:addEmployee'"> 添加员工 </a-button>
|
<a-button class="button-style" type="primary" @click="addEmployee" v-privilege="'oa:enterprise:addEmployee'"> 添加员工 </a-button>
|
||||||
<a-button class="button-style" type="primary" danger @click="batchDelete" v-privilege="'oa:enterprise:deleteEmployee'"> 批量移除 </a-button>
|
<a-button class="button-style" type="primary" danger @click="batchDelete" v-privilege="'oa:enterprise:deleteEmployee'"> 批量移除 </a-button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<a-card size="small" :bordered="false" :hoverable="false">
|
<a-table
|
||||||
<a-row justify="end">
|
:loading="tableLoading"
|
||||||
<TableOperator
|
:dataSource="tableData"
|
||||||
class="smart-margin-bottom5"
|
:columns="columns"
|
||||||
v-model="columns"
|
:pagination="false"
|
||||||
:tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE_EMPLOYEE"
|
rowKey="employeeId"
|
||||||
:refresh="queryEmployee"
|
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
|
||||||
/>
|
size="small"
|
||||||
</a-row>
|
bordered
|
||||||
<a-table
|
>
|
||||||
:loading="tableLoading"
|
<template #bodyCell="{ text, record, index, column }">
|
||||||
:dataSource="tableData"
|
<template v-if="column.dataIndex === 'disabledFlag'">
|
||||||
:columns="columns"
|
<a-tag :color="text ? 'error' : 'processing'">{{ text ? '禁用' : '启用' }}</a-tag>
|
||||||
:pagination="false"
|
|
||||||
rowKey="employeeId"
|
|
||||||
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
|
|
||||||
size="small"
|
|
||||||
bordered
|
|
||||||
>
|
|
||||||
<template #bodyCell="{ text, record, column }">
|
|
||||||
<template v-if="column.dataIndex === 'disabledFlag'">
|
|
||||||
<a-tag :color="text ? 'error' : 'processing'">{{ text ? '禁用' : '启用' }}</a-tag>
|
|
||||||
</template>
|
|
||||||
<template v-else-if="column.dataIndex === 'gender'">
|
|
||||||
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
|
|
||||||
</template>
|
|
||||||
<template v-if="column.dataIndex === 'operate'">
|
|
||||||
<a-button type="link" @click="deleteEmployee(record.employeeId)" v-privilege="'oa:enterprise:deleteEmployee'">移除</a-button>
|
|
||||||
</template>
|
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
<template v-else-if="column.dataIndex === 'gender'">
|
||||||
<div class="smart-query-table-page">
|
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
|
||||||
<a-pagination
|
</template>
|
||||||
showSizeChanger
|
<template v-if="column.dataIndex === 'operate'">
|
||||||
showQuickJumper
|
<a @click="deleteEmployee(record.employeeId)" v-privilege="'oa:enterprise:deleteEmployee'">移除</a>
|
||||||
show-less-items
|
</template>
|
||||||
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
</template>
|
||||||
:defaultPageSize="queryForm.pageSize"
|
</a-table>
|
||||||
v-model:current="queryForm.pageNum"
|
<div class="smart-query-table-page">
|
||||||
v-model:pageSize="queryForm.pageSize"
|
<a-pagination
|
||||||
:total="total"
|
showSizeChanger
|
||||||
@change="queryEmployee"
|
showQuickJumper
|
||||||
@showSizeChange="queryEmployee"
|
show-less-items
|
||||||
:show-total="showTableTotal"
|
:pageSizeOptions="PAGE_SIZE_OPTIONS"
|
||||||
/>
|
:defaultPageSize="queryForm.pageSize"
|
||||||
</div>
|
v-model:current="queryForm.pageNum"
|
||||||
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="selectData" />
|
v-model:pageSize="queryForm.pageSize"
|
||||||
</a-card>
|
:total="total"
|
||||||
|
@change="queryEmployee"
|
||||||
|
@showSizeChange="queryEmployee"
|
||||||
|
:show-total="showTableTotal"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="selectData" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
@ -81,8 +72,6 @@
|
|||||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, showTableTotal } from '/@/constants/common-const';
|
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, showTableTotal } from '/@/constants/common-const';
|
||||||
import { smartSentry } from '/@/lib/smart-sentry';
|
import { smartSentry } from '/@/lib/smart-sentry';
|
||||||
import TableOperator from '/@/components/support/table-operator/index.vue';
|
|
||||||
import { TABLE_ID_CONST } from '/@/constants/support/table-id-const';
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
enterpriseId: {
|
enterpriseId: {
|
||||||
@ -123,8 +112,7 @@
|
|||||||
{
|
{
|
||||||
title: '操作',
|
title: '操作',
|
||||||
dataIndex: 'operate',
|
dataIndex: 'operate',
|
||||||
width: 90,
|
width: 60,
|
||||||
align: 'center',
|
|
||||||
},
|
},
|
||||||
]);
|
]);
|
||||||
|
|
||||||
@ -283,8 +271,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
padding: 10px 10px;
|
margin: 20px 0;
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.button-style {
|
.button-style {
|
||||||
|
@ -36,8 +36,7 @@
|
|||||||
</a-button>
|
</a-button>
|
||||||
</a-button-group>
|
</a-button-group>
|
||||||
|
|
||||||
|
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20">
|
||||||
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20" v-if="$privilege('oa:invoice:add')">
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<PlusOutlined />
|
<PlusOutlined />
|
||||||
</template>
|
</template>
|
||||||
@ -52,14 +51,14 @@
|
|||||||
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE_INVOICE" :refresh="ajaxQuery" />
|
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE_INVOICE" :refresh="ajaxQuery" />
|
||||||
</a-row>
|
</a-row>
|
||||||
<a-table :scroll="{ x: 1300 }" size="small" :dataSource="tableData" :columns="columns" rowKey="invoiceId" :pagination="false" bordered>
|
<a-table :scroll="{ x: 1300 }" size="small" :dataSource="tableData" :columns="columns" rowKey="invoiceId" :pagination="false" bordered>
|
||||||
<template #bodyCell="{ record, column }">
|
<template #bodyCell="{ text, record, index, column }">
|
||||||
<template v-if="column.dataIndex === 'disabledFlag'">
|
<template v-if="column.dataIndex === 'disabledFlag'">
|
||||||
{{ record.disabledFlag ? '禁用' : '启用' }}
|
{{ record.disabledFlag ? '禁用' : '启用' }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else-if="column.dataIndex === 'action'">
|
<template v-else-if="column.dataIndex === 'action'">
|
||||||
<div class="smart-table-operate">
|
<div class="smart-table-operate">
|
||||||
<a-button @click="addOrUpdate(record)" type="link" v-if="$privilege('oa:invoice:update')">编辑</a-button>
|
<a-button @click="addOrUpdate(record)" type="link">编辑</a-button>
|
||||||
<a-button @click="confirmDelete(record.invoiceId)" type="link" danger v-if="$privilege('oa:invoice:delete')">删除</a-button>
|
<a-button @click="confirmDelete(record.invoiceId)" type="link" danger>删除</a-button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
@ -8,8 +8,8 @@
|
|||||||
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
* @Copyright 1024创新实验室 ( https://1024lab.net ),Since 2012
|
||||||
-->
|
-->
|
||||||
<template>
|
<template>
|
||||||
<a-modal :open="visible" :title="form.invoiceId ? '编辑' : '添加'" :width="700" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
<a-modal :open="visible" :title="form.invoiceId ? '编辑' : '添加'" ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 4 }" :wrapper-col="{ span: 19 }">
|
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 12 }">
|
||||||
<a-form-item label="开票抬头" name="invoiceHeads">
|
<a-form-item label="开票抬头" name="invoiceHeads">
|
||||||
<a-input v-model:value="form.invoiceHeads" placeholder="请输入开票抬头" />
|
<a-input v-model:value="form.invoiceHeads" placeholder="请输入开票抬头" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -1,15 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal
|
<a-modal :open="visible" title="添加" :width="700" forceRender ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
|
||||||
:open="visible"
|
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }">
|
||||||
:title="form.enterpriseId ? '编辑' : '添加'"
|
|
||||||
:width="700"
|
|
||||||
forceRender
|
|
||||||
ok-text="确认"
|
|
||||||
cancel-text="取消"
|
|
||||||
@ok="onSubmit"
|
|
||||||
@cancel="onClose"
|
|
||||||
>
|
|
||||||
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 5 }" :wrapper-col="{ span: 18 }">
|
|
||||||
<a-form-item label="企业名称" name="enterpriseName">
|
<a-form-item label="企业名称" name="enterpriseName">
|
||||||
<a-input v-model:value="form.enterpriseName" placeholder="请输入企业名称" />
|
<a-input v-model:value="form.enterpriseName" placeholder="请输入企业名称" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<a-table
|
<a-table
|
||||||
size="small"
|
size="small"
|
||||||
:scroll="{ y: 800 }"
|
:scroll="{ x: 1000 }"
|
||||||
:loading="tableLoading"
|
:loading="tableLoading"
|
||||||
bordered
|
bordered
|
||||||
:dataSource="tableData"
|
:dataSource="tableData"
|
||||||
|
@ -19,7 +19,7 @@
|
|||||||
</a-form-item>
|
</a-form-item>
|
||||||
|
|
||||||
<a-form-item label="备注" name="remark">
|
<a-form-item label="备注" name="remark">
|
||||||
<a-textarea v-model="form.remark" style="width: 100%; height: 100px; outline: none"/>
|
<a-textarea v-model="form.remark" style="width: 100%; height: 100px; outline: none" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</a-form>
|
</a-form>
|
||||||
</a-modal>
|
</a-modal>
|
||||||
|
@ -45,13 +45,7 @@
|
|||||||
新建
|
新建
|
||||||
</a-button>
|
</a-button>
|
||||||
|
|
||||||
<a-button
|
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:delete'" type="primary" danger :disabled="selectedRowKeyList.length === 0">
|
||||||
@click="confirmBatchDelete"
|
|
||||||
v-privilege="'support:dict:delete'"
|
|
||||||
type="primary"
|
|
||||||
danger
|
|
||||||
:disabled="selectedRowKeyList.length === 0"
|
|
||||||
>
|
|
||||||
<template #icon>
|
<template #icon>
|
||||||
<DeleteOutlined />
|
<DeleteOutlined />
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<a-modal v-model:open="visible" title="推送人" width="1100px" ok-text="确定" cancel-text="取消" @ok="onSubmit" @cancel="onClose" :zIndex="9999">
|
<a-modal v-model:open="visible" title="推送人" width="1100px" ok-text="确定" cancel-text="取消" @ok="onSubmit" @cancel="onClose" :zIndex="9999">
|
||||||
<a-form class="smart-query-form">
|
<a-form class="smart-query-form">
|
||||||
<a-row class="smart-query-form-row">
|
<a-row class="smart-query-form-row">
|
||||||
<a-form-item label="关键词搜索" class="smart-query-form-item">
|
<a-form-item label="关键词搜索" class="smart-query-form-item">
|
||||||
@ -54,13 +54,11 @@
|
|||||||
</a-modal>
|
</a-modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { reactive, ref } from 'vue';
|
import { reactive, ref } from 'vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
|
||||||
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
|
||||||
import { smartSentry } from '/@/lib/smart-sentry';
|
import { smartSentry } from '/@/lib/smart-sentry';
|
||||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||||
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
|
|
||||||
import { employeeApi } from '/@/api/system/employee-api';
|
import { employeeApi } from '/@/api/system/employee-api';
|
||||||
// ---------------查询条件----------------
|
// ---------------查询条件----------------
|
||||||
const queryParamState = {
|
const queryParamState = {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
</a-modal>
|
</a-modal>
|
||||||
<MessageReceiverModal ref="receiverModalRef" @reloadList="addReceiverIdList" />
|
<MessageReceiverModal ref="receiverModalRef" @reloadList="addReceiverIdList" />
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { nextTick, reactive, ref } from 'vue';
|
import { nextTick, reactive, ref } from 'vue';
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||||
|
@ -86,7 +86,7 @@
|
|||||||
<MessageSendForm ref="formRef" @reloadList="queryData" />
|
<MessageSendForm ref="formRef" @reloadList="queryData" />
|
||||||
</a-card>
|
</a-card>
|
||||||
</template>
|
</template>
|
||||||
<script setup>
|
<script setup lang="ts">
|
||||||
import { onMounted, reactive, ref } from 'vue';
|
import { onMounted, reactive, ref } from 'vue';
|
||||||
import { message, Modal } from 'ant-design-vue';
|
import { message, Modal } from 'ant-design-vue';
|
||||||
import { SmartLoading } from '/@/components/framework/smart-loading';
|
import { SmartLoading } from '/@/components/framework/smart-loading';
|
||||||
|
@ -54,11 +54,11 @@
|
|||||||
</a-col>
|
</a-col>
|
||||||
<!--待办、已办-->
|
<!--待办、已办-->
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<ToBeDoneCard />
|
<ChangelogCard />
|
||||||
</a-col>
|
</a-col>
|
||||||
<!--更新日志-->
|
<!--更新日志-->
|
||||||
<a-col :span="24">
|
<a-col :span="24">
|
||||||
<ChangelogCard />
|
<ToBeDoneCard />
|
||||||
</a-col>
|
</a-col>
|
||||||
</a-row>
|
</a-row>
|
||||||
</a-col>
|
</a-col>
|
||||||
|
@ -80,8 +80,7 @@
|
|||||||
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
|
||||||
import { useUserStore } from '/@/store/modules/system/user';
|
import { useUserStore } from '/@/store/modules/system/user';
|
||||||
import loginQR from '/@/assets/images/login/login-qr.png';
|
import loginQR from '/@/assets/images/login/login-qr.png';
|
||||||
import leftBg2 from '/@/assets/images/login/left-bg2.png';
|
import loginGif from '/@/assets/images/login/login-min.gif';
|
||||||
import loginGif from '/@/assets/images/login/login.gif';
|
|
||||||
import wechatIcon from '/@/assets/images/login/wechat-icon.png';
|
import wechatIcon from '/@/assets/images/login/wechat-icon.png';
|
||||||
import aliIcon from '/@/assets/images/login/ali-icon.png';
|
import aliIcon from '/@/assets/images/login/ali-icon.png';
|
||||||
import douyinIcon from '/@/assets/images/login/douyin-icon.png';
|
import douyinIcon from '/@/assets/images/login/douyin-icon.png';
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
@close="onClose"
|
@close="onClose"
|
||||||
destroyOnClose
|
destroyOnClose
|
||||||
>
|
>
|
||||||
<a-form ref="formRef" :labelCol="{ span: labelColSpan }" :labelWrap="true" :model="form" :rules="rules">
|
<a-form ref="formRef" :labelCol="{ span: 5 }" :labelWrap="true" :model="form" :rules="rules">
|
||||||
<a-form-item label="菜单类型" name="menuType">
|
<a-form-item label="菜单类型" name="menuType">
|
||||||
<a-radio-group v-model:value="form.menuType" button-style="solid">
|
<a-radio-group v-model:value="form.menuType" button-style="solid">
|
||||||
<a-radio-button v-for="item in MENU_TYPE_ENUM" :key="item.value" :value="item.value">
|
<a-radio-button v-for="item in MENU_TYPE_ENUM" :key="item.value" :value="item.value">
|
||||||
@ -62,7 +62,13 @@
|
|||||||
<a-switch v-model:checked="form.visibleFlag" checked-children="显示" un-checked-children="不显示" />
|
<a-switch v-model:checked="form.visibleFlag" checked-children="显示" un-checked-children="不显示" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="禁用状态" name="disabledFlag">
|
<a-form-item label="禁用状态" name="disabledFlag">
|
||||||
<a-switch v-model:checked="form.disabledFlag" :checkedValue="false" :unCheckedValue="true" checked-children="启用" un-checked-children="禁用" />
|
<a-switch
|
||||||
|
v-model:checked="form.disabledFlag"
|
||||||
|
:checkedValue="false"
|
||||||
|
:unCheckedValue="true"
|
||||||
|
checked-children="启用"
|
||||||
|
un-checked-children="禁用"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
</template>
|
</template>
|
||||||
<!-- 目录 菜单 end -->
|
<!-- 目录 菜单 end -->
|
||||||
@ -75,7 +81,13 @@
|
|||||||
<MenuTreeSelect ref="contextMenuTreeSelect" v-model:value="form.contextMenuId" />
|
<MenuTreeSelect ref="contextMenuTreeSelect" v-model:value="form.contextMenuId" />
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="功能点状态" name="funcDisabledFlag">
|
<a-form-item label="功能点状态" name="funcDisabledFlag">
|
||||||
<a-switch v-model:checked="form.disabledFlag" :checkedValue="false" :unCheckedValue="true" checked-children="启用" un-checked-children="禁用" />
|
<a-switch
|
||||||
|
v-model:checked="form.disabledFlag"
|
||||||
|
:checkedValue="false"
|
||||||
|
:unCheckedValue="true"
|
||||||
|
checked-children="启用"
|
||||||
|
un-checked-children="禁用"
|
||||||
|
/>
|
||||||
</a-form-item>
|
</a-form-item>
|
||||||
<a-form-item label="权限类型" name="permsType">
|
<a-form-item label="权限类型" name="permsType">
|
||||||
<a-radio-group v-model:value="form.permsType">
|
<a-radio-group v-model:value="form.permsType">
|
||||||
@ -106,7 +118,7 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { message } from 'ant-design-vue';
|
import { message } from 'ant-design-vue';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { computed, nextTick, reactive, ref } from 'vue';
|
import { nextTick, reactive, ref } from 'vue';
|
||||||
import MenuTreeSelect from './menu-tree-select.vue';
|
import MenuTreeSelect from './menu-tree-select.vue';
|
||||||
import { menuApi } from '/@/api/system/menu-api';
|
import { menuApi } from '/@/api/system/menu-api';
|
||||||
import IconSelect from '/@/components/framework/icon-select/index.vue';
|
import IconSelect from '/@/components/framework/icon-select/index.vue';
|
||||||
@ -123,13 +135,6 @@
|
|||||||
// 是否展示抽屉
|
// 是否展示抽屉
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
|
|
||||||
const labelColSpan = computed(() => {
|
|
||||||
if (form.menuType === MENU_TYPE_ENUM.POINTS.value) {
|
|
||||||
return 6;
|
|
||||||
}
|
|
||||||
return 4;
|
|
||||||
});
|
|
||||||
|
|
||||||
const contextMenuTreeSelect = ref();
|
const contextMenuTreeSelect = ref();
|
||||||
const parentMenuTreeSelect = ref();
|
const parentMenuTreeSelect = ref();
|
||||||
|
|
||||||
@ -179,7 +184,7 @@
|
|||||||
apiPerms: undefined,
|
apiPerms: undefined,
|
||||||
sort: undefined,
|
sort: undefined,
|
||||||
visibleFlag: true,
|
visibleFlag: true,
|
||||||
cacheFlag: true,
|
cacheFlag: false,
|
||||||
component: undefined,
|
component: undefined,
|
||||||
contextMenuId: undefined,
|
contextMenuId: undefined,
|
||||||
disabledFlag: false,
|
disabledFlag: false,
|
||||||
@ -197,6 +202,9 @@
|
|||||||
formRef.value.resetFields();
|
formRef.value.resetFields();
|
||||||
form.menuType = menuType;
|
form.menuType = menuType;
|
||||||
form.parentId = parentId;
|
form.parentId = parentId;
|
||||||
|
if (form.menuType === MENU_TYPE_ENUM.POINTS.value) {
|
||||||
|
form.contextMenuId = parentId;
|
||||||
|
}
|
||||||
// 移除最后一个:后面的内容
|
// 移除最后一个:后面的内容
|
||||||
if (webPerms && webPerms.lastIndexOf(':')) {
|
if (webPerms && webPerms.lastIndexOf(':')) {
|
||||||
form.webPerms = webPerms.substring(0, webPerms.lastIndexOf(':') + 1);
|
form.webPerms = webPerms.substring(0, webPerms.lastIndexOf(':') + 1);
|
||||||
|
@ -126,7 +126,7 @@ function isMenuExistMenuType(menu, menuType) {
|
|||||||
/**
|
/**
|
||||||
* 过滤关键字
|
* 过滤关键字
|
||||||
*/
|
*/
|
||||||
function isMenuExistKeywords(menu: any, keywords: string) {
|
function isMenuExistKeywords(menu, keywords) {
|
||||||
if (!keywords) {
|
if (!keywords) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -266,7 +266,7 @@
|
|||||||
function showDrawer(rowData) {
|
function showDrawer(rowData) {
|
||||||
menuOperateModal.value.showDrawer(rowData);
|
menuOperateModal.value.showDrawer(rowData);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showAddSub(rowData) {
|
function showAddSub(rowData) {
|
||||||
const subData = {
|
const subData = {
|
||||||
parentId: rowData.menuId,
|
parentId: rowData.menuId,
|
||||||
|
@ -12,11 +12,11 @@
|
|||||||
<li v-for="module in props.tree" :key="module.menuId">
|
<li v-for="module in props.tree" :key="module.menuId">
|
||||||
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
|
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
|
||||||
<a-checkbox @change="selectCheckbox(module)" class="checked-box-label" :value="module.menuId">{{ module.menuName }} </a-checkbox>
|
<a-checkbox @change="selectCheckbox(module)" class="checked-box-label" :value="module.menuId">{{ module.menuName }} </a-checkbox>
|
||||||
<div v-if="module.children && module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
|
<div v-if="module.children && module.children.some((e) => e.menuType === MENU_TYPE_ENUM.POINTS.value)">
|
||||||
<RoleTreePoint :tree="module.children" @selectCheckbox="selectCheckbox" />
|
<RoleTreePoint :tree="module.children" @selectCheckbox="selectCheckbox" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<template v-if="module.children && !module.children.some((e) => e.menuType == MENU_TYPE_ENUM.POINTS.value)">
|
<template v-if="module.children && !module.children.some((e) => e.menuType === MENU_TYPE_ENUM.POINTS.value)">
|
||||||
<RoleTreeMenu :tree="module.children" :index="props.index + 1" />
|
<RoleTreeMenu :tree="module.children" :index="props.index + 1" />
|
||||||
</template>
|
</template>
|
||||||
</li>
|
</li>
|
||||||
@ -47,7 +47,7 @@
|
|||||||
let checkedData = roleStore.checkedData;
|
let checkedData = roleStore.checkedData;
|
||||||
let findIndex = checkedData.indexOf(module.menuId);
|
let findIndex = checkedData.indexOf(module.menuId);
|
||||||
// 选中
|
// 选中
|
||||||
if (findIndex == -1) {
|
if (findIndex === -1) {
|
||||||
// 选中本级以及子级
|
// 选中本级以及子级
|
||||||
roleStore.addCheckedDataAndChildren(module);
|
roleStore.addCheckedDataAndChildren(module);
|
||||||
// 选中上级
|
// 选中上级
|
||||||
|
Loading…
Reference in New Issue
Block a user