|
@@ -18,6 +18,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
|
+import com.google.common.collect.Lists;
|
|
|
|
+import com.rongwei.bscommon.sys.dao.ApsDeliveryOffsetDao;
|
|
import com.rongwei.bscommon.sys.dao.ApsProcessOperationProcessEquDao;
|
|
import com.rongwei.bscommon.sys.dao.ApsProcessOperationProcessEquDao;
|
|
import com.rongwei.bscommon.sys.listener.SpecificRowDropDownHandler;
|
|
import com.rongwei.bscommon.sys.listener.SpecificRowDropDownHandler;
|
|
import com.rongwei.bscommon.sys.listener.WorkShopImportListener;
|
|
import com.rongwei.bscommon.sys.listener.WorkShopImportListener;
|
|
@@ -30,7 +32,9 @@ import com.rongwei.rwcommon.base.exception.CustomException;
|
|
import com.rongwei.rwcommon.utils.SecurityUtil;
|
|
import com.rongwei.rwcommon.utils.SecurityUtil;
|
|
import com.rongwei.rwcommon.utils.StringUtils;
|
|
import com.rongwei.rwcommon.utils.StringUtils;
|
|
import com.rongwei.rwcommon.vo.CriteriaQuery;
|
|
import com.rongwei.rwcommon.vo.CriteriaQuery;
|
|
|
|
+import com.rongwei.rwcommon.vo.MailDo;
|
|
import com.rongwei.safecommon.fegin.CXAdminFeginClient;
|
|
import com.rongwei.safecommon.fegin.CXAdminFeginClient;
|
|
|
|
+import com.rongwei.safecommon.fegin.CXCommonFeginClient;
|
|
import com.rongwei.safecommon.utils.CXCommonUtils;
|
|
import com.rongwei.safecommon.utils.CXCommonUtils;
|
|
import com.rongwei.wfserver.wfcommon.sys.service.impl.ProcessServiceImpl;
|
|
import com.rongwei.wfserver.wfcommon.sys.service.impl.ProcessServiceImpl;
|
|
import lombok.extern.log4j.Log4j2;
|
|
import lombok.extern.log4j.Log4j2;
|
|
@@ -44,10 +48,12 @@ import org.springframework.transaction.annotation.Transactional;
|
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
import org.springframework.transaction.support.DefaultTransactionDefinition;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
+import javax.annotation.Resource;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletRequest;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import javax.servlet.http.HttpServletResponse;
|
|
import java.io.IOException;
|
|
import java.io.IOException;
|
|
import java.math.BigDecimal;
|
|
import java.math.BigDecimal;
|
|
|
|
+import java.math.RoundingMode;
|
|
import java.net.URLEncoder;
|
|
import java.net.URLEncoder;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
import java.util.concurrent.ConcurrentHashMap;
|
|
@@ -59,6 +65,9 @@ import static com.rongwei.safecommon.utils.SaveConstans.ForcedConflictsDescripti
|
|
import static com.rongwei.safecommon.utils.SaveConstans.JobStatus.*;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.JobStatus.*;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_N;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_N;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_Y;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.LockmarkType.LOCKMARK_Y;
|
|
|
|
+import static com.rongwei.safecommon.utils.SaveConstans.NotifyContent.PROCESSDELAY_CONTENT;
|
|
|
|
+import static com.rongwei.safecommon.utils.SaveConstans.NotifyTitle.PROCESSDELAY_TITLE;
|
|
|
|
+import static com.rongwei.safecommon.utils.SaveConstans.NotifyType.PROCESSDELAY_REMIND;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.ProcessWay.PROCESS_WAY_MERGE;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.ProcessWay.PROCESS_WAY_MERGE;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.*;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.ProductionStatus.*;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.UNForcedConflictsDescription.*;
|
|
import static com.rongwei.safecommon.utils.SaveConstans.UNForcedConflictsDescription.*;
|
|
@@ -115,6 +124,12 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
|
|
private CXAdminFeginClient cxAdminFeginClient;
|
|
private CXAdminFeginClient cxAdminFeginClient;
|
|
@Autowired
|
|
@Autowired
|
|
private ApsProductionProcessesService apsProductionProcessesService;
|
|
private ApsProductionProcessesService apsProductionProcessesService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ApsDeliveryOffsetService apsDeliveryOffsetService;
|
|
|
|
+ @Autowired
|
|
|
|
+ private ApsDeliveryOffsetDao apsDeliveryOffsetDao;
|
|
|
|
+ @Resource
|
|
|
|
+ private CXCommonFeginClient cxCommonFeginClient;
|
|
|
|
|
|
// /**
|
|
// /**
|
|
// * 更新工序的待加工批次号信息
|
|
// * 更新工序的待加工批次号信息
|
|
@@ -3005,6 +3020,286 @@ public class ApsProcessOperationProcessEquServiceImpl extends ServiceImpl<ApsPro
|
|
return R.ok(res);
|
|
return R.ok(res);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ @Override
|
|
|
|
+ public R workDeliveryOffset(WorkDeliveryOffsetReq req) {
|
|
|
|
+ SysUserVo currentUser = CXCommonUtils.getCurrentUser();
|
|
|
|
+ String tenantId = "";
|
|
|
|
+ if (currentUser == null) {
|
|
|
|
+ currentUser = new SysUserVo();
|
|
|
|
+ currentUser.setId("0");
|
|
|
|
+ currentUser.setName("定时任务操作");
|
|
|
|
+ }else {
|
|
|
|
+ tenantId = CXCommonUtils.getCurrentUserFactoryId(currentUser);
|
|
|
|
+ }
|
|
|
|
+ //查询所有没有交期偏差的生产卡片
|
|
|
|
+ List<ProductCardVo> list = this.baseMapper.selectProductionCards(tenantId);
|
|
|
|
+ if (list.isEmpty()) {
|
|
|
|
+ log.info("没有查询到需要计算的卡片信息");
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+ //卡片ID集合
|
|
|
|
+ List<String> cardIdList = list.stream().map(ProductCardVo::getId).distinct().collect(Collectors.toList());
|
|
|
|
+ //查询卡片对应的 计划成品卷数>0的作业明细的最晚的排程完工时间
|
|
|
|
+ List<ProductCardAndLatestScheduleEndDateVo> cardIdAndScheduleEndDateList = this.baseMapper.selectAllLatestEndDateByCarIds(cardIdList);
|
|
|
|
+ //查询卡片对应的 计划成品卷数>0并且作业状态=待开工或加工中的作业明细的最晚的排程完工时间
|
|
|
|
+ List<ProductCardAndLatestScheduleEndDateVo> cardIdAndScheduleEndDateList2 = this.baseMapper.selectAllLatestEndDateByCarIds2(cardIdList);
|
|
|
|
+ //查询卡片对应的 计划成品卷数>0的作业明细最晚的实际完工时间
|
|
|
|
+ List<ProductCardAndLatestScheduleEndDateVo> cardIdAndScheduleEndDateList3 = this.baseMapper.selectAllLatestEndDateByCarIds3(cardIdList);
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算每个料卷(卡片ID区分料卷)正在加工(作业状态=加工中)和准备开工(作业状态=待开工,并且待加工料卷批次号不为空)的作业明细,与原计划(预排程计划)完工时间偏差(整小时数,四舍五入),计算逻辑如下:
|
|
|
|
+ * 如果作业状态=加工中,则完工时间偏差=计划完工时间-排程完工时间
|
|
|
|
+ * 如果作业状态=待开工,则完工时间偏差=取其大(计划完工时间,当前时间+作业时长)-排程完工时间
|
|
|
|
+ */
|
|
|
|
+ List<ApsProcessOperationProcessEquDo> apsProcessOperationProcessEquDos = this.baseMapper.selectDeliveryOffestList(cardIdList);
|
|
|
|
+ //聚合<卡片ID,最大的时间偏差>
|
|
|
|
+ Map<String, Integer> maxOffsetTimeMap = apsProcessOperationProcessEquDos.stream()
|
|
|
|
+ .collect(
|
|
|
|
+ Collectors.groupingBy(
|
|
|
|
+ ApsProcessOperationProcessEquDo::getRoottaskid, Collectors.reducing(
|
|
|
|
+ 0, // 默认值
|
|
|
|
+ ApsProcessOperationProcessEquDo::getTimeoffset,
|
|
|
|
+ Integer::max
|
|
|
|
+ )));
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ DateTime now = DateUtil.date();
|
|
|
|
+ //需要修改或新增的集合
|
|
|
|
+ List<ApsDeliveryOffsetDo> needUpdateOrInsertList = new LinkedList<>();
|
|
|
|
+ for (ProductCardVo productCardVo : list) {
|
|
|
|
+ ApsDeliveryOffsetDo apsDeliveryOffsetDo = new ApsDeliveryOffsetDo();
|
|
|
|
+ apsDeliveryOffsetDo.setId(productCardVo.getId());
|
|
|
|
+ apsDeliveryOffsetDo.setOrderid(productCardVo.getOrderId());
|
|
|
|
+ apsDeliveryOffsetDo.setBlankid(productCardVo.getBlankId());
|
|
|
|
+ apsDeliveryOffsetDo.setStatus(productCardVo.getStatus());
|
|
|
|
+ apsDeliveryOffsetDo.setTenantid(productCardVo.getTenantId());
|
|
|
|
+ apsDeliveryOffsetDo.setCreatedate(now);
|
|
|
|
+ apsDeliveryOffsetDo.setModifydate(now);
|
|
|
|
+ apsDeliveryOffsetDo.setCreateuserid(currentUser.getId());
|
|
|
|
+ apsDeliveryOffsetDo.setCreateusername(currentUser.getName());
|
|
|
|
+ apsDeliveryOffsetDo.setModifyuserid(currentUser.getId());
|
|
|
|
+ apsDeliveryOffsetDo.setModifyusername(currentUser.getName());
|
|
|
|
+ apsDeliveryOffsetDo.setDeleted("0");
|
|
|
|
+
|
|
|
|
+ //计算每个料卷(卡片ID区分料卷)计划完工时间=计划成品卷数>0的作业明细的最晚的排程完工时间+订单的送货时长
|
|
|
|
+ //订单的送货时长(小时)
|
|
|
|
+ Integer deliverTime = productCardVo.getDeliverTime();
|
|
|
|
+ if (deliverTime == null) {
|
|
|
|
+ deliverTime = 0;
|
|
|
|
+ }
|
|
|
|
+ //计划成品卷数>0的作业明细的最晚的排程完工时间
|
|
|
|
+ ProductCardAndLatestScheduleEndDateVo productCardAndLatestScheduleEndDateVo = cardIdAndScheduleEndDateList.stream().filter(item -> item.getCardId().equals(productCardVo.getId())).findFirst().orElse(null);
|
|
|
|
+ if (productCardAndLatestScheduleEndDateVo != null) {
|
|
|
|
+ Date latestScheduleEndDate = productCardAndLatestScheduleEndDateVo.getLatestScheduleEndDate();
|
|
|
|
+ //料卷计划完工时间
|
|
|
|
+ DateTime planEndDate = DateUtil.offsetHour(latestScheduleEndDate, deliverTime);
|
|
|
|
+ apsDeliveryOffsetDo.setPlanenddate(planEndDate);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算每个料卷预计完工时间:
|
|
|
|
+ * 如果卡片的生产状态=待开工或加工中,
|
|
|
|
+ * 则=(计划成品卷数>0,并且作业状态=待开工或加工中的作业明细的最晚的排程完工时间)+订单的送货时长+料卷交货期偏差,
|
|
|
|
+ * 料卷交货期偏差=该料卷准备开工和正在加工的作业计划完工时间与原计划(预排程计划)完工时间偏差的最大偏差(大于零表示延期,小于零表示提前,零表示没有偏差)
|
|
|
|
+ * 如果卡片的生产状态=全部取消或部分取消或已完工,则=空(表示不需要显示)
|
|
|
|
+ */
|
|
|
|
+ if (Arrays.asList("待开工", "加工中").contains(productCardVo.getStatus())) {
|
|
|
|
+ ProductCardAndLatestScheduleEndDateVo latestScheduleEndDateVo = cardIdAndScheduleEndDateList2.stream().filter(item -> item.getCardId().equals(productCardVo.getId())).findFirst().orElse(null);
|
|
|
|
+ if (latestScheduleEndDateVo != null) {
|
|
|
|
+ Date latestScheduleEndDate = latestScheduleEndDateVo.getLatestScheduleEndDate();
|
|
|
|
+ Integer maxOffsetTime = maxOffsetTimeMap.getOrDefault(productCardVo.getId(), 0);
|
|
|
|
+ int time = deliverTime + maxOffsetTime;
|
|
|
|
+ DateTime guessEndDate = DateUtil.offsetHour(latestScheduleEndDate, time);
|
|
|
|
+ apsDeliveryOffsetDo.setGuessenddate(guessEndDate);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ apsDeliveryOffsetDo.setGuessenddate(null);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * 计算每个料卷实际完工时间:
|
|
|
|
+ * 如果卡片的生产状态=部分取消或已完工,则=计划成品卷数>0的作业明细最晚的实际完工时间;
|
|
|
|
+ * 如果卡片的生产状态=待开工或加工中或全部取消,则为空(表示未完工,不需要显示)
|
|
|
|
+ */
|
|
|
|
+ if (Arrays.asList("部分取消", "已完工").contains(productCardVo.getStatus())) {
|
|
|
|
+ ProductCardAndLatestScheduleEndDateVo latestScheduleEndDateVo = cardIdAndScheduleEndDateList3.stream().filter(item -> item.getCardId().equals(productCardVo.getId())).findFirst().orElse(null);
|
|
|
|
+ if (latestScheduleEndDateVo != null) {
|
|
|
|
+ Date latestScheduleEndDate = latestScheduleEndDateVo.getLatestScheduleEndDate();
|
|
|
|
+ apsDeliveryOffsetDo.setActualenddate(latestScheduleEndDate);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ apsDeliveryOffsetDo.setActualenddate(null);
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 计算每个料卷交货期偏差(天):
|
|
|
|
+ * 如果卡片的生产状态=待开工或加工中,
|
|
|
|
+ * 如果料卷计划完工时间的日期在坯料计划承诺交货期起止范围内,则=空
|
|
|
|
+ * 如果料卷计划完工时间的日期<坯料计划承诺交货期起,则=料卷计划完工时间的日期-坯料计划承诺交货期起
|
|
|
|
+ * 如果料卷计划完工时间的日期>坯料计划承诺交货期止,则=料卷计划完工时间的日期-坯料计划承诺交货期止
|
|
|
|
+ * 如果卡片的生产状态=部分取消或已完工,
|
|
|
|
+ * 如果料卷实际完工时间的日期在坯料计划承诺交货期起止范围内,则=空
|
|
|
|
+ * 如果料卷实际完工时间的日期<坯料计划承诺交货期起,则=料卷实际完工时间的日期-坯料计划承诺交货期起
|
|
|
|
+ * 如果料卷实际完工时间的日期>坯料计划承诺交货期止,则=料卷实际完工时间的日期-坯料计划承诺交货期止
|
|
|
|
+ * 如果卡片的生产状态=全部取消,则=空(表示不显示偏差)
|
|
|
|
+ */
|
|
|
|
+ //坯料计划承诺交货期
|
|
|
|
+ String[] split = productCardVo.getPromiseDate().split("~");
|
|
|
|
+ DateTime promiseStartDate = DateUtil.parse(split[0] + " 00:00:00");
|
|
|
|
+ DateTime promiseEndDate = DateUtil.parse(split[1] + " 23:59:59");
|
|
|
|
+ if (Arrays.asList("待开工", "加工中", "部分取消", "已完工").contains(productCardVo.getStatus())) {
|
|
|
|
+ DateTime endDate = null;
|
|
|
|
+ if (Arrays.asList("待开工", "加工中").contains(productCardVo.getStatus())) {
|
|
|
|
+ endDate = DateTime.of(apsDeliveryOffsetDo.getGuessenddate());
|
|
|
|
+ } else {
|
|
|
|
+ endDate = DateTime.of(apsDeliveryOffsetDo.getActualenddate());
|
|
|
|
+ }
|
|
|
|
+ if (endDate != null) {
|
|
|
|
+ //如果料卷计划完工时间的日期<坯料计划承诺交货期起,则=料卷预计完工时间的日期-坯料计划承诺交货期起
|
|
|
|
+ if (endDate.before(promiseStartDate)) {
|
|
|
|
+ long between = DateUtil.between(promiseStartDate, endDate, DateUnit.HOUR, false);
|
|
|
|
+ //取整
|
|
|
|
+ BigDecimal divide = new BigDecimal(between).divide(new BigDecimal(24), RoundingMode.UP);
|
|
|
|
+ int offsetDay = divide.intValue();
|
|
|
|
+ apsDeliveryOffsetDo.setDeliveryoffset(offsetDay);
|
|
|
|
+ // 如果料卷计划完工时间的日期>坯料计划承诺交货期止,则=料卷预计完工时间的日期-坯料计划承诺交货期止
|
|
|
|
+ } else if (endDate.after(promiseEndDate)) {
|
|
|
|
+ long between = DateUtil.between(promiseEndDate, endDate, DateUnit.HOUR, false);
|
|
|
|
+ //取整
|
|
|
|
+ BigDecimal divide = new BigDecimal(between).divide(new BigDecimal(24), RoundingMode.UP);
|
|
|
|
+ int offsetDay = divide.intValue();
|
|
|
|
+ apsDeliveryOffsetDo.setDeliveryoffset(offsetDay);
|
|
|
|
+ } else {
|
|
|
|
+ apsDeliveryOffsetDo.setDeliveryoffset(null);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ apsDeliveryOffsetDo.setDeliveryoffset(null);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ apsDeliveryOffsetDo.setDeliveryoffset(null);
|
|
|
|
+ }
|
|
|
|
+ needUpdateOrInsertList.add(apsDeliveryOffsetDo);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ if (!apsProcessOperationProcessEquDos.isEmpty()) {
|
|
|
|
+ Lists.partition(apsProcessOperationProcessEquDos, 1000).forEach(apsProcessOperationProcessEquDoList -> {
|
|
|
|
+ this.baseMapper.updateProcessEquBatchById(apsProcessOperationProcessEquDoList);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ if (!needUpdateOrInsertList.isEmpty()) {
|
|
|
|
+ Lists.partition(needUpdateOrInsertList, 50).forEach(needUpdateOrInsertListVo -> {
|
|
|
|
+ this.baseMapper.saveOrUpdateDeliverOffsetBatch(needUpdateOrInsertListVo);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+ //反查需要删除的数据
|
|
|
|
+ List<String> needDelIdList = this.baseMapper.selectAllNeedDelIds();
|
|
|
|
+ if (!needDelIdList.isEmpty()) {
|
|
|
|
+ this.baseMapper.myDeleteByIds(needDelIdList);
|
|
|
|
+ }
|
|
|
|
+ if (req.getNeedSendMessage()) {
|
|
|
|
+ //发送消息和邮件
|
|
|
|
+ sendMessageAndEmail(needUpdateOrInsertList, list);
|
|
|
|
+ }
|
|
|
|
+ return R.ok();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void sendMessageAndEmail(List<ApsDeliveryOffsetDo> needUpdateOrInsertList, List<ProductCardVo> list) {
|
|
|
|
+ //过滤需要发送消息的数据
|
|
|
|
+ List<ApsDeliveryOffsetDo> needSendMessageList = needUpdateOrInsertList.stream().filter(item ->
|
|
|
|
+ Arrays.asList("待开工", "加工中").contains(item.getStatus())
|
|
|
|
+ && item.getDeliveryoffset() != null
|
|
|
|
+ && item.getDeliveryoffset() > 0).collect(Collectors.toList());
|
|
|
|
+ if (!needSendMessageList.isEmpty()) {
|
|
|
|
+ //查询每个工厂的 生产计划主任(role071)、车间调度组长(cjddzz)
|
|
|
|
+ List<TenantIdAndUserIdsVo> tenantIdAndUserIdsVoList = this.baseMapper.selectNeedPushMessageUsers();
|
|
|
|
+ Map<String, List<String>> tenantIdAndUserIdListMap = new HashMap<>();
|
|
|
|
+ Map<String, String> tenantIdAndEmailsListMap = new HashMap<>();
|
|
|
|
+ for (TenantIdAndUserIdsVo tenantIdAndUserIdsVo : tenantIdAndUserIdsVoList) {
|
|
|
|
+ List<String> userList = new LinkedList<>();
|
|
|
|
+ if (StringUtils.isNotBlank(tenantIdAndUserIdsVo.getUserIds())) {
|
|
|
|
+ userList = new LinkedList<>(Arrays.asList(tenantIdAndUserIdsVo.getUserIds().split(",")));
|
|
|
|
+ }
|
|
|
|
+ tenantIdAndUserIdListMap.putIfAbsent(tenantIdAndUserIdsVo.getTenantId(), userList);
|
|
|
|
+ tenantIdAndEmailsListMap.putIfAbsent(tenantIdAndUserIdsVo.getTenantId(), tenantIdAndUserIdsVo.getEmails());
|
|
|
|
+ }
|
|
|
|
+ //<工厂ID,<订单号,批次号集合>>
|
|
|
|
+ Map<String, Map<String, List<String>>> resMap = new HashMap<>();
|
|
|
|
+ for (ApsDeliveryOffsetDo apsDeliveryOffsetDo : needSendMessageList) {
|
|
|
|
+ ProductCardVo productCardVo = list.stream().filter(item -> item.getId().equals(apsDeliveryOffsetDo.getId())).findFirst().orElse(null);
|
|
|
|
+ if (productCardVo == null) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //订单号 优先使用客户订单号
|
|
|
|
+ String orderNo = productCardVo.getCustomOrderNo();
|
|
|
|
+ if (StringUtils.isBlank(orderNo)) {
|
|
|
|
+ orderNo = productCardVo.getOrderNo();
|
|
|
|
+ if (StringUtils.isBlank(orderNo)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //批次号
|
|
|
|
+ String blankBatchNumber = productCardVo.getBlankBatchNumber();
|
|
|
|
+ if (StringUtils.isBlank(blankBatchNumber)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ String tenantId = productCardVo.getTenantId();
|
|
|
|
+ if (resMap.containsKey(tenantId)) {
|
|
|
|
+ Map<String, List<String>> orderMap = resMap.get(tenantId);
|
|
|
|
+ if (orderMap.containsKey(orderNo)) {
|
|
|
|
+ List<String> blankNumberList = orderMap.get(orderNo);
|
|
|
|
+ blankNumberList.add(blankBatchNumber);
|
|
|
|
+ } else {
|
|
|
|
+ orderMap.put(orderNo, new LinkedList<>(Collections.singletonList(blankBatchNumber)));
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ Map<String, List<String>> orderMap = new HashMap<>();
|
|
|
|
+ orderMap.put(orderNo, new LinkedList<>(Collections.singletonList(blankBatchNumber)));
|
|
|
|
+ resMap.put(tenantId, orderMap);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ //按照工厂发送消息
|
|
|
|
+ for (String key : resMap.keySet()) {
|
|
|
|
+ Map<String, List<String>> orderMap = resMap.get(key);
|
|
|
|
+ List<String> messageList = new LinkedList<>();
|
|
|
|
+ for (String orderNo : orderMap.keySet()) {
|
|
|
|
+ List<String> numberList = orderMap.get(orderNo);
|
|
|
|
+ String message = "订单号:【" + orderNo + "】,料卷批次号:【" + String.join(",", numberList) + "】";
|
|
|
|
+ messageList.add(message);
|
|
|
|
+ }
|
|
|
|
+ if (messageList.isEmpty()) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //获取此工厂需要发送通知的人的ID
|
|
|
|
+ List<String> userIdList = tenantIdAndUserIdListMap.getOrDefault(key, null);
|
|
|
|
+ if (userIdList.isEmpty()) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //系统通知(移动端和PC端个人工作台)
|
|
|
|
+ CXCommonUtils.sendNotify("料卷延期",
|
|
|
|
+ "以下料卷预计延期,请及时调整计划:\r\n" + String.join("\r\n", messageList),
|
|
|
|
+ null,
|
|
|
|
+ userIdList,
|
|
|
|
+ null,
|
|
|
|
+ PROCESSDELAY_REMIND,
|
|
|
|
+ false);
|
|
|
|
+
|
|
|
|
+ //获取需要邮件的邮箱
|
|
|
|
+ String emails = tenantIdAndEmailsListMap.getOrDefault(key, null);
|
|
|
|
+ if (StringUtils.isBlank(emails)) {
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ //邮件提醒
|
|
|
|
+ MailDo mailDo = new MailDo();
|
|
|
|
+ mailDo.setReceiveEmail(emails.split(","));
|
|
|
|
+ mailDo.setNeedTransReceive(false);
|
|
|
|
+ mailDo.setCcEmail(new String[]{});
|
|
|
|
+ mailDo.setSubject("料卷延期");
|
|
|
|
+ mailDo.setContent("以下料卷预计延期,请及时调整计划:<br>" + String.join("<br>", messageList));
|
|
|
|
+ cxCommonFeginClient.sendHtmlMail(mailDo);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|