perf: 临时权限记录性能优化

This commit is contained in:
2024-04-17 11:30:08 +08:00
parent 3f8290198c
commit c5b9d7129c
7 changed files with 184 additions and 41 deletions
@@ -2,6 +2,8 @@ package com.jero.modules.laws.enterprise.mapper;
import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthDept; import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthDept;
import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto;
import org.apache.ibatis.annotations.Param;
import java.util.List; import java.util.List;
@@ -15,6 +17,10 @@ public interface EnterpriseStandardAuthDeptMapper extends BaseMapper<EnterpriseS
int batchInsert(List<EnterpriseStandardAuthDept> list); int batchInsert(List<EnterpriseStandardAuthDept> list);
int countDeptAuths(@Param("param") TempAuthRecordQueryDto tempAuthRecordQueryDto);
List<TempAuthRecordQueryDto> queryDeptAuths(@Param("param") TempAuthRecordQueryDto tempAuthRecordQueryDto,
int pageSize, int offset);
} }
@@ -6,6 +6,8 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto; import com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import java.util.List;
/** /**
* @author ThinkBook * @author ThinkBook
* @description 针对表【laws_enterprise_standard_temp_permission(企业标准)】的数据库操作Mapper * @description 针对表【laws_enterprise_standard_temp_permission(企业标准)】的数据库操作Mapper
@@ -14,7 +16,10 @@ import org.apache.ibatis.annotations.Param;
*/ */
public interface EnterpriseStandardAuthUserMapper extends BaseMapper<EnterpriseStandardAuthUser> { public interface EnterpriseStandardAuthUserMapper extends BaseMapper<EnterpriseStandardAuthUser> {
IPage<TempAuthRecordQueryDto> tempAuthRecord(IPage<TempAuthRecordQueryDto> page, @Param("param") TempAuthRecordQueryDto tempAuthRecordQueryDto); int countUserAuths(@Param("param") TempAuthRecordQueryDto tempAuthRecordQueryDto);
List<TempAuthRecordQueryDto> queryUserAuths(@Param("param") TempAuthRecordQueryDto tempAuthRecordQueryDto,
int pageSize, int offset);
} }
@@ -29,4 +29,66 @@
(#{item.id}, #{item.standardId}, #{item.authDept}) (#{item.id}, #{item.standardId}, #{item.authDept})
</foreach> </foreach>
</insert> </insert>
<select id="queryDeptAuths" resultType="com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto">
SELECT
auth.id AS Id,
auth.auth_dept AS authDept,
auth.create_time AS createTime,
auth.standard_id AS standardId,
auth.auth_expire_date AS authExpireDate
FROM (select * from laws_enterprise_standard_auth_dept WHERE auth_expire_date IS NOT NULL) auth
<if test="param.standardNumber != null and param.standardNumber != ''">
LEFT JOIN laws_enterprise_standard AS es ON auth.standard_id = es.id
</if>
WHERE auth.auth_expire_date IS NOT NULL
<!--企标编号-->
<if test="param.standardNumber != null and param.standardNumber != ''">
AND es.standard_number LIKE CONCAT('%',#{param.standardNumber},'%')
</if>
<!--授权到期日期-->
<if test="param.startAuthExpireDate != null and param.endAuthExpireDate != ''">
AND auth.auth_expire_date >= #{param.startAuthExpireDate}
AND auth.auth_expire_date &lt;= #{param.endAuthExpireDate}
</if>
<!--授权部门-->
<if test="param.authDeptList != null and param.authDeptList.size() > 0">
AND auth.auth_dept IN
<foreach item="item" index="index" collection="param.authDeptList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
ORDER BY
auth.create_time DESC,
auth.auth_expire_date DESC
LIMIT #{pageSize} OFFSET #{offset}
</select>
<!-- 统计部门授权总数 -->
<select id="countDeptAuths" resultType="int">
SELECT COUNT(*)
FROM (select * from laws_enterprise_standard_auth_dept WHERE auth_expire_date IS NOT NULL) auth
<if test="param.standardNumber != null and param.standardNumber != ''">
LEFT JOIN laws_enterprise_standard AS es ON auth.standard_id = es.id
</if>
<where>
<!--企标编号-->
<if test="param.standardNumber != null and param.standardNumber != ''">
AND es.standard_number LIKE CONCAT('%',#{param.standardNumber},'%')
</if>
<!--授权到期日期-->
<if test="param.startAuthExpireDate != null and param.endAuthExpireDate != ''">
AND auth.auth_expire_date >= #{param.startAuthExpireDate}
AND auth.auth_expire_date &lt;= #{param.endAuthExpireDate}
</if>
<!--授权部门-->
<if test="param.authDeptList != null and param.authDeptList.size() > 0">
AND auth.auth_dept IN
<foreach item="item" index="index" collection="param.authDeptList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
</where>
</select>
</mapper> </mapper>
@@ -22,48 +22,28 @@
standard_id,auth_user,auth_expire_date standard_id,auth_user,auth_expire_date
</sql> </sql>
<select id="tempAuthRecord" resultType="com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto"> <select id="queryUserAuths" resultType="com.jero.modules.laws.standard.controller.TempAuthRecordQueryDto">
SELECT SELECT
auth.id AS Id, auth.id AS Id,
auth.auth_user AS authUser, auth.auth_user AS authUser,
auth.auth_dept AS authDept,
auth.create_time AS createTime, auth.create_time AS createTime,
auth.standard_id AS standardId, auth.standard_id AS standardId,
es.standard_number AS standardNumber,
auth.auth_expire_date AS authExpireDate auth.auth_expire_date AS authExpireDate
FROM FROM (select * from laws_enterprise_standard_auth_user WHERE auth_expire_date IS NOT NULL) auth
( <if test="param.standardNumber != null and param.standardNumber != ''">
SELECT LEFT JOIN laws_enterprise_standard AS es ON auth.standard_id = es.id
id, </if>
NULL AS auth_user, <!--授权人员-->
auth_dept, <if test="param.authUser != null and param.authUser != ''">
standard_id, LEFT JOIN sys_user AS u ON u.id = auth.auth_user
auth_expire_date, </if>
create_time
FROM
laws_enterprise_standard_auth_dept
WHERE
auth_expire_date IS NOT NULL
UNION
SELECT
id,
auth_user,
NULL AS auth_dept,
standard_id,
auth_expire_date,
create_time
FROM
laws_enterprise_standard_auth_user
) AS auth
LEFT JOIN laws_enterprise_standard AS es ON auth.standard_id = es.id
LEFT JOIN sys_user AS u ON u.id = auth.auth_user
WHERE WHERE
es.del_flag = 0 auth.auth_expire_date IS NOT NULL
<!--企标编号--> <!--企标编号-->
<if test="param.standardNumber != null and param.standardNumber != ''"> <if test="param.standardNumber != null and param.standardNumber != ''">
AND es.standard_number LIKE CONCAT('%',#{param.standardNumber},'%') AND es.standard_number LIKE CONCAT('%',#{param.standardNumber},'%')
</if> </if>
<!--企标编号--> <!--授权人员-->
<if test="param.authUser != null and param.authUser != ''"> <if test="param.authUser != null and param.authUser != ''">
AND CONCAT(u.realname, '(', u.username, ')') LIKE CONCAT('%',#{param.authUser},'%') AND CONCAT(u.realname, '(', u.username, ')') LIKE CONCAT('%',#{param.authUser},'%')
</if> </if>
@@ -72,16 +52,38 @@
AND auth.auth_expire_date >= #{param.startAuthExpireDate} AND auth.auth_expire_date >= #{param.startAuthExpireDate}
AND auth.auth_expire_date &lt;= #{param.endAuthExpireDate} AND auth.auth_expire_date &lt;= #{param.endAuthExpireDate}
</if> </if>
<!--授权部门-->
<if test="param.authDeptList != null and param.authDeptList.size() > 0">
AND auth.auth_dept IN
<foreach item="item" index="index" collection="param.authDeptList" open="(" separator="," close=")">
#{item}
</foreach>
</if>
ORDER BY ORDER BY
auth.create_time DESC, auth.create_time DESC,
auth.auth_expire_date DESC auth.auth_expire_date DESC
LIMIT #{pageSize} OFFSET #{offset}
</select> </select>
<!-- 统计用户授权总数 -->
<select id="countUserAuths" resultType="int">
SELECT COUNT(*)
FROM (select * from laws_enterprise_standard_auth_user WHERE auth_expire_date IS NOT NULL) auth
<if test="param.standardNumber != null and param.standardNumber != ''">
LEFT JOIN laws_enterprise_standard AS es ON auth.standard_id = es.id
</if>
<if test="param.authUser != null and param.authUser != ''">
LEFT JOIN sys_user AS u ON u.id = auth.auth_user
</if>
<where>
<!--企标编号-->
<if test="param.standardNumber != null and param.standardNumber != ''">
AND es.standard_number LIKE CONCAT('%',#{param.standardNumber},'%')
</if>
<!--授权到期日期-->
<if test="param.startAuthExpireDate != null and param.endAuthExpireDate != ''">
AND auth.auth_expire_date >= #{param.startAuthExpireDate}
AND auth.auth_expire_date &lt;= #{param.endAuthExpireDate}
</if>
<!--授权人员-->
<if test="param.authUser != null and param.authUser != ''">
AND CONCAT(u.realname, '(', u.username, ')') LIKE CONCAT('%',#{param.authUser},'%')
</if>
</where>
</select>
</mapper> </mapper>
@@ -14,6 +14,7 @@ import com.jero.modules.laws.common.constant.FieldCommon;
import com.jero.modules.laws.common.vo.ManyStandardSelectionBox; import com.jero.modules.laws.common.vo.ManyStandardSelectionBox;
import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthDept; import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthDept;
import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthUser; import com.jero.modules.laws.enterprise.entity.EnterpriseStandardAuthUser;
import com.jero.modules.laws.enterprise.mapper.EnterpriseStandardAuthDeptMapper;
import com.jero.modules.laws.enterprise.mapper.EnterpriseStandardAuthUserMapper; import com.jero.modules.laws.enterprise.mapper.EnterpriseStandardAuthUserMapper;
import com.jero.modules.laws.enterprise.service.EnterpriseStandardAuthDeptService; import com.jero.modules.laws.enterprise.service.EnterpriseStandardAuthDeptService;
import com.jero.modules.laws.enterprise.service.EnterpriseStandardAuthUserService; import com.jero.modules.laws.enterprise.service.EnterpriseStandardAuthUserService;
@@ -37,6 +38,7 @@ import com.jero.modules.system.service.ISysUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -84,6 +86,9 @@ public class EnterpriseStandardAuthUserServiceImpl extends ServiceImpl<Enterpris
@Resource @Resource
private EnterpriseStandardAuthUserMapper authUserMapper; private EnterpriseStandardAuthUserMapper authUserMapper;
@Resource
private EnterpriseStandardAuthDeptMapper authDeptMapper;
@Value("#{'${adminRoleCode}'.split(',')}") @Value("#{'${adminRoleCode}'.split(',')}")
private List<String> adminRoleCodeList; private List<String> adminRoleCodeList;
@@ -788,9 +793,67 @@ public class EnterpriseStandardAuthUserServiceImpl extends ServiceImpl<Enterpris
} }
@Override @Override
@Cacheable(value = "tempAuthRecord", key = "{#tempAuthRecordQueryDto, #pageNo, #pageSize}")
public IPage<TempAuthRecordQueryDto> tempAuthRecord(TempAuthRecordQueryDto tempAuthRecordQueryDto, Integer pageNo, Integer pageSize) { public IPage<TempAuthRecordQueryDto> tempAuthRecord(TempAuthRecordQueryDto tempAuthRecordQueryDto, Integer pageNo, Integer pageSize) {
IPage<TempAuthRecordQueryDto> page = new Page<>(pageNo, pageSize); List<String> authDeptList = tempAuthRecordQueryDto.getAuthDeptList();
return authUserMapper.tempAuthRecord(page, tempAuthRecordQueryDto); String authUser = tempAuthRecordQueryDto.getAuthUser();
int totalDeptAuths = 0;
int totalUserAuths = 0;
// 没有授权人员筛选的时候
if (StrUtil.isBlank(authUser)) {
totalDeptAuths = authDeptMapper.countDeptAuths(tempAuthRecordQueryDto);
}
// 授权部门和授权人员都没有查询条件的时候
if (authDeptList == null || authDeptList.isEmpty()) {
totalUserAuths = authUserMapper.countUserAuths(tempAuthRecordQueryDto);
}
int totalRecords = totalDeptAuths + totalUserAuths;
// 分页查询
List<TempAuthRecordQueryDto> results = new ArrayList<>();
if (totalRecords > 0) {
// 计算offset和实际pageSize
int offset = (pageNo - 1) * pageSize;
// 首先查询auth_dept数据
List<TempAuthRecordQueryDto> deptAuths = new ArrayList<>();
if (totalDeptAuths > 0) {
deptAuths = authDeptMapper.queryDeptAuths(tempAuthRecordQueryDto, pageSize, offset);
}
// 如果deptAuths的数量少于pageSize,则查询auth_user填充剩余空间
int remainingSize = pageSize - deptAuths.size();
List<TempAuthRecordQueryDto> userAuths = new ArrayList<>();
if (remainingSize > 0 && deptAuths.size() <= totalDeptAuths && totalUserAuths > 0) {
// 计算auth_user的offset
int userOffset = Math.max(0, offset - totalDeptAuths);
userAuths = authUserMapper.queryUserAuths(tempAuthRecordQueryDto, remainingSize, userOffset);
}
results.addAll(deptAuths);
results.addAll(userAuths);
}
// 手动翻译标准编号
if (!results.isEmpty()) {
Set<String> standardIdSet = results.stream().map(TempAuthRecordQueryDto::getStandardId).collect(Collectors.toSet());
LambdaQueryWrapper<LawsEnterpriseStandard> esWrapper = new LambdaQueryWrapper<>();
esWrapper.in(LawsEnterpriseStandard::getId, standardIdSet);
List<LawsEnterpriseStandard> esList = esService.list(esWrapper);
Map<String, String> esStandardMap = esList.stream().collect(
Collectors.toMap(LawsEnterpriseStandard::getId, LawsEnterpriseStandard::getStandardNumber));
results.forEach(r -> {
r.setStandardNumber(esStandardMap.get(r.getStandardId()));
});
}
// 构建分页结果
Page<TempAuthRecordQueryDto> page = new Page<>();
page.setRecords(results);
page.setCurrent(pageNo);
page.setSize(pageSize);
page.setTotal(totalRecords);
return page;
} }
@Override @Override
@@ -33,6 +33,7 @@ import com.jero.modules.tag.enums.TableNameEnum;
import io.swagger.annotations.*; import io.swagger.annotations.*;
import org.apache.shiro.authz.annotation.RequiresPermissions; import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -259,6 +260,7 @@ public class LawsEnterpriseController {
@PostMapping(value = "/tempPermission") @PostMapping(value = "/tempPermission")
@ApiOperationSupport(order = 13) @ApiOperationSupport(order = 13)
@RequiresPermissions("enterpriseStandard:temporaryPermissSet") @RequiresPermissions("enterpriseStandard:temporaryPermissSet")
@CacheEvict(value = "tempAuthRecord", allEntries = true)
public Result<?> tempPermission(@RequestBody LawsStandardTempPermission lawsStandardTempPermission) { public Result<?> tempPermission(@RequestBody LawsStandardTempPermission lawsStandardTempPermission) {
String userIds = lawsStandardTempPermission.getUserIds(); String userIds = lawsStandardTempPermission.getUserIds();
String deptIds = lawsStandardTempPermission.getDeptIds(); String deptIds = lawsStandardTempPermission.getDeptIds();
@@ -385,6 +387,7 @@ public class LawsEnterpriseController {
@GetMapping(value = "/revokeAuth") @GetMapping(value = "/revokeAuth")
@ApiOperationSupport(order = 22) @ApiOperationSupport(order = 22)
@RequiresPermissions("enterpriseStandard:temporaryPermissRecord") @RequiresPermissions("enterpriseStandard:temporaryPermissRecord")
@CacheEvict(value = "tempAuthRecord", allEntries = true)
public Result<?> revokeAuth(@RequestParam(name="id", required = false) @ApiParam("Id") String authId) { public Result<?> revokeAuth(@RequestParam(name="id", required = false) @ApiParam("Id") String authId) {
esAuthUserService.revokeAuth(authId); esAuthUserService.revokeAuth(authId);
return Result.OK(); return Result.OK();
@@ -9,6 +9,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.ConfigurableApplicationContext; import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment; import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@@ -23,6 +24,7 @@ import java.net.UnknownHostException;
**/ **/
@Slf4j @Slf4j
@EnableScheduling @EnableScheduling
@EnableCaching
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class, @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class, org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration.class,
SecurityAutoConfiguration.class, SecurityAutoConfiguration.class,