@@ -12,7 +12,6 @@ import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil ;
import cn.hutool.core.util.ZipUtil ;
import cn.hutool.extra.spring.SpringUtil ;
import cn.hutool.json.JSONConfig ;
import cn.hutool.json.JSONUtil ;
import com.baomidou.mybatisplus.core.conditions.Wrapper ;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper ;
@@ -23,7 +22,6 @@ import com.njcn.common.pojo.enums.common.DataStateEnum;
import com.njcn.common.pojo.enums.response.CommonResponseEnum ;
import com.njcn.common.pojo.exception.BusinessException ;
import com.njcn.common.pojo.poi.PullDown ;
import com.njcn.gather.detection.pojo.po.AdPair ;
import com.njcn.gather.detection.service.IAdPariService ;
import com.njcn.gather.device.mapper.PqDevMapper ;
import com.njcn.gather.device.pojo.enums.* ;
@@ -80,7 +78,6 @@ import com.njcn.gather.system.dictionary.pojo.po.DictType;
import com.njcn.gather.system.dictionary.service.IDictDataService ;
import com.njcn.gather.system.dictionary.service.IDictTreeService ;
import com.njcn.gather.system.dictionary.service.IDictTypeService ;
import com.njcn.gather.tools.report.model.constant.ReportConstant ;
import com.njcn.gather.type.pojo.po.DevType ;
import com.njcn.gather.type.service.IDevTypeService ;
import com.njcn.gather.user.user.pojo.po.SysUser ;
@@ -1883,166 +1880,6 @@ public class AdPlanServiceImpl extends ServiceImpl<AdPlanMapper, AdPlan> impleme
}
}
@Override
public void exportPlanCheckDataZip ( String planId , List < String > devIds , Integer report , HttpServletResponse response ) {
AdPlanCheckDataVO planCheckDataVO = new AdPlanCheckDataVO ( ) ;
// 获取检测计划基本数据
AdPlan plan = this . getById ( planId ) ;
planCheckDataVO . setPlan ( plan ) ;
// 获取检测计划绑定的被检设备数据
List < PqDev > devList = pqDevService . list ( new LambdaQueryWrapper < PqDev > ( ) . eq ( PqDev : : getPlanId , planId ) . in ( PqDev : : getId , devIds ) ) ;
if ( CollUtil . isEmpty ( devList ) ) {
throw new BusinessException ( CommonResponseEnum . FAIL , " 选择的被检设备不存在 " ) ;
}
planCheckDataVO . setDevList ( devList ) ;
List < String > devIdList = devList . stream ( ) . map ( PqDev : : getId ) . collect ( Collectors . toList ( ) ) ;
// 被检设备状态统计
List < PqDevSub > devSubList = pqDevSubService . list ( new LambdaQueryWrapper < PqDevSub > ( ) . in ( PqDevSub : : getDevId , devIdList ) ) ;
planCheckDataVO . setDevSubList ( devSubList ) ;
// 被检设备监测点信息
List < PqMonitor > monitorList = pqMonitorService . list ( new LambdaQueryWrapper < PqMonitor > ( ) . in ( PqMonitor : : getDevId , devIdList ) ) ;
planCheckDataVO . setMonitorList ( monitorList ) ;
// devMonitorId = 被检设备ID+通道号
List < String > devMonitorIds = new ArrayList < > ( ) ;
for ( PqDev dev : devList ) {
List < String > channelNoList = StrUtil . split ( dev . getInspectChannel ( ) , StrUtil . COMMA ) ;
for ( String channelNo : channelNoList ) {
devMonitorIds . add ( dev . getId ( ) + StrUtil . UNDERLINE + channelNo ) ;
}
}
planCheckDataVO . setDevMonitorIds ( devMonitorIds ) ;
// 设备通道匹对关系
List < AdPair > pairList = adPairService . list ( new LambdaQueryWrapper < AdPair > ( ) . eq ( AdPair : : getPlanId , planId ) . in ( AdPair : : getDevMonitorId , devMonitorIds ) ) ;
planCheckDataVO . setPairList ( pairList ) ;
// 获取计划检测结果数据表以及数据
Integer code = plan . getCode ( ) ;
List < String > dataTableNames = CollUtil . newArrayList ( " ad_harmonic_ " + code , " ad_non_harmonic_ " + code , " ad_harmonic_result_ " + code , " ad_non_harmonic_result_ " + code ) ;
// 创建临时目录用于存储txt文件
File tempDataDir = FileUtil . mkdir ( FileUtil . getTmpDirPath ( ) + " plan_data_ " + System . currentTimeMillis ( ) + " / " ) ;
List < File > dataFiles = new ArrayList < > ( ) ;
int dataBatch = 0 ;
if ( CollUtil . isNotEmpty ( pairList ) ) {
for ( String dataTableName : dataTableNames ) {
// 创建数据文件
String fileName = dataTableName . replace ( " _ " + code , " " ) + " .txt " ;
File dataFile = FileUtil . file ( tempDataDir , fileName ) ;
// 确保文件存在
FileUtil . touch ( dataFile ) ;
// 初始化写入标志,用于判断是否已写入字段名
boolean isFirstWrite = true ;
// 分页查询,避免一次性加载大量数据
int pageSize = 10000 ; // 每页查询10000条记录
int offset = 0 ;
List < Map < String , Object > > pageData ;
do {
dataBatch + = 1 ;
String paginatedSql = buildPaginatedQuery ( dataTableName , devMonitorIds , pageSize , offset ) ;
pageData = jdbcTemplate . queryForList ( paginatedSql ) ;
// 将当前页数据追加到文件中
if ( CollUtil . isNotEmpty ( pageData ) ) {
StringBuilder content = new StringBuilder ( ) ;
// 如果是第一次写入,先写入字段名
if ( isFirstWrite ) {
// 获取字段名
Map < String , Object > firstRow = pageData . get ( 0 ) ;
List < String > fieldNames = new ArrayList < > ( firstRow . keySet ( ) ) ;
// 写入字段名作为第一行
content . append ( StrUtil . join ( " \ t " , fieldNames ) ) . append ( System . lineSeparator ( ) ) ;
isFirstWrite = false ;
}
// 写入数据行
for ( Map < String , Object > data : pageData ) {
List < Object > values = new ArrayList < > ( data . values ( ) ) ;
content . append ( StrUtil . join ( " \ t " , values ) ) . append ( System . lineSeparator ( ) ) ;
}
// 追加内容到文件
FileUtil . appendUtf8String ( content . toString ( ) , dataFile ) ;
}
offset + = pageSize ;
} while ( pageData . size ( ) = = pageSize ) ; // 如果查询结果少于pageSize, 说明已经查询完所有数据
// 如果文件存在且不为空,则添加到数据文件列表中
if ( FileUtil . exist ( dataFile ) & & FileUtil . size ( dataFile ) > 0 ) {
dataFiles . add ( dataFile ) ;
}
}
}
planCheckDataVO . setDataBatch ( dataBatch ) ;
// 导出数据.zip文件
String jsonStr = JSONUtil . toJsonStr ( planCheckDataVO , new JSONConfig ( ) . setIgnoreNullValue ( false ) ) ;
try {
// 创建临时目录
File tempDir = FileUtil . mkdir ( FileUtil . getTmpDirPath ( ) + " export_ " + System . currentTimeMillis ( ) + " / " ) ;
// 创建 JSON 文件
String jsonFileName = plan . getName ( ) + " .json " ;
File jsonFile = FileUtil . file ( tempDir , jsonFileName ) ;
FileUtil . writeUtf8String ( jsonStr , jsonFile ) ;
// 创建 ZIP 文件
String zipFileName = URLEncoder . encode ( plan . getName ( ) + " _检测数据.zip " , " UTF-8 " ) ;
File zipFile = FileUtil . file ( tempDir , zipFileName ) ;
// 创建一个临时目录存放所有文件
File tempZipDir = FileUtil . mkdir ( FileUtil . getTmpDirPath ( ) + " temp_plan_check_data_ " + System . currentTimeMillis ( ) + " / " ) ;
// 复制json文件到临时目录
FileUtil . copy ( jsonFile , tempZipDir , true ) ;
// 复制数据txt文件到临时目录
for ( File dataFile : dataFiles ) {
FileUtil . copy ( dataFile , tempZipDir , true ) ;
}
// 添加检测报告文件
if ( ObjectUtil . isNotNull ( report ) & & report . equals ( 1 ) ) {
for ( PqDev dev : devList ) {
DevType devType = devTypeService . getById ( dev . getDevType ( ) ) ;
String dirPath = reportPath . concat ( File . separator ) . concat ( devType . getName ( ) ) ;
File reportFile = new File ( dirPath . concat ( File . separator ) . concat ( dev . getCreateId ( ) ) . concat ( ReportConstant . DOCX ) ) ;
// 如果reportFile存在, 则将reportFile中的文件添加到已有的zip文件中
if ( FileUtil . exist ( reportFile ) ) {
// 复制reportFile到临时目录
FileUtil . copy ( reportFile , tempZipDir , true ) ;
}
}
}
// 重新创建zip文件, 包含所有文件
ZipUtil . zip ( tempZipDir . getAbsolutePath ( ) , zipFile . getAbsolutePath ( ) ) ;
// 删除临时目录
FileUtil . del ( tempZipDir ) ;
FileUtil . del ( tempDataDir ) ;
// 设置响应头
response . reset ( ) ;
response . setContentType ( " application/octet-stream;charset=UTF-8 " ) ;
response . setHeader ( " Content-Disposition " , " attachment; filename= \" " + zipFileName + " \" " ) ;
// 将 ZIP 文件写入响应
ServletOutputStream os = response . getOutputStream ( ) ;
FileUtil . writeToStream ( zipFile , os ) ;
os . flush ( ) ;
os . close ( ) ;
// 删除临时文件
FileUtil . del ( tempDir ) ;
} catch ( IOException e ) {
log . error ( " 导出计划检测数据.zip文件失败: " , e ) ;
throw new BusinessException ( CommonResponseEnum . FAIL ) ;
}
}
// 构建分页查询SQL
private String buildPaginatedQuery ( String tableName , List < String > devMonitorIds , int limit , int offset ) {
StringBuilder sql = new StringBuilder ( " SELECT * FROM " + tableName ) ;