From 2b31fa203f3435a582be51f45899d99164c9917a Mon Sep 17 00:00:00 2001
From: zhuguifei <312353457@qq.com>
Date: 星期四, 09 四月 2026 13:34:59 +0800
Subject: [PATCH] Merge branch 'master' of http://lanpucloud.cn:1111/r/SC/gfzl
---
RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/analy/service/impl/StoreSilkInfoServiceImpl.java | 624 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 608 insertions(+), 16 deletions(-)
diff --git a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/analy/service/impl/StoreSilkInfoServiceImpl.java b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/analy/service/impl/StoreSilkInfoServiceImpl.java
index 5747535..ba00d90 100644
--- a/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/analy/service/impl/StoreSilkInfoServiceImpl.java
+++ b/RuoYi-Vue-Plus/ruoyi-modules/ruoyi-qa/src/main/java/org/dromara/qa/analy/service/impl/StoreSilkInfoServiceImpl.java
@@ -1,5 +1,6 @@
package org.dromara.qa.analy.service.impl;
+import com.baomidou.dynamic.datasource.annotation.DS;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -9,17 +10,30 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
+import org.dromara.qa.analy.domain.FeedmatchTimeData;
+import org.dromara.qa.analy.domain.PackerTimeData;
+import org.dromara.qa.analy.domain.RollerTimeData;
+import org.dromara.qa.analy.domain.vo.StoreSilkDetailVo;
+import org.dromara.qa.analy.service.IRollerTimeDataService;
+import org.dromara.qa.analy.service.IPackerTimeDataService;
+import org.dromara.qa.md.domain.MdShift;
+import org.dromara.qa.md.domain.bo.MdShiftBo;
+import org.dromara.qa.md.service.OracleShiftReader;
import org.springframework.stereotype.Service;
import org.dromara.qa.analy.domain.bo.StoreSilkInfoBo;
import org.dromara.qa.analy.domain.vo.StoreSilkInfoVo;
import org.dromara.qa.analy.domain.StoreSilkInfo;
import org.dromara.qa.analy.mapper.StoreSilkInfoMapper;
import org.dromara.qa.analy.service.IStoreSilkInfoService;
-import org.dromara.qa.analy.mapper.FeedmatchTimeDataMapper;
-
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import org.dromara.qa.analy.service.IFeedmatchTimeDataService;
+import java.lang.reflect.Field;
+import java.sql.Timestamp;
+import java.util.*;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.LocalTime;
+import java.time.ZoneId;
+import java.time.format.DateTimeFormatter;
/**
* 鍌ㄤ笣鏌滀骇閲廠ervice涓氬姟灞傚鐞�
@@ -27,13 +41,17 @@
* @author zhuguifei
* @date 2026-03-02
*/
+@DS("oracle_zs")
@Slf4j
@RequiredArgsConstructor
@Service
public class StoreSilkInfoServiceImpl implements IStoreSilkInfoService {
private final StoreSilkInfoMapper baseMapper;
- private final FeedmatchTimeDataMapper feedmatchTimeDataMapper;
+ private final IFeedmatchTimeDataService feedmatchTimeDataService;
+ private final IRollerTimeDataService rollerTimeDataService;
+ private final IPackerTimeDataService packerTimeDataService;
+ private final OracleShiftReader oracleShiftReader;
/**
* 鏌ヨ鍌ㄤ笣鏌滀骇閲�
@@ -42,7 +60,7 @@
* @return 鍌ㄤ笣鏌滀骇閲�
*/
@Override
- public StoreSilkInfoVo queryById(Long id){
+ public StoreSilkInfoVo queryById(Long id) {
return baseMapper.selectVoById(id);
}
@@ -61,19 +79,557 @@
queryFeedmatchData(result);
return TableDataInfo.build(result);
}
-
+
private void queryFeedmatchData(Page<StoreSilkInfoVo> page) {
if (page == null || page.getRecords() == null || page.getRecords().isEmpty()) {
return;
}
+ // 鏌ヨ鏁伴噰绯荤粺鐝鏃堕棿锛堢嫭绔嬩娇鐢� oracle 鏁版嵁婧愶級
+ List<MdShift> mdShifts = oracleShiftReader.listAll();
+
+
List<StoreSilkInfoVo> storeSilkInfoList = page.getRecords();
for (int i = 0; i < storeSilkInfoList.size(); i++) {
- //
+ //鍌ㄤ笣鏌�
StoreSilkInfoVo storeSilkInfoVo = storeSilkInfoList.get(i);
+ //鍑烘枡寮�濮嬫椂闂�
+ Date distimebegin = storeSilkInfoVo.getDistimebegin();
+ //鍑烘枡缁撴潫鏃堕棿
+ Date distimeend = storeSilkInfoVo.getDistimeend();
+ if (distimebegin == null) {
+ continue;
+ }
+ /**
+ * 缁熻鈥滃嚭鏂欒繘琛屼腑鈥濈殑鍏抽敭鐐癸細
+ * - 鍑烘枡缁撴潫鏃堕棿 distimeend 鍙兘涓虹┖锛堜粛鍦ㄥ嚭鏂欎腑锛�
+ * - 涔熷彲鑳藉凡缁忔湁缁撴潫鏃堕棿锛堝嚭鏂欏凡缁撴潫锛�
+ *
+ * 鍥犳杩欓噷缁熶竴璁$畻涓�涓�滄湰娆$粺璁$殑鏈夋晥缁撴潫鏃堕棿鈥� effectiveDistEnd锛�
+ * 1) distimeend == null 锛氳鏄庤繕鍦ㄥ嚭鏂欎腑锛屾湰娆$粺璁℃埅姝㈠埌褰撳墠鏃堕棿 now
+ * 2) distimeend != null 锛氳鏄庡凡鍑烘枡缁撴潫锛屾埅姝㈠埌 distimeend
+ * 3) 鑻� distimeend 鍦ㄦ湭鏉ワ紙鑴忔暟鎹�/鏃堕挓璇樊锛夛紝涔熸寜 now 鎴锛岄伩鍏嶇粺璁″埌鏈潵
+ *
+ * 鍚庣画鎵�鏈夋煡璇€�佺彮娆″垏鍒嗐�佹墸鍑忛兘鍩轰簬 effectiveDistEnd锛�
+ * 杩欐牱鍚屼竴濂楅�昏緫鍚屾椂閫傞厤鈥滃嚭鏂欏凡缁撴潫鈥濆拰鈥滃嚭鏂欐湭缁撴潫鈥濅袱绉嶅満鏅��
+ */
+ Date now = new Date();
+ Date effectiveDistEnd;
+ if (distimeend == null) {
+ effectiveDistEnd = now;
+ } else {
+ effectiveDistEnd = distimeend.after(now) ? now : distimeend;
+ }
+ if (!effectiveDistEnd.after(distimebegin)) {
+ continue;
+ }
+
+ //鍌ㄤ笣鏌滄煖鍙�
+ String siloid = storeSilkInfoVo.getSiloid();
+ if (StringUtils.isEmpty(siloid)) continue;
+ int lastIndex = siloid.lastIndexOf("_");
+ String containerNum = siloid.substring(lastIndex + 1);
+ if (StringUtils.isEmpty(containerNum)) continue;
+
+ /**
+ * 鏍规嵁鍑烘枡寮�濮嬫椂闂存煡璇⑩�滃杺涓濇満 -> 鍌ㄤ笣鏌� -> 鏈哄彴(绠¢亾)鈥濆搴斿叧绯�(feedmatch_time_data)
+ *
+ * 璇存槑锛�
+ * - 杩欓噷涓嶆槸鐩存帴鐢� distimebegin锛岃�屾槸鍙栧嚭鏂欏紑濮嬪悗 10 鍒嗛挓鐨勭涓�鏉¤褰曪紝
+ * 鐩殑鏄伩寮�鍑烘枡鍒氬紑濮嬫椂鐨勬尝鍔�/鏄犲皠鏈ǔ瀹氶棶棰橈紝淇濊瘉鏄犲皠鍑嗙‘鎬с��
+ * - 鏌ヨ涓婄晫浣跨敤 effectiveDistEnd锛氬鏋滃嚭鏂欒繕娌$粨鏉燂紝灏变互褰撳墠鏃堕棿浣滀负涓婄晫锛屼粛鐒惰兘鍙栧埌瀵瑰簲鍏崇郴銆�
+ */
+ Timestamp targetTime = new Timestamp(distimebegin.getTime() + 10 * 60 * 1000); // 鍑烘枡寮�濮嬪悗10鍒嗛挓
+ String containerStr = StringUtils.isEmpty(containerNum) ? "" : containerNum.trim();
+ //灏忎簬10鐨勬煖鍙疯ˉ0
+ if (containerStr.length() == 1) {
+ containerStr = "0" + containerStr;
+ }
+ LambdaQueryWrapper<FeedmatchTimeData> lqw = new LambdaQueryWrapper<>();
+ String finalContainerStr = containerStr;
+ lqw.ge(FeedmatchTimeData::getTime, targetTime)
+ .le(FeedmatchTimeData::getTime, effectiveDistEnd)
+ .and(wrapper -> wrapper
+ .like(FeedmatchTimeData::getFs11, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs12, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs21, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs22, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs31, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs32, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs41, finalContainerStr)
+ .or()
+ .like(FeedmatchTimeData::getFs42, finalContainerStr)
+ )
+ .orderByAsc(FeedmatchTimeData::getTime)
+ .last("LIMIT 1");
+
+ FeedmatchTimeData feedMatch = feedmatchTimeDataService.selectOne(lqw);
+ if (feedMatch == null) {
+ // TODO 娣诲姞鎻愮ず
+ continue;
+ }
+
+ // feedMatch 杞琺ap锛氶�氳繃鍙嶅悜鏄犲皠蹇�熷畾浣嶁�滆鏌滃搴斿摢涓杺涓濇満鈥濄�佲�滆鏈虹粍瀵瑰簲鍝釜绠¢亾鈥�
+ // fsRevMap锛歬ey=鍌ㄤ笣鏌滃彿鍚庝袱浣嶏紙濡� 01/09锛夛紝value=瀛楁鍚嶏紙濡� fs11/fs12...锛�
+ Map<String, String> fsRevMap = new HashMap<>();
+ // pipeRevMap锛歬ey=鍠備笣鏈哄彿+绠¢亾缁勫悎锛堝 1x / 2x...锛夛紝value=瀛楁鍚嶏紙濡� pipe01/pipe02...锛�
+ Map<String, String> pipeRevMap = new HashMap<>();
+ // pipeMap锛歬ey=瀛楁鍚嶏紙pipe01/pipe02...锛夛紝value=瀛楁鍊硷紙鐢ㄤ簬鍚庣画瑙f瀽鍏蜂綋绠¢亾鍙凤級
+ Map<String, String> pipeMap = new HashMap<>();
+ Field[] fields = feedMatch.getClass().getDeclaredFields();
+ for (Field field : fields) {
+ field.setAccessible(true);
+ Object value = null;
+ try {
+ value = field.get(feedMatch);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ if (field.getName().startsWith("fs") && value != null) {
+ String key = value.toString().trim();
+ if (key.length() == 1) {
+ key = "0" + key;
+ } else if (key.length() > 2) {
+ key = key.substring(key.length() - 2);
+ }
+ fsRevMap.put(key, field.getName());
+ } else if (field.getName().startsWith("pipe") && value != null) {
+ pipeRevMap.put(value.toString(), field.getName());
+ pipeMap.put(field.getName(),value.toString());
+ }
+ }
+ // 鏍规嵁鍌ㄤ笣鏌滃彿鑾峰彇鍠備笣鏈哄彿
+ String containerKey = StringUtils.isEmpty(containerNum) ? "" : containerNum.trim();
+ if (containerKey.length() == 1) {
+ containerKey = "0" + containerKey;
+ } else if (containerKey.length() > 2) {
+ containerKey = containerKey.substring(containerKey.length() - 2);
+ }
+ String fsNum = fsRevMap.get(containerKey);
+ if (StringUtils.isEmpty(fsNum)) {
+ // TODO 鍠備笣鏈哄彿绌鸿繑鍥炰俊鎭�
+ continue;
+ }
+ if (pipeRevMap.isEmpty()) {
+ // TODO 绠¢亾鍙风┖杩斿洖淇℃伅
+ continue;
+ }
+ /**
+ * pipeList 瀛樻斁鈥滆鍠備笣鏈哄搴旂殑鏈虹粍瀛楁鍚嶁��
+ * - 渚嬪 pipe01銆乸ipe02 浠h〃 1#銆�2#鍗锋帴/鍖呰鏈虹粍
+ * - 鍚庣画浼氫粠 pipe01/pipe02 鎻愬彇鏈虹粍鍙� equNo锛屽苟鐢ㄤ簬鎷兼帴 key 鏌ヨ鍗锋帴/鍖呰琛�
+ */
+ List<String> pipeList = new ArrayList<>();
+ for (Map.Entry<String, String> entry : pipeRevMap.entrySet()) {
+ //fsNum绗笁浣嶆槸鍠備笣鏈哄簭鍙�
+ if (entry.getKey().length() > 1 && entry.getKey().startsWith(fsNum.substring(2, 3))) {
+ pipeList.add(entry.getValue());
+ }
+ }
+ if (pipeList.isEmpty()) {
+ //TODO 娣诲姞鎻愮ず
+ continue;
+ }
+
+ /**
+ * 鏍规嵁 [distimebegin, effectiveDistEnd] 璁$畻娑夊強鍒扮殑鐝鍒楄〃
+ * - 鍑烘枡宸茬粨鏉燂細effectiveDistEnd=distimeend
+ * - 鍑烘枡鏈粨鏉燂細effectiveDistEnd=now
+ */
+ List<MdShiftBo> distShiftList = calcShiftSpans(distimebegin, effectiveDistEnd, mdShifts);
+ storeSilkInfoVo.setDistShiftList(distShiftList);
+ if (distShiftList.isEmpty()) continue;
+ //鏌ヨ鏃ユ湡鍜岀彮娆″唴鍗锋帴鏈虹粍鐨勪骇閲�
+ ZoneId zone = ZoneId.systemDefault();
+ // 鍗峰寘浜ч噺缁熻
+ Double rollerOutput = 0.0;
+ Double packerOutput = 0.0;
+ // 鏄庣粏鍒楄〃锛堜粎瀛樻渶缁堟鏁扮粨鏋滐級
+ List<StoreSilkDetailVo> rollerDetailList = new ArrayList<>();
+ List<StoreSilkDetailVo> packerDetailList = new ArrayList<>();
+ // 鎿嶄綔璁板綍鍒楄〃锛堝瓨鎵�鏈夊鍑忚繃绋嬶級
+ List<StoreSilkDetailVo> rollerRecordList = new ArrayList<>();
+ List<StoreSilkDetailVo> packerRecordList = new ArrayList<>();
+
+ for (int s = 0; s < distShiftList.size(); s++) {
+ MdShiftBo shiftBo = distShiftList.get(s);
+ if (shiftBo.getDay() == null || StringUtils.isEmpty(shiftBo.getCode())) {
+ continue;
+ }
+ String shift = shiftBo.getCode();
+
+ // 瑙f瀽鐝鏃堕棿
+ // 1) 鑾峰彇鐝閰嶇疆鐨勫紑濮�/缁撴潫鏃堕棿 (鍙兘鏄� "HH:mm" 鎴� "HH:mm:ss")
+ String stimStr = shiftBo.getStim();
+ String etimStr = shiftBo.getEtim();
+ if (StringUtils.isEmpty(stimStr) || StringUtils.isEmpty(etimStr)) {
+ continue;
+ }
+ // 2) 琛ュ叏绉掓暟锛堝鏋滈厤缃粎涓� HH:mm锛�
+ if (stimStr.length() == 5) stimStr += ":00";
+ if (etimStr.length() == 5) etimStr += ":00";
+
+ // 3) 缁撳悎鏃ユ湡锛坰hiftBo.getDay() 涓虹彮娆″綊灞炴棩锛夎В鏋愪负 LocalDateTime
+ String dateStr = shiftBo.getDay().toInstant().atZone(zone).toLocalDate().toString();
+ DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
+ LocalDateTime shiftStart = LocalDateTime.parse(dateStr + " " + stimStr, formatter);
+ LocalDateTime shiftEnd = LocalDateTime.parse(dateStr + " " + etimStr, formatter);
+
+ // 4) 澶勭悊璺ㄥぉ鐝锛氬鏋� 缁撴潫鏃堕棿 <= 寮�濮嬫椂闂达紝璇存槑璺ㄥぉ锛岀粨鏉熸椂闂� +1 澶�
+ if (!shiftEnd.isAfter(shiftStart)) {
+ shiftEnd = shiftEnd.plusDays(1);
+ }
+
+ // 杞崲 Date 瀵硅薄鐢ㄤ簬姣旇緝锛堝吋瀹圭幇鏈夐�昏緫锛�
+ Date stimDate = Date.from(shiftStart.atZone(zone).toInstant());
+ Date etimDate = Date.from(shiftEnd.atZone(zone).toInstant());
+
+ /**
+ * 涓轰簡鍚屾椂鏀寔鈥滃嚭鏂欐湭缁撴潫鈥濓紝杩欓噷寮曞叆涓�涓�滄湰鐝鐨勭粺璁$獥鍙b�濓細
+ *
+ * 缁熻缁撴潫鏃跺埢 calcEnd = min(鐝缁撴潫, effectiveDistEnd)
+ * - 鍑烘枡宸茬粨鏉燂細effectiveDistEnd=distimeend锛屽彲鑳芥棭浜庣彮娆$粨鏉燂紝calcEnd=distimeend
+ * - 鍑烘枡鏈粨鏉燂細effectiveDistEnd=now锛宑alcEnd=now 鎴� 鐝缁撴潫锛堝彇杈冨皬锛�
+ *
+ * 缁熻寮�濮嬫椂鍒� calcStart = max(鐝寮�濮�, distimebegin)
+ * - 鑻ュ嚭鏂欏紑濮嬫櫄浜庣彮娆″紑濮嬶紝鍒欎粠鍑烘枡寮�濮嬬粺璁�
+ * - 鑻ュ嚭鏂欏紑濮嬫棭浜庣彮娆″紑濮嬶紝鍒欎粠鐝寮�濮嬬粺璁�
+ *
+ * 鏈�缁堟湰鐝鏈夋晥浜ч噺鍙e緞涓猴細
+ * output = Qty(calcEnd) - Qty(calcStart)
+ *
+ * 璇存槑锛氳繖涓彛寰勫凡缁忊�滈殣鍚簡鎵e熬鈥�
+ * - 濡傛灉 calcEnd < 鐝缁撴潫锛堜緥濡傚嚭鏂欏凡缁撴潫鎴栫粺璁″埌褰撳墠鏃跺埢锛夛紝灏惧反鑷劧涓嶄細琚粺璁¤繘鍘�
+ * - 鍥犳涓嶉渶瑕佸啀棰濆鍐欎竴涓�滄墸灏� if(...)鈥濆垎鏀紝閫昏緫鏇寸粺涓�銆佹洿涓嶅鏄撳嚭閿�
+ */
+ LocalDateTime effectiveEndLdt = LocalDateTime.ofInstant(effectiveDistEnd.toInstant(), zone);
+ LocalDateTime calcEnd = shiftEnd.isBefore(effectiveEndLdt) ? shiftEnd : effectiveEndLdt;
+ Date calcEndDate = Date.from(calcEnd.atZone(zone).toInstant());
+ if (!calcEndDate.after(stimDate)) {
+ continue;
+ }
+ Date calcStartDate = distimebegin.after(stimDate) ? distimebegin : stimDate;
+ if (!calcEndDate.after(calcStartDate)) {
+ continue;
+ }
+ String calcEndStr = calcEnd.format(formatter);
+ String tenMinBeforeCalcEnd = calcEnd.minusMinutes(10).format(formatter);
+
+ // 鏍规嵁鍗锋帴鏈虹粍鍜岀彮娆¤幏鍙栦骇閲忥紙pipeList = 澶氬皯涓満缁勶級
+ for (int j = 0; j < pipeList.size(); j++) {
+ String pipe = pipeList.get(j);
+ // 鎻愬彇鏈虹粍鍙�
+ String equNo = pipe.replaceAll("\\D+", "");
+ // 绠¢亾鍙凤紙鐢ㄤ簬鏄庣粏灞曠ず锛夛細浠� feedMatch 鐨� pipe01/pipe02... 瀛楁鍊奸噷鍙栨湯浣�
+ String channel = pipeMap.get("pipe" + equNo);
+ if (channel != null && channel.length() > 0) {
+ channel = channel.substring(channel.length() - 1);
+ }else {
+ channel = "";
+ }
+
+ /**
+ * 鏈虹粍鍙锋槧灏勮鍒欙紙涓氬姟绾﹀畾锛夛細
+ * - pipe04 瀵瑰簲鐨勬満缁勫彿鍦ㄧ郴缁熼噷鏄┖缂虹殑锛岄渶瑕佽烦鍒� 5 鍙�
+ * - 鍥犳褰撶閬撳彿 >= 4 鏃讹紝鏈虹粍鍙烽渶瑕� +1
+ * - 鍚屾椂杩欓噷琛ラ綈涓� 2 浣嶆暟瀛楋紝渚夸簬鎷� key锛堜緥濡� 01/02/05...锛�
+ */
+ try {
+ int equ = Integer.parseInt(equNo);
+ equNo = String.format("%02d", equ >= 4 ? equ + 1 : equ);
+ } catch (Exception e) {
+ e.printStackTrace();
+ // TODO 娣诲姞鎻愮ず
+ continue;
+ }
+
+
+ // key 鎷兼帴瑙勫垯锛�
+ // - 鍗锋帴鏈猴細鐝 + "1" + 鏈虹粍鍙凤紙渚嬪 101銆�105...锛�
+ String key = shift + "1" + equNo;
+ // - 鍖呰鏈猴細鐝 + "2" + 鏈虹粍鍙凤紙渚嬪 201銆�205...锛�
+ String packerKey = shift + "2" + equNo;
+
+ // ================= 鍗锋帴鏈轰骇閲忕粺璁� =================
+ Double currentRollerOutput = 0.0;
+ /**
+ * 鍙栨暟绛栫暐璇存槑锛堝嵎鎺�/鍖呰涓�鑷达級锛�
+ * - 琛ㄥ唴鐨� qty 瑙嗕负绱鍊硷紙鍚屼竴 key 涓嬪崟璋冮�掑锛�
+ * - 鐢变簬鏁版嵁鏄噰鏍蜂笂鎶ワ紝鏌愪釜鏃跺埢涓嶄竴瀹氬垰濂芥湁璁板綍
+ * - 鍥犳閲囩敤鈥滅洰鏍囨椂鍒诲墠 10 鍒嗛挓鍐咃紝绂荤洰鏍囨渶杩戠殑涓�鏉¤褰曗�濅綔涓哄揩鐓у��
+ *
+ * 娉ㄦ剰锛�10鍒嗛挓鏄粡楠岀獥鍙o紝濡傛灉鐜板満閲囨牱鏇寸█鐤忥紝鍙�冭檻鏀惧绐楀彛
+ */
+ // 1) 鏌ヨ缁熻缁撴潫鏃跺埢 calcEnd 鐨勫揩鐓у�� Qty(calcEnd)
+ LambdaQueryWrapper<RollerTimeData> rlqw = new LambdaQueryWrapper<>();
+ rlqw.le(RollerTimeData::getTime, calcEndStr)
+ .eq(RollerTimeData::getKey, key)
+ .ge(RollerTimeData::getTime, tenMinBeforeCalcEnd)
+ .orderByDesc(RollerTimeData::getTime)
+ .isNotNull(RollerTimeData::getQty)
+ .gt(RollerTimeData::getQty, 0)
+ .last("LIMIT 1");
+ RollerTimeData rData = rollerTimeDataService.selectOne(rlqw);
+ if (rData != null) {
+ // 鍏堟妸缁熻缁撴潫鏃跺埢绱鍊煎姞杩涙潵锛歝urrent = Qty(calcEnd)
+ currentRollerOutput += rData.getQty();
+
+ // 璁板綍杩囩▼锛氱彮娆℃埅姝㈢疮璁�
+ StoreSilkDetailVo endRecord = new StoreSilkDetailVo();
+ endRecord.setFsNum(fsNum.substring(2, 3));
+ endRecord.setSiloNum(containerNum);
+ endRecord.setPipeNum(channel);
+ endRecord.setEquNo(equNo);
+ endRecord.setShiftCode(shift);
+ endRecord.setShiftStartTime(calcStartDate);
+ endRecord.setShiftEndTime(calcEndDate);
+ endRecord.setOutput(rData.getQty());
+ endRecord.setCalcType("鐝鎴绱");
+ endRecord.setHitTime(rData.getTime());
+ rollerRecordList.add(endRecord);
+
+ // 2) 鎵b�滃ご鈥濓細濡傛灉缁熻寮�濮嬫椂鍒绘櫄浜庣彮娆″紑濮嬶紝鍒欏噺鍘� Qty(calcStart)
+ if (calcStartDate.after(stimDate)) {
+ LocalDateTime calcStartLdt = LocalDateTime.ofInstant(calcStartDate.toInstant(), zone);
+ String calcStartStr = calcStartLdt.format(formatter);
+ String tenMinBeforeCalcStart = calcStartLdt.minusMinutes(10).format(formatter);
+
+ LambdaQueryWrapper<RollerTimeData> beginRlqw = new LambdaQueryWrapper<>();
+ beginRlqw.le(RollerTimeData::getTime, calcStartStr)
+ .eq(RollerTimeData::getKey, key)
+ .ge(RollerTimeData::getTime, tenMinBeforeCalcStart)
+ .orderByDesc(RollerTimeData::getTime)
+ .isNotNull(RollerTimeData::getQty)
+ .gt(RollerTimeData::getQty, 0)
+ .last("LIMIT 1");
+
+ RollerTimeData rBeginData = rollerTimeDataService.selectOne(beginRlqw);
+ if (rBeginData != null) {
+ currentRollerOutput -= rBeginData.getQty();
+
+ // 璁板綍杩囩▼锛氭墸闄ゅご閮ㄤ骇閲�
+ StoreSilkDetailVo beginRecord = new StoreSilkDetailVo();
+ beginRecord.setFsNum(fsNum.substring(2, 3));
+ beginRecord.setSiloNum(containerNum);
+ beginRecord.setPipeNum(channel);
+ beginRecord.setEquNo(equNo);
+ beginRecord.setShiftCode(shift);
+ beginRecord.setShiftStartTime(calcStartDate);
+ beginRecord.setShiftEndTime(calcEndDate);
+ beginRecord.setOutput(-rBeginData.getQty()); // 璐熸暟琛ㄧず鎵i櫎
+ beginRecord.setCalcType("鎵i櫎鍑烘枡鍓嶇疮璁�");
+ beginRecord.setHitTime(rBeginData.getTime());
+ rollerRecordList.add(beginRecord);
+ }
+ }
+ }
+ // 绱鎬讳骇閲�
+ rollerOutput += currentRollerOutput;
+ // 璁板綍鍗锋帴鏈烘槑缁�
+ if (currentRollerOutput > 0) {
+ StoreSilkDetailVo detail = new StoreSilkDetailVo();
+ detail.setFsNum(fsNum.substring(2, 3));
+ detail.setSiloNum(containerNum);
+ detail.setPipeNum(channel);
+ detail.setEquNo(equNo);
+ detail.setShiftCode(shift);
+ detail.setShiftStartTime(calcStartDate);
+ detail.setShiftEndTime(calcEndDate);
+ detail.setOutput(currentRollerOutput);
+ rollerDetailList.add(detail);
+ }
+
+ // ================= 鍖呰鏈轰骇閲忕粺璁� =================
+ Double currentPackerOutput = 0.0;
+ // 1) 鏌ヨ缁熻缁撴潫鏃跺埢 calcEnd 鐨勫揩鐓у�� Qty(calcEnd)
+ LambdaQueryWrapper<PackerTimeData> plqw = new LambdaQueryWrapper<>();
+ plqw.le(PackerTimeData::getTime, calcEndStr)
+ .eq(PackerTimeData::getKey, packerKey)
+ .ge(PackerTimeData::getTime, tenMinBeforeCalcEnd)
+ .orderByDesc(PackerTimeData::getTime)
+ .isNotNull(PackerTimeData::getQty)
+ .gt(PackerTimeData::getQty, 0)
+ .last("LIMIT 1");
+
+ PackerTimeData pData = packerTimeDataService.selectOne(plqw);
+ if (pData != null) {
+ // 鍏堟妸缁熻缁撴潫鏃跺埢绱鍊煎姞杩涙潵锛歝urrent = Qty(calcEnd)
+ currentPackerOutput += pData.getQty();
+
+ // 璁板綍杩囩▼锛氱彮娆℃埅姝㈢疮璁�
+ StoreSilkDetailVo endRecord = new StoreSilkDetailVo();
+ endRecord.setFsNum(fsNum.substring(2, 3));
+ endRecord.setSiloNum(containerNum);
+ endRecord.setPipeNum(channel);
+ endRecord.setEquNo(equNo);
+ endRecord.setShiftCode(shift);
+ endRecord.setShiftStartTime(calcStartDate);
+ endRecord.setShiftEndTime(calcEndDate);
+ endRecord.setOutput(pData.getQty());
+ endRecord.setCalcType("鐝鎴绱");
+ endRecord.setHitTime(pData.getTime());
+ packerRecordList.add(endRecord);
+
+ // 2) 鎵b�滃ご鈥濓細濡傛灉缁熻寮�濮嬫椂鍒绘櫄浜庣彮娆″紑濮嬶紝鍒欏噺鍘� Qty(calcStart)
+ if (calcStartDate.after(stimDate)) {
+ LocalDateTime calcStartLdt = LocalDateTime.ofInstant(calcStartDate.toInstant(), zone);
+ String calcStartStr = calcStartLdt.format(formatter);
+ String tenMinBeforeCalcStart = calcStartLdt.minusMinutes(10).format(formatter);
+
+ LambdaQueryWrapper<PackerTimeData> beginPlqw = new LambdaQueryWrapper<>();
+ beginPlqw.le(PackerTimeData::getTime, calcStartStr)
+ .eq(PackerTimeData::getKey, packerKey)
+ .ge(PackerTimeData::getTime, tenMinBeforeCalcStart)
+ .orderByDesc(PackerTimeData::getTime)
+ .isNotNull(PackerTimeData::getQty)
+ .gt(PackerTimeData::getQty, 0)
+ .last("LIMIT 1");
+
+ PackerTimeData pBeginData = packerTimeDataService.selectOne(beginPlqw);
+ if (pBeginData != null) {
+ currentPackerOutput -= pBeginData.getQty();
+
+ // 璁板綍杩囩▼锛氭墸闄ゅご閮ㄤ骇閲�
+ StoreSilkDetailVo beginRecord = new StoreSilkDetailVo();
+ beginRecord.setFsNum(fsNum.substring(2, 3));
+ beginRecord.setSiloNum(containerNum);
+ beginRecord.setPipeNum(channel);
+ beginRecord.setEquNo(equNo);
+ beginRecord.setShiftCode(shift);
+ beginRecord.setShiftStartTime(calcStartDate);
+ beginRecord.setShiftEndTime(calcEndDate);
+ beginRecord.setOutput(-pBeginData.getQty()); // 璐熸暟琛ㄧず鎵i櫎
+ beginRecord.setCalcType("鎵i櫎鍑烘枡鍓嶇疮璁�");
+ beginRecord.setHitTime(pBeginData.getTime());
+ packerRecordList.add(beginRecord);
+ }
+ }
+ }
+ // 绱鎬讳骇閲�
+ packerOutput += currentPackerOutput;
+ // 璁板綍鍖呰鏈烘槑缁�
+ if (currentPackerOutput > 0) {
+ StoreSilkDetailVo detail = new StoreSilkDetailVo();
+ detail.setFsNum(fsNum.substring(2, 3));
+ detail.setSiloNum(containerNum);
+ detail.setPipeNum(channel);
+ detail.setEquNo(equNo);
+ detail.setShiftCode(shift);
+ detail.setShiftStartTime(calcStartDate);
+ detail.setShiftEndTime(calcEndDate);
+ detail.setOutput(currentPackerOutput);
+ packerDetailList.add(detail);
+ }
+ }
+ }
+ // 灏嗘眹鎬荤粨鏋滀笌鏄庣粏缁撴灉鍥炲啓鍒� StoreSilkInfoVo锛屼緵鍓嶇鍒楄〃/鎶藉眽鏄庣粏灞曠ず浣跨敤
+ storeSilkInfoVo.setRollerOutput(rollerOutput);
+ storeSilkInfoVo.setPackerOutput(packerOutput);
+ storeSilkInfoVo.setRollerDetailList(rollerDetailList);
+ storeSilkInfoVo.setPackerDetailList(packerDetailList);
+ storeSilkInfoVo.setRollerRecordList(rollerRecordList);
+ storeSilkInfoVo.setPackerRecordList(packerRecordList);
}
+ }
+
+ /**
+ * 璁$畻鍑烘枡鍖洪棿 [begin, end) 娑夊強鍒扮殑鐝锛堜粎 code=1銆�2 鐨勬棭/涓彮锛�
+ * 杩斿洖 Map<yyyy-MM-dd, code>锛岃〃绀鸿鏃ユ湡涓婄殑璇ョ彮娆′笌鍑烘枡鍖洪棿瀛樺湪鏃堕棿閲嶅彔
+ * 鑻ュ悓涓�鏃ユ湡鏃�/涓彮鍧囨湁閲嶅彔锛寁alue 浣跨敤閫楀彿鎷兼帴锛屽 "1,2"
+ * <p>
+ * 绠�鍖栨�濊矾锛�
+ * 1. 灏� begin/end 杞负 LocalDateTime锛屽彇鍑鸿鐩栫殑鎵�鏈夎嚜鐒舵棩
+ * 2. 瀵规瘡涓�澶╂寜鐝鐨� stim/etim 鐢熸垚鐝鏃堕棿绐� [shiftStart, shiftEnd)
+ * - 鑻� etim <= stim锛岃涓鸿法澶╃彮娆★細shiftEnd = 褰撳ぉ鏃ユ湡 + 1 澶� + etim
+ * 3. 鐢ㄧ畝鍗曠殑鍖洪棿閲嶅彔鍒ゆ柇锛歴hiftEnd > begin && shiftStart < end
+ */
+ private List<MdShiftBo> calcShiftSpans(Date begin, Date end, List<MdShift> mdShifts) {
+ List<MdShiftBo> result = new ArrayList<>();
+
+ // 鍩虹鏍¢獙
+ if (begin == null || end == null || !end.after(begin) || mdShifts == null || mdShifts.isEmpty()) {
+ return result;
+ }
+
+ // 浠呬繚鐣欐棭鐝�(code=1)涓庝腑鐝�(code=2)
+ // 鍚屾椂蹇界暐 stim/etim 涓虹┖鐨勭彮娆�
+ ZoneId zone = ZoneId.systemDefault();
+ LocalDateTime intervalStart = LocalDateTime.ofInstant(begin.toInstant(), zone);
+ LocalDateTime intervalEnd = LocalDateTime.ofInstant(end.toInstant(), zone);
+ LocalDate day = intervalStart.toLocalDate();
+ LocalDate lastDay = intervalEnd.toLocalDate();
+
+ // 瑙f瀽鏃堕棿鏍煎紡锛氭敮鎸� "H:mm" 鎴� "H:mm:ss"
+ DateTimeFormatter tf = DateTimeFormatter.ofPattern("H:mm[:ss]");
+ Set<String> seen = new HashSet<>();
+
+ // 鎸夊ぉ閬嶅巻瑕嗙洊鑼冨洿
+ while (!day.isAfter(lastDay)) {
+ for (MdShift s : mdShifts) {
+ // 浠呮棭/涓彮
+ String code = s.getCode();
+ if (!"1".equals(code) && !"2".equals(code)) {
+ continue;
+ }
+ String st = s.getStim();
+ String et = s.getEtim();
+ if (st == null || et == null) {
+ continue;
+ }
+ // 瑙f瀽鐝璧锋鏃堕棿
+ LocalTime stt;
+ LocalTime ett;
+ try {
+ stt = LocalTime.parse(st.trim(), tf);
+ ett = LocalTime.parse(et.trim(), tf);
+ } catch (Exception ignore) {
+ // 鏃堕棿鏍煎紡寮傚父鍒欒烦杩囪鐝
+ continue;
+ }
+ // 鐢熸垚褰撳ぉ璇ョ彮娆$殑鏃堕棿绐�
+ LocalDateTime shiftStart = LocalDateTime.of(day, stt);
+ LocalDateTime shiftEnd = ett.isAfter(stt) || ett.equals(stt)
+ ? LocalDateTime.of(day, ett)
+ : LocalDateTime.of(day.plusDays(1), ett); // 璺ㄥぉ澶勭悊
+
+ // 鍒ゆ柇鍖洪棿鏄惁閲嶅彔锛� [shiftStart, shiftEnd) 涓� [intervalStart, intervalEnd)
+ if (shiftEnd.isAfter(intervalStart) && shiftStart.isBefore(intervalEnd)) {
+ Date shiftDay = Date.from(day.atStartOfDay(zone).toInstant());
+ String dedupeKey = shiftDay.getTime() + "-" + code;
+ if (seen.add(dedupeKey)) {
+ MdShiftBo bo = new MdShiftBo();
+ bo.setId(s.getId());
+ bo.setWsId(s.getWsId());
+ bo.setCode(s.getCode());
+ bo.setName(s.getName());
+ bo.setStim(s.getStim());
+ bo.setEtim(s.getEtim());
+ bo.setSeq(s.getSeq());
+ bo.setEnable(s.getEnable());
+ bo.setDel(s.getDel());
+ bo.setCreateUserName(s.getCreateUserName());
+ bo.setCreateUserTime(s.getCreateUserTime());
+ bo.setUpdateUserName(s.getUpdateUserName());
+ bo.setUpdateUserTime(s.getUpdateUserTime());
+ bo.setDay(shiftDay);
+ result.add(bo);
+ }
+ }
+ }
+ day = day.plusDays(1);
+ }
+ result.sort(Comparator
+ .comparing(MdShiftBo::getDay, Comparator.nullsLast(Date::compareTo))
+ .thenComparing(MdShiftBo::getCode, Comparator.nullsLast(String::compareTo)));
+ return result;
}
/**
@@ -91,13 +647,50 @@
private LambdaQueryWrapper<StoreSilkInfo> buildQueryWrapper(StoreSilkInfoBo bo) {
Map<String, Object> params = bo.getParams();
LambdaQueryWrapper<StoreSilkInfo> lqw = Wrappers.lambdaQuery();
- lqw.orderByAsc(StoreSilkInfo::getId);
lqw.like(StringUtils.isNotBlank(bo.getMaterialname()), StoreSilkInfo::getMaterialname, bo.getMaterialname());
- lqw.eq(StringUtils.isNotBlank(bo.getBatchcode()), StoreSilkInfo::getBatchcode, bo.getBatchcode());
- lqw.eq(bo.getActualstarttime() != null, StoreSilkInfo::getActualstarttime, bo.getActualstarttime());
+ lqw.like(StringUtils.isNotBlank(bo.getBatchcode()), StoreSilkInfo::getBatchcode, bo.getBatchcode());
+ if (bo.getActualstarttime() != null) {
+ ZoneId zone = ZoneId.systemDefault();
+ LocalDate day = bo.getActualstarttime().toInstant().atZone(zone).toLocalDate();
+ Date dayStart = Date.from(day.atStartOfDay(zone).toInstant());
+ Date nextDayStart = Date.from(day.plusDays(1).atStartOfDay(zone).toInstant());
+ lqw.ge(StoreSilkInfo::getActualstarttime, dayStart);
+ lqw.lt(StoreSilkInfo::getActualstarttime, nextDayStart);
+ }
lqw.eq(bo.getDistimebegin() != null, StoreSilkInfo::getDistimebegin, bo.getDistimebegin());
lqw.eq(bo.getDistimeend() != null, StoreSilkInfo::getDistimeend, bo.getDistimeend());
- lqw.eq(StringUtils.isNotBlank(bo.getSiloid()), StoreSilkInfo::getSiloid, bo.getSiloid());
+ if (StringUtils.isNotBlank(bo.getSiloid())) {
+ // 鏀寔澶氫釜鏌滃彿鏌ヨ锛屼互閫楀彿鍒嗛殧
+ String[] siloids = bo.getSiloid().split(",");
+ lqw.and(wrapper -> {
+ for (String val : siloids) {
+ val = val.trim();
+ if (StringUtils.isBlank(val)) {
+ continue;
+ }
+ String finalVal = val;
+ // 浣跨敤 OR 杩炴帴澶氫釜鏌滃彿鏉′欢
+ wrapper.or(w -> {
+ try {
+ int num = Integer.parseInt(finalVal);
+ String padded = String.format("%02d", num);
+ // 鍖归厤 _1 鎴� _01 (鍏煎涓嶈ˉ闆跺拰琛ラ浂鐨勬儏鍐�)
+ w.likeLeft(StoreSilkInfo::getSiloid, "_" + num)
+ .or()
+ .likeLeft(StoreSilkInfo::getSiloid, "_" + padded);
+ } catch (NumberFormatException e) {
+ // 闈炴暟瀛楀垯鎸夊師鍊煎尮閰�
+ w.eq(StoreSilkInfo::getSiloid, finalVal);
+ }
+ });
+ }
+ });
+ }
+ if (params.get("beginTime") != null && params.get("endTime") != null) {
+ lqw.apply("distimeend BETWEEN TO_DATE({0}, 'YYYY-MM-DD HH24:MI:SS') AND TO_DATE({1}, 'YYYY-MM-DD HH24:MI:SS')",
+ params.get("beginTime"),
+ params.get("endTime"));
+ }
return lqw;
}
@@ -113,7 +706,6 @@
validEntityBeforeSave(add);
boolean flag = baseMapper.insert(add) > 0;
if (flag) {
- bo.setId(add.getId());
}
return flag;
}
@@ -134,7 +726,7 @@
/**
* 淇濆瓨鍓嶇殑鏁版嵁鏍¢獙
*/
- private void validEntityBeforeSave(StoreSilkInfo entity){
+ private void validEntityBeforeSave(StoreSilkInfo entity) {
//TODO 鍋氫竴浜涙暟鎹牎楠�,濡傚敮涓�绾︽潫
}
@@ -147,7 +739,7 @@
*/
@Override
public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
- if(isValid){
+ if (isValid) {
//TODO 鍋氫竴浜涗笟鍔′笂鐨勬牎楠�,鍒ゆ柇鏄惁闇�瑕佹牎楠�
}
return baseMapper.deleteByIds(ids) > 0;
--
Gitblit v1.9.3