排产相关-sjx

develop-QA
sunjianxi 3 months ago
parent d18b98f069
commit 02a6c1bbe7
  1. 3
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/dto/WorkOrderDto.java
  2. 2
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/entity/EquipResourceEntity.java
  3. 8
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/entity/ProcessSetEntity.java
  4. 6
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/entity/TeamSetEntity.java
  5. 7
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/mapper/WorkOrderMapper.xml
  6. 9
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/mapper/YieldOrderMapper.xml
  7. 2
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/impl/EquipResourceServiceImpl.java
  8. 157
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/impl/WorkOrderServiceImpl.java
  9. 20
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/impl/YieldOrderServiceImpl.java
  10. 9
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/vo/YieldOrderVO.java

@ -37,8 +37,11 @@ public class WorkOrderDto {
private String makeQty;
private String workCenterName;
private String workCenterId;
private Integer totalCount;
private Integer schedulingCount;
private Integer unschedulingCount;
private Integer errorCount;
private String schedulingRate;
private String productIdent;
private String receiveTime;

@ -157,6 +157,8 @@ public class EquipResourceEntity extends BaseEntity {
@Schema(description = "玻璃粉牌号")
private String GlassCode;
private Integer isDeleted;

@ -59,7 +59,7 @@ public class ProcessSetEntity extends BaseEntity {
* 转速/振频
*/
@Schema(description = "转速/振频")
private String vSpeed;
private String viSpeed;
/**
* 整流机控制模式
*/
@ -70,11 +70,7 @@ public class ProcessSetEntity extends BaseEntity {
*/
@Schema(description = "班组")
private String team;
/**
*
*/
@Schema(description = "")
private BigDecimal newColumn;
/**
* 编码
*/

@ -63,17 +63,17 @@ public class TeamSetEntity extends BaseEntity {
* 班组长外键-人员
*/
@Schema(description = "班组长(外键-人员)")
private BigDecimal teamLeader;
private Long teamLeader;
/**
* 计划员外键-人员
*/
@Schema(description = "计划员(外键-人员)")
private BigDecimal planner;
private Long planner;
/**
* 调度员外键-人员
*/
@Schema(description = "调度员(外键-人员)")
private BigDecimal dispatcher;
private Long dispatcher;
/**
* 班组成员
*/

@ -171,7 +171,9 @@
-- 统计待排产的数量
COUNT(CASE WHEN a.STATUS >= 10003 THEN a.WORK_CENTER_ID END) AS "totalCount",
-- 统计已排产的数量
COUNT(CASE WHEN a.STATUS not in (10003,10006) THEN a.WORK_CENTER_ID END) AS "schedulingCount"
COUNT(CASE WHEN a.STATUS not in (10003,10006) THEN a.WORK_CENTER_ID END) AS "schedulingCount",
COUNT(CASE WHEN a.STATUS = 10003 THEN a.WORK_CENTER_ID END) AS "unschedulingCount",
COUNT(CASE WHEN a.STATUS = 10006 THEN a.WORK_CENTER_ID END) AS "errorCount"
FROM MES_YIELD_ORDER a
LEFT JOIN BS_WORK_CENTER b ON a.WORK_CENTER_ID = b.ID
<where>
@ -183,7 +185,8 @@
and a.receive_time <![CDATA[ <= ]]> to_date(#{endTime},'YYYY-MM-DD HH24:MI:SS')
</if>
</where>
GROUP BY b.WC_NAME, a.WORK_CENTER_ID;
GROUP BY b.WC_NAME, a.WORK_CENTER_ID
order by COUNT( CASE WHEN a.STATUS NOT IN ( 10003, 10006 ) THEN a.WORK_CENTER_ID END )/COUNT( CASE WHEN a.STATUS >= 10003 THEN a.WORK_CENTER_ID END ) desc
</select>
<select id="selectTeam" resultType="java.lang.String">

@ -77,6 +77,15 @@
<if test="yieldOrder.roamNo != null and yieldOrder.roamNo != ''">
and roam_no = #{yieldOrder.roamNo}
</if>
<if test="yieldOrder.startTime !=null and yieldOrder.startTime != ''">
and receive_time <![CDATA[ >= ]]> to_date(concat(#{yieldOrder.startTime},' 00:00:00'),'YYYY-MM-DD HH24:MI:SS')
</if>
<if test="yieldOrder.endTime !=null and yieldOrder.endTime != ''">
and receive_time <![CDATA[ <= ]]> to_date(concat(#{yieldOrder.endTime},' 23:59:59'),'YYYY-MM-DD HH24:MI:SS')
</if>
<if test="yieldOrder.workCenterId != null">
and work_center_id = #{yieldOrder.workCenterId}
</if>
</where>
</select>

@ -90,7 +90,7 @@ public class EquipResourceServiceImpl extends BaseServiceImpl<EquipResourceMappe
}
//删除3天之前的数据
List<EquipResourceEntity> deleteList = this.list(Wrappers.<EquipResourceEntity>lambdaQuery().le(EquipResourceEntity::getDateTime,DateFormatUtils.format(DateUtils.addDays(date,-3),"yyyy-MM-dd")));
this.removeByIds(deleteList.stream().map(BaseEntity::getId).collect(Collectors.toList()));
deleteList.forEach(item -> baseMapper.deleteById(item.getId()));
}
@Override

@ -85,6 +85,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
private final IProcessSetService processSetService;
private final IPartService partService;
private final ISintTempCurveService sintTempCurveService;
private final ITeamSetService teamSetService;
@Value("${business.oldMes.url}")
private String oldMesUrl;
@ -184,64 +185,14 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
@Override
public List<WorkOrderDto> schedulingBoard(WorkOrderDto workOrder) {
List<WorkOrderDto> list = baseMapper.selectWorkOrderList(workOrder);
//Map<String, List<WorkOrderDto>> resultList = new HashMap<>();
Map<String, List<WorkOrderDto>> woCodeGroup = list.stream().collect(Collectors.groupingBy(WorkOrderDto::getWoCode));
List<WorkOrderDto> resultList = new ArrayList<>();
for (Map.Entry<String, List<WorkOrderDto>> entry : woCodeGroup.entrySet()) {
WorkOrderDto workOrderDto = new WorkOrderDto();
String woCode = entry.getKey();
List<WorkOrderDto> woList = entry.getValue();
workOrderDto.setWoCode(woCode);
workOrderDto.setWorkOrderList(entry.getValue());
resultList.add(workOrderDto);
//按processName二次分组
/* Map<String, List<WorkOrderDto>> processGroup = woList.stream()
.collect(Collectors.groupingBy(WorkOrderDto::getProcessName));
//整合每个processName的时间
List<WorkOrderDto> mergedProcessList = new ArrayList<>();
for (Map.Entry<String, List<WorkOrderDto>> processEntry : processGroup.entrySet()) {
String processName = processEntry.getKey();
List<WorkOrderDto> processList = processEntry.getValue();
// 计算最早的开始时间、最晚的结束时间
String minStartTime = getMinTime(processList.stream().map(WorkOrderDto::getPlanStartTime).toList());
String maxEndTime = getMaxTime(processList.stream().map(WorkOrderDto::getPlanEndTime).toList());
// 封装整合后的DTO(复用第一个对象或新建)
WorkOrderDto mergedDto = new WorkOrderDto();
mergedDto.setWoCode(woCode);
mergedDto.setProcessName(processName);
for (WorkOrderDto dto : processList) {
mergedDto.setTeamName(dto.getTeamName());
mergedDto.setCardNo(dto.getCardNo());
mergedDto.setBatchNo(dto.getBatchNo());
mergedDto.setPartCode(dto.getPartCode());
mergedDto.setCurrentProcessName(dto.getCurrentProcessName());
mergedDto.setMakeQty(dto.getMakeQty());
mergedDto.setEquipName(dto.getEquipName());
mergedDto.setProductIdent(dto.getProductIdent());
mergedDto.setPriorityAps(YieldOrderEnum.getName(Integer.parseInt(dto.getPriorityAps())));
if (dto.getPlanStartTime().equals(minStartTime)) {
mergedDto.setStartTime(dto.getStartTime());
mergedDto.setFactStartTime(dto.getFactStartTime());
}
if (dto.getPlanEndTime().equals(maxEndTime)) {
mergedDto.setEndTime(dto.getEndTime());
mergedDto.setFactEndTime(dto.getFactEndTime());
mergedDto.setPlanStatus(dto.getPlanStatus());
}
}
mergedDto.setPlanStartTime(minStartTime);
mergedDto.setPlanEndTime(maxEndTime);
mergedProcessList.add(mergedDto);
}
mergedProcessList.sort(Comparator.comparing(WorkOrderDto::getPlanStartTime));
workOrderDto.setWoCode(woCode);
workOrderDto.setWorkOrderList(mergedProcessList);
resultList.add(workOrderDto);*/
//resultList.put(woCode, mergedProcessList);
}
return resultList;
@ -429,7 +380,6 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
if(maxMatchList != null){
glassCodeStr = maxMatchList.stream().collect(Collectors.joining(","));
log.info("订单:"+order.getYoCode()+",温度曲线是:"+glassCodeStr);
//if(sameFurnaceMap.containsKey(glassCodeStr))
}
}
//包含说明之前有过这个温度曲线的订单
@ -489,7 +439,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
//根据作业中心查询所有设备
List<EquipAbilityEntity> equipAbilityList = equipAbilityService.list(Wrappers.<EquipAbilityEntity>lambdaQuery().in(EquipAbilityEntity::getWorkCenterId, craft.getWorkCenterId()).eq(EquipAbilityEntity::getCraftId, craft.getCaId()));
if (CollectionUtils.isEmpty(equipAbilityList)) {
order.setErrorInfo("工序:"+processMap.get(craft.getPpsId()) +"设备未匹配到对应的设备能力");
order.setErrorInfo("工序:"+processMap.get(craft.getPpsId()) +",未匹配到对应的设备能力");
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCode());
yieldOrderService.updateById(order);
isSchecuding = false;
@ -505,7 +455,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
List<EquipResourceEntity> equipResourceList = equipResourceService.list(Wrappers.<EquipResourceEntity>lambdaQuery().eq(EquipResourceEntity::getCraftId, craft.getCaId()).eq(EquipResourceEntity::getWorkCenterId, craft.getWorkCenterId()).ge(EquipResourceEntity::getStartTime, dateTime).eq(EquipResourceEntity::getIsUsed, 0).in(EquipResourceEntity::getEquipOrder, entry.getKey()));
if (CollectionUtils.isEmpty(equipResourceList)) {
order.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCode());
order.setErrorInfo("工序:" + processMap.get(craft.getPpsId()) + "未匹配到对应的设备资源");
order.setErrorInfo("工序:" + processMap.get(craft.getPpsId()) + ",未匹配到对应的设备资源");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
@ -528,7 +478,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
.collect(Collectors.toList())
)
));
//计算生产所需产能,需将m2换算成dm2
//计算生产所需产能
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(order.getYpQty()));
//需要判断设备额定生产能力是否满足订单总产能,如果不满足,则需要把总产能进行拆分
List<BigDecimal> capacityList = capacitySplit(equipResourceMap, sumCapacity);
@ -643,72 +593,6 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
if(CollectionUtils.isNotEmpty(personResourceList)){
workPlan.setMakeTeam(personResourceList.get(0).getTeamId());
}
//通过加锁的方式保证每次查询到的人力资源都是最新的
/*Long craftId = craft.getCaId();
Lock craftLock = getCraftLock(craftId);
craftLock.lock(); // 加本地锁,同一工艺ID串行执行
try{
//查询大于当前时间+半小时的所有人员资源
List<PersonResourceEntity> personResourceList = personResourceService.list(Wrappers.<PersonResourceEntity>lambdaQuery().ge(PersonResourceEntity::getStartTime,prevProcessEnd.plusMinutes(30)).eq(PersonResourceEntity::getCraftId,craft.getCaId()).eq(PersonResourceEntity::getIsUsed,0).orderByAsc(PersonResourceEntity::getStartTime).last("for update"));
//如果personResourceList不为空,说明是镀后检验或者镀后验收这类跨作业中心的工艺
if(CollectionUtils.isNotEmpty(personResourceList)){
//剔除掉personResourceList中isUsed=1之前的数据,isUsed=1说明这些时间被占用了
*//* int isUsedIndex = -1;
for(int m=0;m<personResourceList.size();m++){
if("1".equals(personResourceList.get(m).getIsUsed())){
isUsedIndex = m;
}
}
if(isUsedIndex != -1){
personResourceList = personResourceList.subList(isUsedIndex + 1, personResourceList.size());
}*//*
//计算加工时间占几个人力片段
//int period = totalTime.divide(BigDecimal.valueOf(30),0, RoundingMode.CEILING).intValue();
//1.如果size=0,说明最近3天的资源都排满了,就不需要排了
if(personResourceList.size() == 0){
//还原已占用资源
restoreResource(workPlanList);
order.setErrorInfo("最近3天人力资源已占满,需下次排产");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}
//占用时间段
*//*LocalDateTime startTime = LocalDateTime.now();
LocalDateTime endTime = LocalDateTime.now();
StringBuilder personResourceIds = new StringBuilder();
for(int j=0;j<period;j++){
PersonResourceEntity personResource = personResourceList.get(j);
if(j == 0){
startTime = personResource.getStartTime();
}
if(j == period - 1){
endTime = personResource.getEndTime();
}
personResource.setIsUsed("1");
personResourceService.updateById(personResource);
if(j!=period-1){
personResourceIds.append(personResource.getId()).append(",");
}else{
personResourceIds.append(personResource.getId());
}
}*//*
PersonResourceEntity personResource = personResourceList.get(0);
personResource.setIsUsed("1");
personResourceService.updateById(personResource);
workPlan.setPersonResourceIds(personResource.getId().toString());
workPlan.setStartTime(personResource.getStartTime());
workPlan.setEndTime(personResource.getEndTime());
workPlan.setMakeTeam(personResourceList.get(0).getTeamId());
prevProcessEnd = personResource.getEndTime();
}
}finally {
craftLock.unlock(); // 释放本地锁
}*/
}else{
prevProcessEnd = prevProcessEnd.plusMinutes(30);
@ -729,7 +613,6 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
workPlan.setScrapQty(0);
workPlanList.add(workPlan);
} else {
//未匹配到设备和人力资源,将工序状态改为6,标识为未排产
craft.setStatus(YieldOrderEnum.STATUS_PROCESS_ERROR.getCode());
@ -773,6 +656,14 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
workOrder.setReInStore("0");
workOrder.setPartCode(order.getPartCode());
workOrder.setDemandDate(order.getDemandDate());
//调度员是主工序加工班组的调度员
if(workPlanList.get(0).getMakeTeam() != null){
TeamSetEntity teamSet = teamSetService.getById(workPlanList.get(0).getMakeTeam());
if(teamSet != null){
workOrder.setDispatcher(teamSet.getDispatcher());
}
}
this.save(workOrder);
workPlanList.forEach(workPlanEntity -> {
@ -897,6 +788,18 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
}
}
}
//判断是否所有数据都没有开始结束时间,说明订单只有人力资源匹配
boolean isEmpty = list.stream().allMatch(item -> Objects.isNull(item.getStartTime())
&& Objects.isNull(item.getEndTime()));
if(isEmpty){
//上一道工序结束时间
LocalDateTime prevProcessEnd = LocalDateTime.now();
for(int i=0;i<list.size();i++){
list.get(i).setStartTime(prevProcessEnd);
list.get(i).setEndTime(prevProcessEnd.plusMinutes(list.get(i).getHourQuota().longValue()));
prevProcessEnd = list.get(i).getEndTime();
}
}
}
@ -1234,5 +1137,17 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
}
}
public void sameTrough(List<YieldOrderEntity> list){
//相同零件号判断键位、生产厂家、检验编号、生产标识
Map<String,List<YieldOrderEntity>> map = list.stream().collect(Collectors.groupingBy(YieldOrderEntity::getPartCode));
for(Map.Entry<String,List<YieldOrderEntity>> entry : map.entrySet()){
List<YieldOrderEntity> list1 = entry.getValue();
if(list1.size() > 1){
}
}
//不同零件号判断工艺
}
}

@ -25,12 +25,23 @@
*/
package org.springblade.scheduling.scheduling.service.impl;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.springblade.desk.order.pojo.enums.YieldOrderEnum;
import org.springblade.scheduling.scheduling.entity.TeamSetEntity;
import org.springblade.scheduling.scheduling.entity.WorkOrderEntity;
import org.springblade.scheduling.scheduling.entity.YieldOrderEntity;
import org.springblade.scheduling.scheduling.mapper.TeamSetMapper;
import org.springblade.scheduling.scheduling.mapper.WorkOrderMapper;
import org.springblade.scheduling.scheduling.service.IWorkOrderService;
import org.springblade.scheduling.scheduling.vo.YieldOrderVO;
import org.springblade.scheduling.scheduling.excel.YieldOrderExcel;
import org.springblade.scheduling.scheduling.mapper.YieldOrderMapper;
import org.springblade.scheduling.scheduling.service.IYieldOrderService;
import org.springblade.system.cache.UserCache;
import org.springblade.system.pojo.entity.User;
import org.springblade.system.pojo.entity.UserInfo;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
@ -44,13 +55,22 @@ import java.util.List;
* @since 2025-11-28
*/
@Service
@RequiredArgsConstructor
public class YieldOrderServiceImpl extends BaseServiceImpl<YieldOrderMapper, YieldOrderEntity> implements IYieldOrderService {
private final TeamSetMapper teamSetMapper;
@Override
public IPage<YieldOrderVO> selectYieldOrderPage(IPage<YieldOrderVO> page, YieldOrderVO yieldOrder) {
List<YieldOrderVO> list = baseMapper.selectYieldOrderPage(page, yieldOrder);
for(YieldOrderVO vo : list){
vo.setPriorityApsStr(YieldOrderEnum.getName(vo.getPriorityAps()));
List<TeamSetEntity> teamSetList = teamSetMapper.selectList(Wrappers.<TeamSetEntity>lambdaQuery().eq(TeamSetEntity::getWcId,vo.getWorkCenterId()));
if(CollectionUtils.isNotEmpty(teamSetList)){
User userInfo = UserCache.getUser(teamSetList.get(0).getDispatcher());
if(userInfo != null){
vo.setDispatcher(userInfo.getRealName());
}
}
}
return page.setRecords(list);
}

@ -49,4 +49,13 @@ public class YieldOrderVO extends YieldOrderEntity {
*/
private String priorityApsStr;
/**
* 调度员
*/
private String dispatcher;
private String startTime;
private String endTime;
}

Loading…
Cancel
Save