需求
1、新增财务订单导出—现定时任务实现方式,只有财务角色和系统管理员角色才能看到此导出按钮并导出,无筛选导出功能
2、请求去重—为防止用户重复刷新发起导出请求,只导出用户10分钟内发起的最新导出请求。如10分钟内一个用户连续发起三次导出请求,只会导出用户第三次的导出请求。
实现
后端
OrderInfoController
private final FeignSysUserService feignSysUserService;
private final UserFinancialExportTaskMapper userFinancialExportTaskMapper;
/** * @Description: 请求导出财务订单记录列表 */
@ApiOperation(value = "请求导出财务订单记录列表")
@SysLog("请求导出财务订单记录列表")
@PostMapping("/financialExport")
public void financialExport() throws Exception {
BaseUser user = SecurityUtils.getUser();
if (ObjectUtil.isNull(user)) {
throw new CheckedException("auto datascope, set up security details true");
}
R r = feignSysUserService.getUser(user.getId(),user.getType(),SecurityConstants.FROM_IN);
if (!r.isOk()) {
log.warn("全部订单下载通知的获取管理员信息远程服务查询失败!");
throw new RuntimeException(r.getMsg());
}
//把object转换成json字符串
String json = JSON.toJSONString(r.getData());
//把json字符串转换成UserInfo对象
UserVO userInfo = JSON.parseObject(json, UserVO.class);
if (Objects.isNull(userInfo)) {
log.warn("全部订单下载通知管理员信息不存在");
}
List<SysRole> sysRoleList= userInfo.getRoleList();
String roleCode = sysRoleList.get(0).getRoleCode();
if ((!CommonConstants.ROLE_CODE_FC.equals(roleCode))&&(!CommonConstants.USER_TYPE_S.equals(userInfo.getTenantId()))) {
log.error("当前用户不是财务人员或者系统管理员,无法导出{}财务订单记录列表",roleCode);
throw new RuntimeException("当前用户不是财务人员或者系统管理员,无法导出财务订单记录列表");
}
UserFinancialExportTask userFinancialExportTask = new UserFinancialExportTask();
userFinancialExportTask.setId(userInfo.getId());
userFinancialExportTask.setUsername(userInfo.getUsername());
userFinancialExportTask.setNickName(userInfo.getNickName());
userFinancialExportTask.setCreateTime(new Date());
userFinancialExportTask.setEmail(userInfo.getEmail());
userFinancialExportTask.setRoleCode(roleCode);
userFinancialExportTask.setStatus(OrderInfoEnum.STATUS_TASK_0.getValue());
userFinancialExportTask.setTenantId(userInfo.getTenantId());
userFinancialExportTaskMapper.insert(userFinancialExportTask);
}
UserFinancialOrderExportTask
/** * @Description: 商城财务订单导出任务 */
@Slf4j
@Component("financialOrderInfoExportTask")
@AllArgsConstructor
public class UserFinancialOrderExportTask {
private final CosConfigProperties cosConfigProperties;
private final MailConfigProperties mailConfigProperties;
private final UserFinancialExportTaskService userFinancialExportTaskService;
private final OrderInfoExportFinanceService orderInfoExportFinanceService;
/** * @Description: 商城财务订单导出任务 */
@XxlJob("financialOrderInfoExportJobHandler")
public ReturnT<String> financialOrderInfoExportJob(String s) throws Exception {
//查询出所有的需要导出的任务
QueryWrapper<UserFinancialExportTask> wapper = new QueryWrapper<UserFinancialExportTask>();
List<UserFinancialExportTask> taskList = userFinancialExportTaskService.list(wapper.eq("status", OrderInfoEnum.STATUS_TASK_0.getValue()).orderByDesc("create_time"));
//去重
List<UserFinancialExportTask> arraysList = taskList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(()
-> new TreeSet<>(Comparator.comparing(UserFinancialExportTask :: getId))), ArrayList::new));
//如果有重复的任务,则将重复的任务状态改为已完成
List<UserFinancialExportTask> duplicatedList = new ArrayList<>(taskList);
duplicatedList.removeAll(arraysList);
if(duplicatedList.size()>0){
log.info("有重复的任务,重复的任务数量为:{}",duplicatedList.size());
for (UserFinancialExportTask task : duplicatedList) {
LambdaUpdateWrapper<UserFinancialExportTask> updateWrapper = new UpdateWrapper<UserFinancialExportTask>().lambda();
updateWrapper.eq(UserFinancialExportTask::getCreateTime, task.getCreateTime());
updateWrapper.set(UserFinancialExportTask::getStatus, OrderInfoEnum.STATUS_TASK_1.getValue());
userFinancialExportTaskService.update(updateWrapper);
}
}
//如果有任务,则执行
if (arraysList.size() > 0) {
for (UserFinancialExportTask exportTask1 : arraysList) {
exportTask1.setStatus(OrderInfoEnum.STATUS_TASK_00.getValue());
long diffInMilliSec = System.currentTimeMillis() - exportTask1.getCreateTime().getTime();
long diffInMinutes = TimeUnit.MILLISECONDS.toMinutes(diffInMilliSec);
//如果时间在10分钟以内,则执行
if (diffInMinutes <= 10) {
log.debug("orderInfoExportJob start...");
List<OrderInfoExportFinance> list = orderInfoExportFinanceService.getList(new OrderInfoExportFinance());
//讲数据写入到excel,并上传到cos上,生成地址
String responseURL = excelLink(list);
if (StringUtils.isEmpty(responseURL)) {
exportTask1.setStatus(OrderInfoEnum.STATUS_TASK_11.getValue());
throw new CheckedException("将数据写入到excel,并上传到cos上,生成地址失败");
}
//异步邮件通知用户去下载
notifyUser(responseURL, exportTask1.getEmail(), exportTask1.getUsername());
exportTask1.setStatus(OrderInfoEnum.STATUS_TASK_1.getValue());
log.info("financialOrderInfoExportJob end...");
} else {
exportTask1.setStatus(OrderInfoEnum.STATUS_TASK_11.getValue());
}
LambdaUpdateWrapper<UserFinancialExportTask> updateWrapper = new UpdateWrapper<UserFinancialExportTask>().lambda();
updateWrapper.eq(UserFinancialExportTask::getCreateTime, exportTask1.getCreateTime());
updateWrapper.set(UserFinancialExportTask::getStatus, exportTask1.getStatus());
userFinancialExportTaskService.update(updateWrapper);
}
}
return SUCCESS;
}
/** * @Description: 将数据写入到excel, 并上传到cos上, 生成地址 */
private String excelLink(List<OrderInfoExportFinance> list) throws Exception {
String sheetName = "订单记录列表";
FileItem fileItem;
List<OrderInfoExportFinance> exportCsList = BeanUtil.copyToList(list, OrderInfoExportFinance.class, null);
ExcelUtil<OrderInfoExportFinance> util = new ExcelUtil<>(OrderInfoExportFinance.class);
util.exportExcelNew(exportCsList, sheetName);
fileItem = util.exportExcelNew(exportCsList, sheetName);
//存入cos,生成链接地址,并设置2小时后失效
return uploadFile(fileItem, sheetName);
}
/** * @Description: 上传文件到cos, 并设置2小时后失效 */
private String uploadFile(FileItem fileItem, String dir) throws Exception {
MultipartFile multipartFile = new CommonsMultipartFile(fileItem);
File file = FileUtils.multipartFileToFile(multipartFile);
SysConfigStorage sysConfigStorage = initSysConfigStorage();
StorageConfig storageConfig = new StorageConfig();
storageConfig.setAccessKeyId(sysConfigStorage.getAccessKeyId());
storageConfig.setAccessKeySecret(sysConfigStorage.getAccessKeySecret());
storageConfig.setEndpoint(sysConfigStorage.getEndpoint());
storageConfig.setBucket(sysConfigStorage.getBucket());
QcloudCosUtils qcloudCosUtils = new QcloudCosUtils(storageConfig);
return qcloudCosUtils.uploadFileWithDeleteTime(file, dir);
}
/** * @Description: 获取默认配置 */
public SysConfigStorage initSysConfigStorage() {
SysConfigStorage sysConfigStorage = new SysConfigStorage();
sysConfigStorage.setStorageType(SysConfigStorage.StorageTypeEnum.QCLOUDCOS.getType());
sysConfigStorage.setAccessKeyId(cosConfigProperties.getSecretId());
sysConfigStorage.setAccessKeySecret(cosConfigProperties.getSecretKey());
sysConfigStorage.setEndpoint(cosConfigProperties.getRegion());
sysConfigStorage.setBucket(cosConfigProperties.getBucket());
return sysConfigStorage;
}
/** * @Description: 下载通知 */
public void notifyUser(String responseURL, String email, String realName) {
DesvMailUtil mailUtil = new DesvMailUtil(mailConfigProperties.getUsername(), mailConfigProperties.getPassword(), mailConfigProperties.getDomain(), mailConfigProperties.getUri());
HashMap<String, Object> params = new HashMap<String, Object>();
String today = DateUtil.format(new Date(), DatePattern.CHINESE_DATE_PATTERN);
params.put("to", email);
params.put("username", "【】");
params.put("title", "财务订单导出结果通知");
String msgBody =
"<p style=\"text-align:left;\">\r\n" +
" <br />\r\n" +
"</p>\r\n" +
"<p style=\"text-align:left;\">\r\n" +
" <span style=\"color:#333333;font-size:14px;\">To {}:</span> \r\n" +
"</p>\r\n" +
"<p style=\"text-align:left;\">\r\n" +
" <span style=\"color:#333333;font-size:14px;\">全部订单导出地址为:{},请于两小时内下载。</span> \r\n" +
"</p>\r\n" +
"<p style=\"text-align:left;\">\r\n" +
" <span style=\"color:#333333;font-size:14px;\"> 两小时后链接将会失效哦,如失效,请再次发起导出需求。</span>\r\n" +
"</p>\r\n" +
"<p style=\"text-align:left;\">\r\n" +
" <span style=\"color:#333333;font-size:14px;\">{} </span> \r\n" +
"<br />";
msgBody = StrUtil.format(msgBody, realName, responseURL, today);
params.put("item", msgBody);
try {
mailUtil.sendEmail(params);
} catch (Exception e) {
log.error("notifyUser error:{}", e.getMessage());
}
log.info("notifyUser {} sucesss", realName);
}
}
前端
/** 财政导出按钮操作 */
handleFCExport() {
this.$confirm(
"请确认您“个人信息”里的邮箱"+ this.email+"为您正在使用的邮箱,如果是,请点击导出订单",
"提示",
{
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
}
)
.then(() => {
this.$message({
type: "success",
message:
"收到,导出下载地址会在15分钟内通过邮件发送给您,请耐心等候。",
});
this.isFCDisabled = true; // 禁用按钮
toFCExport();
setTimeout(function () {
this.isFCDisabled = false; // 启用按钮
}, 600000); // 10分钟后执行
})
.catch(() => {
this.$message({
type: "info",
message: "已取消",
});
});
}
this.$store.dispatch("GetUserInfo").then(res => {
this.roles=res.roles[0];
this.tenantId=res.sysUser.tenantId;
this.email=res.sysUser.email;
});
文章评论