Merge pull request 'develop' (#246) from develop into master
Reviewed-on: http://git.xdadan.loc/tanex/emis-service/pulls/246
This commit is contained in:
commit
f377b55361
@ -28,6 +28,7 @@ import com.xdadan.erp.emis.domain.exception.EmisBizError;
|
|||||||
import com.xdadan.erp.emis.domain.stat.BillPayStatInfo;
|
import com.xdadan.erp.emis.domain.stat.BillPayStatInfo;
|
||||||
import com.xdadan.erp.emis.domain.stat.OpenBillStatInfo;
|
import com.xdadan.erp.emis.domain.stat.OpenBillStatInfo;
|
||||||
import com.xdadan.erp.emis.domain.vo.AddressParseResult;
|
import com.xdadan.erp.emis.domain.vo.AddressParseResult;
|
||||||
|
import com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper;
|
||||||
import com.xdadan.erp.emis.service.*;
|
import com.xdadan.erp.emis.service.*;
|
||||||
import com.xdadan.erp.emis.service.kefu.RL7moorService;
|
import com.xdadan.erp.emis.service.kefu.RL7moorService;
|
||||||
import com.xdadan.erp.emis.service.print.IXddTplPrint;
|
import com.xdadan.erp.emis.service.print.IXddTplPrint;
|
||||||
@ -140,6 +141,9 @@ public class EmisCommonController extends EmisBaseController
|
|||||||
@Autowired
|
@Autowired
|
||||||
private IEmisTransLineService emisTransLineService;
|
private IEmisTransLineService emisTransLineService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private EmisTmsSiteBatchMissMapper emisTmsSiteBatchMissMapper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线支付回调
|
* 在线支付回调
|
||||||
* @param method
|
* @param method
|
||||||
@ -903,6 +907,42 @@ public class EmisCommonController extends EmisBaseController
|
|||||||
return AjaxResult.success("发送成功");
|
return AjaxResult.success("发送成功");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* 定时扫描运单货物组批次是否正确录入-V2
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/autoScanSiteBatchV2")
|
||||||
|
public AjaxResult autoScanSiteBatchV2(String lineCode) {
|
||||||
|
String statusKey = "autoScanSiteBatchV2_status";
|
||||||
|
log.info("autoScanSiteBatchV2 start");
|
||||||
|
|
||||||
|
// 检查任务是否正在执行
|
||||||
|
String currentStatus = redissonService.getStr(statusKey);
|
||||||
|
if ("RUNNING".equals(currentStatus)) {
|
||||||
|
log.warn("autoScanSiteBatchV2 is already running, request rejected");
|
||||||
|
return AjaxResult.error("任务正在执行中,请稍后再试");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// 设置任务状态为运行中,设置较长的过期时间(30分钟)
|
||||||
|
// 这样即使异步任务没有正确清除状态,也会在30分钟后自动过期
|
||||||
|
redissonService.setStr(statusKey, "RUNNING", 1800);
|
||||||
|
|
||||||
|
// 异步执行任务
|
||||||
|
emisTmsSiteBatchMissService.autoScanSiteBatchV2(lineCode);
|
||||||
|
log.info("autoScanSiteBatchV2 async task started");
|
||||||
|
|
||||||
|
return AjaxResult.success("异步任务已启动,请稍后查看执行结果");
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
log.error("autoScanSiteBatchV2 exception:" + ex.getMessage());
|
||||||
|
// 如果启动失败,清除状态
|
||||||
|
redissonService.setStr(statusKey, "", 0);
|
||||||
|
return AjaxResult.error("任务启动失败:" + ex.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 定时扫描运单货物组批次是否正确录入
|
* 定时扫描运单货物组批次是否正确录入
|
||||||
@ -929,6 +969,7 @@ public class EmisCommonController extends EmisBaseController
|
|||||||
// 如果lineCode为空,查询所有线路的lineCode,去重后循环调用
|
// 如果lineCode为空,查询所有线路的lineCode,去重后循环调用
|
||||||
if (StringUtils.isEmpty(lineCode)) {
|
if (StringUtils.isEmpty(lineCode)) {
|
||||||
log.info("lineCode is empty, querying all line codes");
|
log.info("lineCode is empty, querying all line codes");
|
||||||
|
emisTmsSiteBatchMissMapper.deleteReally(lineCode);
|
||||||
EmisTransLine queryLine = new EmisTransLine();
|
EmisTransLine queryLine = new EmisTransLine();
|
||||||
// queryLine.setStatus(1); // 只查询启用的线路
|
// queryLine.setStatus(1); // 只查询启用的线路
|
||||||
List<EmisTransLine> lineList = emisTransLineService.selectEmisTransLineList(queryLine);
|
List<EmisTransLine> lineList = emisTransLineService.selectEmisTransLineList(queryLine);
|
||||||
@ -959,6 +1000,7 @@ public class EmisCommonController extends EmisBaseController
|
|||||||
log.info("autoScanSiteBatch async task started for all line codes");
|
log.info("autoScanSiteBatch async task started for all line codes");
|
||||||
return AjaxResult.success("异步任务已启动,共处理 " + lineCodeSet.size() + " 个线路,请稍后查看执行结果");
|
return AjaxResult.success("异步任务已启动,共处理 " + lineCodeSet.size() + " 个线路,请稍后查看执行结果");
|
||||||
} else {
|
} else {
|
||||||
|
emisTmsSiteBatchMissMapper.deleteReally(lineCode);
|
||||||
// 异步执行任务
|
// 异步执行任务
|
||||||
emisTmsSiteBatchMissService.autoScanSiteBatch(lineCode);
|
emisTmsSiteBatchMissService.autoScanSiteBatch(lineCode);
|
||||||
log.info("autoScanSiteBatch async task started for lineCode: {}", lineCode);
|
log.info("autoScanSiteBatch async task started for lineCode: {}", lineCode);
|
||||||
|
|||||||
@ -116,6 +116,19 @@ public class EmisTmsSiteBatchController extends EmisBaseController
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据批次号扫描组批次--V2
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
@GetMapping("/scanSiteBatchV2")
|
||||||
|
// @PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatch:scanSiteBatch')")
|
||||||
|
public AjaxResult scanSiteBatchV2(String batchNo) {
|
||||||
|
emisTmsSiteBatchService.scanSiteBatchV2(batchNo);
|
||||||
|
return AjaxResult.success("发送成功");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批次明细
|
* 批次明细
|
||||||
* @param emisTmsSiteBatch
|
* @param emisTmsSiteBatch
|
||||||
|
|||||||
@ -74,6 +74,24 @@ public class EmisTmsSiteBatchMissController extends EmisBaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询TMS漏组批次信息列表
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMiss:listV2')")
|
||||||
|
@GetMapping("/list/v2")
|
||||||
|
public TableDataInfo listV2(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss) {
|
||||||
|
startPage();
|
||||||
|
setPrivParams(emisTmsSiteBatchMiss);
|
||||||
|
|
||||||
|
List<EmisTmsSiteBatchMiss> list = emisTmsSiteBatchMissService.selectEmisTmsSiteBatchMissListV2(emisTmsSiteBatchMiss);
|
||||||
|
if(emisTmsSiteBatchMiss.getParams().containsKey("blZExport")){
|
||||||
|
List exportList=getCompressExportList(list);
|
||||||
|
return getDataTable(exportList);
|
||||||
|
}else {
|
||||||
|
return getDataTable(list);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出TMS漏组批次信息列表
|
* 导出TMS漏组批次信息列表
|
||||||
*/
|
*/
|
||||||
@ -218,4 +236,50 @@ public class EmisTmsSiteBatchMissController extends EmisBaseController {
|
|||||||
emisTmsSiteBatchMissService.cancelConfirmBatch(billCodes);
|
emisTmsSiteBatchMissService.cancelConfirmBatch(billCodes);
|
||||||
return AjaxResult.success("取消确认成功");
|
return AjaxResult.success("取消确认成功");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量取消确认组批次--v2
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMiss:cancelConfirmV2')")
|
||||||
|
@Log(title = "TMS漏组批次信息", businessType = BusinessType.UPDATE)
|
||||||
|
@PostMapping("/cancelConfirmBatchV2")
|
||||||
|
public AjaxResult cancelConfirmBatchV2(@RequestBody EmisTmsSiteBatchMiss req) throws EmisBizError {
|
||||||
|
Object listObj = req.getParams() != null ? req.getParams().get("billCodeList") : null;
|
||||||
|
if (listObj == null) {
|
||||||
|
return AjaxResult.error("参数缺失:billCodeList");
|
||||||
|
}
|
||||||
|
List<String> billCodes;
|
||||||
|
if (listObj instanceof List) {
|
||||||
|
List<?> tmp = (List<?>) listObj;
|
||||||
|
billCodes = new java.util.ArrayList<>();
|
||||||
|
for (Object o : tmp) {
|
||||||
|
if (o != null) {
|
||||||
|
String s = String.valueOf(o).trim();
|
||||||
|
if (!s.isEmpty()) {
|
||||||
|
billCodes.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (listObj instanceof String) {
|
||||||
|
String str = ((String) listObj).trim();
|
||||||
|
if (str.isEmpty()) {
|
||||||
|
billCodes = java.util.Collections.emptyList();
|
||||||
|
} else {
|
||||||
|
String[] arr = str.split(",");
|
||||||
|
billCodes = new java.util.ArrayList<>(arr.length);
|
||||||
|
for (String a : arr) {
|
||||||
|
if (a != null) {
|
||||||
|
String s = a.trim();
|
||||||
|
if (!s.isEmpty()) {
|
||||||
|
billCodes.add(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return AjaxResult.error("参数格式错误:billCodeList");
|
||||||
|
}
|
||||||
|
emisTmsSiteBatchMissService.cancelConfirmBatchV2(billCodes);
|
||||||
|
return AjaxResult.success("取消确认成功");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,6 +51,26 @@ public class EmisTmsSiteBatchMissStatisticsController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询漏组批次统计列表--v2
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:listV2')")
|
||||||
|
@GetMapping("/list/v2")
|
||||||
|
public TableDataInfo listV2(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
try {
|
||||||
|
startPage();
|
||||||
|
List<EmisTmsSiteBatchMissStatistics> list = statisticsService
|
||||||
|
.selectStatisticsListV2(emisTmsSiteBatchMissStatistics);
|
||||||
|
return getDataTable(list);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("查询漏组批次统计列表失败", e);
|
||||||
|
TableDataInfo tableDataInfo = getDataTable(new ArrayList<>());
|
||||||
|
tableDataInfo.setCode(500);
|
||||||
|
tableDataInfo.setMsg("查询失败:" + e.getMessage());
|
||||||
|
return tableDataInfo;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出漏组详细数据(按月份分sheet)
|
* 导出漏组详细数据(按月份分sheet)
|
||||||
* 优化版本:支持异步处理、流式导出、缓存优化
|
* 优化版本:支持异步处理、流式导出、缓存优化
|
||||||
@ -85,6 +105,40 @@ public class EmisTmsSiteBatchMissStatisticsController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出漏组详细数据(按月份分sheet)--V2
|
||||||
|
* 优化版本:支持异步处理、流式导出、缓存优化
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:exportDetailV2')")
|
||||||
|
@Log(title = "漏组详细数据导出", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/exportDetailV2")
|
||||||
|
public void exportDetailV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
try {
|
||||||
|
// 设置响应头,支持流式传输
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
response.setHeader("Cache-Control", "no-cache");
|
||||||
|
response.setHeader("Pragma", "no-cache");
|
||||||
|
response.setHeader("Expires", "0");
|
||||||
|
|
||||||
|
// 异步流式导出,避免内存溢出
|
||||||
|
statisticsService.exportDetailDataByMonthStreamV2(response, emisTmsSiteBatchMissStatistics);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出漏组详细数据失败", e);
|
||||||
|
try {
|
||||||
|
// 检查响应是否已经开始
|
||||||
|
if (!response.isCommitted()) {
|
||||||
|
response.reset();
|
||||||
|
response.setContentType("application/json;charset=utf-8");
|
||||||
|
response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("写入错误信息失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出漏组批次统计查询接口数据
|
* 导出漏组批次统计查询接口数据
|
||||||
*/
|
*/
|
||||||
@ -104,4 +158,24 @@ public class EmisTmsSiteBatchMissStatisticsController extends BaseController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出漏组批次统计查询接口数据
|
||||||
|
*/
|
||||||
|
@PreAuthorize("@ss.hasPermi('emis:emisTmsSiteBatchMissStatistics:exportStatisticsV2')")
|
||||||
|
@Log(title = "漏组批次统计导出", businessType = BusinessType.EXPORT)
|
||||||
|
@PostMapping("/exportStatisticsV2")
|
||||||
|
public void exportStatisticsV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
try {
|
||||||
|
statisticsService.exportStatisticsDataV2(response, emisTmsSiteBatchMissStatistics);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("导出漏组批次统计数据失败", e);
|
||||||
|
try {
|
||||||
|
response.getWriter().write("导出失败:" + e.getMessage());
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("写入错误信息失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import lombok.Data;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* TMS漏组批次扫描记录对象
|
* TMS漏组批次扫描记录对象
|
||||||
*
|
*
|
||||||
* @author heyu
|
* @author heyu
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
@ -36,4 +36,7 @@ public class EmisTmsSiteBatchMissRecord extends BaseEntity {
|
|||||||
/** 失败运单号列表 */
|
/** 失败运单号列表 */
|
||||||
private String failedBillCodes;
|
private String failedBillCodes;
|
||||||
|
|
||||||
}
|
/** 扫描版本 */
|
||||||
|
private String scanVersion;
|
||||||
|
|
||||||
|
}
|
||||||
|
|||||||
@ -7,13 +7,13 @@ import org.apache.ibatis.annotations.Param;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* TMS漏组批次信息Mapper接口
|
* TMS漏组批次信息Mapper接口
|
||||||
*
|
*
|
||||||
* @author heyu
|
* @author heyu
|
||||||
*/
|
*/
|
||||||
public interface EmisTmsSiteBatchMissMapper {
|
public interface EmisTmsSiteBatchMissMapper {
|
||||||
/**
|
/**
|
||||||
* 查询TMS漏组批次信息
|
* 查询TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param id TMS漏组批次信息主键
|
* @param id TMS漏组批次信息主键
|
||||||
* @return TMS漏组批次信息
|
* @return TMS漏组批次信息
|
||||||
*/
|
*/
|
||||||
@ -21,15 +21,23 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询TMS漏组批次信息列表
|
* 查询TMS漏组批次信息列表
|
||||||
*
|
*
|
||||||
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
* @return TMS漏组批次信息集合
|
* @return TMS漏组批次信息集合
|
||||||
*/
|
*/
|
||||||
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissList(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissList(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询TMS漏组批次信息列表_v2
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
|
* @return TMS漏组批次信息集合
|
||||||
|
*/
|
||||||
|
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissListV2(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增TMS漏组批次信息
|
* 新增TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -37,7 +45,7 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 修改TMS漏组批次信息
|
* 修改TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -45,7 +53,7 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 删除TMS漏组批次信息
|
* 删除TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param id TMS漏组批次信息主键
|
* @param id TMS漏组批次信息主键
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -53,7 +61,7 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量删除TMS漏组批次信息
|
* 批量删除TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param ids 需要删除的数据主键集合
|
* @param ids 需要删除的数据主键集合
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
@ -61,12 +69,20 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量插入TMS漏组批次信息
|
* 批量插入TMS漏组批次信息
|
||||||
*
|
*
|
||||||
* @param list TMS漏组批次信息列表
|
* @param list TMS漏组批次信息列表
|
||||||
* @return 结果
|
* @return 结果
|
||||||
*/
|
*/
|
||||||
public int batchInsertEmisTmsSiteBatchMiss(List<EmisTmsSiteBatchMiss> list);
|
public int batchInsertEmisTmsSiteBatchMiss(List<EmisTmsSiteBatchMiss> list);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量插入TMS漏组批次信息--V2
|
||||||
|
*
|
||||||
|
* @param list TMS漏组批次信息列表
|
||||||
|
* @return 结果
|
||||||
|
*/
|
||||||
|
public int batchInsertEmisTmsSiteBatchMissV2(List<EmisTmsSiteBatchMiss> list);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param lineCode
|
* @param lineCode
|
||||||
@ -87,10 +103,19 @@ public interface EmisTmsSiteBatchMissMapper {
|
|||||||
*/
|
*/
|
||||||
void deleteByBillCodes(@Param("billCodes") List<String> billCodes);
|
void deleteByBillCodes(@Param("billCodes") List<String> billCodes);
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param billCodes
|
||||||
|
*/
|
||||||
|
void deleteByBillCodesV2(@Param("billCodes") List<String> billCodes);
|
||||||
|
|
||||||
void deleteReally(String lineCode);
|
void deleteReally(String lineCode);
|
||||||
|
|
||||||
|
void deleteReallyV2(String lineCode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 根据运单号批量查询TMS漏组批次信息
|
* 根据运单号批量查询TMS漏组批次信息
|
||||||
*/
|
*/
|
||||||
List<EmisWaybill> selectByBillCodes(@Param("billCodes") List<String> billCodes);
|
List<EmisWaybill> selectByBillCodes(@Param("billCodes") List<String> billCodes);
|
||||||
}
|
|
||||||
|
}
|
||||||
|
|||||||
@ -23,6 +23,15 @@ public interface EmisTmsSiteBatchMissStatisticsMapper {
|
|||||||
List<EmisTmsSiteBatchMissStatistics> selectStatisticsList(
|
List<EmisTmsSiteBatchMissStatistics> selectStatisticsList(
|
||||||
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询漏组批次统计列表--V2
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件对象
|
||||||
|
* @return 统计结果列表
|
||||||
|
*/
|
||||||
|
List<EmisTmsSiteBatchMissStatistics> selectStatisticsListV2(
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询漏组详细数据列表(按月份分组)
|
* 查询漏组详细数据列表(按月份分组)
|
||||||
*
|
*
|
||||||
@ -31,6 +40,14 @@ public interface EmisTmsSiteBatchMissStatisticsMapper {
|
|||||||
*/
|
*/
|
||||||
List<EmisTmsSiteBatchMiss> selectDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
List<EmisTmsSiteBatchMiss> selectDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询漏组详细数据列表(按月份分组)
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件
|
||||||
|
* @return 详细数据列表
|
||||||
|
*/
|
||||||
|
List<EmisTmsSiteBatchMiss> selectDetailDataByMonthV2(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 分页查询漏组详细数据列表(按月份分组)- 性能优化版本
|
* 分页查询漏组详细数据列表(按月份分组)- 性能优化版本
|
||||||
*
|
*
|
||||||
@ -51,4 +68,12 @@ public interface EmisTmsSiteBatchMissStatisticsMapper {
|
|||||||
* @return 总记录数
|
* @return 总记录数
|
||||||
*/
|
*/
|
||||||
long countDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
long countDetailDataByMonth(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 统计漏组详细数据总数
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件
|
||||||
|
* @return 总记录数
|
||||||
|
*/
|
||||||
|
long countDetailDataByMonthV2(EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4669,7 +4669,7 @@ public class EmisBaseService {
|
|||||||
|
|
||||||
// 保存扫描记录
|
// 保存扫描记录
|
||||||
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
||||||
totalMissRecords);
|
totalMissRecords,"1");
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"Auto scan completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
"Auto scan completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
||||||
@ -4744,7 +4744,7 @@ public class EmisBaseService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void saveRecord(int totalProcessed, int successCount, int failCount, long processTime,
|
public void saveRecord(int totalProcessed, int successCount, int failCount, long processTime,
|
||||||
List<String> failedBillCodes, int totalBatchStatusRecords, int totalMissRecords) {
|
List<String> failedBillCodes, int totalBatchStatusRecords, int totalMissRecords,String scanVersion) {
|
||||||
EmisTmsSiteBatchMissRecord record = new EmisTmsSiteBatchMissRecord();
|
EmisTmsSiteBatchMissRecord record = new EmisTmsSiteBatchMissRecord();
|
||||||
record.setTotalProcessed(totalProcessed);
|
record.setTotalProcessed(totalProcessed);
|
||||||
record.setSuccessCount(successCount);
|
record.setSuccessCount(successCount);
|
||||||
@ -4757,6 +4757,7 @@ public class EmisBaseService {
|
|||||||
record.setCreateBy("system");
|
record.setCreateBy("system");
|
||||||
record.setCreateTime(new Date());
|
record.setCreateTime(new Date());
|
||||||
record.setCreateSite("88888");
|
record.setCreateSite("88888");
|
||||||
|
record.setScanVersion(scanVersion);
|
||||||
|
|
||||||
emisTmsSiteBatchMissRecordMapper.insertEmisTmsSiteBatchMissRecord(record);
|
emisTmsSiteBatchMissRecordMapper.insertEmisTmsSiteBatchMissRecord(record);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package com.xdadan.erp.emis.service;
|
|||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMiss;
|
import com.xdadan.erp.emis.domain.EmisTmsSiteBatchMiss;
|
||||||
|
import com.xdadan.erp.emis.domain.EmisWaybill;
|
||||||
import com.xdadan.erp.emis.domain.exception.EmisBizError;
|
import com.xdadan.erp.emis.domain.exception.EmisBizError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -26,6 +27,14 @@ public interface IEmisTmsSiteBatchMissService {
|
|||||||
*/
|
*/
|
||||||
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissList(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissList(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询TMS漏组批次信息列表_v2
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
|
* @return TMS漏组批次信息集合
|
||||||
|
*/
|
||||||
|
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissListV2(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增TMS漏组批次信息
|
* 新增TMS漏组批次信息
|
||||||
*
|
*
|
||||||
@ -90,4 +99,21 @@ public interface IEmisTmsSiteBatchMissService {
|
|||||||
* @param billCodes 运单号列表
|
* @param billCodes 运单号列表
|
||||||
*/
|
*/
|
||||||
void cancelConfirmBatch(List<String> billCodes) throws EmisBizError;
|
void cancelConfirmBatch(List<String> billCodes) throws EmisBizError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量取消确认组批次--V2:
|
||||||
|
* 1) 根据运单号列表删除运单组批次状态数据
|
||||||
|
* 2) 重新扫描运单组批次状态
|
||||||
|
*
|
||||||
|
* @param billCodes 运单号列表
|
||||||
|
*/
|
||||||
|
void cancelConfirmBatchV2(List<String> billCodes) throws EmisBizError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 定时扫描运单货物组批次是否正确录入-V2
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void autoScanSiteBatchV2(String lineCode);
|
||||||
|
|
||||||
|
void scanSiteBatchByWaybillsV2(List<EmisWaybill> emisWaybills);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,15 @@ public interface IEmisTmsSiteBatchMissStatisticsService {
|
|||||||
List<EmisTmsSiteBatchMissStatistics> selectStatisticsList(
|
List<EmisTmsSiteBatchMissStatistics> selectStatisticsList(
|
||||||
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询漏组批次统计列表--V2
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件
|
||||||
|
* @return 统计结果列表
|
||||||
|
*/
|
||||||
|
List<EmisTmsSiteBatchMissStatistics> selectStatisticsListV2(
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 流式导出漏组详细数据(按月份分sheet)- 性能优化版本
|
* 流式导出漏组详细数据(按月份分sheet)- 性能优化版本
|
||||||
* 支持大数据量导出,避免内存溢出
|
* 支持大数据量导出,避免内存溢出
|
||||||
@ -34,6 +43,16 @@ public interface IEmisTmsSiteBatchMissStatisticsService {
|
|||||||
void exportDetailDataByMonthStream(HttpServletResponse response,
|
void exportDetailDataByMonthStream(HttpServletResponse response,
|
||||||
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流式导出漏组详细数据(按月份分sheet)- 性能优化版本
|
||||||
|
* 支持大数据量导出,避免内存溢出
|
||||||
|
*
|
||||||
|
* @param response HTTP响应
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件
|
||||||
|
*/
|
||||||
|
void exportDetailDataByMonthStreamV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出漏组批次统计查询接口数据
|
* 导出漏组批次统计查询接口数据
|
||||||
*
|
*
|
||||||
@ -42,4 +61,13 @@ public interface IEmisTmsSiteBatchMissStatisticsService {
|
|||||||
*/
|
*/
|
||||||
void exportStatisticsData(HttpServletResponse response,
|
void exportStatisticsData(HttpServletResponse response,
|
||||||
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出漏组批次统计查询接口数据
|
||||||
|
*
|
||||||
|
* @param response HTTP响应
|
||||||
|
* @param emisTmsSiteBatchMissStatistics 查询条件
|
||||||
|
*/
|
||||||
|
void exportStatisticsDataV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,6 +114,13 @@ public interface IEmisTmsSiteBatchService extends IDataAuditService
|
|||||||
*/
|
*/
|
||||||
void scanSiteBatch(String batchNo);
|
void scanSiteBatch(String batchNo);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据批次号扫描组批次--V2
|
||||||
|
*
|
||||||
|
* @param batchNo
|
||||||
|
*/
|
||||||
|
void scanSiteBatchV2(String batchNo);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param emisTmsSiteBatch
|
* @param emisTmsSiteBatch
|
||||||
|
|||||||
@ -20,6 +20,7 @@ import com.xdadan.erp.emis.utils.WaybillHelper;
|
|||||||
import jodd.util.StringUtil;
|
import jodd.util.StringUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.scheduling.annotation.Async;
|
import org.springframework.scheduling.annotation.Async;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
@ -137,6 +138,31 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询TMS漏组批次信息列表_v2
|
||||||
|
*
|
||||||
|
* @param emisTmsSiteBatchMiss TMS漏组批次信息
|
||||||
|
* @return TMS漏组批次信息
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<EmisTmsSiteBatchMiss> selectEmisTmsSiteBatchMissListV2(EmisTmsSiteBatchMiss emisTmsSiteBatchMiss) {
|
||||||
|
log.info("Selecting TMS site batch miss list with params: {}", emisTmsSiteBatchMiss);
|
||||||
|
List<EmisTmsSiteBatchMiss> list = null;
|
||||||
|
// 如果单号不为空,则去除其他参数
|
||||||
|
if (!StringUtils.isEmpty(emisTmsSiteBatchMiss.getBillCode())) {
|
||||||
|
emisTmsSiteBatchMiss.setBillCode(WaybillHelper.formatQueryValue(emisTmsSiteBatchMiss.getBillCode()));
|
||||||
|
String[] billCodeSortList = emisTmsSiteBatchMiss.getBillCode().split(",");
|
||||||
|
if (billCodeSortList.length > 1) {
|
||||||
|
emisTmsSiteBatchMiss.getParams().put("billCodeSortList", Arrays.asList(billCodeSortList));
|
||||||
|
}
|
||||||
|
list = emisTmsSiteBatchMissMapper.selectEmisTmsSiteBatchMissListV2(emisTmsSiteBatchMiss);
|
||||||
|
} else {
|
||||||
|
list = emisTmsSiteBatchMissMapper.selectEmisTmsSiteBatchMissListV2(emisTmsSiteBatchMiss);
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 新增TMS漏组批次信息
|
* 新增TMS漏组批次信息
|
||||||
*
|
*
|
||||||
@ -208,6 +234,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
|
|
||||||
// 1) 逻辑删除漏组批次数据
|
// 1) 逻辑删除漏组批次数据
|
||||||
emisTmsSiteBatchMissMapper.deleteByBillCodes(billCodes);
|
emisTmsSiteBatchMissMapper.deleteByBillCodes(billCodes);
|
||||||
|
emisTmsSiteBatchMissMapper.deleteByBillCodesV2(billCodes);
|
||||||
|
|
||||||
// 2) 新增运单组批次状态 site_batch_status=1(幂等:insert ignore)
|
// 2) 新增运单组批次状态 site_batch_status=1(幂等:insert ignore)
|
||||||
Date now = new Date();
|
Date now = new Date();
|
||||||
@ -249,6 +276,29 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
// 3) 调用scanSiteBatchByWaybills重新扫描
|
// 3) 调用scanSiteBatchByWaybills重新扫描
|
||||||
if (!waybills.isEmpty()) {
|
if (!waybills.isEmpty()) {
|
||||||
this.scanSiteBatchByWaybills(waybills);
|
this.scanSiteBatchByWaybills(waybills);
|
||||||
|
this.scanSiteBatchByWaybillsV2(waybills);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 批量取消确认组批次--V2
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
@Transactional(rollbackFor = Exception.class)
|
||||||
|
public void cancelConfirmBatchV2(List<String> billCodes) throws EmisBizError {
|
||||||
|
if (billCodes == null || billCodes.isEmpty()) {
|
||||||
|
throw new EmisBizError(EmisBizErrorType.PARAM_ERROR, "运单号不能为空");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1) 彻底删除运单组批次状态数据
|
||||||
|
emisWaybillBatchStatusMapper.deleteByBillCodes(billCodes);
|
||||||
|
|
||||||
|
// 2) 批量查询运单信息
|
||||||
|
List<EmisWaybill> waybills = emisWaybillMapper.selectEmisWaybillListByBillCodes(billCodes);
|
||||||
|
|
||||||
|
// 3) 调用scanSiteBatchByWaybills重新扫描
|
||||||
|
if (!waybills.isEmpty()) {
|
||||||
|
this.scanSiteBatchByWaybillsV2(waybills);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,7 +307,6 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
public void autoScanSiteBatch(String lineCode) {
|
public void autoScanSiteBatch(String lineCode) {
|
||||||
ExecutorService executorService = null;
|
ExecutorService executorService = null;
|
||||||
try {
|
try {
|
||||||
emisTmsSiteBatchMissMapper.deleteReally(lineCode);
|
|
||||||
long startTime = System.currentTimeMillis();
|
long startTime = System.currentTimeMillis();
|
||||||
int pageSize = 1000;
|
int pageSize = 1000;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
@ -272,6 +321,20 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
List<EmisTransPlanRule> treeRules = this.selectEmisTransPlanRuleTree(lineCode);
|
List<EmisTransPlanRule> treeRules = this.selectEmisTransPlanRuleTree(lineCode);
|
||||||
if (treeRules.isEmpty()) {
|
if (treeRules.isEmpty()) {
|
||||||
log.info("No trans plan rules found, skip auto scan");
|
log.info("No trans plan rules found, skip auto scan");
|
||||||
|
List<EmisWaybill> waybills = emisWaybillMapper.selectWaybillListBySiteBatchStatus(0, 100000,
|
||||||
|
lineCode);
|
||||||
|
if (waybills.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<EmisTmsSiteBatchMiss> missRecords = waybills.stream().map(waybill -> {
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
miss.setMissReason("当前线路没有创建对应的线路规划");
|
||||||
|
miss.setMissType("1");
|
||||||
|
miss.setLineCode(waybill.getTransLineType());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
return miss;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
emisTmsSiteBatchMissMapper.batchInsertEmisTmsSiteBatchMiss(missRecords);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -282,7 +345,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
// 创建线程池
|
// 创建线程池
|
||||||
int processors = Runtime.getRuntime().availableProcessors() ;
|
int processors = Runtime.getRuntime().availableProcessors() ;
|
||||||
executorService = new ThreadPoolExecutor(
|
executorService = new ThreadPoolExecutor(
|
||||||
processors/2, // 核心线程数
|
1, // 核心线程数
|
||||||
processors, // 最大线程数
|
processors, // 最大线程数
|
||||||
60L, // 空闲线程存活时间
|
60L, // 空闲线程存活时间
|
||||||
TimeUnit.SECONDS, // 时间单位
|
TimeUnit.SECONDS, // 时间单位
|
||||||
@ -335,7 +398,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
batches.size(), batchSize, allWaybills.size());
|
batches.size(), batchSize, allWaybills.size());
|
||||||
|
|
||||||
// 复用现有线程池
|
// 复用现有线程池
|
||||||
List<Future<ProcessResult>> processFutures = new ArrayList<>();
|
List<Future<EmisBaseService.ProcessResult>> processFutures = new ArrayList<>();
|
||||||
|
|
||||||
for (List<EmisWaybill> batch : batches) {
|
for (List<EmisWaybill> batch : batches) {
|
||||||
processFutures.add(executorService.submit(() -> processWaybillBatch(batch, transPlanRulesByLineCode)));
|
processFutures.add(executorService.submit(() -> processWaybillBatch(batch, transPlanRulesByLineCode)));
|
||||||
@ -346,9 +409,9 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
List<EmisTmsSiteBatchMiss> allMissRecords = new ArrayList<>();
|
List<EmisTmsSiteBatchMiss> allMissRecords = new ArrayList<>();
|
||||||
int timeoutMinutes = 10; // 10分钟超时
|
int timeoutMinutes = 10; // 10分钟超时
|
||||||
|
|
||||||
for (Future<ProcessResult> future : processFutures) {
|
for (Future<EmisBaseService.ProcessResult> future : processFutures) {
|
||||||
try {
|
try {
|
||||||
ProcessResult result = future.get(timeoutMinutes, TimeUnit.MINUTES);
|
EmisBaseService.ProcessResult result = future.get(timeoutMinutes, TimeUnit.MINUTES);
|
||||||
successCount += result.getSuccessCount();
|
successCount += result.getSuccessCount();
|
||||||
failCount += result.getFailCount();
|
failCount += result.getFailCount();
|
||||||
failedBillCodes.addAll(result.getFailedBillCodes());
|
failedBillCodes.addAll(result.getFailedBillCodes());
|
||||||
@ -406,7 +469,7 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
|
|
||||||
// 保存扫描记录
|
// 保存扫描记录
|
||||||
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
||||||
totalMissRecords);
|
totalMissRecords,"1");
|
||||||
|
|
||||||
log.info(
|
log.info(
|
||||||
"Auto scan completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
"Auto scan completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
||||||
@ -451,4 +514,718 @@ public class EmisTmsSiteBatchMissServiceImpl extends EmisBaseService implements
|
|||||||
return tree;
|
return tree;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<EmisTransPlanRule> selectEmisTransPlanRuleTreeV2(String lineCode) {
|
||||||
|
EmisTransPlanRule emisTransPlanRule = new EmisTransPlanRule();
|
||||||
|
emisTransPlanRule.setLineCode(lineCode);
|
||||||
|
List<EmisTransPlanRule> allRules = emisTransPlanRuleMapper.selectRulesForAllScan(emisTransPlanRule);
|
||||||
|
// List<EmisTransPlanRule> tree = buildTree(allRules, new EmisTransPlanRule());
|
||||||
|
return allRules;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Async
|
||||||
|
@Override
|
||||||
|
public void autoScanSiteBatchV2(String lineCode) {
|
||||||
|
ExecutorService executorService = null;
|
||||||
|
try {
|
||||||
|
emisTmsSiteBatchMissMapper.deleteReallyV2(lineCode);
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
int pageSize = 1000;
|
||||||
|
int offset = 0;
|
||||||
|
int totalProcessed = 0;
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
int totalBatchStatusRecords = 0;
|
||||||
|
int totalMissRecords = 0;
|
||||||
|
List<String> failedBillCodes = new ArrayList<>();
|
||||||
|
|
||||||
|
// 获取所有线路规划
|
||||||
|
List<EmisTransPlanRule> treeRules = this.selectEmisTransPlanRuleTreeV2(lineCode);
|
||||||
|
if (treeRules.isEmpty()) {
|
||||||
|
log.info("No trans plan rules found, skip auto scan v2");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按线路编码分组
|
||||||
|
Map<String, List<EmisTransPlanRule>> transPlanRulesByLineCode = treeRules.stream()
|
||||||
|
.collect(Collectors.groupingBy(EmisTransPlanRule::getLineCode));
|
||||||
|
|
||||||
|
// 创建线程池
|
||||||
|
int processors = Runtime.getRuntime().availableProcessors() ;
|
||||||
|
executorService = new ThreadPoolExecutor(
|
||||||
|
1, // 核心线程数
|
||||||
|
processors, // 最大线程数
|
||||||
|
60L, // 空闲线程存活时间
|
||||||
|
TimeUnit.SECONDS, // 时间单位
|
||||||
|
new LinkedBlockingQueue<>(), // 工作队列
|
||||||
|
r -> {
|
||||||
|
Thread t = new Thread(r);
|
||||||
|
t.setName("emis-scan-" + t.getId());
|
||||||
|
t.setDaemon(false);
|
||||||
|
return t;
|
||||||
|
} // 线程工厂
|
||||||
|
);
|
||||||
|
List<Future<List<EmisWaybill>>> futures = new ArrayList<>();
|
||||||
|
|
||||||
|
// 先查询所有数据
|
||||||
|
while (true) {
|
||||||
|
List<EmisWaybill> waybills = emisWaybillMapper.selectWaybillListBySiteBatchStatus(offset, pageSize,
|
||||||
|
lineCode);
|
||||||
|
if (waybills.isEmpty()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
futures.add(executorService.submit(() -> waybills));
|
||||||
|
offset += pageSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 等待所有查询完成并收集结果
|
||||||
|
List<EmisWaybill> allWaybills = new ArrayList<>();
|
||||||
|
for (Future<List<EmisWaybill>> future : futures) {
|
||||||
|
try {
|
||||||
|
List<EmisWaybill> waybills = future.get();
|
||||||
|
allWaybills.addAll(waybills);
|
||||||
|
totalProcessed += waybills.size();
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error getting waybill results", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int batchSize = 1000;
|
||||||
|
List<List<EmisWaybill>> batches = new ArrayList<>();
|
||||||
|
for (int i = 0; i < allWaybills.size(); i += batchSize) {
|
||||||
|
int end = Math.min(i + batchSize, allWaybills.size());
|
||||||
|
batches.add(allWaybills.subList(i, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(batches)) {
|
||||||
|
log.info("No waybills to process, skip batch processing");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("Processing {} batches with batch size: {}, total waybills: {}",
|
||||||
|
batches.size(), batchSize, allWaybills.size());
|
||||||
|
|
||||||
|
// 复用现有线程池
|
||||||
|
List<Future<ProcessResult>> processFutures = new ArrayList<>();
|
||||||
|
|
||||||
|
for (List<EmisWaybill> batch : batches) {
|
||||||
|
processFutures.add(executorService.submit(() -> processWaybillBatchV2(batch, transPlanRulesByLineCode)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加超时机制,避免长时间阻塞
|
||||||
|
List<EmisWaybillBatchStatus> allBatchStatus = new ArrayList<>();
|
||||||
|
List<EmisTmsSiteBatchMiss> allMissRecords = new ArrayList<>();
|
||||||
|
int timeoutMinutes = 10; // 10分钟超时
|
||||||
|
|
||||||
|
for (Future<ProcessResult> future : processFutures) {
|
||||||
|
try {
|
||||||
|
ProcessResult result = future.get(timeoutMinutes, TimeUnit.MINUTES);
|
||||||
|
successCount += result.getSuccessCount();
|
||||||
|
failCount += result.getFailCount();
|
||||||
|
failedBillCodes.addAll(result.getFailedBillCodes());
|
||||||
|
allBatchStatus.addAll(result.getBatchStatusList());
|
||||||
|
allMissRecords.addAll(result.getMissRecords());
|
||||||
|
} catch (TimeoutException e) {
|
||||||
|
log.error("Batch processing timeout after {} minutes", timeoutMinutes);
|
||||||
|
future.cancel(true); // 取消超时任务
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error processing batch", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 全局去重
|
||||||
|
Map<String, EmisWaybillBatchStatus> batchStatusMap = allBatchStatus.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
EmisWaybillBatchStatus::getBillCode,
|
||||||
|
v -> v,
|
||||||
|
(existing, replacement) -> existing));
|
||||||
|
List<EmisWaybillBatchStatus> uniqueBatchStatus = new ArrayList<>(batchStatusMap.values());
|
||||||
|
|
||||||
|
Map<String, EmisTmsSiteBatchMiss> missMap = allMissRecords.stream()
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
r -> r.getBillCode() + "_" + r.getMissReason(),
|
||||||
|
v -> v,
|
||||||
|
(existing, replacement) -> existing));
|
||||||
|
List<EmisTmsSiteBatchMiss> uniqueMissRecords = new ArrayList<>(missMap.values());
|
||||||
|
|
||||||
|
if (!uniqueBatchStatus.isEmpty()) {
|
||||||
|
filterBatchStatusList(uniqueBatchStatus, uniqueMissRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量插入 - 每次插入5000条
|
||||||
|
if (!uniqueBatchStatus.isEmpty()) {
|
||||||
|
int insertBatchSize = 5000;
|
||||||
|
for (int i = 0; i < uniqueBatchStatus.size(); i += insertBatchSize) {
|
||||||
|
int end = Math.min(i + insertBatchSize, uniqueBatchStatus.size());
|
||||||
|
List<EmisWaybillBatchStatus> batch = uniqueBatchStatus.subList(i, end);
|
||||||
|
emisWaybillBatchStatusMapper.batchInsertEmisWaybillBatchStatus(batch);
|
||||||
|
totalBatchStatusRecords += batch.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!uniqueMissRecords.isEmpty()) {
|
||||||
|
int insertBatchSize = 5000;
|
||||||
|
for (int i = 0; i < uniqueMissRecords.size(); i += insertBatchSize) {
|
||||||
|
int end = Math.min(i + insertBatchSize, uniqueMissRecords.size());
|
||||||
|
List<EmisTmsSiteBatchMiss> batch = uniqueMissRecords.subList(i, end);
|
||||||
|
emisTmsSiteBatchMissMapper.batchInsertEmisTmsSiteBatchMissV2(batch);
|
||||||
|
totalMissRecords += batch.size();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
long processTime = endTime - startTime;
|
||||||
|
|
||||||
|
// 保存扫描记录
|
||||||
|
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
||||||
|
totalMissRecords,"2");
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"Auto scan v2 completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
||||||
|
totalProcessed, successCount, failCount, processTime,
|
||||||
|
totalBatchStatusRecords, totalMissRecords);
|
||||||
|
if (CollectionUtil.isNotEmpty(failedBillCodes)) {
|
||||||
|
log.warn("Failed bill codes: {}", failedBillCodes);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in autoScanSiteBatch v2", e);
|
||||||
|
} finally {
|
||||||
|
// 确保线程池资源释放
|
||||||
|
if (executorService != null && !executorService.isShutdown()) {
|
||||||
|
executorService.shutdown();
|
||||||
|
try {
|
||||||
|
if (!executorService.awaitTermination(30, TimeUnit.SECONDS)) {
|
||||||
|
log.warn("Thread pool did not terminate gracefully, forcing shutdown");
|
||||||
|
executorService.shutdownNow();
|
||||||
|
}
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
log.error("Thread pool shutdown interrupted", e);
|
||||||
|
executorService.shutdownNow();
|
||||||
|
Thread.currentThread().interrupt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 清除任务状态
|
||||||
|
try {
|
||||||
|
String statusKey = "autoScanSiteBatchV2_status";
|
||||||
|
redissonService.setStr(statusKey, "", 0);
|
||||||
|
log.info("autoScanSiteBatch v2 task status cleared");
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to clear autoScanSiteBatch status", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void scanSiteBatchByWaybillsV2(List<EmisWaybill> emisWaybills) {
|
||||||
|
try {
|
||||||
|
if (CollectionUtil.isEmpty(emisWaybills)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> billCodes = emisWaybills.stream().map(EmisWaybill::getBillCode).collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isEmpty(billCodes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<String> lineCodes = emisWaybills.stream().map(EmisWaybill::getTransLineType).distinct()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isEmpty(lineCodes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emisTmsSiteBatchMissMapper.deleteByBillCodesV2(billCodes);
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
int totalProcessed = emisWaybills.size();
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
int totalBatchStatusRecords = 0;
|
||||||
|
int totalMissRecords = 0;
|
||||||
|
List<String> failedBillCodes = new ArrayList<>();
|
||||||
|
|
||||||
|
// 获取所有线路规划
|
||||||
|
List<EmisTransPlanRule> treeRules = this.selectEmisTransPlanRuleTree(lineCodes);
|
||||||
|
if (treeRules.isEmpty()) {
|
||||||
|
log.info("No trans plan rules found, skip auto scan v2");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按线路编码分组
|
||||||
|
Map<String, List<EmisTransPlanRule>> transPlanRulesByLineCode = treeRules.stream()
|
||||||
|
.collect(Collectors.groupingBy(EmisTransPlanRule::getLineCode));
|
||||||
|
|
||||||
|
// 直接处理运单批次
|
||||||
|
ProcessResult result = processWaybillBatchV2(emisWaybills, transPlanRulesByLineCode);
|
||||||
|
successCount += result.getSuccessCount();
|
||||||
|
failCount += result.getFailCount();
|
||||||
|
failedBillCodes.addAll(result.getFailedBillCodes());
|
||||||
|
|
||||||
|
// 批量插入运单组批次状态记录
|
||||||
|
List<EmisWaybillBatchStatus> batchStatusList = result.getBatchStatusList();
|
||||||
|
List<EmisTmsSiteBatchMiss> missRecords = result.getMissRecords();
|
||||||
|
if (!batchStatusList.isEmpty()) {
|
||||||
|
filterBatchStatusList(batchStatusList, missRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量插入运单组批次状态记录
|
||||||
|
if (!batchStatusList.isEmpty()) {
|
||||||
|
emisWaybillBatchStatusMapper.batchInsertEmisWaybillBatchStatus(result.getBatchStatusList());
|
||||||
|
totalBatchStatusRecords += result.getBatchStatusList().size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 批量保存漏组记录
|
||||||
|
if (!missRecords.isEmpty()) {
|
||||||
|
List<EmisTmsSiteBatchMiss> filteredRecords = missRecords.stream()
|
||||||
|
.collect(Collectors.collectingAndThen(
|
||||||
|
Collectors.toMap(
|
||||||
|
record -> record.getBillCode() + "_" + record.getMissReason(),
|
||||||
|
record -> record,
|
||||||
|
(existing, replacement) -> existing),
|
||||||
|
map -> new ArrayList<>(map.values())));
|
||||||
|
emisTmsSiteBatchMissMapper.batchInsertEmisTmsSiteBatchMissV2(filteredRecords);
|
||||||
|
totalMissRecords += filteredRecords.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
long processTime = endTime - startTime;
|
||||||
|
|
||||||
|
// 保存扫描记录
|
||||||
|
saveRecord(totalProcessed, successCount, failCount, processTime, failedBillCodes, totalBatchStatusRecords,
|
||||||
|
totalMissRecords,"2");
|
||||||
|
|
||||||
|
log.info(
|
||||||
|
"Auto scan V2 completed. Total processed: {}, Success: {}, Failed: {}, Time taken: {}ms, Batch status records: {}, Miss records: {}",
|
||||||
|
totalProcessed, successCount, failCount, processTime,
|
||||||
|
totalBatchStatusRecords, totalMissRecords);
|
||||||
|
if (CollectionUtil.isNotEmpty(failedBillCodes)) {
|
||||||
|
log.warn("Failed bill codes: {}", failedBillCodes);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Error in autoScanSiteBatch V2", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ProcessResult {
|
||||||
|
private final int successCount;
|
||||||
|
private final int failCount;
|
||||||
|
private final List<String> failedBillCodes;
|
||||||
|
private final List<EmisWaybillBatchStatus> batchStatusList;
|
||||||
|
private final List<EmisTmsSiteBatchMiss> missRecords;
|
||||||
|
|
||||||
|
public ProcessResult(int successCount, int failCount, List<String> failedBillCodes,
|
||||||
|
List<EmisWaybillBatchStatus> batchStatusList, List<EmisTmsSiteBatchMiss> missRecords) {
|
||||||
|
this.successCount = successCount;
|
||||||
|
this.failCount = failCount;
|
||||||
|
this.failedBillCodes = failedBillCodes;
|
||||||
|
this.batchStatusList = batchStatusList;
|
||||||
|
this.missRecords = missRecords;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getSuccessCount() {
|
||||||
|
return successCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFailCount() {
|
||||||
|
return failCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getFailedBillCodes() {
|
||||||
|
return failedBillCodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmisWaybillBatchStatus> getBatchStatusList() {
|
||||||
|
return batchStatusList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EmisTmsSiteBatchMiss> getMissRecords() {
|
||||||
|
return missRecords;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcessResult processWaybillBatchV2(List<EmisWaybill> waybills,
|
||||||
|
Map<String, List<EmisTransPlanRule>> transPlanRulesByLineCode) {
|
||||||
|
int successCount = 0;
|
||||||
|
int failCount = 0;
|
||||||
|
List<String> failedBillCodes = new ArrayList<>();
|
||||||
|
List<EmisTmsSiteBatchMiss> missRecords = new ArrayList<>();
|
||||||
|
List<EmisWaybillBatchStatus> batchStatusList = new ArrayList<>();
|
||||||
|
|
||||||
|
// 获取所有运单号
|
||||||
|
List<String> billCodes = waybills.stream()
|
||||||
|
.map(EmisWaybill::getBillCode)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 一次性查询所有运单对应的组批次信息
|
||||||
|
List<EmisTmsSiteBatch> siteBatches = emisTmsSiteBatchMapper
|
||||||
|
.selectEmisTmsSiteBatchListByBillCodes(billCodes);
|
||||||
|
|
||||||
|
// 按运单号分组
|
||||||
|
Map<String, List<EmisTmsSiteBatch>> siteBatchesByBillCode = new HashMap<>();
|
||||||
|
for (EmisTmsSiteBatch batch : siteBatches) {
|
||||||
|
if (batch.getBatchDtlList() != null) {
|
||||||
|
for (EmisTmsSiteBatchDtl dtl : batch.getBatchDtlList()) {
|
||||||
|
siteBatchesByBillCode.computeIfAbsent(dtl.getBillCode(), k -> new ArrayList<>()).add(batch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (EmisWaybill waybill : waybills) {
|
||||||
|
try {
|
||||||
|
// 获取运单对应的线路规划
|
||||||
|
List<EmisTransPlanRule> ruleListByTransLineType = transPlanRulesByLineCode
|
||||||
|
.get(waybill.getTransLineType());
|
||||||
|
if (CollectionUtil.isEmpty(ruleListByTransLineType)) {
|
||||||
|
// 创建漏组记录
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
miss.setMissReason("当前线路没有创建对应的线路规划");
|
||||||
|
miss.setMissType("1");
|
||||||
|
miss.setLineCode(waybill.getTransLineType());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
missRecords.add(miss);
|
||||||
|
successCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<EmisTransPlanRule> ruleListByProductType = ruleListByTransLineType.stream()
|
||||||
|
.filter(i -> StringUtils.isNotBlank(i.getProductType())
|
||||||
|
&& i.getProductType().contains(waybill.getProductType()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(ruleListByProductType)) {
|
||||||
|
// 创建漏组记录
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
miss.setMissReason("当前线路没有创建对应的产品类型");
|
||||||
|
miss.setMissType("1");
|
||||||
|
miss.setLineCode(waybill.getTransLineType());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
missRecords.add(miss);
|
||||||
|
successCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取运单对应的组批次信息
|
||||||
|
List<EmisTmsSiteBatch> waybillBatches = siteBatchesByBillCode.get(waybill.getBillCode());
|
||||||
|
if (CollectionUtil.isEmpty(waybillBatches)) {
|
||||||
|
// 创建漏组记录
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
|
||||||
|
miss.setMissReason(waybill.getStartSiteName() +" 尚未完成组批次,请尽快完成,避免影响下一程同事组批次进度" );
|
||||||
|
miss.setLineCode(waybill.getTransLineType());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
miss.setStartSiteCode(waybill.getStartSiteCode());
|
||||||
|
miss.setNextSiteCode("");
|
||||||
|
miss.setMissType("0");
|
||||||
|
|
||||||
|
missRecords.add(miss);
|
||||||
|
successCount++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 合并相同起始网点和下一网点的批次
|
||||||
|
Map<String, EmisTmsSiteBatch> mergedBatches = new HashMap<>();
|
||||||
|
int status2Index = 0;
|
||||||
|
for (EmisTmsSiteBatch batch : waybillBatches) {
|
||||||
|
if (StringUtils.isAnyBlank(batch.getStartSiteCode(), batch.getNextSiteCode(),
|
||||||
|
batch.getSupplierCode())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查明细列表中是否有waybillBatchStatus=2的记录,如果有则不合并
|
||||||
|
boolean hasWaybillBatchStatus2 = false;
|
||||||
|
if (batch.getBatchDtlList() != null && !batch.getBatchDtlList().isEmpty()) {
|
||||||
|
for (EmisTmsSiteBatchDtl dtl : batch.getBatchDtlList()) {
|
||||||
|
if ("2".equals(dtl.getWaybillBatchStatus())||"1".equals(dtl.getWaybillBatchStatus())) {
|
||||||
|
hasWaybillBatchStatus2 = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有waybillBatchStatus=2的记录,不合并supplierCode,但添加到mergedBatches
|
||||||
|
if (hasWaybillBatchStatus2) {
|
||||||
|
String specialKey = batch.getStartSiteCode() + "_" + batch.getNextSiteCode() + "_S2_"
|
||||||
|
+ (status2Index++);
|
||||||
|
EmisTmsSiteBatch newBatch = new EmisTmsSiteBatch();
|
||||||
|
BeanUtils.copyProperties(batch, newBatch);
|
||||||
|
Set<String> supplierSet = new TreeSet<>();
|
||||||
|
if (StringUtils.isNotBlank(batch.getSupplierCode())) {
|
||||||
|
supplierSet.addAll(Arrays.asList(batch.getSupplierCode().split(",")));
|
||||||
|
}
|
||||||
|
newBatch.setSupplierCode(String.join(",", supplierSet));
|
||||||
|
mergedBatches.put(specialKey, newBatch);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String key = batch.getStartSiteCode() + "_" + batch.getNextSiteCode();
|
||||||
|
if (mergedBatches.containsKey(key)) {
|
||||||
|
EmisTmsSiteBatch existingBatch = mergedBatches.get(key);
|
||||||
|
// 合并supplierCode,去重、排序
|
||||||
|
Set<String> supplierSet = new TreeSet<>();
|
||||||
|
if (StringUtils.isNotBlank(existingBatch.getSupplierCode())) {
|
||||||
|
supplierSet.addAll(Arrays.asList(existingBatch.getSupplierCode().split(",")));
|
||||||
|
}
|
||||||
|
if (StringUtils.isNotBlank(batch.getSupplierCode())) {
|
||||||
|
supplierSet.addAll(Arrays.asList(batch.getSupplierCode().split(",")));
|
||||||
|
}
|
||||||
|
// 新建一个新的Batch对象,复制属性,保证线程安全
|
||||||
|
EmisTmsSiteBatch newBatch = new EmisTmsSiteBatch();
|
||||||
|
BeanUtils.copyProperties(existingBatch, newBatch);
|
||||||
|
newBatch.setSupplierCode(String.join(",", supplierSet));
|
||||||
|
mergedBatches.put(key, newBatch);
|
||||||
|
} else {
|
||||||
|
// 新建对象,避免外部引用被修改
|
||||||
|
EmisTmsSiteBatch newBatch = new EmisTmsSiteBatch();
|
||||||
|
BeanUtils.copyProperties(batch, newBatch);
|
||||||
|
Set<String> supplierSet = new TreeSet<>();
|
||||||
|
if (StringUtils.isNotBlank(batch.getSupplierCode())) {
|
||||||
|
supplierSet.addAll(Arrays.asList(batch.getSupplierCode().split(",")));
|
||||||
|
}
|
||||||
|
newBatch.setSupplierCode(String.join(",", supplierSet));
|
||||||
|
mergedBatches.put(key, newBatch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
waybillBatches = new ArrayList<>(mergedBatches.values());
|
||||||
|
|
||||||
|
// 检查运单是否匹配线路规划树
|
||||||
|
String startSiteCode = StringUtil.isBlank(waybill.getStartSiteCode()) ? waybill.getSendSiteCode() : waybill.getStartSiteCode();
|
||||||
|
boolean isAnyBranchMatched = checkBranchMatchV2(ruleListByProductType, waybillBatches, waybill,
|
||||||
|
missRecords,startSiteCode);
|
||||||
|
|
||||||
|
if (isAnyBranchMatched) {
|
||||||
|
// 创建批次状态记录
|
||||||
|
EmisWaybillBatchStatus batchStatus = new EmisWaybillBatchStatus();
|
||||||
|
batchStatus.setBillCode(waybill.getBillCode());
|
||||||
|
batchStatus.setSiteBatchStatus("1"); // 1表示匹配成功
|
||||||
|
// batchStatus.setBlManual("1");
|
||||||
|
Date now = new Date();
|
||||||
|
batchStatus.setCreateBy("system");
|
||||||
|
batchStatus.setCreateTime(now);
|
||||||
|
batchStatus.setCreateSite("88888");
|
||||||
|
batchStatusList.add(batchStatus);
|
||||||
|
}
|
||||||
|
successCount++;
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("Failed to process waybill: {}", waybill.getBillCode(), e);
|
||||||
|
failCount++;
|
||||||
|
failedBillCodes.add(waybill.getBillCode());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new ProcessResult(successCount, failCount, failedBillCodes, batchStatusList,
|
||||||
|
missRecords);
|
||||||
|
}
|
||||||
|
|
||||||
|
private EmisTmsSiteBatchMiss createMissRecord(EmisWaybill waybill) {
|
||||||
|
EmisTmsSiteBatchMiss miss = new EmisTmsSiteBatchMiss();
|
||||||
|
miss.setBillCode(waybill.getBillCode());
|
||||||
|
Date now = new Date();
|
||||||
|
miss.setCreateBy("system");
|
||||||
|
miss.setCreateTime(now);
|
||||||
|
miss.setCreateSite("88888");
|
||||||
|
miss.setStartSiteCode(waybill.getStartSiteCode());
|
||||||
|
miss.setNextSiteCode(waybill.getDestinationCode());
|
||||||
|
return miss;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 检查一个分支是否完全匹配(按起始网点递归向下遍历)
|
||||||
|
*
|
||||||
|
* @param ruleList 线路规划规则列表(同一线路+产品类型)
|
||||||
|
* @param waybillBatches 运单批次列表(已按起始/下一网点合并)
|
||||||
|
* @param waybill 运单
|
||||||
|
* @param missRecords 漏组记录集合
|
||||||
|
* @param startSiteCode 当前起始网点
|
||||||
|
* @return 是否存在任意一条完全匹配的路径
|
||||||
|
*/
|
||||||
|
private boolean checkBranchMatchV2(List<EmisTransPlanRule> ruleList, List<EmisTmsSiteBatch> waybillBatches,
|
||||||
|
EmisWaybill waybill, List<EmisTmsSiteBatchMiss> missRecords, String startSiteCode) {
|
||||||
|
if (StringUtils.isBlank(startSiteCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前起始网点下的规则
|
||||||
|
List<EmisTransPlanRule> currentRules = ruleList.stream()
|
||||||
|
.filter(rule -> StringUtils.equals(rule.getStartSiteCode(), startSiteCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
if (CollectionUtil.isEmpty(currentRules)) {
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
|
||||||
|
miss.setMissReason(waybill.getStartSiteName() +" 尚未完成组批次,请尽快完成,避免影响下一程同事组批次进度" );
|
||||||
|
miss.setLineCode(waybill.getTransLineType());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
miss.setStartSiteCode(startSiteCode);
|
||||||
|
miss.setNextSiteCode("");
|
||||||
|
miss.setMissType("0");
|
||||||
|
|
||||||
|
missRecords.add(miss);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 使用包装方法,内部带 visitedSite 防止死循环
|
||||||
|
return checkBranchMatchV2(ruleList, waybillBatches, waybill, missRecords, startSiteCode, new HashSet<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 真正的递归实现,增加 visitedSiteCode 防止起始网点出现环路导致死递归。
|
||||||
|
*/
|
||||||
|
private boolean checkBranchMatchV2(List<EmisTransPlanRule> ruleList,
|
||||||
|
List<EmisTmsSiteBatch> waybillBatches,
|
||||||
|
EmisWaybill waybill,
|
||||||
|
List<EmisTmsSiteBatchMiss> missRecords,
|
||||||
|
String startSiteCode,
|
||||||
|
Set<String> visitedSiteCodes) {
|
||||||
|
|
||||||
|
if (StringUtils.isBlank(startSiteCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 防止环路递归
|
||||||
|
if (!visitedSiteCodes.add(startSiteCode)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前起始网点下的规则
|
||||||
|
List<EmisTransPlanRule> currentRules = ruleList.stream()
|
||||||
|
.filter(rule -> StringUtils.equals(rule.getStartSiteCode(), startSiteCode))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 当前起始网点下没有配置规则,认为本分支到此结束,不再校验
|
||||||
|
if (CollectionUtil.isEmpty(currentRules)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
boolean hasNextSite = false;
|
||||||
|
for (EmisTransPlanRule rule : currentRules) {
|
||||||
|
// 当前下一网点下的规则
|
||||||
|
List<EmisTransPlanRule> nextRules = ruleList.stream()
|
||||||
|
.filter(r -> StringUtils.equals(r.getStartSiteCode(), rule.getNextSiteCode()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
if (CollectionUtil.isNotEmpty(nextRules)) {
|
||||||
|
hasNextSite = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 检查是否为特殊运输线路类型或清关类型
|
||||||
|
boolean isSpecialTransLine = "004".equals(waybill.getTransLineType()) &&
|
||||||
|
("24401".equals(waybill.getProductType()) || "24402".equals(waybill.getProductType()));
|
||||||
|
boolean isSpecialCustomsClear = "2".equals(waybill.getCustomsClear()) && "2".equals(waybill.getTransType());
|
||||||
|
if ((isSpecialTransLine || isSpecialCustomsClear) && !hasNextSite && currentRules.get(0).getStartSiteName().contains("机场")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 当前起点对应的所有批次
|
||||||
|
List<EmisTmsSiteBatch> startBatches = waybillBatches.stream()
|
||||||
|
.filter(batch -> startSiteCode.equals(batch.getStartSiteCode()))
|
||||||
|
.collect(Collectors.toMap(
|
||||||
|
// 以起始网点、下一网点、供应商的组合作为key进行去重
|
||||||
|
batch -> StringUtils.defaultString(batch.getStartSiteCode()) + "_" +
|
||||||
|
StringUtils.defaultString(batch.getNextSiteCode()) + "_" +
|
||||||
|
StringUtils.defaultString(batch.getSupplierCode()),
|
||||||
|
batch -> batch,
|
||||||
|
// 如果key重复,保留第一个
|
||||||
|
(existing, replacement) -> existing
|
||||||
|
))
|
||||||
|
.values()
|
||||||
|
.stream()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 没有任何批次从该网点发出,则这些规则都视为漏组
|
||||||
|
if (CollectionUtil.isEmpty(startBatches)) {
|
||||||
|
setMissRecordsV2(waybill, missRecords, currentRules);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(startBatches.size()>1){
|
||||||
|
setMissRecordsV2(waybill, missRecords, currentRules);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
EmisTmsSiteBatch startBatch = startBatches.get(0);
|
||||||
|
|
||||||
|
boolean anyPathMatched = false;
|
||||||
|
|
||||||
|
// 找到与当前批次(nextSiteCode + supplier)完全匹配的规则
|
||||||
|
List<EmisTransPlanRule> matchedRules = currentRules.stream()
|
||||||
|
.filter(rule -> StringUtils.equals(rule.getNextSiteCode(), startBatch.getNextSiteCode())
|
||||||
|
&& compareSupplierCodes(rule.getSupplierCode(), startBatch.getSupplierCode()) && startBatch.getEtd().before(rule.getEndDate())
|
||||||
|
&& !startBatch.getEtd().before(rule.getStartDate()))
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 如果该批次在当前起点下没有任何匹配规则,则当前起点下的规则整体视为漏组
|
||||||
|
if (CollectionUtil.isEmpty(matchedRules)) {
|
||||||
|
setMissRecordsV2(waybill, missRecords, currentRules);
|
||||||
|
return anyPathMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 存在匹配规则,则沿着下一网点继续递归校验
|
||||||
|
boolean childMatched = checkBranchMatchV2(ruleList, waybillBatches, waybill,
|
||||||
|
missRecords, startBatch.getNextSiteCode(), visitedSiteCodes);
|
||||||
|
|
||||||
|
if (childMatched) {
|
||||||
|
anyPathMatched = true;
|
||||||
|
// 已经有一条路径完全匹配,可以直接返回
|
||||||
|
}
|
||||||
|
|
||||||
|
return anyPathMatched;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 按 V2 规则生成漏组记录:
|
||||||
|
* 循环 ruleList,为每一个 EmisTransPlanRule 生成一条 miss 记录。
|
||||||
|
* 参考 EmisBaseService.setMissRecords 中设置 miss 的逻辑。
|
||||||
|
*/
|
||||||
|
private void setMissRecordsV2(EmisWaybill waybill,
|
||||||
|
List<EmisTmsSiteBatchMiss> missRecords,
|
||||||
|
List<EmisTransPlanRule> ruleList) {
|
||||||
|
if (CollectionUtil.isEmpty(ruleList)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 按规则 ID 去重,避免重复生成同一规则的漏组
|
||||||
|
List<EmisTransPlanRule> distinctRules = ruleList.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.collectingAndThen(
|
||||||
|
Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(EmisTransPlanRule::getId))),
|
||||||
|
ArrayList::new));
|
||||||
|
|
||||||
|
// for (EmisTransPlanRule rule : distinctRules) {
|
||||||
|
// if (rule == null) {
|
||||||
|
// continue;
|
||||||
|
// }
|
||||||
|
// EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
//
|
||||||
|
// String supplierNames = rule.getSupplierName();
|
||||||
|
// String missReasonDetail = String.format("%s-%s-%s",
|
||||||
|
// StringUtils.defaultString(rule.getStartSiteName(), rule.getStartSiteCode()),
|
||||||
|
// StringUtils.defaultString(rule.getNextSiteName(), rule.getNextSiteCode()),
|
||||||
|
// StringUtils.defaultString(supplierNames, rule.getSupplierCode()));
|
||||||
|
// miss.setMissReason("组批次有遗漏/错误,请根据推荐路线排查: " + missReasonDetail);
|
||||||
|
//
|
||||||
|
// // 参考 EmisBaseService.setRule 填充规则相关字段
|
||||||
|
// miss.setTransPlanRuleId(rule.getId());
|
||||||
|
// miss.setLineCode(rule.getLineCode());
|
||||||
|
// miss.setProductType(waybill.getProductType());
|
||||||
|
// miss.setStartSiteCode(rule.getStartSiteCode());
|
||||||
|
// miss.setNextSiteCode(rule.getNextSiteCode());
|
||||||
|
// miss.setManager(rule.getManager());
|
||||||
|
// miss.setSupplierCode(rule.getSupplierCode());
|
||||||
|
// miss.setStartDate(rule.getStartDate());
|
||||||
|
// miss.setEndDate(rule.getEndDate());
|
||||||
|
// miss.setMissType("0");
|
||||||
|
//
|
||||||
|
// missRecords.add(miss);
|
||||||
|
// }
|
||||||
|
|
||||||
|
EmisTransPlanRule rule = distinctRules.get(0);
|
||||||
|
EmisTmsSiteBatchMiss miss = createMissRecord(waybill);
|
||||||
|
|
||||||
|
miss.setMissReason(rule.getStartSiteName() +" 尚未完成组批次,请尽快完成,避免影响下一程同事组批次进度" );
|
||||||
|
|
||||||
|
// 参考 EmisBaseService.setRule 填充规则相关字段
|
||||||
|
miss.setTransPlanRuleId(rule.getId());
|
||||||
|
miss.setLineCode(rule.getLineCode());
|
||||||
|
miss.setProductType(waybill.getProductType());
|
||||||
|
miss.setStartSiteCode(rule.getStartSiteCode());
|
||||||
|
miss.setNextSiteCode("");
|
||||||
|
miss.setManager(rule.getManager());
|
||||||
|
// miss.setSupplierCode(rule.getSupplierCode());
|
||||||
|
miss.setStartDate(rule.getStartDate());
|
||||||
|
miss.setEndDate(rule.getEndDate());
|
||||||
|
miss.setMissType("0");
|
||||||
|
|
||||||
|
missRecords.add(miss);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -55,6 +55,21 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 查询漏组批次统计列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public List<EmisTmsSiteBatchMissStatistics> selectStatisticsListV2(
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
log.info("查询漏组批次统计列表,startSiteCode: {}, billMonth: {}",
|
||||||
|
emisTmsSiteBatchMissStatistics.getStartSiteCode(), emisTmsSiteBatchMissStatistics.getBillMonth());
|
||||||
|
|
||||||
|
List<EmisTmsSiteBatchMissStatistics> result = statisticsMapper
|
||||||
|
.selectStatisticsListV2(emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 导出漏组批次统计查询接口数据
|
* 导出漏组批次统计查询接口数据
|
||||||
*/
|
*/
|
||||||
@ -89,6 +104,40 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出漏组批次统计查询接口数据
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void exportStatisticsDataV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
try {
|
||||||
|
// 设置响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("漏组批次统计汇总_" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+",
|
||||||
|
"%20");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
// 查询统计数据
|
||||||
|
List<EmisTmsSiteBatchMissStatistics> statisticsList = selectStatisticsListV2(emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
// 转换为导出格式
|
||||||
|
List<EmisTmsSiteBatchMissStatisticsExport> exportList = convertToExportFormat(statisticsList);
|
||||||
|
|
||||||
|
// 添加合计行
|
||||||
|
addTotalRow(exportList);
|
||||||
|
|
||||||
|
// 导出Excel
|
||||||
|
EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMissStatisticsExport.class)
|
||||||
|
.sheet("漏组批次统计汇总")
|
||||||
|
.doWrite(exportList);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
log.error("导出漏组批次统计数据失败", e);
|
||||||
|
throw new RuntimeException("导出失败:" + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 转换为导出格式
|
* 转换为导出格式
|
||||||
*/
|
*/
|
||||||
@ -363,6 +412,136 @@ public class EmisTmsSiteBatchMissStatisticsServiceImpl implements IEmisTmsSiteBa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 流式导出漏组详细数据(按月份分sheet)- 性能优化版本
|
||||||
|
* 支持大数据量导出,避免内存溢出
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void exportDetailDataByMonthStreamV2(HttpServletResponse response,
|
||||||
|
EmisTmsSiteBatchMissStatistics emisTmsSiteBatchMissStatistics) {
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
try {
|
||||||
|
// 设置响应头
|
||||||
|
response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
|
||||||
|
response.setCharacterEncoding("utf-8");
|
||||||
|
String fileName = URLEncoder.encode("漏组详细数据_" + System.currentTimeMillis(), "UTF-8").replaceAll("\\+",
|
||||||
|
"%20");
|
||||||
|
response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
|
||||||
|
|
||||||
|
// 先获取总记录数,用于进度跟踪
|
||||||
|
long totalCount = statisticsMapper.countDetailDataByMonthV2(emisTmsSiteBatchMissStatistics);
|
||||||
|
log.info("开始流式导出漏组详细数据,总记录数: {}, 查询条件: {}", totalCount, emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
if (totalCount == 0) {
|
||||||
|
// 创建空Excel
|
||||||
|
EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMiss.class)
|
||||||
|
.sheet("无数据")
|
||||||
|
.doWrite(new ArrayList<>());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 简化版本:直接查询所有数据并导出,避免复杂的流式处理
|
||||||
|
// 如果数据量很大,可以考虑分批处理
|
||||||
|
List<EmisTmsSiteBatchMiss> allData = statisticsMapper
|
||||||
|
.selectDetailDataByMonthV2(emisTmsSiteBatchMissStatistics);
|
||||||
|
|
||||||
|
log.info("查询到数据条数: {}", allData != null ? allData.size() : 0);
|
||||||
|
|
||||||
|
if (allData == null || allData.isEmpty()) {
|
||||||
|
EasyExcel.write(response.getOutputStream(), EmisTmsSiteBatchMissExport.class)
|
||||||
|
.sheet("无数据")
|
||||||
|
.doWrite(new ArrayList<>());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 转换为专门的导出DTO,避免Map类型问题
|
||||||
|
List<EmisTmsSiteBatchMissExport> exportData = allData.stream()
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.map(this::convertToExportDto)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
log.info("转换后数据条数: {}", exportData.size());
|
||||||
|
|
||||||
|
// 按月份分组数据
|
||||||
|
Map<String, List<EmisTmsSiteBatchMissExport>> dataByMonth = exportData.stream()
|
||||||
|
.collect(Collectors.groupingBy(item -> {
|
||||||
|
if (item.getSendDate() != null) {
|
||||||
|
synchronized (MONTH_FORMAT) {
|
||||||
|
return MONTH_FORMAT.format(item.getSendDate());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "未知月份";
|
||||||
|
}));
|
||||||
|
|
||||||
|
// 创建Excel写入器
|
||||||
|
ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).build();
|
||||||
|
|
||||||
|
// 按月份从小到大排序
|
||||||
|
List<String> sortedMonths = dataByMonth.keySet().stream()
|
||||||
|
.filter(month -> !"未知月份".equals(month))
|
||||||
|
.sorted()
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 如果有未知月份,放在最后
|
||||||
|
if (dataByMonth.containsKey("未知月份")) {
|
||||||
|
sortedMonths.add("未知月份");
|
||||||
|
}
|
||||||
|
|
||||||
|
int sheetIndex = 0;
|
||||||
|
for (String month : sortedMonths) {
|
||||||
|
List<EmisTmsSiteBatchMissExport> monthData = dataByMonth.get(month);
|
||||||
|
|
||||||
|
if (monthData != null && !monthData.isEmpty()) {
|
||||||
|
// 创建sheet,使用月份作为sheet名称
|
||||||
|
String sheetName = month + "月";
|
||||||
|
WriteSheet writeSheet = EasyExcel.writerSheet(sheetIndex, sheetName)
|
||||||
|
.head(EmisTmsSiteBatchMissExport.class)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// 写入数据
|
||||||
|
excelWriter.write(monthData, writeSheet);
|
||||||
|
sheetIndex++;
|
||||||
|
log.info("写入{}月数据,条数: {}", month, monthData.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 关闭写入器
|
||||||
|
excelWriter.finish();
|
||||||
|
log.info("Excel写入成功,共创建{}个sheet", sheetIndex);
|
||||||
|
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
long duration = endTime - startTime;
|
||||||
|
log.info("流式导出完成,总处理记录数: {}, 耗时: {}ms, 平均处理速度: {}/s",
|
||||||
|
allData.size(), duration, allData.size() > 0 ? (allData.size() * 1000 / duration) : 0);
|
||||||
|
|
||||||
|
} catch (IOException e) {
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
log.error("流式导出漏组详细数据失败,耗时: {}ms", endTime - startTime, e);
|
||||||
|
// 不抛出异常,避免重复处理响应
|
||||||
|
try {
|
||||||
|
if (!response.isCommitted()) {
|
||||||
|
response.reset();
|
||||||
|
response.setContentType("application/json;charset=utf-8");
|
||||||
|
response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("写入错误响应失败", ex);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
long endTime = System.currentTimeMillis();
|
||||||
|
log.error("流式导出漏组详细数据发生未知错误,耗时: {}ms", endTime - startTime, e);
|
||||||
|
try {
|
||||||
|
if (!response.isCommitted()) {
|
||||||
|
response.reset();
|
||||||
|
response.setContentType("application/json;charset=utf-8");
|
||||||
|
response.getWriter().write("{\"success\":false,\"message\":\"导出失败:" + e.getMessage() + "\"}");
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
log.error("写入错误响应失败", ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 将EmisTmsSiteBatchMiss转换为EmisTmsSiteBatchMissExport用于导出
|
* 将EmisTmsSiteBatchMiss转换为EmisTmsSiteBatchMissExport用于导出
|
||||||
* 根据实际Excel截图字段进行映射
|
* 根据实际Excel截图字段进行映射
|
||||||
|
|||||||
@ -27,6 +27,7 @@ import com.xdadan.erp.emis.mapper.EmisTmsSiteBatchLogMapper;
|
|||||||
import com.xdadan.erp.emis.mapper.EmisWaybillMapper;
|
import com.xdadan.erp.emis.mapper.EmisWaybillMapper;
|
||||||
import com.xdadan.erp.emis.mapper.EmisTmsCostFeeMapper;
|
import com.xdadan.erp.emis.mapper.EmisTmsCostFeeMapper;
|
||||||
import com.xdadan.erp.emis.service.EmisBaseService;
|
import com.xdadan.erp.emis.service.EmisBaseService;
|
||||||
|
import com.xdadan.erp.emis.service.IEmisTmsSiteBatchMissService;
|
||||||
import jodd.util.StringUtil;
|
import jodd.util.StringUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
@ -71,6 +72,9 @@ public class EmisTmsSiteBatchServiceImpl extends EmisBaseService implements IEmi
|
|||||||
@Autowired
|
@Autowired
|
||||||
private EmisTmsCostFeeMapper emisTmsCostFeeMapper;
|
private EmisTmsCostFeeMapper emisTmsCostFeeMapper;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private IEmisTmsSiteBatchMissService emisTmsSiteBatchMissService;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取稽核数据
|
* 获取稽核数据
|
||||||
*
|
*
|
||||||
@ -512,6 +516,20 @@ public class EmisTmsSiteBatchServiceImpl extends EmisBaseService implements IEmi
|
|||||||
scanSiteBatchByWaybills(waybills);
|
scanSiteBatchByWaybills(waybills);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Async
|
||||||
|
public void scanSiteBatchV2(String batchNo) {
|
||||||
|
log.info("start scan site batch V2 ,batchNo:{}", batchNo);
|
||||||
|
if (StringUtil.isBlank(batchNo)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<EmisWaybill> waybills = emisTmsSiteBatchDtlMapper.selectEmisWayBillByBatchNo(batchNo);
|
||||||
|
if (CollectionUtil.isEmpty(waybills)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
emisTmsSiteBatchMissService.scanSiteBatchByWaybillsV2(waybills);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional
|
@Transactional
|
||||||
public int addAll(EmisTmsSiteBatch emisTmsSiteBatch) throws EmisBizError {
|
public int addAll(EmisTmsSiteBatch emisTmsSiteBatch) throws EmisBizError {
|
||||||
|
|||||||
@ -91,6 +91,42 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
left join sys_user u on w.register_man_code=u.emp_code and u.del_flag='0'
|
left join sys_user u on w.register_man_code=u.emp_code and u.del_flag='0'
|
||||||
</sql>
|
</sql>
|
||||||
|
|
||||||
|
<sql id="selectEmisTmsSiteBatchMissVoV2">
|
||||||
|
select
|
||||||
|
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
||||||
|
m.line_code, m.product_type,
|
||||||
|
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
|
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
||||||
|
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
||||||
|
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
||||||
|
l.line_name as line_name,
|
||||||
|
w.receive_country, c2.name as receive_country_name, w.send_date, w.bl_sign, w.sign_date,
|
||||||
|
w.product_type,w.problem_type,w.virtual_remark,w.dispatch_underling_site_code,
|
||||||
|
w.payment_type, w.parcel_qty, w.bill_weight, w.total_volume, w.volume_weight,
|
||||||
|
w.settlement_weight, w.freight, w.remark as waybill_remark, w.fee_remark, m.manager, k.trans_manager,
|
||||||
|
w.payee, w.salesmen, u.emp_name as registerManName,
|
||||||
|
(SELECT GROUP_CONCAT(s.name)
|
||||||
|
FROM emis_supplier s
|
||||||
|
WHERE FIND_IN_SET(s.code, m.supplier_code)
|
||||||
|
AND s.del_flag = '0') as supplier_name,
|
||||||
|
(SELECT GROUP_CONCAT(p.prod_name)
|
||||||
|
FROM emis_trans_product p
|
||||||
|
WHERE FIND_IN_SET(p.prod_code, m.product_type)
|
||||||
|
AND p.del_flag = '0') as product_type_name
|
||||||
|
from emis_tms_site_batch_miss_v2 m
|
||||||
|
left join emis_waybill w on m.bill_code = w.bill_code and w.del_flag='0'
|
||||||
|
left join emis_site s1 on w.send_site_code=s1.site_code and s1.del_flag=0
|
||||||
|
left join emis_site s2 on COALESCE(m.start_site_code, w.start_site_code, w.send_site_code)=s2.site_code and s2.del_flag=0
|
||||||
|
left join emis_site s3 on COALESCE(m.next_site_code, w.destination_code)=s3.site_code and s3.del_flag=0
|
||||||
|
left join emis_country c1 on w.send_country=c1.code and c1.del_flag='0'
|
||||||
|
left join emis_country c2 on w.receive_country=c2.code and c2.del_flag='0'
|
||||||
|
left join emis_site s4 on w.dispatch_underling_site_code=s4.site_code and s4.del_flag=0
|
||||||
|
left join emis_trans_line k on w.trans_line_type=k.line_code and k.del_flag='0'
|
||||||
|
left join emis_trans_plan_rule r on m.trans_plan_rule_id=r.id and r.del_flag='0'
|
||||||
|
left join emis_trans_line l on m.line_code=l.line_code and l.del_flag='0'
|
||||||
|
left join sys_user u on w.register_man_code=u.emp_code and u.del_flag='0'
|
||||||
|
</sql>
|
||||||
|
|
||||||
<!-- <select id="selectEmisTmsSiteBatchMissList" parameterType="EmisTmsSiteBatchMiss" resultMap="EmisTmsSiteBatchMissResult">-->
|
<!-- <select id="selectEmisTmsSiteBatchMissList" parameterType="EmisTmsSiteBatchMiss" resultMap="EmisTmsSiteBatchMissResult">-->
|
||||||
<!-- <include refid="selectEmisTmsSiteBatchMissVo"/>-->
|
<!-- <include refid="selectEmisTmsSiteBatchMissVo"/>-->
|
||||||
<!-- <where>-->
|
<!-- <where>-->
|
||||||
@ -148,8 +184,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
b.bill_code, null as id, '已组批次成功' as miss_reason,
|
b.bill_code, null as id, '已组批次成功' as miss_reason,
|
||||||
null as create_by, null as create_time, null as update_by, null as update_time,
|
null as create_by, null as create_time, null as update_by, null as update_time,
|
||||||
null as remark, '0' as del_flag,
|
null as remark, '0' as del_flag,
|
||||||
w.trans_line_type as line_code, w.product_type,
|
w.trans_line_type as line_code, w.product_type,
|
||||||
COALESCE(null, w.start_site_code, w.send_site_code) as start_site_code,
|
COALESCE(null, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
COALESCE(null, w.destination_code) as next_site_code,
|
COALESCE(null, w.destination_code) as next_site_code,
|
||||||
null as supplier_code, null as start_date, null as end_date, '0' as miss_type,
|
null as supplier_code, null as start_date, null as end_date, '0' as miss_type,
|
||||||
w.send_site_code, s1.site_name as send_site_name,
|
w.send_site_code, s1.site_name as send_site_name,
|
||||||
@ -350,6 +386,219 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</choose>
|
</choose>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectEmisTmsSiteBatchMissListV2" parameterType="EmisTmsSiteBatchMiss" resultMap="EmisTmsSiteBatchMissResult">
|
||||||
|
<choose>
|
||||||
|
<when test="missCount == -4 or missCount == -7">
|
||||||
|
<!-- 当missCount=-4时,查询emis_waybill_batch_status表 -->
|
||||||
|
select
|
||||||
|
b.bill_code, null as id, '已组批次成功' as miss_reason,
|
||||||
|
null as create_by, null as create_time, null as update_by, null as update_time,
|
||||||
|
null as remark, '0' as del_flag,
|
||||||
|
w.trans_line_type as line_code, w.product_type,
|
||||||
|
COALESCE(null, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
|
COALESCE(null, w.destination_code) as next_site_code,
|
||||||
|
null as supplier_code, null as start_date, null as end_date, '0' as miss_type,
|
||||||
|
w.send_site_code, s1.site_name as send_site_name,
|
||||||
|
w.send_country, c1.name as send_country_name, w.destination_code, s2.site_name as dispatch_underling_site_name, w.bl_is_question,
|
||||||
|
l.line_name as line_name,
|
||||||
|
w.receive_country, c2.name as receive_country_name, w.send_date, w.bl_sign, w.sign_date,
|
||||||
|
w.payment_type, w.parcel_qty, w.bill_weight, w.total_volume, w.volume_weight,
|
||||||
|
w.settlement_weight, w.freight, w.remark as waybill_remark, w.fee_remark,
|
||||||
|
null as manager, null as trans_manager,
|
||||||
|
w.payee, w.salesmen, u.emp_name as registerManName,
|
||||||
|
(SELECT GROUP_CONCAT(s.site_name ORDER BY FIND_IN_SET(s.site_code, w.start_site_code))
|
||||||
|
FROM emis_site s
|
||||||
|
WHERE FIND_IN_SET(s.site_code, w.start_site_code) AND s.del_flag = 0) as start_site_name,
|
||||||
|
(SELECT GROUP_CONCAT(s.site_name ORDER BY FIND_IN_SET(s.site_code, w.next_site_code))
|
||||||
|
FROM emis_site s
|
||||||
|
WHERE FIND_IN_SET(s.site_code, w.next_site_code) AND s.del_flag = 0) as next_site_name,
|
||||||
|
null as supplier_name,
|
||||||
|
(SELECT GROUP_CONCAT(p.prod_name)
|
||||||
|
FROM emis_trans_product p
|
||||||
|
WHERE FIND_IN_SET(p.prod_code, w.product_type)
|
||||||
|
AND p.del_flag = '0') as product_type_name,
|
||||||
|
b.remark as manual_remark,b.bl_manual
|
||||||
|
from emis_waybill_batch_status b
|
||||||
|
inner join emis_waybill w on b.bill_code = w.bill_code and w.del_flag='0'
|
||||||
|
left join emis_site s1 on w.send_site_code=s1.site_code and s1.del_flag=0
|
||||||
|
left join emis_country c1 on w.send_country=c1.code and c1.del_flag=0
|
||||||
|
left join emis_site s2 on w.dispatch_underling_site_code=s2.site_code and s2.del_flag=0
|
||||||
|
left join emis_trans_line l on w.trans_line_type=l.line_code and l.del_flag=0
|
||||||
|
left join emis_country c2 on w.receive_country=c2.code and c2.del_flag=0
|
||||||
|
left join sys_user u on w.register_man_code=u.emp_code and u.del_flag='0'
|
||||||
|
<where>
|
||||||
|
b.site_batch_status = '1'
|
||||||
|
<if test="billCode != null and billCode != '' and ( params.billCodeSortList == null or (params.billCodeSortList != null and params.billCodeSortList.size() == 1 ) )">
|
||||||
|
and ( b.`bill_code`=#{billCode} or b.bill_code like concat('%',#{billCode}) )
|
||||||
|
</if>
|
||||||
|
<if test="missCount == -7">
|
||||||
|
AND (b.bl_manual = '2' or b.bl_manual = '3')
|
||||||
|
</if>
|
||||||
|
<if test="params.billCodeSortList != null and params.billCodeSortList.size() > 1 ">
|
||||||
|
and b.bill_code in
|
||||||
|
<foreach collection="params.billCodeSortList" item="item" open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="lineCode != null and lineCode != ''">
|
||||||
|
AND w.trans_line_type = #{lineCode}
|
||||||
|
</if>
|
||||||
|
<if test="productType != null and productType != ''">
|
||||||
|
AND FIND_IN_SET(#{productType}, w.product_type)
|
||||||
|
</if>
|
||||||
|
<if test="startSiteCode != null and startSiteCode != ''">
|
||||||
|
AND (
|
||||||
|
w.start_site_code REGEXP REPLACE(#{startSiteCode}, ',', '|')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="nextSiteCode != null and nextSiteCode != ''">
|
||||||
|
AND (
|
||||||
|
w.next_site_code REGEXP REPLACE(#{nextSiteCode}, ',', '|')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="blIsQuestion != null and blIsQuestion != ''">
|
||||||
|
AND w.bl_is_question = #{blIsQuestion}
|
||||||
|
</if>
|
||||||
|
<if test="sendSiteCode != null and sendSiteCode != ''">
|
||||||
|
AND w.send_site_code = #{sendSiteCode}
|
||||||
|
</if>
|
||||||
|
<if test="params.beginSendDate != null and params.beginSendDate != ''">
|
||||||
|
and w.send_date <![CDATA[ >= ]]> #{params.beginSendDate}
|
||||||
|
</if>
|
||||||
|
<if test="params.endSendDate != null and params.endSendDate != ''">
|
||||||
|
and w.send_date <![CDATA[ <= ]]> #{params.endSendDate}
|
||||||
|
</if>
|
||||||
|
<if test="params.privSiteCode != null and params.privSiteCode != '88888'">
|
||||||
|
and (w.start_site_code=#{params.privSiteCode} or w.send_site_code=#{params.privSiteCode})
|
||||||
|
</if>
|
||||||
|
<if test="payee != null and payee != ''">
|
||||||
|
AND w.payee like concat('%', #{payee}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="salesmen != null and salesmen != ''">
|
||||||
|
AND w.salesmen like concat('%', #{salesmen}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="registerManName != null and registerManName != ''">
|
||||||
|
AND u.emp_name like concat('%', #{registerManName}, '%')
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
</when>
|
||||||
|
<otherwise>
|
||||||
|
<include refid="selectEmisTmsSiteBatchMissVoV2"/>
|
||||||
|
<where>
|
||||||
|
m.del_flag = '0'
|
||||||
|
<if test="missCount != null">
|
||||||
|
<choose>
|
||||||
|
<when test="missCount == -1">
|
||||||
|
AND m.miss_type = 2
|
||||||
|
</when>
|
||||||
|
<when test="missCount == -2">
|
||||||
|
AND m.miss_type = 3
|
||||||
|
</when>
|
||||||
|
<when test="missCount == -3">
|
||||||
|
AND m.miss_type = 1
|
||||||
|
</when>
|
||||||
|
<when test="missCount == -6">
|
||||||
|
AND m.miss_type = 4
|
||||||
|
</when>
|
||||||
|
<when test="missCount == 1">
|
||||||
|
AND m.miss_type = 0
|
||||||
|
</when>
|
||||||
|
<!-- <when test="missCount == -5">-->
|
||||||
|
<!-- AND m.bill_code IN (-->
|
||||||
|
<!-- SELECT bill_code-->
|
||||||
|
<!-- FROM emis_tms_site_batch_miss-->
|
||||||
|
<!-- WHERE del_flag = '0'-->
|
||||||
|
<!-- GROUP BY bill_code-->
|
||||||
|
<!-- HAVING COUNT(*) > 9-->
|
||||||
|
<!-- )-->
|
||||||
|
<!-- </when>-->
|
||||||
|
<!-- <when test="missCount > 0">-->
|
||||||
|
<!-- AND m.bill_code IN (-->
|
||||||
|
<!-- SELECT bill_code-->
|
||||||
|
<!-- FROM emis_tms_site_batch_miss-->
|
||||||
|
<!-- WHERE del_flag = '0'-->
|
||||||
|
<!-- GROUP BY bill_code-->
|
||||||
|
<!-- HAVING COUNT(*) = #{missCount}-->
|
||||||
|
<!-- )-->
|
||||||
|
<!-- AND m.miss_type = 0-->
|
||||||
|
<!-- </when>-->
|
||||||
|
</choose>
|
||||||
|
</if>
|
||||||
|
<if test="billCode != null and billCode != '' and ( params.billCodeSortList == null or (params.billCodeSortList != null and params.billCodeSortList.size() == 1 ) )">
|
||||||
|
and ( m.`bill_code`=#{billCode} or m.bill_code like concat('%',#{billCode}) )
|
||||||
|
</if>
|
||||||
|
<if test="params.billCodeSortList != null and params.billCodeSortList.size() > 1 ">
|
||||||
|
and m.bill_code in
|
||||||
|
<foreach collection="params.billCodeSortList" item="item" open="(" separator="," close=")">
|
||||||
|
#{item}
|
||||||
|
</foreach>
|
||||||
|
</if>
|
||||||
|
<if test="missReason != null and missReason != ''">
|
||||||
|
AND m.miss_reason like concat('%', #{missReason}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="manager != null and manager != ''">
|
||||||
|
AND (
|
||||||
|
m.manager REGEXP REPLACE(#{manager}, ',', '|')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="transManager != null and transManager != ''">
|
||||||
|
AND k.trans_manager like concat('%', #{transManager}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="params.privSiteCode != null and params.privSiteCode != '88888'">
|
||||||
|
and (w.start_site_code=#{params.privSiteCode} or w.send_site_code=#{params.privSiteCode} or m.start_site_code=#{params.privSiteCode} or m.next_site_code=#{params.privSiteCode})
|
||||||
|
</if>
|
||||||
|
<if test="lineCode != null and lineCode != ''">
|
||||||
|
AND m.line_code = #{lineCode}
|
||||||
|
</if>
|
||||||
|
<if test="productType != null and productType != ''">
|
||||||
|
AND FIND_IN_SET(#{productType}, m.product_type)
|
||||||
|
</if>
|
||||||
|
<if test="startSiteCode != null and startSiteCode != ''">
|
||||||
|
AND (
|
||||||
|
m.start_site_code REGEXP REPLACE(#{startSiteCode}, ',', '|')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="nextSiteCode != null and nextSiteCode != ''">
|
||||||
|
AND (
|
||||||
|
m.next_site_code REGEXP REPLACE(#{nextSiteCode}, ',', '|')
|
||||||
|
)
|
||||||
|
</if>
|
||||||
|
<if test="supplierCode != null and supplierCode != ''">
|
||||||
|
AND FIND_IN_SET(#{supplierCode}, m.supplier_code)
|
||||||
|
</if>
|
||||||
|
<if test="startDate != null">
|
||||||
|
AND m.start_date = #{startDate}
|
||||||
|
</if>
|
||||||
|
<if test="endDate != null">
|
||||||
|
AND m.end_date = #{endDate}
|
||||||
|
</if>
|
||||||
|
<if test="blIsQuestion != null and blIsQuestion != ''">
|
||||||
|
AND w.bl_is_question = #{blIsQuestion}
|
||||||
|
</if>
|
||||||
|
<if test="sendSiteCode != null and sendSiteCode != ''">
|
||||||
|
AND w.send_site_code = #{sendSiteCode}
|
||||||
|
</if>
|
||||||
|
<if test="params.beginSendDate != null and params.beginSendDate != ''">
|
||||||
|
and w.send_date <![CDATA[ >= ]]> #{params.beginSendDate}
|
||||||
|
</if>
|
||||||
|
<if test="params.endSendDate != null and params.endSendDate != ''">
|
||||||
|
and w.send_date <![CDATA[ <= ]]> #{params.endSendDate}
|
||||||
|
</if>
|
||||||
|
<if test="payee != null and payee != ''">
|
||||||
|
AND w.payee like concat('%', #{payee}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="salesmen != null and salesmen != ''">
|
||||||
|
AND w.salesmen like concat('%', #{salesmen}, '%')
|
||||||
|
</if>
|
||||||
|
<if test="registerManName != null and registerManName != ''">
|
||||||
|
AND u.emp_name like concat('%', #{registerManName}, '%')
|
||||||
|
</if>
|
||||||
|
</where>
|
||||||
|
order by m.bill_code desc
|
||||||
|
</otherwise>
|
||||||
|
</choose>
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectEmisTmsSiteBatchMissById" parameterType="Long" resultMap="EmisTmsSiteBatchMissResult">
|
<select id="selectEmisTmsSiteBatchMissById" parameterType="Long" resultMap="EmisTmsSiteBatchMissResult">
|
||||||
<include refid="selectEmisTmsSiteBatchMissVo"/>
|
<include refid="selectEmisTmsSiteBatchMissVo"/>
|
||||||
where m.id = #{id} and m.del_flag = '0'
|
where m.id = #{id} and m.del_flag = '0'
|
||||||
@ -414,6 +663,13 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</if>
|
</if>
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
|
<delete id="deleteReallyV2">
|
||||||
|
delete from emis_tms_site_batch_miss_v2
|
||||||
|
<if test="lineCode != null and lineCode != ''">
|
||||||
|
where line_code = #{lineCode}
|
||||||
|
</if>
|
||||||
|
</delete>
|
||||||
|
|
||||||
<update id="deleteByBillCodes">
|
<update id="deleteByBillCodes">
|
||||||
update emis_tms_site_batch_miss set del_flag = '1'
|
update emis_tms_site_batch_miss set del_flag = '1'
|
||||||
where bill_code in
|
where bill_code in
|
||||||
@ -422,6 +678,14 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</foreach>
|
</foreach>
|
||||||
</update>
|
</update>
|
||||||
|
|
||||||
|
<update id="deleteByBillCodesV2">
|
||||||
|
update emis_tms_site_batch_miss_v2 set del_flag = '1'
|
||||||
|
where bill_code in
|
||||||
|
<foreach collection="billCodes" item="billCode" open="(" separator="," close=")">
|
||||||
|
#{billCode}
|
||||||
|
</foreach>
|
||||||
|
</update>
|
||||||
|
|
||||||
<insert id="batchInsertEmisTmsSiteBatchMiss" parameterType="java.util.List">
|
<insert id="batchInsertEmisTmsSiteBatchMiss" parameterType="java.util.List">
|
||||||
insert into emis_tms_site_batch_miss
|
insert into emis_tms_site_batch_miss
|
||||||
(trans_plan_rule_id, bill_code, miss_reason, line_code,manager, product_type,
|
(trans_plan_rule_id, bill_code, miss_reason, line_code,manager, product_type,
|
||||||
@ -454,6 +718,38 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</foreach>
|
</foreach>
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
|
<insert id="batchInsertEmisTmsSiteBatchMissV2" parameterType="java.util.List">
|
||||||
|
insert into emis_tms_site_batch_miss_v2
|
||||||
|
(trans_plan_rule_id, bill_code, miss_reason, line_code,manager, product_type,
|
||||||
|
start_site_code, next_site_code, supplier_code, start_date, end_date,
|
||||||
|
create_by, create_time, update_by, update_time, remark,
|
||||||
|
create_site, update_site, miss_type)
|
||||||
|
values
|
||||||
|
<foreach collection="list" item="item" separator=",">
|
||||||
|
(
|
||||||
|
#{item.transPlanRuleId,jdbcType=BIGINT},
|
||||||
|
#{item.billCode,jdbcType=VARCHAR},
|
||||||
|
#{item.missReason,jdbcType=VARCHAR},
|
||||||
|
#{item.lineCode,jdbcType=VARCHAR},
|
||||||
|
#{item.manager,jdbcType=VARCHAR},
|
||||||
|
#{item.productType,jdbcType=VARCHAR},
|
||||||
|
#{item.startSiteCode,jdbcType=VARCHAR},
|
||||||
|
#{item.nextSiteCode,jdbcType=VARCHAR},
|
||||||
|
#{item.supplierCode,jdbcType=VARCHAR},
|
||||||
|
#{item.startDate,jdbcType=TIMESTAMP},
|
||||||
|
#{item.endDate,jdbcType=TIMESTAMP},
|
||||||
|
#{item.createBy,jdbcType=VARCHAR},
|
||||||
|
#{item.createTime,jdbcType=TIMESTAMP},
|
||||||
|
#{item.updateBy,jdbcType=VARCHAR},
|
||||||
|
#{item.updateTime,jdbcType=TIMESTAMP},
|
||||||
|
#{item.remark,jdbcType=VARCHAR},
|
||||||
|
#{item.createSite,jdbcType=VARCHAR},
|
||||||
|
#{item.updateSite,jdbcType=VARCHAR},
|
||||||
|
#{item.missType,jdbcType=VARCHAR}
|
||||||
|
)
|
||||||
|
</foreach>
|
||||||
|
</insert>
|
||||||
|
|
||||||
<select id="selectByBillCodeCount" parameterType="Integer" resultMap="EmisTmsSiteBatchMissResult">
|
<select id="selectByBillCodeCount" parameterType="Integer" resultMap="EmisTmsSiteBatchMissResult">
|
||||||
SELECT t.*
|
SELECT t.*
|
||||||
FROM emis_tms_site_batch_miss t
|
FROM emis_tms_site_batch_miss t
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
<mapper namespace="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissRecordMapper">
|
<mapper namespace="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissRecordMapper">
|
||||||
|
|
||||||
<resultMap type="EmisTmsSiteBatchMissRecord" id="EmisTmsSiteBatchMissRecordResult">
|
<resultMap type="EmisTmsSiteBatchMissRecord" id="EmisTmsSiteBatchMissRecordResult">
|
||||||
<result property="id" column="id"/>
|
<result property="id" column="id"/>
|
||||||
<result property="totalProcessed" column="total_processed"/>
|
<result property="totalProcessed" column="total_processed"/>
|
||||||
@ -29,7 +29,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
failed_bill_codes,
|
failed_bill_codes,
|
||||||
create_by,
|
create_by,
|
||||||
create_time,
|
create_time,
|
||||||
create_site
|
create_site,
|
||||||
|
scan_version
|
||||||
) values (
|
) values (
|
||||||
#{totalProcessed},
|
#{totalProcessed},
|
||||||
#{successCount},
|
#{successCount},
|
||||||
@ -40,8 +41,9 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
#{failedBillCodes},
|
#{failedBillCodes},
|
||||||
#{createBy},
|
#{createBy},
|
||||||
#{createTime},
|
#{createTime},
|
||||||
#{createSite}
|
#{createSite},
|
||||||
|
#{scanVersion}
|
||||||
)
|
)
|
||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -39,12 +39,40 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
ORDER BY w.send_date, COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code)
|
ORDER BY w.send_date, COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code)
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectStatisticsListV2" parameterType="EmisTmsSiteBatchMissStatistics" resultMap="EmisTmsSiteBatchMissStatisticsResult">
|
||||||
|
SELECT
|
||||||
|
COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
|
s.site_name as start_site_name,
|
||||||
|
STR_TO_DATE(CONCAT(DATE_FORMAT(w.send_date, '%Y-%m'), '-01'), '%Y-%m-%d') as bill_month,
|
||||||
|
COUNT(*) as ticket_count
|
||||||
|
FROM emis_tms_site_batch_miss_v2 bm
|
||||||
|
LEFT JOIN emis_waybill w ON bm.bill_code = w.bill_code AND w.del_flag = '0'
|
||||||
|
LEFT JOIN emis_site s ON COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code) = s.site_code AND s.del_flag = '0'
|
||||||
|
WHERE bm.del_flag = '0'
|
||||||
|
<if test="startSiteCode != null and startSiteCode != ''">
|
||||||
|
AND COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code) = #{startSiteCode}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null and startTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null and endTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
<if test="(startTime == null or startTime == '') and (endTime == null or endTime == '')">
|
||||||
|
<if test="billMonth != null">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
|
||||||
|
</if>
|
||||||
|
</if>
|
||||||
|
GROUP BY COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code), s.site_name, DATE_FORMAT(w.send_date, '%Y-%m')
|
||||||
|
ORDER BY w.send_date, COALESCE(bm.start_site_code, w.start_site_code, w.send_site_code)
|
||||||
|
</select>
|
||||||
|
|
||||||
<select id="selectDetailDataByMonth" parameterType="EmisTmsSiteBatchMiss" resultMap="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper.EmisTmsSiteBatchMissResult">
|
<select id="selectDetailDataByMonth" parameterType="EmisTmsSiteBatchMiss" resultMap="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper.EmisTmsSiteBatchMissResult">
|
||||||
select
|
select
|
||||||
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
||||||
m.line_code, m.product_type,
|
m.line_code, m.product_type,
|
||||||
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
||||||
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
||||||
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
||||||
l.line_name as line_name,
|
l.line_name as line_name,
|
||||||
@ -93,13 +121,67 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
ORDER BY w.send_date DESC, m.bill_code
|
ORDER BY w.send_date DESC, m.bill_code
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<select id="selectDetailDataByMonthV2" parameterType="EmisTmsSiteBatchMiss" resultMap="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper.EmisTmsSiteBatchMissResult">
|
||||||
|
select
|
||||||
|
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
||||||
|
m.line_code, m.product_type,
|
||||||
|
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
|
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
||||||
|
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
||||||
|
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
||||||
|
l.line_name as line_name,
|
||||||
|
w.receive_country, c2.name as receive_country_name, w.send_date, w.bl_sign, w.sign_date,
|
||||||
|
w.product_type,w.problem_type,w.virtual_remark,w.dispatch_underling_site_code,
|
||||||
|
w.payment_type, w.parcel_qty, w.bill_weight, w.total_volume, w.volume_weight,
|
||||||
|
w.settlement_weight, w.freight, w.remark as waybill_remark, w.fee_remark, m.manager, k.trans_manager,
|
||||||
|
w.payee, w.salesmen, u.emp_name as registerManName,
|
||||||
|
(SELECT s.name
|
||||||
|
FROM emis_supplier s
|
||||||
|
WHERE FIND_IN_SET(s.code, m.supplier_code)
|
||||||
|
AND s.del_flag = '0'
|
||||||
|
LIMIT 1) as supplier_name,
|
||||||
|
(SELECT p.prod_name
|
||||||
|
FROM emis_trans_product p
|
||||||
|
WHERE FIND_IN_SET(p.prod_code, m.product_type)
|
||||||
|
AND p.del_flag = '0'
|
||||||
|
LIMIT 1) as product_type_name
|
||||||
|
from emis_tms_site_batch_miss_v2 m
|
||||||
|
left join emis_waybill w on m.bill_code = w.bill_code and w.del_flag='0'
|
||||||
|
left join emis_site s1 on w.send_site_code=s1.site_code and s1.del_flag='0'
|
||||||
|
left join emis_site s2 on COALESCE(m.start_site_code, w.start_site_code, w.send_site_code)=s2.site_code and s2.del_flag='0'
|
||||||
|
left join emis_site s3 on COALESCE(m.next_site_code, w.destination_code)=s3.site_code and s3.del_flag='0'
|
||||||
|
left join emis_country c1 on w.send_country=c1.code and c1.del_flag='0'
|
||||||
|
left join emis_country c2 on w.receive_country=c2.code and c2.del_flag='0'
|
||||||
|
left join emis_site s4 on w.dispatch_underling_site_code=s4.site_code and s4.del_flag='0'
|
||||||
|
left join emis_trans_line k on w.trans_line_type=k.line_code and k.del_flag='0'
|
||||||
|
left join emis_trans_plan_rule r on m.trans_plan_rule_id=r.id and r.del_flag='0'
|
||||||
|
left join emis_trans_line l on m.line_code=l.line_code and l.del_flag='0'
|
||||||
|
left join sys_user u on w.register_man_code=u.emp_code and u.del_flag='0'
|
||||||
|
WHERE m.del_flag = '0'
|
||||||
|
<if test="startSiteCode != null and startSiteCode != ''">
|
||||||
|
AND COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) = #{startSiteCode}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null and startTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null and endTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
<if test="(startTime == null or startTime == '') and (endTime == null or endTime == '')">
|
||||||
|
<if test="billMonth != null">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
|
||||||
|
</if>
|
||||||
|
</if>
|
||||||
|
ORDER BY w.send_date DESC, m.bill_code
|
||||||
|
</select>
|
||||||
|
|
||||||
<!-- 分页查询漏组详细数据列表(按月份分组)- 性能优化版本 -->
|
<!-- 分页查询漏组详细数据列表(按月份分组)- 性能优化版本 -->
|
||||||
<select id="selectDetailDataByMonthWithPaging" resultMap="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper.EmisTmsSiteBatchMissResult">
|
<select id="selectDetailDataByMonthWithPaging" resultMap="com.xdadan.erp.emis.mapper.EmisTmsSiteBatchMissMapper.EmisTmsSiteBatchMissResult">
|
||||||
select
|
select
|
||||||
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
m.id, m.bill_code, m.miss_reason, m.create_time, m.update_time, m.remark, m.del_flag,
|
||||||
m.line_code, m.product_type,
|
m.line_code, m.product_type,
|
||||||
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) as start_site_code,
|
||||||
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
COALESCE(m.next_site_code, w.destination_code) as next_site_code,
|
||||||
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
m.supplier_code, m.start_date, m.end_date,m.miss_type,
|
||||||
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
w.send_site_code, s1.site_name as send_site_name,s2.site_name as start_site_name,s3.site_name as next_site_name, w.send_country, c1.name as send_country_name, w.destination_code, s4.site_name as dispatch_underling_site_name,w.bl_is_question,
|
||||||
l.line_name as line_name,
|
l.line_name as line_name,
|
||||||
@ -171,4 +253,26 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
|||||||
</if>
|
</if>
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
<!-- 统计漏组详细数据总数 -->
|
||||||
|
<select id="countDetailDataByMonthV2" parameterType="EmisTmsSiteBatchMissStatistics" resultType="long">
|
||||||
|
SELECT COUNT(*)
|
||||||
|
FROM emis_tms_site_batch_miss_v2 m
|
||||||
|
LEFT JOIN emis_waybill w ON m.bill_code = w.bill_code AND w.del_flag='0'
|
||||||
|
WHERE m.del_flag = '0'
|
||||||
|
<if test="startSiteCode != null and startSiteCode != ''">
|
||||||
|
AND COALESCE(m.start_site_code, w.start_site_code, w.send_site_code) = #{startSiteCode}
|
||||||
|
</if>
|
||||||
|
<if test="startTime != null and startTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ >= ]]> #{startTime}
|
||||||
|
</if>
|
||||||
|
<if test="endTime != null and endTime != ''">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') <![CDATA[ <= ]]> #{endTime}
|
||||||
|
</if>
|
||||||
|
<if test="(startTime == null or startTime == '') and (endTime == null or endTime == '')">
|
||||||
|
<if test="billMonth != null">
|
||||||
|
AND DATE_FORMAT(w.send_date, '%Y-%m') = DATE_FORMAT(#{billMonth}, '%Y-%m')
|
||||||
|
</if>
|
||||||
|
</if>
|
||||||
|
</select>
|
||||||
|
|
||||||
</mapper>
|
</mapper>
|
||||||
|
|||||||
@ -3925,9 +3925,10 @@
|
|||||||
</insert>
|
</insert>
|
||||||
|
|
||||||
<select id="selectWaybillListBySiteBatchStatus" resultMap="EmisWaybillResult">
|
<select id="selectWaybillListBySiteBatchStatus" resultMap="EmisWaybillResult">
|
||||||
select a.*,k.trans_type
|
select a.*,k.trans_type,start.site_name as start_site_name
|
||||||
from emis_waybill a
|
from emis_waybill a
|
||||||
left join emis_trans_line k on a.trans_line_type=k.line_code and k.del_flag='0'
|
left join emis_trans_line k on a.trans_line_type=k.line_code and k.del_flag='0'
|
||||||
|
left join emis_site start on a.start_site_code=start.site_code and start.del_flag='0'
|
||||||
where a.del_flag = '0'
|
where a.del_flag = '0'
|
||||||
<if test="lineCode != null and lineCode != ''">
|
<if test="lineCode != null and lineCode != ''">
|
||||||
and a.trans_line_type = #{lineCode}
|
and a.trans_line_type = #{lineCode}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user