diff --git a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesShippingKanbanCfgService.java b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesShippingKanbanCfgService.java index 61687bb..628cf7d 100644 --- a/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesShippingKanbanCfgService.java +++ b/modules/i3plus-ext-mes-pcn-api/src/main/java/cn/estsh/i3plus/ext/mes/pcn/api/busi/IMesShippingKanbanCfgService.java @@ -1,10 +1,15 @@ package cn.estsh.i3plus.ext.mes.pcn.api.busi; +import cn.estsh.i3plus.ext.mes.pcn.pojo.model.CustQtyByTimeChartDataModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesShippingKanbanCfgModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesShippingKanbanModel; +import java.util.List; + public interface IMesShippingKanbanCfgService { MesShippingKanbanCfgModel queryShippingKanbanCfg(String organizeCode, String shippingGroupCode); void doSaveShippingKanbanCfg(MesShippingKanbanCfgModel request, String organizeCode, String username); MesShippingKanbanModel queryShippingKanbanContext(String organizeCode, String shippingGroupCode); + List queryCustQtyByTimeChartData(String organizeCode, String shippingGroupCode); + void doCreateCustQtyByTime(String organizeCode, String username); } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/busi/MesShippingKanbanCfgController.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/busi/MesShippingKanbanCfgController.java index c367bc8..ea22648 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/busi/MesShippingKanbanCfgController.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/controller/busi/MesShippingKanbanCfgController.java @@ -13,9 +13,9 @@ import org.springframework.util.StringUtils; import org.springframework.web.bind.annotation.*; /** - * @Description: 产线与班组的对应关系 - * @Author: gsz - * @Date: 2024/5/25 18:16 + * @Description: 龙兴发运看板 + * @Author: jason.niu + * @Date: 2025/3/25 18:16 * @Modify: */ @RestController @@ -64,4 +64,18 @@ public class MesShippingKanbanCfgController { return ImppExceptionBuilder.newInstance().buildExceptionResult(e); } } + + @GetMapping("/queryCustQtyByTimeChartData") + @ApiOperation(value = "查询库存趋势折线图数据") + public ResultBean queryCustQtyByTimeChartData(String organizeCode, String shippingGroupCode) { + try { + organizeCode = !StringUtils.isEmpty(organizeCode) ? organizeCode : AuthUtil.getOrganize().getOrganizeCode(); + return ResultBean.success("查询成功").setResultList(shippingKanbanCfgService.queryCustQtyByTimeChartData(organizeCode, shippingGroupCode)); + } catch (ImppBusiException imppException) { + return ResultBean.fail(imppException); + } catch (Exception e) { + e.printStackTrace(); + return ImppExceptionBuilder.newInstance().buildExceptionResult(e); + } + } } diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesCustQtyByTimeJob.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesCustQtyByTimeJob.java new file mode 100644 index 0000000..7ce36ea --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/schedulejob/MesCustQtyByTimeJob.java @@ -0,0 +1,43 @@ +package cn.estsh.i3plus.ext.mes.pcn.apiservice.schedulejob; + +import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesShippingKanbanCfgService; +import cn.estsh.impp.framework.boot.init.ApplicationProperties; +import cn.hutool.json.JSONObject; +import cn.hutool.json.JSONUtil; +import io.swagger.annotations.ApiOperation; +import lombok.extern.slf4j.Slf4j; +import org.quartz.DisallowConcurrentExecution; +import org.quartz.JobExecutionContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.util.StringUtils; + +/** + * @author 龙兴发运看板抓取客户端库存数据job + * @version 1.0 + * @date 2025/04/30 16:44 + **/ +@Slf4j +@DisallowConcurrentExecution +@Component +@ApiOperation("龙兴发运看板抓取客户端库存数据job") +public class MesCustQtyByTimeJob extends BaseMesScheduleJob { + @Autowired + private IMesShippingKanbanCfgService shippingKanbanCfgService; + + public MesCustQtyByTimeJob() { + super(MesCustQtyByTimeJob.class, "龙兴发运看板抓取客户端库存数据job"); + } + + @Override + public void executeMesJob(JobExecutionContext context, ApplicationProperties applicationProperties) { + String jobParam = this.getJobParam(); + JSONObject jsonObject= JSONUtil.parseObj(jobParam); + String organizeCode = jsonObject.getStr("organizeCode"); + if (StringUtils.isEmpty(organizeCode)){ + log.error("请添加需要抓取的工厂代码!"); + return; + } + shippingKanbanCfgService.doCreateCustQtyByTime(organizeCode, "job"); + } +} diff --git a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesShippingKanbanCfgServiceImpl.java b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesShippingKanbanCfgServiceImpl.java index 1e8edfa..e71ff16 100644 --- a/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesShippingKanbanCfgServiceImpl.java +++ b/modules/i3plus-ext-mes-pcn-apiservice/src/main/java/cn/estsh/i3plus/ext/mes/pcn/apiservice/serviceimpl/busi/MesShippingKanbanCfgServiceImpl.java @@ -1,32 +1,29 @@ package cn.estsh.i3plus.ext.mes.pcn.apiservice.serviceimpl.busi; import cn.estsh.i3plus.ext.mes.pcn.api.busi.IMesShippingKanbanCfgService; +import cn.estsh.i3plus.ext.mes.pcn.pojo.model.CustQtyByTimeChartDataModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesShippingKanbanCfgModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesShippingKanbanModel; import cn.estsh.i3plus.ext.mes.pcn.pojo.model.MesShippingKanbanViewModel; -import cn.estsh.i3plus.ext.mes.pcn.pojo.util.MesPcnExtConstWords; import cn.estsh.i3plus.mes.pcn.util.DateUtil; import cn.estsh.i3plus.platform.common.convert.ConvertBean; import cn.estsh.i3plus.platform.common.tool.TimeTool; import cn.estsh.i3plus.pojo.base.bean.DdlPackBean; import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil; import cn.estsh.i3plus.pojo.base.tool.DdlPreparedPack; +import cn.estsh.i3plus.pojo.mes.bean.MesCustQtyByTime; import cn.estsh.i3plus.pojo.mes.bean.MesPartShippingGroup; import cn.estsh.i3plus.pojo.mes.bean.MesProductionRecord; import cn.estsh.i3plus.pojo.mes.bean.seres.MesCimSeresJisVinOverPoint; -import cn.estsh.i3plus.pojo.mes.bean.shipping.MesLoadingListDetail; import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingKanbanCfg; import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingKanbanCfgDetail; -import cn.estsh.i3plus.pojo.mes.bean.shipping.MesShippingOrderManagement; +import cn.estsh.i3plus.pojo.mes.repository.MesCustQtyByTimeRepository; import cn.estsh.i3plus.pojo.mes.repository.MesPartShippingGroupRepository; import cn.estsh.i3plus.pojo.mes.repository.MesShippingKanbanCfgDetailRepository; import cn.estsh.i3plus.pojo.mes.repository.MesShippingKanbanCfgRepository; import cn.estsh.i3plus.pojo.mes.repository.seres.IMesCimSeresJisVinOverPointRepository; import cn.estsh.i3plus.pojo.mes.util.MesExtEnumUtil; -import cn.hutool.core.date.DateTime; -import cn.hutool.core.date.LocalDateTimeUtil; import cn.hutool.core.util.NumberUtil; -import cn.hutool.core.util.StrUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; @@ -51,6 +48,8 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer @Autowired private IMesCimSeresJisVinOverPointRepository vinOverPointRDao; @Autowired + private MesCustQtyByTimeRepository custQtyByTimeRDao; + @Autowired private EntityManager entityManager; @Override @@ -113,6 +112,7 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer oldCfg.setCustStartShift(cfg.getCustStartShift()); oldCfg.setInterStartShift(cfg.getInterStartShift()); oldCfg.setCustJph(cfg.getCustJph()); + oldCfg.setCarouselTime(cfg.getCarouselTime()); ConvertBean.serviceModelUpdate(oldCfg, username); shippingKanbanCfgRDao.update(oldCfg); @@ -188,7 +188,7 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer List values = null; switch (index) { case CLIENT_STOCK_QTY: - values = getClientStockQty(cfg, cfgDetail); + values = getClientStockQty(cfg); break; case WAIT_SHIPPING_QTY: values = getWaitShippingQty(cfg, cfgDetail); @@ -244,6 +244,107 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer return model; } + /** + * 定时根据发运组获取客户端库存 + * @param cfg 发运组配置参数 + * @param shippingGroupCode 发运组编码 + * @return 返回客户端库存数据 + */ + private int getClientStockQtyForJob(MesShippingKanbanCfg cfg, String shippingGroupCode) { + if (StringUtils.isEmpty(shippingGroupCode)) { + return 0; + } + + // 获取赛力斯上线的最新流水号 + String onNumber = ""; + if (!StringUtils.isEmpty(cfg.getOnlinePoint())) { + StringBuilder onNumberHql = new StringBuilder(); + onNumberHql.append("select max(serialNumber) from ").append(MesCimSeresJisVinOverPoint.class.getName()); + onNumberHql.append(" where organizeCode = :organizeCode and isDeleted = :isDeleted and isValid = :isValid "); + onNumberHql.append(" and overPoint = :overPoint "); + try { + onNumber = entityManager.createQuery(onNumberHql.toString(), String.class) + .setParameter("organizeCode", cfg.getOrganizeCode()) + .setParameter("isValid", CommonEnumUtil.VALID) + .setParameter("isDeleted", CommonEnumUtil.FALSE) + .setParameter("overPoint", cfg.getOnlinePoint()) + .getSingleResult(); + } catch (NoResultException ignored) { + } + } + if (StringUtils.isEmpty(onNumber)) { + onNumber = "0"; + } + + List strShippingGroupList = new ArrayList<>(); + strShippingGroupList.add(shippingGroupCode); + String offNumber = getMaxOffNumber(cfg.getOrganizeCode(), strShippingGroupList); + if (StringUtils.isEmpty(offNumber)) { + offNumber = "0"; + } + + int adjustValue = cfg.getAdjustValue() != null ? cfg.getAdjustValue() : 0; + return Integer.parseInt(offNumber) - Integer.parseInt(onNumber) + adjustValue; + } + + @Override + public List queryCustQtyByTimeChartData(String organizeCode, String shippingGroupCode) { + List result = new ArrayList<>(); + if (StringUtils.isEmpty(organizeCode) || StringUtils.isEmpty(shippingGroupCode)) { + return result; + } + for (String groupCode : shippingGroupCode.split(",")) { + Date endTime = DateUtil.now(); + Date startTime = DateUtil.addDays(endTime, -1); + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + DdlPreparedPack.getStringEqualPack(groupCode, "shippingGroupCode", packBean); + DdlPreparedPack.getStringBiggerPack(DateUtil.formatDate(startTime), "createDatetime", packBean); + DdlPreparedPack.getStringSmallerPack(DateUtil.formatDate(endTime), "createDatetime", packBean); + DdlPreparedPack.getOrderBy("createDatetime", CommonEnumUtil.ASC_OR_DESC.ASC.getValue(), packBean); + List custQtyByTimes = custQtyByTimeRDao.findByHqlWhere(packBean); + if (CollectionUtils.isEmpty(custQtyByTimes)) { + continue; + } + + CustQtyByTimeChartDataModel model = new CustQtyByTimeChartDataModel(); + model.setTitle(groupCode); + for (MesCustQtyByTime byTime : custQtyByTimes) { + Date createDate = DateUtil.parse(byTime.getCreateDatetime()); + model.getXAxis().add(TimeTool.getDay(createDate) + "日" + TimeTool.getHour(createDate) + "时"); + model.getSeries().add(byTime.getCustQty()); + } + result.add(model); + } + + return result; + } + + @Override + public void doCreateCustQtyByTime(String organizeCode, String username) { + DdlPackBean packBean = DdlPackBean.getDdlPackBean(organizeCode); + Set handleShippingGroup = new HashSet<>(); + List kanbanCfg = shippingKanbanCfgRDao.findByHqlWhere(packBean); + for (MesShippingKanbanCfg cfg : kanbanCfg) { + if (StringUtils.isEmpty(cfg.getShippingGroupCode())) { + continue; + } + for (String shippingGroupCode : cfg.getShippingGroupCode().split(",")) { + if (handleShippingGroup.contains(shippingGroupCode)) { + continue; + } + handleShippingGroup.add(shippingGroupCode); + + int custQty = getClientStockQtyForJob(cfg, shippingGroupCode); + MesCustQtyByTime byTime = new MesCustQtyByTime(); + byTime.setShippingGroupCode(shippingGroupCode); + byTime.setCustQty(custQty); + byTime.setOrganizeCode(organizeCode); + ConvertBean.serviceModelInitialize(byTime, username); + custQtyByTimeRDao.insert(byTime); + } + } + } + private String getColor(MesShippingKanbanCfgDetail cfgDetail, List values) { if (CollectionUtils.isEmpty(values)) { return cfgDetail.getDefaultColor(); @@ -306,17 +407,25 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer hql.append("select sd.vin"); hql.append(" from MesShippingOrderManagement s inner join MesShippingOrderManagementDetail sd on s.id = sd.pid and sd.organizeCode = :organizeCode and sd.isDeleted=:isDeleted and sd.isValid=:isValid "); hql.append(" and s.status in (:status) "); - hql.append(" and s.shippingGroupCode in (:shippingGroupCode) "); + if (shippingGroupCodes.size() == 1) { + hql.append(" and s.shippingGroupCode = :shippingGroupCode "); + } else { + hql.append(" and s.shippingGroupCode in (:shippingGroupCode) "); + } hql.append(" ORDER BY sd.id desc"); try { - return entityManager.createQuery(hql.toString(), String.class) - .setParameter("organizeCode", organizeCode) - .setParameter("isValid", CommonEnumUtil.VALID) - .setParameter("isDeleted", CommonEnumUtil.FALSE) - .setParameter("status", status) - .setParameter("shippingGroupCode", shippingGroupCodes) - .setMaxResults(1) - .getSingleResult(); + Query query = entityManager.createQuery(hql.toString(), String.class); + query.setParameter("organizeCode", organizeCode); + query.setParameter("isValid", CommonEnumUtil.VALID); + query.setParameter("isDeleted", CommonEnumUtil.FALSE); + query.setParameter("status", status); + if (shippingGroupCodes.size() == 1) { + query.setParameter("shippingGroupCode", shippingGroupCodes.get(0)); + } else { + query.setParameter("shippingGroupCode", shippingGroupCodes); + } + query.setMaxResults(1); + return query.getSingleResult().toString(); } catch (NoResultException e) { return ""; } @@ -334,7 +443,7 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer return ""; } StringBuilder offNumberHql = new StringBuilder(); - offNumberHql.append("select max(serialNumber) from " + MesCimSeresJisVinOverPoint.class.getName()); + offNumberHql.append("select max(serialNumber) from ").append(MesCimSeresJisVinOverPoint.class.getName()); offNumberHql.append(" where organizeCode = :organizeCode and isDeleted = :isDeleted and isValid = :isValid "); offNumberHql.append(" and vin = :vin "); try { @@ -353,10 +462,9 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer * 客户端库存 * 最新下线的排序发运单客户流水号(SERIAL_NUMBER)- 赛力斯上线的最新流水号+调整值。 * @param cfg - * @param cfgDetail * @return */ - private List getClientStockQty(MesShippingKanbanCfg cfg, MesShippingKanbanCfgDetail cfgDetail) { + private List getClientStockQty(MesShippingKanbanCfg cfg) { List values = new ArrayList<>(); List strShippingGroupList = Arrays.asList(cfg.getShippingGroupCode().split(",")); if (CollectionUtils.isEmpty(strShippingGroupList)) { @@ -368,7 +476,7 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer String onNumber = ""; if (!StringUtils.isEmpty(cfg.getOnlinePoint())) { StringBuilder onNumberHql = new StringBuilder(); - onNumberHql.append("select max(serialNumber) from " + MesCimSeresJisVinOverPoint.class.getName()); + onNumberHql.append("select max(serialNumber) from ").append(MesCimSeresJisVinOverPoint.class.getName()); onNumberHql.append(" where organizeCode = :organizeCode and isDeleted = :isDeleted and isValid = :isValid "); onNumberHql.append(" and overPoint = :overPoint "); try { @@ -708,7 +816,7 @@ public class MesShippingKanbanCfgServiceImpl implements IMesShippingKanbanCfgSer List values = new ArrayList<>(); Date nowTime = DateUtil.now(); //获取客户端库存 - List clientStockValue = getClientStockQty(cfg, cfgDetail); + List clientStockValue = getClientStockQty(cfg); if (StringUtils.isEmpty(clientStockValue)) { return values; } diff --git a/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/model/CustQtyByTimeChartDataModel.java b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/model/CustQtyByTimeChartDataModel.java new file mode 100644 index 0000000..92c9ab2 --- /dev/null +++ b/modules/i3plus-ext-mes-pcn-pojo/src/main/java/cn/estsh/i3plus/ext/mes/pcn/pojo/model/CustQtyByTimeChartDataModel.java @@ -0,0 +1,19 @@ +package cn.estsh.i3plus.ext.mes.pcn.pojo.model; + +import io.swagger.annotations.ApiParam; +import lombok.Data; + +import java.util.ArrayList; +import java.util.List; + +@Data +public class CustQtyByTimeChartDataModel { + @ApiParam("发运组编码") + private String title; + + @ApiParam("日期") + private List xAxis = new ArrayList<>(); + + @ApiParam("数值") + private List series = new ArrayList<>(); +}