Browse Source

增加rabbitmq

develop
bobol 6 months ago
parent
commit
54aa3dc657
  1. 27
      lzbi-admin/src/main/resources/application-dev.yml
  2. 31
      lzbi-admin/src/main/resources/application-test.yml
  3. 24
      lzbi-common/src/main/java/com/lzbi/common/config/RabbitConfig.java
  4. 14
      lzbi-common/src/main/java/com/lzbi/common/constant/BizConstants.java
  5. 10
      lzbi-common/src/main/java/com/lzbi/common/constant/CacheConstants.java
  6. 4
      lzbi-common/src/main/java/com/lzbi/common/core/redis/RedisCache.java
  7. 9
      lzbi-module/src/main/java/com/lzbi/bi/controller/DcBusiHisReportController.java
  8. 57
      lzbi-module/src/main/java/com/lzbi/code/service/LogTimesacleHistoryThreeService.java
  9. 4
      lzbi-module/src/main/java/com/lzbi/rabbit/config/ReportExportRabbitConfig.java
  10. 4
      lzbi-module/src/main/java/com/lzbi/rabbit/consumer/IConsumerService.java
  11. 117
      lzbi-module/src/main/java/com/lzbi/rabbit/consumer/impl/ReportExportConsumer.java
  12. 7
      lzbi-module/src/main/java/com/lzbi/rabbit/producer/ReportExportProducer.java
  13. 20
      lzbi-module/src/main/java/com/lzbi/report/domain/DcBusiReportRecord.java
  14. 42
      lzbi-module/src/main/java/com/lzbi/report/service/DcBusiReportRecordService.java
  15. 57
      lzbi-module/src/main/resources/mapper/report/DcBusiReportRecordMapper.xml

27
lzbi-admin/src/main/resources/application-dev.yml

@ -11,16 +11,31 @@ spring:
username: admin username: admin
password: admin password: admin
virtual-host: / virtual-host: /
# 这个配置是保证提供者确保消息推送到交换机中,不管成不成功,都会回调 publisher-confirm-type: correlated # 这个配置是保证提供者确保消息推送到交换机中,不管成不成功,都会回调
publisher-confirm-type: correlated publisher-returns: true # 保证交换机能把消息推送到队列中
# 保证交换机能把消息推送到队列中
publisher-returns: true
# 这个配置是保证消费者会消费消息,手动确认
listener: listener:
simple: simple:
acknowledge-mode: manual acknowledge-mode: manual # 这个配置是保证消费者会消费消息,手动确认
concurrency: 1 # 最小消费者数量
max-concurrency: 1 # 最大的消费者数量
prefetch: 1 # 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量
default-requeue-rejected: true #设置是否重回队列 true即出现异常会将消息重新发送到队列中
# 重试机制
retry:
stateless: false #有无状态
enabled: true #设置是否启用消息重试机制,默认为false
maxAttempts: 3 #最大重试次数,默认3
initial-interval: 1000ms #设置消息重试的初始间隔时间,默认为1000ms
multiplier: 1 #设置消息重试的时间间隔倍数,默认为1(重试时间越来越长)
max-interval: 10000ms #设置消息重试的最大时间间隔,默认为10000ms。
template: template:
mandatory: true mandatory: true
retry:
enabled: true # 开启rabbit初始化重试机制
initial-interval: 1000ms # 初始重试间隔时间
max-interval: 10000ms # 最大重试间隔时间
multiplier: 1 # 重试间隔时间倍数
max-attempts: 3 # 最大重试次数
redis: redis:
# 地址 # 地址
host: 10.10.10.55 host: 10.10.10.55

31
lzbi-admin/src/main/resources/application-test.yml

@ -5,6 +5,37 @@ server:
# redis 配置 # redis 配置
spring: spring:
rabbitmq:
host: 10.10.10.55
port: 5672
username: admin
password: admin
virtual-host: /
publisher-confirm-type: correlated # 这个配置是保证提供者确保消息推送到交换机中,不管成不成功,都会回调
publisher-returns: true # 保证交换机能把消息推送到队列中
listener:
simple:
acknowledge-mode: manual # 这个配置是保证消费者会消费消息,手动确认
concurrency: 1 # 最小消费者数量
max-concurrency: 1 # 最大的消费者数量
prefetch: 1 # 指定一个请求能处理多少个消息,如果有事务的话,必须大于等于transaction数量
default-requeue-rejected: true #设置是否重回队列 true即出现异常会将消息重新发送到队列中
# 重试机制
retry:
stateless: false #有无状态
enabled: true #设置是否启用消息重试机制,默认为false
maxAttempts: 3 #最大重试次数,默认3
initial-interval: 1000ms #设置消息重试的初始间隔时间,默认为1000ms
multiplier: 1 #设置消息重试的时间间隔倍数,默认为1(重试时间越来越长)
max-interval: 10000ms #设置消息重试的最大时间间隔,默认为10000ms。
template:
mandatory: true
retry:
enabled: true # 开启rabbit初始化重试机制
initial-interval: 1000ms # 初始重试间隔时间
max-interval: 10000ms # 最大重试间隔时间
multiplier: 1 # 重试间隔时间倍数
max-attempts: 3 # 最大重试次数
redis: redis:
# 地址 # 地址
host: 10.10.10.55 host: 10.10.10.55

24
lzbi-common/src/main/java/com/lzbi/common/config/RabbitConfig.java

@ -1,5 +1,6 @@
package com.lzbi.common.config; package com.lzbi.common.config;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.AcknowledgeMode; import org.springframework.amqp.core.AcknowledgeMode;
import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder; import org.springframework.amqp.rabbit.config.RetryInterceptorBuilder;
import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory; import org.springframework.amqp.rabbit.config.SimpleRabbitListenerContainerFactory;
@ -30,6 +31,7 @@ import org.springframework.retry.support.RetryTemplate;
* mandatory: true) * mandatory: true)
* 3---设置重试 * 3---设置重试
*/ */
@Slf4j
@Configuration @Configuration
public class RabbitConfig { public class RabbitConfig {
@ -100,17 +102,17 @@ public class RabbitConfig {
rabbitTemplate.setRetryTemplate(rabbitRetryTemplate()); rabbitTemplate.setRetryTemplate(rabbitRetryTemplate());
//CorrelationData correlationData, boolean b, String s //CorrelationData correlationData, boolean b, String s
rabbitTemplate.setConfirmCallback((correlationData, b, s) -> { rabbitTemplate.setConfirmCallback((correlationData, b, s) -> {
System.out.println("ConfirmCallback " + "相关数据:" + correlationData); log.info("ConfirmCallback " + "相关数据:{}", correlationData);
System.out.println("ConfirmCallback " + "确认情况:" + b); log.info("ConfirmCallback " + "确认情况:{}", b);
System.out.println("ConfirmCallback " + "原因:" + s); log.info("ConfirmCallback " + "原因:{}", s);
}); });
//Message message, int i, String s, String s1, String s2 //Message message, int i, String s, String s1, String s2
rabbitTemplate.setReturnCallback((message, i, s, s1, s2) -> { rabbitTemplate.setReturnCallback((message, i, s, s1, s2) -> {
System.out.println("ReturnCallback " + "消息:" + message); log.info("ReturnCallback " + "消息:{}", message);
System.out.println("ReturnCallback " + "回应码:" + i); log.info("ReturnCallback " + "回应码:{}", i);
System.out.println("ReturnCallback " + "回应消息:" + s); log.info("ReturnCallback " + "回应消息:{}", s);
System.out.println("ReturnCallback " + "交换机:" + s1); log.info("ReturnCallback " + "交换机:{}", s1);
System.out.println("ReturnCallback " + "路由键:" + s2); log.info("ReturnCallback " + "路由键:{}", s2);
}); });
return rabbitTemplate; return rabbitTemplate;
@ -131,15 +133,13 @@ public class RabbitConfig {
@Override @Override
public <T, E extends Throwable> void close(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) { public <T, E extends Throwable> void close(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) {
// 重试结束的时候调用 (最后一次重试 ) // 重试结束的时候调用 (最后一次重试 )
System.out.println("---------------最后一次调用"); log.info("---------------最后一次调用");
return;
} }
@Override @Override
public <T, E extends Throwable> void onError(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) { public <T, E extends Throwable> void onError(RetryContext retryContext, RetryCallback<T, E> retryCallback, Throwable throwable) {
// 异常 都会调用 // 异常 都会调用
System.err.println("-----第{}次调用" + retryContext.getRetryCount()); log.info("-----第{}次调用", retryContext.getRetryCount());
} }
}); });
retryTemplate.setBackOffPolicy(backOffPolicyByProperties()); retryTemplate.setBackOffPolicy(backOffPolicyByProperties());

14
lzbi-common/src/main/java/com/lzbi/common/constant/BizConstants.java

@ -9,22 +9,26 @@ public interface BizConstants {
* 报表记录状态 * 报表记录状态
*/ */
interface ReportRecordStatus { interface ReportRecordStatus {
/**
* 待处理
*/
String PENDING = "0";
/** /**
* 准备数据 * 准备数据
*/ */
String PREPARE_DATA = "0"; String PREPARE_DATA = "1";
/** /**
* 未下载 * 未下载
*/ */
String NOT_DOWNLOAD = "1"; String NOT_DOWNLOAD = "2";
/** /**
* 已下载 * 已下载
*/ */
String DOWNLOADED = "2"; String DOWNLOADED = "3";
/** /**
* 导出失败 * 发生错误
*/ */
String ERROR = "3"; String ERROR = "4";
} }
/** /**

10
lzbi-common/src/main/java/com/lzbi/common/constant/CacheConstants.java

@ -46,6 +46,12 @@ public class CacheConstants
public static final String PATROL_SYS_ROUTE_TREE = "ROUTE_TREE"; public static final String PATROL_SYS_ROUTE_TREE = "ROUTE_TREE";
public static final String PATROL_SYS_ALARM_MAP = "ALARM_MAP"; public static final String PATROL_SYS_ALARM_MAP = "ALARM_MAP";
public static final String PATROL_SYS_TOKEN = "TOKEN:"; public static final String PATROL_SYS_TOKEN = "TOKEN:";
/**
* RabbitMQ 幂等性Key
*/
public static final String RABBITMQ_IDEMPOTENT_KEY = "RABBITMQ_IDEMPOTENT_KEY:";
/**
* 报表编号生成 redis key
*/
public static final String REPORT_CODE_GENERATE_KEY = "REPORT_CODE_GENERATE";
} }

4
lzbi-common/src/main/java/com/lzbi/common/core/redis/RedisCache.java

@ -265,4 +265,8 @@ public class RedisCache
{ {
return redisTemplate.keys(pattern); return redisTemplate.keys(pattern);
} }
public long incr(final String key, final long delta) {
return redisTemplate.opsForValue().increment(key, delta);
}
} }

9
lzbi-module/src/main/java/com/lzbi/bi/controller/DcBusiHisReportController.java

@ -191,8 +191,7 @@ public class DcBusiHisReportController extends BaseController {
@PreAuthorize("@ss.hasPermi('report:iot:export')") @PreAuthorize("@ss.hasPermi('report:iot:export')")
@PostMapping("/export") @PostMapping("/export")
public AjaxResult export(@Validated @RequestBody LogTimeThreeQueryParamVo queryVo) { public AjaxResult export(@Validated @RequestBody LogTimeThreeQueryParamVo queryVo) {
LoginUser loginUser = SecurityUtils.getLoginUser(); logTimesacleHistoryThreeService.exportDataReport(queryVo, 2);
logTimesacleHistoryThreeService.exportDataReport(queryVo, 2, loginUser);
return AjaxResult.success(); return AjaxResult.success();
} }
@ -200,8 +199,7 @@ public class DcBusiHisReportController extends BaseController {
@PreAuthorize("@ss.hasPermi('report:iot:export')") @PreAuthorize("@ss.hasPermi('report:iot:export')")
@PostMapping("/export2") @PostMapping("/export2")
public AjaxResult export2(@Validated @RequestBody LogTimeThreeQueryParamVo queryVo) { public AjaxResult export2(@Validated @RequestBody LogTimeThreeQueryParamVo queryVo) {
LoginUser loginUser = SecurityUtils.getLoginUser(); logTimesacleHistoryThreeService.exportDataReport(queryVo, 1);
logTimesacleHistoryThreeService.exportDataReport(queryVo, 1, loginUser);
return AjaxResult.success(); return AjaxResult.success();
} }
@ -237,8 +235,7 @@ public class DcBusiHisReportController extends BaseController {
@PreAuthorize("@ss.hasPermi('report:iot:export')") @PreAuthorize("@ss.hasPermi('report:iot:export')")
@PostMapping("/exportWeather") @PostMapping("/exportWeather")
public AjaxResult exportWeather(@Validated @RequestBody ExportWeatherReq exportWeatherReq) throws IOException { public AjaxResult exportWeather(@Validated @RequestBody ExportWeatherReq exportWeatherReq) throws IOException {
LoginUser loginUser = SecurityUtils.getLoginUser(); logTimesacleHistoryThreeService.exportWeather(exportWeatherReq);
logTimesacleHistoryThreeService.exportWeather(exportWeatherReq, loginUser);
return AjaxResult.success(); return AjaxResult.success();
} }
} }

57
lzbi-module/src/main/java/com/lzbi/code/service/LogTimesacleHistoryThreeService.java

@ -6,6 +6,7 @@ import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.BigExcelWriter; import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson2.JSONArray; import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.extension.service.IService; import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
@ -40,9 +41,6 @@ import java.util.stream.Collectors;
@Service @Service
public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThreeMapper, LogTimescaleHistoryThreeVo> implements IService<LogTimescaleHistoryThreeVo> { public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThreeMapper, LogTimescaleHistoryThreeVo> implements IService<LogTimescaleHistoryThreeVo> {
@Value("${reportFilePath}")
private String reportFilePath;
@Autowired @Autowired
private DcBusiReportRecordService dcBusiReportRecordService; private DcBusiReportRecordService dcBusiReportRecordService;
@ -88,7 +86,7 @@ public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThr
return list; return list;
} }
public void exportDataReport(LogTimeThreeQueryParamVo queryVo, int type, LoginUser loginUser) { public void exportDataReport(LogTimeThreeQueryParamVo queryVo, int type) {
String fileName = "生产数据统计报表_"; String fileName = "生产数据统计报表_";
if (type == 1) { if (type == 1) {
fileName += "设备列格式_"; fileName += "设备列格式_";
@ -97,13 +95,22 @@ public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThr
} }
fileName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); fileName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
fileName += ".xlsx"; fileName += ".xlsx";
JSONArray params = new JSONArray();
params.add(queryVo);
params.add(type);
// 新增报表记录 // 新增报表记录
saveReportRecord(fileName, loginUser); saveReportRecord(fileName, "logTimesacleHistoryThreeService", "getExcelData", params.toJSONString());
} }
//获取excel数据 1 excel设备参数为列模式 2 excel时间为列模式 3 浏览器设备参数为列模式 //获取excel数据 1 excel设备参数为列模式 2 excel时间为列模式 3 浏览器设备参数为列模式
//注意 excel有最大列数显示255 ,超出列数会报错 //注意 excel有最大列数显示255 ,超出列数会报错
public List<Map<String, Object>> getExcellData(DcBusiReportRecord dcBusiReportRecord, LogTimeThreeQueryParamVo queryVo, int type) { public List<Map<String, Object>> getExcelData(String params) {
if (null == params) {
return new ArrayList<>();
}
JSONArray jsonArray = JSONArray.parseArray(params);
LogTimeThreeQueryParamVo queryVo = jsonArray.getObject(0, LogTimeThreeQueryParamVo.class);
int type = jsonArray.getInteger(1);
List<Map<String, Object>> excelData; List<Map<String, Object>> excelData;
// 设置头部数据 // 设置头部数据
DcDymicHeaderQueryVo dcDymicHeaderQueryVo = new DcDymicHeaderQueryVo(); DcDymicHeaderQueryVo dcDymicHeaderQueryVo = new DcDymicHeaderQueryVo();
@ -128,13 +135,13 @@ public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThr
* @param fileName 文件名称 * @param fileName 文件名称
* @return * @return
*/ */
private DcBusiReportRecord saveReportRecord(String fileName, LoginUser loginUser) { private DcBusiReportRecord saveReportRecord(String fileName, String beanName, String methodName, String params) {
DcBusiReportRecord record = new DcBusiReportRecord(); DcBusiReportRecord record = new DcBusiReportRecord();
record.setReportName(fileName); record.setReportName(fileName);
record.setStatus(BizConstants.ReportRecordStatus.PREPARE_DATA); record.setStatus(BizConstants.ReportRecordStatus.PENDING);
record.setCreatedTime(new Date()); record.setBeanName(beanName);
record.setCreatedBy(loginUser.getUsername()); record.setMethodName(methodName);
record.setDeptId(loginUser.getDeptId()); record.setParams(params);
dcBusiReportRecordService.insertDcBusiReportRecord(record); dcBusiReportRecordService.insertDcBusiReportRecord(record);
return record; return record;
} }
@ -197,13 +204,22 @@ public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThr
return baseMapper.getWeatherReport(exportWeatherReq); return baseMapper.getWeatherReport(exportWeatherReq);
} }
@Async public void exportWeather(ExportWeatherReq exportWeatherReq) {
public void exportWeather(ExportWeatherReq exportWeatherReq, LoginUser loginUser) {
String fileName = "天气统计报表_"; String fileName = "天气统计报表_";
fileName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")); fileName += LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
fileName += ".xlsx"; fileName += ".xlsx";
JSONArray params = new JSONArray();
params.add(exportWeatherReq);
// 新增报表记录 // 新增报表记录
DcBusiReportRecord dcBusiReportRecord = saveReportRecord(fileName, loginUser); saveReportRecord(fileName, "logTimesacleHistoryThreeService", "getExportWeatherData", params.toJSONString());
}
public List<Map<String, Object>> getExportWeatherData(String params) {
if (null == params) {
return new ArrayList<>();
}
JSONArray jsonArray = JSONArray.parseArray(params);
ExportWeatherReq exportWeatherReq = jsonArray.getObject(0, ExportWeatherReq.class);
List<WeatherReportVO> weatherReportList = baseMapper.getWeatherReport(exportWeatherReq); List<WeatherReportVO> weatherReportList = baseMapper.getWeatherReport(exportWeatherReq);
List<Map<String, Object>> excelData; List<Map<String, Object>> excelData;
if (CollectionUtils.isEmpty(weatherReportList)) { if (CollectionUtils.isEmpty(weatherReportList)) {
@ -224,17 +240,6 @@ public class LogTimesacleHistoryThreeService extends ServiceImpl<LogTimeScaleThr
return map; return map;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
} }
// try { return excelData;
//
// toExcel(dcBusiReportRecord, excelData);
// // 更新报表记录
// dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.NOT_DOWNLOAD);
// dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord);
// } catch (IOException e) {
// log.error("导出数据异常", e);
// // 更新报表记录
// dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.ERROR);
// dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord);
// }
} }
} }

4
lzbi-common/src/main/java/com/lzbi/common/config/ReportExportRabbitConfig.java → lzbi-module/src/main/java/com/lzbi/rabbit/config/ReportExportRabbitConfig.java

@ -1,4 +1,4 @@
package com.lzbi.common.config; package com.lzbi.rabbit.config;
import org.springframework.amqp.core.Binding; import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder; import org.springframework.amqp.core.BindingBuilder;
@ -32,6 +32,6 @@ public class ReportExportRabbitConfig {
@Bean @Bean
public Binding bindingDirect() { public Binding bindingDirect() {
//bind队列to交换机中with路由key(routing key) //bind队列to交换机中with路由key(routing key)
return BindingBuilder.bind(ReportExportDirectQueue()).to(ReportExportDirectExchange()).with("123"); return BindingBuilder.bind(ReportExportDirectQueue()).to(ReportExportDirectExchange()).with("bigdata.report.export");
} }
} }

4
lzbi-module/src/main/java/com/lzbi/rabbit/consumer/IConsumerService.java

@ -3,9 +3,9 @@ package com.lzbi.rabbit.consumer;
import com.rabbitmq.client.Channel; import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message; import org.springframework.amqp.core.Message;
public interface IConsumerService { public interface IConsumerService<T> {
void process(Object msg, Channel channel, Message message); void process(T msg, Channel channel, Message message);
void business(Object msg); void business(Object msg);
} }

117
lzbi-module/src/main/java/com/lzbi/rabbit/consumer/impl/ReportExportConsumer.java

@ -3,7 +3,11 @@ package com.lzbi.rabbit.consumer.impl;
import cn.hutool.core.io.IoUtil; import cn.hutool.core.io.IoUtil;
import cn.hutool.poi.excel.BigExcelWriter; import cn.hutool.poi.excel.BigExcelWriter;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.fastjson2.JSONArray;
import com.lzbi.common.constant.BizConstants; import com.lzbi.common.constant.BizConstants;
import com.lzbi.common.constant.CacheConstants;
import com.lzbi.common.core.redis.RedisCache;
import com.lzbi.common.utils.spring.SpringUtils;
import com.lzbi.rabbit.consumer.IConsumerService; import com.lzbi.rabbit.consumer.IConsumerService;
import com.lzbi.report.domain.DcBusiReportRecord; import com.lzbi.report.domain.DcBusiReportRecord;
import com.lzbi.report.service.DcBusiReportRecordService; import com.lzbi.report.service.DcBusiReportRecordService;
@ -13,30 +17,47 @@ import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler; import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
@Slf4j @Slf4j
@RabbitListener(queues = "ReportExportDirectQueue") @RabbitListener(queues = "ReportExportDirectQueue")
@Component @Component
public class ReportExportConsumer implements IConsumerService { public class ReportExportConsumer implements IConsumerService<Long> {
@Value("${reportFilePath}")
private String reportFilePath;
@Autowired @Autowired
private DcBusiReportRecordService dcBusiReportRecordService; private DcBusiReportRecordService dcBusiReportRecordService;
@Autowired
private RedisCache redisCache;
@RabbitHandler @RabbitHandler
@Override @Override
public void process(Object msg, Channel channel, Message message) { public void process(Long msg, Channel channel, Message message) {
log.info("收到消息:{}", msg); log.info("收到消息:【{}】,{}", msg, message);
try { try {
String key = CacheConstants.RABBITMQ_IDEMPOTENT_KEY + msg;
// 防止重复消费
if (!redisCache.hasKey(key)) {
// 业务处理
this.business(msg); this.business(msg);
redisCache.setCacheObject(key, msg, 1, TimeUnit.HOURS);
}
//由于配置设置了手动应答,所以这里要进行一个手动应答。注意:如果设置了自动应答,这里又进行手动应答,会出现double ack,那么程序会报错。 //由于配置设置了手动应答,所以这里要进行一个手动应答。注意:如果设置了自动应答,这里又进行手动应答,会出现double ack,那么程序会报错。
channel.basicAck(message.getMessageProperties().getDeliveryTag(), false); channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
} catch (IOException e) { } catch (IOException e) {
@ -48,34 +69,72 @@ public class ReportExportConsumer implements IConsumerService {
public void business(Object msg) { public void business(Object msg) {
Long reportRecordId = (Long) msg; Long reportRecordId = (Long) msg;
DcBusiReportRecord dcBusiReportRecord = dcBusiReportRecordService.selectDcBusiReportRecordById(reportRecordId); DcBusiReportRecord dcBusiReportRecord = dcBusiReportRecordService.selectDcBusiReportRecordById(reportRecordId);
// try { // 判断报表记录状态是否为待处理或发生错误
// if (BizConstants.ReportRecordStatus.PENDING.equals(dcBusiReportRecord.getStatus()) || BizConstants.ReportRecordStatus.ERROR.equals(dcBusiReportRecord.getStatus())) {
// // 更新报表记录 // 更新报表记录状态为准备数据
// dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.NOT_DOWNLOAD); dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.PREPARE_DATA);
// dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord); dcBusiReportRecord.setUpdatedBy("rabbitmq");
// } catch (IOException e) { dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord);
// log.error("导出数据异常", e); try {
// // 更新报表记录 // 获取数据
// dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.ERROR); List<Map<String, Object>> reportData = this.getReportData(dcBusiReportRecord);
// dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord); log.debug("报表数据:{}", JSONArray.toJSONString(reportData));
// } // 导出excel
toExcel(dcBusiReportRecord, reportData);
// 更新报表记录未下载
dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.NOT_DOWNLOAD);
dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord);
} catch (Exception e) {
log.error("导出数据异常", e);
// 更新报表发生错误
dcBusiReportRecord.setStatus(BizConstants.ReportRecordStatus.ERROR);
dcBusiReportRecordService.updateDcBusiReportRecord(dcBusiReportRecord);
}
}
} }
/**
* 获取报表数据
* @param dcBusiReportRecord
* @return
* @throws NoSuchMethodException
* @throws InvocationTargetException
* @throws IllegalAccessException
*/
private List<Map<String, Object>> getReportData(DcBusiReportRecord dcBusiReportRecord) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
String beanName = dcBusiReportRecord.getBeanName();
String methodName = dcBusiReportRecord.getMethodName();
String params = dcBusiReportRecord.getParams();
log.info("获取报表数据,beanName:{},methodName:{},params:{}", beanName, methodName, params);
Object bean = SpringUtils.getBean(beanName);
Method method = bean.getClass().getMethod(methodName, String.class);
Object data = method.invoke(bean, params);
if (null == data) {
return new ArrayList<>();
} else {
return (List<Map<String, Object>>) data;
}
}
/**
// private void toExcel(DcBusiReportRecord dcBusiReportRecord, List<Map<String, Object>> mapList) throws IOException { * 导出excel
// Path folder = Paths.get(reportFilePath); * @param dcBusiReportRecord
// if (!Files.exists(folder)) { * @param reportData
// Files.createDirectories(folder); * @throws IOException
// } */
// OutputStream out = Files.newOutputStream(Paths.get(dcBusiReportRecord.getUrl())); private void toExcel(DcBusiReportRecord dcBusiReportRecord, List<Map<String, Object>> reportData) throws IOException {
// BigExcelWriter writer = ExcelUtil.getBigWriter(); Path folder = Paths.get(reportFilePath);
// writer.write(mapList, true); if (!Files.exists(folder)) {
// writer.flush(out, true); Files.createDirectories(folder);
// // 关闭writer,释放内存 }
// writer.close(); OutputStream out = Files.newOutputStream(Paths.get(dcBusiReportRecord.getUrl()));
// //此处记得关闭输出流 BigExcelWriter writer = ExcelUtil.getBigWriter();
// IoUtil.close(out); writer.write(reportData, true);
// } writer.flush(out, true);
// 关闭writer,释放内存
writer.close();
//此处记得关闭输出流
IoUtil.close(out);
}
} }

7
lzbi-module/src/main/java/com/lzbi/rabbit/producer/ReportExportProducer.java

@ -1,5 +1,7 @@
package com.lzbi.rabbit.producer; package com.lzbi.rabbit.producer;
import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.connection.CorrelationData; import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate; import org.springframework.amqp.rabbit.core.RabbitTemplate;
@ -15,11 +17,14 @@ import java.util.UUID;
@Component @Component
public class ReportExportProducer { public class ReportExportProducer {
// 雪花算法
private static final Snowflake snowflake = IdUtil.getSnowflake(1, 4);
@Autowired @Autowired
private RabbitTemplate rabbitTemplate; private RabbitTemplate rabbitTemplate;
public void sendMsg(Long reportRecordId) { public void sendMsg(Long reportRecordId) {
log.info("发送消息,导出报表,报表记录id:{}", reportRecordId); log.info("发送消息,导出报表,报表记录id:{}", reportRecordId);
rabbitTemplate.convertAndSend("ReportExportDirectExchange", "123", reportRecordId, new CorrelationData(UUID.randomUUID().toString())); rabbitTemplate.convertAndSend("ReportExportDirectExchange", "bigdata.report.export", reportRecordId, new CorrelationData(snowflake.nextIdStr()));
} }
} }

20
lzbi-module/src/main/java/com/lzbi/report/domain/DcBusiReportRecord.java

@ -29,6 +29,11 @@ public class DcBusiReportRecord extends BaseModuleEntity
@TableId(type = IdType.AUTO) @TableId(type = IdType.AUTO)
private Long id; private Long id;
/** 报表编号 */
@Excel(name = "报表编号")
@ApiModelProperty(name = "报表编号",notes = "reportCode")
private String reportCode;
/** 报表名称 */ /** 报表名称 */
@Excel(name = "报表名称") @Excel(name = "报表名称")
@ApiModelProperty(name = "报表名称",notes = "reportName") @ApiModelProperty(name = "报表名称",notes = "reportName")
@ -44,6 +49,21 @@ public class DcBusiReportRecord extends BaseModuleEntity
@ApiModelProperty(name = "状态 0准备数据 1未下载 2已下载",notes = "status") @ApiModelProperty(name = "状态 0准备数据 1未下载 2已下载",notes = "status")
private String status; private String status;
/** spring bean 名称 */
@Excel(name = "spring bean 名称")
@ApiModelProperty(name = "spring bean 名称",notes = "beanName")
private String beanName;
/** 方法名称 */
@Excel(name = "方法名称")
@ApiModelProperty(name = "方法名称",notes = "methodName")
private String methodName;
/** 参数(格式:jsonArray) */
@Excel(name = "参数", readConverterExp = "格=式:jsonArray")
@ApiModelProperty(name = "参数",notes = "")
private String params;
/** 部门ID */ /** 部门ID */
@Excel(name = "部门ID") @Excel(name = "部门ID")
@ApiModelProperty(name = "部门ID",notes = "deptId") @ApiModelProperty(name = "部门ID",notes = "deptId")

42
lzbi-module/src/main/java/com/lzbi/report/service/DcBusiReportRecordService.java

@ -1,26 +1,34 @@
package com.lzbi.report.service; package com.lzbi.report.service;
import java.io.*;
import java.nio.file.Files;
import java.util.Arrays;
import java.util.List;
import cn.hutool.core.lang.Snowflake; import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lzbi.common.constant.BizConstants; import com.lzbi.common.constant.BizConstants;
import com.lzbi.common.constant.CacheConstants;
import com.lzbi.common.core.redis.RedisCache;
import com.lzbi.common.utils.SecurityUtils;
import com.lzbi.rabbit.producer.ReportExportProducer; import com.lzbi.rabbit.producer.ReportExportProducer;
import com.lzbi.report.domain.DcBusiReportRecord;
import com.lzbi.report.mapper.DcBusiReportRecordMapper;
import org.apache.commons.compress.utils.IOUtils; import org.apache.commons.compress.utils.IOUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.lzbi.report.domain.DcBusiReportRecord;
import com.lzbi.report.mapper.DcBusiReportRecordMapper;
import com.baomidou.mybatisplus.extension.service.IService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils; import org.springframework.util.CollectionUtils;
import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;
/** /**
* 报表记录Service业务层处理 * 报表记录Service业务层处理
@ -41,6 +49,9 @@ public class DcBusiReportRecordService extends ServiceImpl<DcBusiReportRecordMap
@Autowired @Autowired
private ReportExportProducer reportExportProducer; private ReportExportProducer reportExportProducer;
@Autowired
private RedisCache redisCache;
/** /**
* 查询报表记录 * 查询报表记录
* *
@ -73,12 +84,24 @@ public class DcBusiReportRecordService extends ServiceImpl<DcBusiReportRecordMap
{ {
String url = reportFilePath + "/" + snowflake.nextId(); String url = reportFilePath + "/" + snowflake.nextId();
dcBusiReportRecord.setUrl(url); dcBusiReportRecord.setUrl(url);
dcBusiReportRecord.setReportCode(this.generateReportCode());
dcBusiReportRecord.setCreatedTime(new Date());
dcBusiReportRecord.setCreatedBy(SecurityUtils.getUsername());
dcBusiReportRecord.setDeptId(SecurityUtils.getDeptId());
int count = baseMapper.insert(dcBusiReportRecord); int count = baseMapper.insert(dcBusiReportRecord);
// 推送 // 推送
reportExportProducer.sendMsg(dcBusiReportRecord.getId()); reportExportProducer.sendMsg(dcBusiReportRecord.getId());
return count; return count;
} }
private String generateReportCode() {
if (!redisCache.hasKey(CacheConstants.REPORT_CODE_GENERATE_KEY)) {
redisCache.setCacheObject(CacheConstants.REPORT_CODE_GENERATE_KEY, 0, 1, TimeUnit.DAYS);
}
long number = redisCache.incr(CacheConstants.REPORT_CODE_GENERATE_KEY, 1);
return String.format("%s%04d", LocalDate.now().format(DateTimeFormatter.ofPattern("yyyyMMdd")), number);
}
/** /**
* 修改报表记录 * 修改报表记录
* *
@ -88,6 +111,7 @@ public class DcBusiReportRecordService extends ServiceImpl<DcBusiReportRecordMap
public int updateDcBusiReportRecord(DcBusiReportRecord dcBusiReportRecord) public int updateDcBusiReportRecord(DcBusiReportRecord dcBusiReportRecord)
{ {
dcBusiReportRecord.setUpdatedTime(new Date());
return baseMapper.updateDcBusiReportRecord(dcBusiReportRecord); return baseMapper.updateDcBusiReportRecord(dcBusiReportRecord);
} }

57
lzbi-module/src/main/resources/mapper/report/DcBusiReportRecordMapper.xml

@ -6,29 +6,39 @@
<resultMap type="com.lzbi.report.domain.DcBusiReportRecord" id="DcBusiReportRecordResult"> <resultMap type="com.lzbi.report.domain.DcBusiReportRecord" id="DcBusiReportRecordResult">
<result property="id" column="id" /> <result property="id" column="id" />
<result property="reportCode" column="report_code" />
<result property="reportName" column="report_name" /> <result property="reportName" column="report_name" />
<result property="url" column="url" /> <result property="url" column="url" />
<result property="status" column="status" /> <result property="status" column="status" />
<result property="beanName" column="bean_name" />
<result property="methodName" column="method_name" />
<result property="params" column="params" />
<result property="deptId" column="dept_id" /> <result property="deptId" column="dept_id" />
<result property="createdBy" column="created_by" /> <result property="createdBy" column="created_by" />
<result property="createdTime" column="created_time" /> <result property="createdTime" column="created_time" />
<result property="updatedBy" column="updated_by" /> <result property="updatedBy" column="updated_by" />
<result property="updatedTime" column="updated_time" /> <result property="updatedTime" column="updated_time" />
<result property="remark" column="remark" /> <result property="remark" column="remark" />
<result property="deptName" column="dept_name" /> <result property="deleteBy" column="delete_by" />
<result property="nickName" column="nick_name" /> <result property="deleteTime" column="delete_time" />
<result property="tenantId" column="tenant_id" />
<result property="revision" column="revision" />
</resultMap> </resultMap>
<sql id="selectDcBusiReportRecordVo"> <sql id="selectDcBusiReportRecordVo">
select id, report_name, url, status, dept_id, created_by, created_time, updated_by, updated_time, remark from dc_busi_report_record select id, report_code, report_name, url, status, bean_name, method_name, params, dept_id, created_by, created_time, updated_by, updated_time, remark, delete_by, delete_time, tenant_id, revision from dc_busi_report_record
</sql> </sql>
<select id="selectDcBusiReportRecordList" parameterType="DcBusiReportRecord" resultMap="DcBusiReportRecordResult"> <select id="selectDcBusiReportRecordList" parameterType="DcBusiReportRecord" resultMap="DcBusiReportRecordResult">
select select
t1.id, t1.id,
t1.report_code,
t1.report_name, t1.report_name,
t1.url, t1.url,
t1.status, t1.status,
t1.bean_name,
t1.method_name,
t1.params,
t1.dept_id, t1.dept_id,
t1.created_by, t1.created_by,
t1.created_time, t1.created_time,
@ -39,16 +49,11 @@
t3.nick_name t3.nick_name
from from
dc_busi_report_record t1 dc_busi_report_record t1
left join left join sys_dept t2 on t1.dept_id = t2.dept_id
sys_dept t2 left join sys_user t3 on t1.created_by = t3.user_name
on
t1.dept_id = t2.dept_id
left join
sys_user t3
on
t1.created_by = t3.user_name
<where> <where>
<if test="status != null and status != ''"> and t1.status = #{status}</if> <if test="status != null and status != ''"> and t1.status = #{status}</if>
<if test="reportCode != null and reportCode != ''"> and t1.report_code = #{reportCode}</if>
<if test="reportName != null and reportName != ''"> and t1.report_name like concat(#{reportName}, '%')</if> <if test="reportName != null and reportName != ''"> and t1.report_name like concat(#{reportName}, '%')</if>
<if test="nickName != null and nickName != ''"> and t3.nick_name like concat(#{nickName}, '%')</if> <if test="nickName != null and nickName != ''"> and t3.nick_name like concat(#{nickName}, '%')</if>
</where> </where>
@ -65,42 +70,66 @@
insert into dc_busi_report_record insert into dc_busi_report_record
<trim prefix="(" suffix=")" suffixOverrides=","> <trim prefix="(" suffix=")" suffixOverrides=",">
<if test="id != null">id,</if> <if test="id != null">id,</if>
<if test="reportCode != null and reportCode != ''">report_code,</if>
<if test="reportName != null and reportName != ''">report_name,</if> <if test="reportName != null and reportName != ''">report_name,</if>
<if test="url != null and url != ''">url,</if> <if test="url != null and url != ''">url,</if>
<if test="status != null">status,</if> <if test="status != null and status != ''">status,</if>
<if test="beanName != null">bean_name,</if>
<if test="methodName != null">method_name,</if>
<if test="params != null">params,</if>
<if test="deptId != null">dept_id,</if> <if test="deptId != null">dept_id,</if>
<if test="createdBy != null">created_by,</if> <if test="createdBy != null">created_by,</if>
<if test="createdTime != null">created_time,</if> <if test="createdTime != null">created_time,</if>
<if test="updatedBy != null">updated_by,</if> <if test="updatedBy != null">updated_by,</if>
<if test="updatedTime != null">updated_time,</if> <if test="updatedTime != null">updated_time,</if>
<if test="remark != null">remark,</if> <if test="remark != null">remark,</if>
<if test="deleteBy != null">delete_by,</if>
<if test="deleteTime != null">delete_time,</if>
<if test="tenantId != null">tenant_id,</if>
<if test="revision != null">revision,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
<if test="reportCode != null and reportCode != ''">#{reportCode},</if>
<if test="reportName != null and reportName != ''">#{reportName},</if> <if test="reportName != null and reportName != ''">#{reportName},</if>
<if test="url != null and url != ''">#{url},</if> <if test="url != null and url != ''">#{url},</if>
<if test="status != null">#{status},</if> <if test="status != null and status != ''">#{status},</if>
<if test="beanName != null">#{beanName},</if>
<if test="methodName != null">#{methodName},</if>
<if test="params != null">#{params},</if>
<if test="deptId != null">#{deptId},</if> <if test="deptId != null">#{deptId},</if>
<if test="createdBy != null">#{createdBy},</if> <if test="createdBy != null">#{createdBy},</if>
<if test="createdTime != null">#{createdTime},</if> <if test="createdTime != null">#{createdTime},</if>
<if test="updatedBy != null">#{updatedBy},</if> <if test="updatedBy != null">#{updatedBy},</if>
<if test="updatedTime != null">#{updatedTime},</if> <if test="updatedTime != null">#{updatedTime},</if>
<if test="remark != null">#{remark},</if> <if test="remark != null">#{remark},</if>
<if test="deleteBy != null">#{deleteBy},</if>
<if test="deleteTime != null">#{deleteTime},</if>
<if test="tenantId != null">#{tenantId},</if>
<if test="revision != null">#{revision},</if>
</trim> </trim>
</insert> </insert>
<update id="updateDcBusiReportRecord" parameterType="DcBusiReportRecord"> <update id="updateDcBusiReportRecord" parameterType="DcBusiReportRecord">
update dc_busi_report_record update dc_busi_report_record
<trim prefix="SET" suffixOverrides=","> <trim prefix="SET" suffixOverrides=",">
<if test="reportCode != null and reportCode != ''">report_code = #{reportCode},</if>
<if test="reportName != null and reportName != ''">report_name = #{reportName},</if> <if test="reportName != null and reportName != ''">report_name = #{reportName},</if>
<if test="url != null and url != ''">url = #{url},</if> <if test="url != null and url != ''">url = #{url},</if>
<if test="status != null">status = #{status},</if> <if test="status != null and status != ''">status = #{status},</if>
<if test="beanName != null">bean_name = #{beanName},</if>
<if test="methodName != null">method_name = #{methodName},</if>
<if test="params != null">params = #{params},</if>
<if test="deptId != null">dept_id = #{deptId},</if> <if test="deptId != null">dept_id = #{deptId},</if>
<if test="createdBy != null">created_by = #{createdBy},</if> <if test="createdBy != null">created_by = #{createdBy},</if>
<if test="createdTime != null">created_time = #{createdTime},</if> <if test="createdTime != null">created_time = #{createdTime},</if>
<if test="updatedBy != null">updated_by = #{updatedBy},</if> <if test="updatedBy != null">updated_by = #{updatedBy},</if>
<if test="updatedTime != null">updated_time = #{updatedTime},</if> <if test="updatedTime != null">updated_time = #{updatedTime},</if>
<if test="remark != null">remark = #{remark},</if> <if test="remark != null">remark = #{remark},</if>
<if test="deleteBy != null">delete_by = #{deleteBy},</if>
<if test="deleteTime != null">delete_time = #{deleteTime},</if>
<if test="tenantId != null">tenant_id = #{tenantId},</if>
<if test="revision != null">revision = #{revision},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>

Loading…
Cancel
Save