v3.20.0 【新增】优化登录使用spring cache;【新增】优化部门cache;【新增】代码生成枚举;【优化】三级等保Label显示宽度

This commit is contained in:
zhuoda
2025-05-03 21:36:37 +08:00
parent 2f332863e2
commit ee12519797
107 changed files with 715 additions and 652 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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(){
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -33,7 +33,7 @@ import java.util.Map;
/**
*
* 发邮件:<br/>
* 发邮件:<br/>
* 1、支持直接发送 <br/>
* 2、支持使用邮件模板发送
*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -0,0 +1,162 @@
package net.lab1024.sa.admin.module.system.login.manager;
import lombok.extern.slf4j.Slf4j;
import net.lab1024.sa.admin.constant.AdminCacheConst;
import net.lab1024.sa.admin.module.system.department.domain.vo.DepartmentVO;
import net.lab1024.sa.admin.module.system.department.service.DepartmentService;
import net.lab1024.sa.admin.module.system.employee.domain.entity.EmployeeEntity;
import net.lab1024.sa.admin.module.system.employee.service.EmployeeService;
import net.lab1024.sa.admin.module.system.login.domain.RequestEmployee;
import net.lab1024.sa.admin.module.system.menu.domain.vo.MenuVO;
import net.lab1024.sa.admin.module.system.role.domain.vo.RoleVO;
import net.lab1024.sa.admin.module.system.role.service.RoleEmployeeService;
import net.lab1024.sa.admin.module.system.role.service.RoleMenuService;
import net.lab1024.sa.base.common.constant.StringConst;
import net.lab1024.sa.base.common.domain.ResponseDTO;
import net.lab1024.sa.base.common.domain.UserPermission;
import net.lab1024.sa.base.common.enumeration.UserTypeEnum;
import net.lab1024.sa.base.common.util.SmartBeanUtil;
import net.lab1024.sa.base.module.support.file.service.IFileStorageService;
import org.apache.commons.lang3.BooleanUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* 登录Manager
*
* @Author 1024创新实验室: 卓大
* @Date 2025-05-03 22:56:34
* @Wechat zhuoda1024
* @Email lab1024@163.com
* @Copyright <a href="https://1024lab.net">1024创新实验室</a>
*/
@Slf4j
@Service
public class LoginManager {
@Resource
private DepartmentService departmentService;
@Resource
private IFileStorageService fileStorageService;
@Resource
private EmployeeService employeeService;
@Resource
private RoleEmployeeService roleEmployeeService;
@Resource
private RoleMenuService roleMenuService;
/**
* 获取请求用户信息
*/
@Cacheable(AdminCacheConst.Login.REQUEST_EMPLOYEE)
public RequestEmployee getRequestEmployee(Long requestEmployeeId ) {
if (requestEmployeeId == null) {
return null;
}
// 员工基本信息
EmployeeEntity employeeEntity = employeeService.getById(requestEmployeeId);
if (employeeEntity == null) {
return null;
}
return this.loadLoginInfo(employeeEntity);
}
/**
* 获取登录的用户信息
*/
@CachePut(value = AdminCacheConst.Login.REQUEST_EMPLOYEE, key = "#employeeEntity.employeeId")
public RequestEmployee loadLoginInfo(EmployeeEntity employeeEntity) {
// 基础信息
RequestEmployee requestEmployee = SmartBeanUtil.copy(employeeEntity, RequestEmployee.class);
requestEmployee.setUserType(UserTypeEnum.ADMIN_EMPLOYEE);
// 部门信息
DepartmentVO department = departmentService.getDepartmentById(employeeEntity.getDepartmentId());
requestEmployee.setDepartmentName(null == department ? StringConst.EMPTY : department.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(){
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,11 +1,17 @@
package net.lab1024.sa.base.config;
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import net.lab1024.sa.base.module.support.cache.CacheService;
import net.lab1024.sa.base.module.support.cache.CaffeineCacheServiceImpl;
import net.lab1024.sa.base.module.support.cache.RedisCacheServiceImpl;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.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";
@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
@ConditionalOnProperty(prefix = "spring.cache", name = {"type"}, havingValue = REDIS_CACHE)
public CacheService redisCacheService() {

View File

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

View File

@@ -33,7 +33,7 @@ import java.util.Map;
/**
*
* 发邮件:<br/>
* 发邮件:<br/>
* 1、支持直接发送 <br/>
* 2、支持使用邮件模板发送
*

View File

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

View File

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

View File

@@ -66,7 +66,7 @@ spring:
# 缓存实现类型
cache:
type: caffeine
type: redis
# tomcat 配置,主要用于 配置 访问日志(便于将来排查错误)
server:
@@ -88,8 +88,8 @@ file:
region: oss-cn-hangzhou
endpoint: oss-cn-hangzhou.aliyuncs.com
bucket-name: 1024lab-smart-admin
access-key:
secret-key:
access-key:
secret-key:
url-prefix: https://${file.storage.cloud.bucket-name}.${file.storage.cloud.endpoint}/
private-url-expire-seconds: 3600

View File

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

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -8,7 +8,7 @@
const props = defineProps({
dictCode: String,
dataValue: String,
dataValue: [String, Number],
});
const dataLabels = computed(() => {
return useDictStore().getDataLabels(props.dictCode, props.dataValue);

View File

@@ -1,6 +1,4 @@
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 _ from 'lodash';
@@ -23,14 +21,21 @@ export const useDictStore = defineStore({
// 获取字典的值名称
getDataLabels(dictCode, dataValue) {
if (!dataValue) {
if (_.isNil(dataValue) || _.isNaN(dataValue)) {
return '';
}
let dict = this.getDictData(dictCode);
if (dict.length === 0) {
return '';
}
// 是数字的话,需要特殊处理
if(_.isNumber(dataValue)){
let target = _.find(dict, { dataValue: dataValue });
return target ? target.dataLabel : '';
}
let valueArray = dataValue.split(DICT_SPLIT);
let result = [];
for (let item of valueArray) {
@@ -42,7 +47,7 @@ export const useDictStore = defineStore({
return result.join(DICT_SPLIT);
},
// 初始化字典
initData(dictDataList){
initData(dictDataList) {
this.dictMap.clear();
for (let data of dictDataList) {
let dataArray = this.dictMap.get(data.dictCode);

View File

@@ -41,7 +41,7 @@
<a-table
size="small"
:scroll="{ y: 800 }"
:scroll="{ x: 1000 }"
:loading="tableLoading"
bordered
:dataSource="tableData"

View File

@@ -24,7 +24,7 @@
:model="form"
:rules="rules"
ref="formRef"
style="width: 800px"
style="width: 100%"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
autocomplete="off"

View File

@@ -1,5 +1,5 @@
<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-row class="smart-query-form-row">
<a-form-item label="关键词搜索" class="smart-query-form-item">
@@ -56,11 +56,9 @@
<script setup>
import { reactive, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { smartSentry } from '/src/lib/smart-sentry';
import { SmartLoading } from '/src/components/framework/smart-loading';
import SmartEnumSelect from '/src/components/framework/smart-enum-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { employeeApi } from '/@/api/system/employee-api';
// ---------------查询条件----------------
const queryParamState = {

View File

@@ -27,12 +27,12 @@
<script setup>
import { nextTick, reactive, ref } from 'vue';
import { message } from 'ant-design-vue';
import { SmartLoading } from '/src/components/framework/smart-loading';
import { smartSentry } from '/src/lib/smart-sentry';
import SmartEnumSelect from '/src/components/framework/smart-enum-select/index.vue';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { smartSentry } from '/@/lib/smart-sentry';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import MessageReceiverModal from './message-receiver-modal.vue';
import { USER_TYPE_ENUM } from '/src/constants/common-const.js';
import { messageApi } from '/@/api/support/message-api.js';
import { USER_TYPE_ENUM } from '/@/constants/common-const';
import { messageApi } from '/@/api/support/message-api';
// ------------------------ 事件 ------------------------
const emits = defineEmits(['reloadList']);

View File

@@ -54,11 +54,11 @@
</a-col>
<!--待办已办-->
<a-col :span="24">
<ToBeDoneCard />
<ChangelogCard />
</a-col>
<!--更新日志-->
<a-col :span="24">
<ChangelogCard />
<ToBeDoneCard />
</a-col>
</a-row>
</a-col>

View File

@@ -80,8 +80,7 @@
import { LOGIN_DEVICE_ENUM } from '/@/constants/system/login-device-const';
import { useUserStore } from '/@/store/modules/system/user';
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.gif';
import loginGif from '/@/assets/images/login/login-min.gif';
import wechatIcon from '/@/assets/images/login/wechat-icon.png';
import aliIcon from '/@/assets/images/login/ali-icon.png';
import douyinIcon from '/@/assets/images/login/douyin-icon.png';

View File

@@ -12,11 +12,11 @@
<li v-for="module in props.tree" :key="module.menuId">
<div class="menu" :style="{ marginLeft: `${props.index * 4}%` }">
<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" />
</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" />
</template>
</li>
@@ -47,7 +47,7 @@
let checkedData = roleStore.checkedData;
let findIndex = checkedData.indexOf(module.menuId);
// 选中
if (findIndex == -1) {
if (findIndex === -1) {
// 选中本级以及子级
roleStore.addCheckedDataAndChildren(module);
// 选中上级

View File

@@ -43,18 +43,15 @@
</template>
<script setup lang="ts">
import dayjs from 'dayjs';
import { computed, h, useSlots } from 'vue';
import { messages } from '/@/i18n';
import { useAppConfigStore } from '/@/store/modules/system/app-config';
import { useSpinStore } from '/@/store/modules/system/spin';
import { theme } from 'ant-design-vue';
import { themeColors } from '/@/theme/color.js';
import { Popover } from 'ant-design-vue';
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
import _ from 'lodash';
import dayjs from 'dayjs';
import {computed, h} from 'vue';
import {messages} from '/@/i18n';
import {useAppConfigStore} from '/@/store/modules/system/app-config';
import {useSpinStore} from '/@/store/modules/system/spin';
import {Popover, theme} from 'ant-design-vue';
import {themeColors} from '/@/theme/color.js';
import SmartCopyIcon from '/@/components/framework/smart-copy-icon/index.vue';
const slots = useSlots();
const antdLocale = computed(() => messages[useAppConfigStore().language].antdLocale);
const dayjsLocale = computed(() => messages[useAppConfigStore().language].dayjsLocale);
dayjs.locale(dayjsLocale);
@@ -91,6 +88,7 @@
return text;
}
}
</script>
<style scoped lang="less">
:deep(.ant-table-column-sorters) {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

View File

@@ -26,7 +26,7 @@
</template>
<script setup lang="ts">
import { ref, watch, onMounted, getCurrentInstance} from 'vue';
import { ref, watch, onMounted, getCurrentInstance } from 'vue';
const props = defineProps({
enumName: String,

View File

@@ -8,7 +8,7 @@
const props = defineProps({
dictCode: String,
dataValue: String,
dataValue: [String, Number],
});
const dataLabels = computed(() => {
return useDictStore().getDataLabels(props.dictCode, props.dataValue);

View File

@@ -7,13 +7,7 @@
* @Email: lab1024@163.com
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
*/
import { AppConfig } from '/@/types/config';
/**
* 应用默认配置
*/
export const appDefaultConfig: AppConfig = {
export const appDefaultConfig = {
// i18n 语言选择
language: 'zh_CN',
// 布局: side 或者 side-expand 或者 top

View File

@@ -208,9 +208,9 @@
// 页面圆角
borderRadius: appConfigStore.borderRadius,
// 标签页
flatPattern: appConfigStore.flatPattern,
// 标签页
pageTagFlag: appConfigStore.pageTagFlag,
// 标签页
flatPattern: appConfigStore.flatPattern,
// 标签页 样式
pageTagStyle: appConfigStore.pageTagStyle,
// 面包屑
@@ -251,7 +251,7 @@
});
}
function changePageTagLocation(e: any) {
function changePageTagLocation(e) {
appConfigStore.$patch({
pageTagLocation: e.target.value,
});

View File

@@ -48,6 +48,7 @@
const menuTree = computed(() => useUserStore().getMenuTree || []);
const rootSubmenuKeys = computed(()=>menuTree.value.map(item=>item.menuId));
//展开的菜单
let currentRoute = useRoute();
const selectedKeys = ref([]);

View File

@@ -1,6 +1,4 @@
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 _ from 'lodash';
@@ -23,14 +21,21 @@ export const useDictStore = defineStore({
// 获取字典的值名称
getDataLabels(dictCode, dataValue) {
if (!dataValue) {
if (_.isNil(dataValue) || _.isNaN(dataValue)) {
return '';
}
let dict = this.getDictData(dictCode);
if (dict.length === 0) {
return '';
}
// 是数字的话,需要特殊处理
if(_.isNumber(dataValue)){
let target = _.find(dict, { dataValue: dataValue });
return target ? target.dataLabel : '';
}
let valueArray = dataValue.split(DICT_SPLIT);
let result = [];
for (let item of valueArray) {
@@ -42,7 +47,7 @@ export const useDictStore = defineStore({
return result.join(DICT_SPLIT);
},
// 初始化字典
initData(dictDataList){
initData(dictDataList) {
this.dictMap.clear();
for (let data of dictDataList) {
let dataArray = this.dictMap.get(data.dictCode);

View File

@@ -36,7 +36,7 @@
</a-button>
</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>
<PlusOutlined />
</template>
@@ -60,8 +60,8 @@
</template>
<template v-else-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button @click="addOrUpdate(record)" type="link" v-if="$privilege('oa:bank:update')">编辑</a-button>
<a-button @click="confirmDelete(record.bankId)" danger type="link" v-if="$privilege('oa:bank:delete')">删除</a-button>
<a-button @click="addOrUpdate(record)" type="link">编辑</a-button>
<a-button @click="confirmDelete(record.bankId)" danger type="link">删除</a-button>
</div>
</template>
</template>

View File

@@ -8,8 +8,8 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal :open="visible" :title="form.bankId ? '编辑' : '添加'" :width="700" 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-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: 5 }" :wrapper-col="{ span: 18 }">
<a-form-item label="开户银行" name="bankName">
<a-input v-model:value="form.bankName" placeholder="请输入开户银行" />
</a-form-item>

View File

@@ -16,59 +16,50 @@
<a-button class="button-style" type="primary" @click="onSearch">搜索</a-button>
<a-button class="button-style" type="default" @click="resetQueryEmployee">重置</a-button>
</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" danger @click="batchDelete" v-privilege="'oa:enterprise:deleteEmployee'"> 批量移除 </a-button>
</div>
</div>
<a-card size="small" :bordered="false" :hoverable="false">
<a-row justify="end">
<TableOperator
class="smart-margin-bottom5"
v-model="columns"
:tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE_EMPLOYEE"
:refresh="queryEmployee"
/>
</a-row>
<a-table
:loading="tableLoading"
:dataSource="tableData"
:columns="columns"
: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>
<a-table
:loading="tableLoading"
:dataSource="tableData"
:columns="columns"
:pagination="false"
rowKey="employeeId"
:row-selection="{ selectedRowKeys: selectedRowKeyList, onChange: onSelectChange }"
size="small"
bordered
>
<template #bodyCell="{ text, record, index, column }">
<template v-if="column.dataIndex === 'disabledFlag'">
<a-tag :color="text ? 'error' : 'processing'">{{ text ? '禁用' : '启用' }}</a-tag>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryEmployee"
@showSizeChange="queryEmployee"
:show-total="showTableTotal"
/>
</div>
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="selectData" />
</a-card>
<template v-else-if="column.dataIndex === 'gender'">
<span>{{ $smartEnumPlugin.getDescByValue('GENDER_ENUM', text) }}</span>
</template>
<template v-if="column.dataIndex === 'operate'">
<a @click="deleteEmployee(record.employeeId)" v-privilege="'oa:enterprise:deleteEmployee'">移除</a>
</template>
</template>
</a-table>
<div class="smart-query-table-page">
<a-pagination
showSizeChanger
showQuickJumper
show-less-items
:pageSizeOptions="PAGE_SIZE_OPTIONS"
:defaultPageSize="queryForm.pageSize"
v-model:current="queryForm.pageNum"
v-model:pageSize="queryForm.pageSize"
:total="total"
@change="queryEmployee"
@showSizeChange="queryEmployee"
:show-total="showTableTotal"
/>
</div>
<EmployeeTableSelectModal ref="selectEmployeeModal" @selectData="selectData" />
</div>
</template>
<script setup lang="ts">
@@ -81,8 +72,6 @@
import { SmartLoading } from '/@/components/framework/smart-loading';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS, showTableTotal } from '/@/constants/common-const';
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({
enterpriseId: {
@@ -123,8 +112,7 @@
{
title: '操作',
dataIndex: 'operate',
width: 90,
align: 'center',
width: 60,
},
]);
@@ -283,8 +271,7 @@
display: flex;
align-items: center;
justify-content: space-between;
padding: 10px 10px;
margin-bottom: 10px;
margin: 20px 0;
}
.button-style {

View File

@@ -36,8 +36,7 @@
</a-button>
</a-button-group>
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20" v-if="$privilege('oa:invoice:add')">
<a-button @click="addOrUpdate()" type="primary" class="smart-margin-left20">
<template #icon>
<PlusOutlined />
</template>
@@ -52,14 +51,14 @@
<TableOperator class="smart-margin-bottom5" v-model="columns" :tableId="TABLE_ID_CONST.BUSINESS.OA.ENTERPRISE_INVOICE" :refresh="ajaxQuery" />
</a-row>
<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'">
{{ record.disabledFlag ? '禁用' : '启用' }}
</template>
<template v-else-if="column.dataIndex === 'action'">
<div class="smart-table-operate">
<a-button @click="addOrUpdate(record)" type="link" v-if="$privilege('oa:invoice:update')">编辑</a-button>
<a-button @click="confirmDelete(record.invoiceId)" type="link" danger v-if="$privilege('oa:invoice:delete')">删除</a-button>
<a-button @click="addOrUpdate(record)" type="link">编辑</a-button>
<a-button @click="confirmDelete(record.invoiceId)" type="link" danger>删除</a-button>
</div>
</template>
</template>

View File

@@ -8,8 +8,8 @@
* @Copyright 1024创新实验室 https://1024lab.net Since 2012
-->
<template>
<a-modal :open="visible" :title="form.invoiceId ? '编辑' : '添加'" :width="700" 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-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: 5 }" :wrapper-col="{ span: 12 }">
<a-form-item label="开票抬头" name="invoiceHeads">
<a-input v-model:value="form.invoiceHeads" placeholder="请输入开票抬头" />
</a-form-item>

View File

@@ -1,15 +1,6 @@
<template>
<a-modal
:open="visible"
: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-modal :open="visible" title="添加" :width="700" forceRender ok-text="确认" cancel-text="取消" @ok="onSubmit" @cancel="onClose">
<a-form ref="formRef" :model="form" :rules="rules" :label-col="{ span: 6 }">
<a-form-item label="企业名称" name="enterpriseName">
<a-input v-model:value="form.enterpriseName" placeholder="请输入企业名称" />
</a-form-item>

View File

@@ -41,7 +41,7 @@
<a-table
size="small"
:scroll="{ y: 800 }"
:scroll="{ x: 1000 }"
:loading="tableLoading"
bordered
:dataSource="tableData"

View File

@@ -19,7 +19,7 @@
</a-form-item>
<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>
</a-modal>

View File

@@ -45,13 +45,7 @@
新建
</a-button>
<a-button
@click="confirmBatchDelete"
v-privilege="'support:dict:delete'"
type="primary"
danger
:disabled="selectedRowKeyList.length === 0"
>
<a-button @click="confirmBatchDelete" v-privilege="'support:dict:delete'" type="primary" danger :disabled="selectedRowKeyList.length === 0">
<template #icon>
<DeleteOutlined />
</template>

View File

@@ -24,7 +24,7 @@
:model="form"
:rules="rules"
ref="formRef"
style="width: 800px"
style="width: 100%"
:label-col="{ span: 6 }"
:wrapper-col="{ span: 18 }"
autocomplete="off"

View File

@@ -1,5 +1,5 @@
<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-row class="smart-query-form-row">
<a-form-item label="关键词搜索" class="smart-query-form-item">
@@ -54,13 +54,11 @@
</a-modal>
</template>
<script setup>
<script setup lang="ts">
import { reactive, ref } from 'vue';
import { message, Modal } from 'ant-design-vue';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '/@/constants/common-const';
import { smartSentry } from '/src/lib/smart-sentry';
import { SmartLoading } from '/src/components/framework/smart-loading';
import SmartEnumSelect from '/src/components/framework/smart-enum-select/index.vue';
import { smartSentry } from '/@/lib/smart-sentry';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { employeeApi } from '/@/api/system/employee-api';
// ---------------查询条件----------------
const queryParamState = {

View File

@@ -24,15 +24,15 @@
</a-modal>
<MessageReceiverModal ref="receiverModalRef" @reloadList="addReceiverIdList" />
</template>
<script setup>
<script setup lang="ts">
import { nextTick, reactive, ref } from 'vue';
import { message } from 'ant-design-vue';
import { SmartLoading } from '/src/components/framework/smart-loading';
import { smartSentry } from '/src/lib/smart-sentry';
import SmartEnumSelect from '/src/components/framework/smart-enum-select/index.vue';
import { SmartLoading } from '/@/components/framework/smart-loading';
import { smartSentry } from '/@/lib/smart-sentry';
import SmartEnumSelect from '/@/components/framework/smart-enum-select/index.vue';
import MessageReceiverModal from './message-receiver-modal.vue';
import { USER_TYPE_ENUM } from '/src/constants/common-const.js';
import { messageApi } from '/@/api/support/message-api.js';
import { USER_TYPE_ENUM } from '/@/constants/common-const';
import { messageApi } from '/@/api/support/message-api';
// ------------------------ 事件 ------------------------
const emits = defineEmits(['reloadList']);

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