|
@@ -3,7 +3,6 @@ package com.qunzhixinxi.hnqz.admin.service.impl;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.core.date.DatePattern;
|
|
|
import cn.hutool.core.util.StrUtil;
|
|
|
-import com.alibaba.excel.EasyExcel;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.constant.CacheConstants;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.constant.UpmsState;
|
|
@@ -16,15 +15,16 @@ import com.qunzhixinxi.hnqz.admin.api.entity.SysDeptRelation;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.SysUser;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmDaDrugEntDrugtable;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmPackageTaskTypeQty;
|
|
|
-import com.qunzhixinxi.hnqz.admin.api.entity.WmReportOpt;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmScorePackage;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmScorePackageStatus;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.entity.WmTask;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.model.excel.SysUserExcelModel;
|
|
|
import com.qunzhixinxi.hnqz.admin.api.model.excel.WmScorePackageSubInfoExcelModel;
|
|
|
+import com.qunzhixinxi.hnqz.admin.aspect.ExportGuard;
|
|
|
import com.qunzhixinxi.hnqz.admin.config.UpmsConfig;
|
|
|
import com.qunzhixinxi.hnqz.admin.event.PackageExportEvent;
|
|
|
import com.qunzhixinxi.hnqz.admin.manager.WmPackageExportScope;
|
|
|
+import com.qunzhixinxi.hnqz.admin.manager.WmPackageManager;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.SysCheckChainNodeCheckHistoryMapper;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.SysDeptMapper;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.SysDeptRelationMapper;
|
|
@@ -33,10 +33,10 @@ import com.qunzhixinxi.hnqz.admin.mapper.WmDaDrugEntDrugtableMapper;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageMapper;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.WmScorePackageStatusMapper;
|
|
|
import com.qunzhixinxi.hnqz.admin.mapper.WmTaskMapper;
|
|
|
-import com.qunzhixinxi.hnqz.admin.service.SysFileService;
|
|
|
import com.qunzhixinxi.hnqz.admin.service.WmPackageTaskTypeQtyService;
|
|
|
import com.qunzhixinxi.hnqz.admin.service.WmScorePackageExportService;
|
|
|
-import com.qunzhixinxi.hnqz.admin.util.OsEnvUtils;
|
|
|
+import com.qunzhixinxi.hnqz.admin.util.ExportUtils;
|
|
|
+import com.qunzhixinxi.hnqz.admin.util.RedisUtils;
|
|
|
import com.qunzhixinxi.hnqz.common.core.constant.CommonConstants;
|
|
|
import com.qunzhixinxi.hnqz.common.core.exception.BizException;
|
|
|
import com.qunzhixinxi.hnqz.common.core.util.SpringContextHolder;
|
|
@@ -44,15 +44,10 @@ import com.qunzhixinxi.hnqz.common.security.service.HnqzUser;
|
|
|
import com.qunzhixinxi.hnqz.common.security.util.SecurityUtils;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.apache.commons.lang3.RandomStringUtils;
|
|
|
import org.springframework.data.redis.core.RedisTemplate;
|
|
|
-import org.springframework.retry.support.RetryTemplate;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
-import java.io.File;
|
|
|
-import java.io.FileInputStream;
|
|
|
import java.time.LocalDate;
|
|
|
-import java.time.LocalDateTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
@@ -61,7 +56,6 @@ import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Set;
|
|
|
-import java.util.concurrent.TimeUnit;
|
|
|
import java.util.function.Function;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
@@ -83,17 +77,11 @@ public class WmScorePackageExportServiceImpl implements WmScorePackageExportServ
|
|
|
private final WmDaDrugEntDrugtableMapper drugEntDrugtableMapper;
|
|
|
private final WmScorePackageStatusMapper scorePackageStatusMapper;
|
|
|
private final SysCheckChainNodeCheckHistoryMapper checkChainNodeCheckHistoryMapper;
|
|
|
- private final SysFileService fileService;
|
|
|
private final WmPackageTaskTypeQtyService packageTaskTypeQtyService;
|
|
|
private final RedisTemplate<String, Object> redisTemplate;
|
|
|
- private final RetryTemplate retryTemplate;
|
|
|
private final UpmsConfig upmsConfig;
|
|
|
-
|
|
|
-
|
|
|
- private static final long DEF_REPORT_TTL = 7L * 24 * 60 * 60 * 1000;
|
|
|
- private static final String ERROR_MSG_UNKNOWN = "ERROR_未知错误,请联系管理员";
|
|
|
- private static final String ERROR_MSG_NO_DATA = "ERROR_没有数据";
|
|
|
- private static final String ERROR_MSG_UPLOAD_FAIL = "ERROR_上传OSS失败";
|
|
|
+ private final RedisUtils redisUtils;
|
|
|
+ private final ExportUtils exportUtils;
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -106,34 +94,12 @@ public class WmScorePackageExportServiceImpl implements WmScorePackageExportServ
|
|
|
* @return {@link Boolean } 是否成功
|
|
|
*/
|
|
|
@Override
|
|
|
+ @ExportGuard(type = "SCORE_PACKAGE_SUB")
|
|
|
public Boolean asyncExport(HnqzUser user, List<Integer> roles, LocalDate startDate, LocalDate endDate) {
|
|
|
- return retryTemplate.execute(retryContext -> {
|
|
|
- log.info("个人执行包数据异步导出第{}次重试", retryContext.getRetryCount());
|
|
|
-
|
|
|
- // 使用Redis原子操作实现限流
|
|
|
- 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("系统繁忙,请稍后再试");
|
|
|
- }
|
|
|
-
|
|
|
- // 缓存key
|
|
|
- String cacheKey = String.format(CacheConstants.ASYNC_EXPORT_CACHE, ExportType.SCORE_PACKAGE_SUB.getType(), user.getId());
|
|
|
- // 更新状态为生成中
|
|
|
- redisTemplate.opsForValue().set(cacheKey, WmReportOpt.WmReportOptStatus.GENERATING.name(), DEF_REPORT_TTL, TimeUnit.MILLISECONDS);
|
|
|
+ redisUtils.setExportStarting(ExportType.SCORE_PACKAGE_SUB, user.getId());
|
|
|
|
|
|
SpringContextHolder.getApplicationContext().publishEvent(new PackageExportEvent(user, roles, startDate, endDate));
|
|
|
return Boolean.TRUE;
|
|
|
- });
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -147,72 +113,31 @@ public class WmScorePackageExportServiceImpl implements WmScorePackageExportServ
|
|
|
*/
|
|
|
@Override
|
|
|
public Boolean export(HnqzUser user, List<Integer> roles, LocalDate startDate, LocalDate endDate) {
|
|
|
- // 缓存key
|
|
|
- String key = String.format(CacheConstants.ASYNC_EXPORT_CACHE, ExportType.SCORE_PACKAGE_SUB.getType(), user.getId());
|
|
|
-
|
|
|
- // 临时文件路径
|
|
|
- String tempPath = OsEnvUtils.getEachEnvPaths().get(OsEnvUtils.TargetFile.TEMP.getName());
|
|
|
- // 缓存文件名
|
|
|
- String fileName = "个人执行包数据_" + DateTimeFormatter.ofPattern(DatePattern.PURE_DATE_PATTERN)
|
|
|
- .format(LocalDateTime.now()) + RandomStringUtils.randomNumeric(6) + ".xlsx";
|
|
|
- String fullPath = tempPath + fileName;
|
|
|
-
|
|
|
- String resultValue = ERROR_MSG_UNKNOWN;
|
|
|
+ redisUtils.checkExportGlobalAllows(upmsConfig.getAsyncExportLimit());
|
|
|
|
|
|
try {
|
|
|
// 获取数据
|
|
|
- List<WmScorePackageSubInfoExcelModel> packageSubModels = this.getExportData(user, roles, startDate, endDate);
|
|
|
- if (CollUtil.isEmpty(packageSubModels)) {
|
|
|
- log.info("个人执行包数据为空");
|
|
|
- redisTemplate.opsForValue().set(key, ERROR_MSG_NO_DATA, DEF_REPORT_TTL, TimeUnit.MILLISECONDS);
|
|
|
- return Boolean.FALSE;
|
|
|
- }
|
|
|
-
|
|
|
- // 写入excel文件
|
|
|
- EasyExcel.write(fullPath, SysUserExcelModel.class).sheet("个人执行包数据")
|
|
|
- .doWrite(packageSubModels);
|
|
|
- log.info("个人执行包数据导出生成缓存文件:{}", fullPath);
|
|
|
-
|
|
|
- // 上传oss
|
|
|
- FileInputStream inputStream = new FileInputStream(fullPath);
|
|
|
- Map<String, String> uploadResult = fileService.upload(inputStream, fileName, fileName, user.getUsername());
|
|
|
- log.info("个人执行包数据导出生成oss文件:{}", uploadResult);
|
|
|
-
|
|
|
- if (CollUtil.isNotEmpty(uploadResult)) {
|
|
|
- resultValue = uploadResult.get("url");
|
|
|
- } else {
|
|
|
- resultValue = ERROR_MSG_UPLOAD_FAIL;
|
|
|
- }
|
|
|
-
|
|
|
- redisTemplate.opsForValue().set(key, resultValue, DEF_REPORT_TTL, TimeUnit.MILLISECONDS);
|
|
|
- } catch (Exception e) {
|
|
|
- log.error("个人执行包数据失败", e);
|
|
|
- } finally {
|
|
|
- // 清理临时文件
|
|
|
- cleanupTempFile(fullPath);
|
|
|
+ List<WmScorePackageSubInfoExcelModel> data = this.getExportData(user, roles, startDate, endDate);
|
|
|
|
|
|
- // 删除限流key
|
|
|
- String limitKey = CacheConstants.ASYNC_EXPORT_LIMIT_KEY;
|
|
|
- redisTemplate.delete(limitKey);
|
|
|
+ // 导出
|
|
|
+ String resultValue = exportUtils.WriteExportExcel(ExportType.SCORE_PACKAGE_SUB, data, SysUserExcelModel.class, user);
|
|
|
+ return !StrUtil.startWith(resultValue, "ERROR");
|
|
|
+ } finally {
|
|
|
+ // 释放全局限流
|
|
|
+ redisTemplate.opsForValue().decrement(CacheConstants.ASYNC_EXPORT_LIMIT_KEY);
|
|
|
}
|
|
|
-
|
|
|
- return !StrUtil.startWith(resultValue, "ERROR");
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 清理临时文件
|
|
|
+ * 获取导出数据
|
|
|
+ *
|
|
|
+ * @param user 用户
|
|
|
+ * @param roles 角色
|
|
|
+ * @param startDate 开始日期
|
|
|
+ * @param endDate 结束日期
|
|
|
+ * @return {@link List }<{@link WmScorePackageSubInfoExcelModel }> 结果
|
|
|
+ * @see WmPackageManager#exportPkgInfo(LocalDate, LocalDate) 参考代码(存在冗余待合并)
|
|
|
*/
|
|
|
- private void cleanupTempFile(String fullPath) {
|
|
|
- try {
|
|
|
- File file = new File(fullPath);
|
|
|
- if (file.exists()) {
|
|
|
- file.delete();
|
|
|
- }
|
|
|
- } catch (Exception e) {
|
|
|
- log.warn("删除临时文件失败: {}", fullPath, e);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
private List<WmScorePackageSubInfoExcelModel> getExportData(HnqzUser user, List<Integer> roles, LocalDate startDate, LocalDate endDate) {
|
|
|
WmPackageExportScope scope = this.getWmPackageExportScope(user, roles, startDate, endDate);
|
|
|
Map<String, WmDaDrugEntDrugtable> drugtableMap = scope.getDrugtableMap();
|