|
@@ -3,6 +3,7 @@ package com.qunzhixinxi.hnqz.admin.service.impl;
|
|
|
import cn.hutool.core.bean.BeanUtil;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.date.DatePattern;
|
|
|
+import cn.hutool.core.io.FileUtil;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
import com.alibaba.excel.EasyExcel;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
@@ -19,6 +20,7 @@ import com.qunzhixinxi.hnqz.admin.api.entity.SysUserCertificate;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.SysUserRole;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmReportOpt;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.model.excel.SysUserExcelModel;
|
|
|
+import com.qunzhixinxi.hnqz.admin.config.UpmsConfig;
|
|
|
import com.qunzhixinxi.hnqz.admin.controller.user.SysUserController;
|
|
|
import com.qunzhixinxi.hnqz.admin.event.UserExportEvent;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.SysAreaEntityMapper;
|
|
@@ -31,6 +33,7 @@ import com.qunzhixinxi.hnqz.admin.service.SysFileService;
|
|
|
import com.qunzhixinxi.hnqz.admin.service.SysUserAreaService;
|
|
|
import com.qunzhixinxi.hnqz.admin.service.SysUserExportService;
|
|
|
import com.qunzhixinxi.hnqz.admin.util.OsEnvUtils;
|
|
|
+import com.qunzhixinxi.hnqz.common.core.exception.BizException;
|
|
|
import com.qunzhixinxi.hnqz.common.core.util.SpringContextHolder;
|
|
|
import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
@@ -74,6 +77,7 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
private final SysDeptMapper deptMapper;
|
|
|
private final SysUserCertificateMapper userCertificateMapper;
|
|
|
private final SysFileService fileService;
|
|
|
+ private final UpmsConfig upmsConfig;
|
|
|
|
|
|
private static final long DEF_REPORT_TTL = 7L * 24 * 60 * 60 * 1000;
|
|
|
private static final String ERROR_MSG_UNKNOWN = "ERROR_未知错误,请联系管理员";
|
|
@@ -91,6 +95,22 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
*/
|
|
|
@Override
|
|
|
public Boolean asyncExport(HnqzUser user, List<Integer> roles, SysUserDTO.OnList query) {
|
|
|
+ // 使用Redis原子操作实现限流,避免使用synchronized影响并发性能
|
|
|
+ String key = CacheConstants.ASYNC_EXPORT_LIMIT_KEY;
|
|
|
+ Long increment = redisTemplate.opsForValue().increment(key);
|
|
|
+
|
|
|
+ // 设置key的过期时间,避免计数器无限增长
|
|
|
+ if (increment != null && increment.equals(1L)) {
|
|
|
+ redisTemplate.expire(key, 1, TimeUnit.MINUTES);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 检查是否超过限流阈值
|
|
|
+ if (increment != null && increment > upmsConfig.getAsyncExportLimit()) {
|
|
|
+ // 超过限流阈值时,减少计数器并抛出异常
|
|
|
+ redisTemplate.opsForValue().decrement(key);
|
|
|
+ throw new BizException("系统繁忙,请稍后再试");
|
|
|
+ }
|
|
|
+
|
|
|
SpringContextHolder.getApplicationContext().publishEvent(new UserExportEvent(user, roles, query));
|
|
|
return Boolean.TRUE;
|
|
|
}
|
|
@@ -105,12 +125,20 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
*/
|
|
|
@Override
|
|
|
public Boolean export(HnqzUser user, List<Integer> roles, SysUserDTO.OnList query) {
|
|
|
+ // 缓存key
|
|
|
String key = String.format(CacheConstants.ASYNC_EXPORT_CACHE, ExportType.USER.getType(), user.getId());
|
|
|
|
|
|
+ // 临时文件路径
|
|
|
+ String tempPath = OsEnvUtils.getEachEnvPaths().get(OsEnvUtils.TargetFile.TEMP.getName());
|
|
|
+ // 缓存文件名
|
|
|
+ String fileName = tempPath + "人员_" + DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN)
|
|
|
+ .format(LocalDateTime.now()) + RandomStringUtils.randomNumeric(6) + ".xlsx";
|
|
|
+
|
|
|
// 查询用户列表
|
|
|
List<SysUser> users = this.listUsers(user, roles, query);
|
|
|
|
|
|
- if (CollUtil.isNotEmpty(users)) {
|
|
|
+ if (CollUtil.isEmpty(users)) {
|
|
|
+ log.info("用户列表为空");
|
|
|
redisTemplate.opsForValue().set(key, ERROR_MSG_NO_DATA, DEF_REPORT_TTL, TimeUnit.MILLISECONDS);
|
|
|
return Boolean.FALSE;
|
|
|
}
|
|
@@ -144,7 +172,7 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
userCertificateMapper.selectList(Wrappers.<SysUserCertificate>lambdaQuery()
|
|
|
.in(SysUserCertificate::getUserId, userIds)
|
|
|
.eq(SysUserCertificate::getType, "REG")
|
|
|
- .select(SysUserCertificate::getCertificateId));
|
|
|
+ .select(SysUserCertificate::getCertificateId, SysUserCertificate::getUserId));
|
|
|
|
|
|
Map<Integer, Long> userCertMap = userCertificates.stream()
|
|
|
.collect(Collectors.groupingBy(SysUserCertificate::getUserId, Collectors.counting()));
|
|
@@ -152,6 +180,13 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
// 转为excel列表
|
|
|
List<SysUserExcelModel> excelModels = users.stream().map(u -> {
|
|
|
SysUserExcelModel excelModel = BeanUtil.copyProperties(u, SysUserExcelModel.class, "lockFlag");
|
|
|
+ excelModel.setRealName(u.getRealname());
|
|
|
+ excelModel.setPhoneNumber(u.getPhone());
|
|
|
+ // 锁定状态
|
|
|
+ excelModel.setLockFlag("0".equals(u.getLockFlag()) ? "活跃" : "休眠");
|
|
|
+ // 创建时间
|
|
|
+ excelModel.setCreateTime(u.getCreateTime().format(DateTimeFormatter.ofPattern(DatePattern.NORM_DATETIME_PATTERN)));
|
|
|
+
|
|
|
// 派工方
|
|
|
SysDept dept = deptMap.get(u.getDeptId());
|
|
|
if (dept != null) {
|
|
@@ -171,17 +206,10 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
long certCount = userCertMap.getOrDefault(u.getUserId(), 0L);
|
|
|
excelModel.setCertificateFlag(certCount > 0 ? "是" : "否");
|
|
|
|
|
|
- // 锁定状态
|
|
|
- excelModel.setLockFlag("0".equals(u.getLockFlag()) ? "活跃" : "休眠");
|
|
|
-
|
|
|
-
|
|
|
return excelModel;
|
|
|
}).collect(Collectors.toList());
|
|
|
|
|
|
// 写入excel文件
|
|
|
- String tempPath = OsEnvUtils.getEachEnvPaths().get(OsEnvUtils.TargetFile.TEMP.getName());
|
|
|
- String fileName = tempPath + "人员_" + DateTimeFormatter.ofPattern(DatePattern.PURE_TIME_PATTERN)
|
|
|
- .format(LocalDateTime.now()) + RandomStringUtils.randomNumeric(6) + ".xlsx";
|
|
|
EasyExcel.write(fileName, SysUserExcelModel.class).sheet("人员")
|
|
|
.doWrite(excelModels);
|
|
|
log.info("人员导出生成缓存文件:{}", fileName);
|
|
@@ -198,13 +226,20 @@ public class SysUserExportServiceImpl implements SysUserExportService {
|
|
|
resultValue = ERROR_MSG_UPLOAD_FAIL;
|
|
|
}
|
|
|
} catch (Exception e) {
|
|
|
- log.error("人员导出写入文件失败", e);
|
|
|
+ log.error("人员导出失败", e);
|
|
|
resultValue = ERROR_MSG_UNKNOWN;
|
|
|
+ } finally {
|
|
|
+ // 移除缓存文件
|
|
|
+ FileUtil.del(fileName);
|
|
|
+
|
|
|
+ // 删除限流key
|
|
|
+ String limitKey = CacheConstants.ASYNC_EXPORT_LIMIT_KEY;
|
|
|
+ redisTemplate.delete(limitKey);
|
|
|
}
|
|
|
|
|
|
redisTemplate.opsForValue().set(key, resultValue, DEF_REPORT_TTL, TimeUnit.MILLISECONDS);
|
|
|
|
|
|
- return Boolean.FALSE;
|
|
|
+ return StrUtil.startWith(resultValue, "ERROR") ? Boolean.FALSE : Boolean.TRUE;
|
|
|
}
|
|
|
|
|
|
/**
|