Merge branch 'master' into develop-QA

develop-QA
Tom Li 7 days ago
commit 8dc2687dbd
  1. 24
      blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/constant/DsCraftConstant.java
  2. 9
      blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/pojo/entity/DsCraftEntity.java
  3. 9
      blade-service/blade-desk/src/main/java/org/springblade/desk/dashboard/pojo/entity/DsProcessEntity.java
  4. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/order/service/IYieldOrderCraftService.java
  5. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/order/service/impl/YieldOrderCraftServiceImpl.java
  6. 106
      blade-service/blade-desk/src/main/java/org/springblade/desk/order/service/impl/YieldOrderServiceImpl.java
  7. 5
      blade-service/blade-desk/src/main/resources/application-dev.yml
  8. 49
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/controller/WorkOrderController.java
  9. 5
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/controller/WorkPlanController.java
  10. 8
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/dto/WorkOrderDto.java
  11. 48
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/entity/WorkPlanEntity.java
  12. 6
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/mapper/WorkOrderMapper.java
  13. 36
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/mapper/WorkOrderMapper.xml
  14. 6
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/IWorkOrderService.java
  15. 623
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/impl/WorkOrderServiceImpl.java
  16. 2
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/service/impl/WorkPlanServiceImpl.java
  17. 2
      blade-service/blade-scheduling/src/main/java/org/springblade/scheduling/scheduling/task/SchedulingJob.java
  18. 1
      blade-service/blade-scheduling/src/main/resources/application-dev.yml

@ -0,0 +1,24 @@
package org.springblade.desk.dashboard.constant;
/**
* 零件工艺信息 常量类
*
* @author lqk
*/
public interface DsCraftConstant {
// region 优先级
/**
* 本次使用
*/
Integer PRIORITY_THIS_USE = 1;
/**
* 标准
*/
Integer PRIORITY_FORMAL = 2;
/**
* 临时
*/
Integer PRIORITY_TEMPORARY = 3;
// endregion
}

@ -25,13 +25,12 @@
*/
package org.springblade.desk.dashboard.pojo.entity;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
/**
@ -78,7 +77,7 @@ public class DsCraftEntity extends BaseEntity {
* 优先级
*/
@Schema(description = "优先级")
private String prority;
private Integer prority;
/**
* 工艺级别
*/

@ -25,13 +25,12 @@
*/
package org.springblade.desk.dashboard.pojo.entity;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.TableName;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
/**
@ -83,7 +82,7 @@ public class DsProcessEntity extends BaseEntity {
* 工时定额
*/
@Schema(description = "工时定额")
private Long proHours;
private Double proHours;
/**
* 工序描述
*/

@ -30,6 +30,14 @@ public interface IYieldOrderCraftService extends BaseService<YieldOrderCraft> {
*/
List<YieldOrderCraft> listByYoId(Long yoId);
/**
* 根据生产订单ID删除工艺列表
*
* @param yoId
* @return
*/
int deleteByYoId(Long yoId);
/**
* 同步旧MES的待排产订单工艺数据
*/

@ -35,6 +35,14 @@ public class YieldOrderCraftServiceImpl extends BaseServiceImpl<YieldOrderCraftM
return craftList;
}
@Override
public int deleteByYoId(Long yoId) {
LambdaQueryWrapper<YieldOrderCraft> deleteWrapper = Wrappers.lambdaQuery(YieldOrderCraft.class)
.eq(YieldOrderCraft::getYoId, yoId)
.eq(YieldOrderCraft::getIsDeleted, CommonConstant.DELETE_FALSE);
return baseMapper.delete(deleteWrapper);
}
@Override
public void syncYieldOrderCraftData() {

@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springblade.common.constant.CommonConstant;
import org.springblade.common.constant.YieldOrderConst;
import org.springblade.common.exception.BusinessException;
import org.springblade.common.utils.StringPrefixUtils;
@ -17,11 +18,14 @@ import org.springblade.core.tool.utils.BeanUtil;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.core.tool.utils.StringPool;
import org.springblade.desk.dashboard.constant.DsCraftConstant;
import org.springblade.desk.dashboard.constant.DsPartConst;
import org.springblade.desk.dashboard.pojo.entity.DsCraftEntity;
import org.springblade.desk.dashboard.pojo.entity.DsPartEntity;
import org.springblade.desk.dashboard.pojo.entity.DsProcessEntity;
import org.springblade.desk.dashboard.service.IDsCraftService;
import org.springblade.desk.dashboard.service.IDsPartService;
import org.springblade.desk.dashboard.service.IDsProcessService;
import org.springblade.desk.order.entity.YieldOrder;
import org.springblade.desk.order.entity.YieldOrderCraft;
import org.springblade.desk.order.mapper.YieldOrderMapper;
@ -29,6 +33,7 @@ import org.springblade.desk.order.service.IYieldOrderCraftService;
import org.springblade.desk.order.service.IYieldOrderService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.text.MessageFormat;
import java.util.ArrayList;
@ -49,6 +54,7 @@ public class YieldOrderServiceImpl extends BaseServiceImpl<YieldOrderMapper, Yie
private final IDsPartService dsPartService;
private final IDsCraftService dsCraftService;
private final IDsProcessService dsProcessService;
@Value("${business.oldMes.url}")
private String oldMesUrl;
@ -172,13 +178,97 @@ public class YieldOrderServiceImpl extends BaseServiceImpl<YieldOrderMapper, Yie
return true;
}
@Transactional(rollbackFor = Exception.class)
@Override
public Boolean verifyYieldOrderCraft(YieldOrder yieldOrder) {
//TODO 匹配工艺
if (StringUtils.isBlank(yieldOrder.getReworkCode())) {
// pjYieldCraftService.renewYieldCraft(yieldOrder);
if (StringUtils.isNotBlank(yieldOrder.getReworkCode())) {
return Boolean.TRUE;
}
return null;
String roamNo = yieldOrder.getRoamNo();
String productIdent = yieldOrder.getProductIdent();
String partCode = yieldOrder.getPartCode();
DsCraftEntity craft = null;
//石墨模零件不考虑B号匹配因素
// if (YieldOrderConst.YIELD_TYPE_6.equals(yieldOrder.getYieldType())) {
// craft = dsCraftService.getCraft(partCode, null, prodIdent, DsCraft.RANK_TWO);
// } else {
// Short rank = judgeRank(yieldOrder);
// if (rank == null) {
// craft = dsCraftService.getCraft(partCode, roamNo, prodIdent, DsCraft.RANK_TWO);
// if (craft == null) {
// craft = dsCraftService.getCraft(partCode, roamNo, prodIdent, DsCraft.RANK_ONE);
// }
// if (craft == null) {
// craft = dsCraftService.getCraft(partCode, roamNo, prodIdent, DsCraft.RANK_THREE);
// }
// } else {
// craft = dsCraftService.getCraft(partCode, roamNo, prodIdent, rank);
// }
// }
if (ObjectUtil.isEmpty(craft)) {
String errMsg = StringUtils.isNotBlank(roamNo) ? "订单流转单号匹配失败,请联系工艺员!" : "未找到B号工艺,请核实订单是否存在B号!";
yieldOrder.setValidationResult(YieldOrderConst.VALIDATION_RESULT_LESS_CRAFT);
yieldOrder.setValidationTime(DateUtil.now());
yieldOrder.setValidationMomo(errMsg);
this.updateById(yieldOrder);
return Boolean.FALSE;
}
DsPartEntity part = dsPartService.getById(craft.getPartId());
//验证零件是否已经被删除
if (CommonConstant.DELETE_TRUE.equals(part.getIsDeleted())) {
yieldOrder.setValidationResult(YieldOrderConst.VALIDATION_RESULT_LESS_CRAFT);
yieldOrder.setValidationTime(DateUtil.now());
yieldOrder.setValidationMomo("零件信息已删除,工艺匹配失败,请联系工艺员!");
this.updateById(yieldOrder);
return Boolean.FALSE;
}
//石墨模不参与验证
if (!YieldOrderConst.YIELD_TYPE_2.equals(yieldOrder.getYieldType())
&& !YieldOrderConst.YIELD_TYPE_6.equals(yieldOrder.getYieldType())
&& ObjectUtil.isEmpty(part.getArea())) {
yieldOrder.setValidationResult(YieldOrderConst.VALIDATION_RESULT_LESS_CRAFT);
yieldOrder.setValidationTime(DateUtil.now());
yieldOrder.setValidationMomo("零件面积为空,工艺匹配失败,请联系工艺员!");
this.updateById(yieldOrder);
return Boolean.FALSE;
}
yieldOrder.setYpArea(part.getArea() == null ? 0D : part.getArea());
yieldOrder.setPlate(part.getPlate());
// yieldOrder.setCraftId(craft.getCraftId());
// yieldOrder.setPdmUrl(craft.getPdmUrl());
List<DsProcessEntity> dsProcessEntityList = dsProcessService.selectDsProcessByCraftId(craft.getId());
//删除之前的
yieldOrderCraftService.deleteByYoId(yieldOrder.getId());
List<YieldOrderCraft> yieldOrderCraftList = new ArrayList<>();
if (dsProcessEntityList != null && dsProcessEntityList.size() > 0) {
if (DsCraftConstant.PRIORITY_THIS_USE.equals(craft.getRank())) {
craft.setPrority(DsCraftConstant.PRIORITY_TEMPORARY);
}
for (DsProcessEntity processEntity : dsProcessEntityList) {
YieldOrderCraft yieldOrderCraft = new YieldOrderCraft();
yieldOrderCraft.setYoId(yieldOrder.getId());
yieldOrderCraft.setProcessNo(processEntity.getProcessNo());
yieldOrderCraft.setMakeMemo(processEntity.getRemarks());
yieldOrderCraft.setHourQuota(processEntity.getProHours());
// yieldOrderCraft.setPpsId(processEntity.getBsProcedureSet());
// yieldOrderCraft.setCraftNo(processEntity.getDsCraft().getCraftNo());
// yieldOrderCraft.setPid(processEntity.getPid());
// yieldOrderCraft.setCaId(processEntity.getBsCraftAbility());
yieldOrderCraftList.add(yieldOrderCraft);
}
yieldOrderCraftService.saveBatch(yieldOrderCraftList);
}
return Boolean.TRUE;
}
@Override
@ -298,17 +388,27 @@ public class YieldOrderServiceImpl extends BaseServiceImpl<YieldOrderMapper, Yie
craft.setYoId(yieldOrder.getId());
craft.setCraftNo(craftJson.getString("craftNo"));
craft.setProcessNo(craftJson.getString("processNo"));
if (ObjectUtil.isEmpty(craft.getProcessNo())) {
craft.setProcessNo(StringPool.EMPTY);
}
craft.setStartTime(craftJson.getDate("startTime"));
craft.setEndTime(craftJson.getDate("endTime"));
craft.setHourQuota(craftJson.getDouble("hourQuota"));
if (ObjectUtil.isEmpty(craft.getHourQuota())) {
craft.setHourQuota(0D);
}
craft.setMakeMemo(craftJson.getString("makeMemo"));
craft.setPid(craftJson.getLong("pid"));
craft.setRpId(craftJson.getLong("rpId"));
craft.setPpsId(craftJson.getLong("ppsId"));
if (ObjectUtil.isEmpty(craft.getPpsId())) {
craft.setPpsId(0L);
}
craft.setMakeTeam(craftJson.getLong("makeTeam"));
craft.setWorkCenterId(craftJson.getLong("wcId"));
craft.setOcId(craftJson.getLong("ocId"));
craft.setCaId(craftJson.getLong("caId"));
craftList.add(craft);
}
yieldOrderCraftService.saveBatch(craftList);

@ -11,7 +11,8 @@ spring:
business:
oldMes:
jobEnable: false
jobEnable: true
url: 192.168.169.172:9000
syncOrderList: /zhgd-rb/aiWebapi/syncApsOrderData
syncOrderList: /zhgd-rb/aiWebapi/syncApsOrderData/化学镀镍
# syncOrderList: /zhgd-rb/aiWebapi/syncApsOrderData/all
pushSyncResult: /zhgd-rb/aiWebapi/syncApsOrderDataResult

@ -43,6 +43,7 @@ import org.springblade.core.secure.annotation.IsAdmin;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.ObjectUtil;
import org.springblade.scheduling.scheduling.dto.WorkOrderDto;
import org.springblade.scheduling.scheduling.entity.WorkOrderEntity;
import org.springblade.scheduling.scheduling.vo.WorkOrderVO;
@ -51,6 +52,7 @@ import org.springblade.scheduling.scheduling.service.IWorkOrderService;
import org.springblade.scheduling.scheduling.wrapper.WorkOrderWrapper;
import org.springframework.web.bind.annotation.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
@ -180,4 +182,51 @@ public class WorkOrderController extends BladeController {
return R.data(workOrderService.schedulingBoard(workOrderDto));
}
/**
* 车间订单表 排产
*/
@PostMapping("/schedulingCount")
@ApiOperationSupport(order = 6)
@Operation(summary = "排产统计", description = "传入WorkOrderDto")
public R<List<WorkOrderDto>> schedulingCount(@RequestBody WorkOrderDto workOrderDto) {
return R.data(workOrderService.schedulingCount(workOrderDto));
}
/**
* 车间订单表 排产
*/
@GetMapping("/sendToOldMesTest/{workOrderId}")
@Operation(summary = "排产统计", description = "传入WorkOrderDto")
public R sendToOldMesTest(@PathVariable Long workOrderId) {
List<WorkOrderEntity> workOrderEntityList = new ArrayList<>();
WorkOrderEntity workOrder = workOrderService.getById(workOrderId);
if (ObjectUtil.isEmpty(workOrder)) {
return R.fail("未找到工单");
}
workOrderEntityList.add(workOrder);
workOrderService.sendWorkOrderToOldMes(workOrderEntityList);
return R.success();
}
/**
* 车间订单表 排产
*/
@GetMapping("/selectTeam")
@Operation(summary = "获取班组列表")
public R<List<String>> selectTeam() {
return R.data(workOrderService.selectTeam());
}
/**
* 车间订单表 排产
*/
@GetMapping("/selectEquip")
@Operation(summary = "获取设备列表")
public R<List<String>> selectEquip() {
return R.data(workOrderService.selectEquip());
}
}

@ -25,6 +25,7 @@
*/
package org.springblade.scheduling.scheduling.controller;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
@ -162,8 +163,8 @@ public class WorkPlanController extends BladeController {
*/
@PostMapping("/updateWorkPlan")
@Operation(summary = "更新作业计划", description = "")
public R updateWorkPlan(@RequestBody WorkPlanEntity entity) {
workPlanService.updateWorkPlan(entity.getId(), entity.getFactStartTime(), entity.getFactEndTime());
public R updateWorkPlan(@RequestBody JSONObject entity) {
workPlanService.updateWorkPlan(entity.getLong("id"), entity.getDate("factStartTime"), entity.getDate("factEndTime"));
return R.success();
}
}

@ -2,6 +2,8 @@ package org.springblade.scheduling.scheduling.dto;
import lombok.Data;
import java.math.BigDecimal;
/**
* TODO功能描述
*
@ -32,4 +34,10 @@ public class WorkOrderDto {
private String orderStatus;
private String planStatus;
private String makeQty;
private String workCenterName;
private Integer totalCount;
private Integer schedulingCount;
private String schedulingRate;
}

@ -25,16 +25,16 @@
*/
package org.springblade.scheduling.scheduling.entity;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.TableName;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springblade.core.mp.base.BaseEntity;
import org.springblade.core.tenant.mp.TenantEntity;
import java.io.Serial;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
/**
* 车间作业计划 实体类
@ -47,6 +47,28 @@ import java.io.Serial;
@Schema(description = "MesWorkPlan对象")
@EqualsAndHashCode(callSuper = true)
public class WorkPlanEntity extends BaseEntity {
/**
* TODO 工序状态要调整到常量类中
* 工序状态未开始
*/
public static Integer STATUS_NO_START = 1;
/**
* 工序状态加工中
*/
public static Integer STATUS_START = 2;
/**
* 工序状态报工完成
*/
public static Integer STATUS_WORK_OK = 3;
/**
* 工序状态已完成
*/
public static Integer STATUS_COMPLETE = 5;
/**
* 工序状态已返工
*/
public static Integer STATUS_VOIDED = 6;
@Serial
private static final long serialVersionUID = 1L;
@ -142,27 +164,27 @@ public class WorkPlanEntity extends BaseEntity {
@Schema(description = "实际结束")
private Date factEndTime;
/**
*
*
*/
@Schema(description = "")
private Short bindStatus;
/**
*
*
*/
@Schema(description = "")
private Integer workQty;
/**
*
*
*/
@Schema(description = "")
private Long receiveMan;
/**
*
*
*/
@Schema(description = "")
private BigDecimal hours;
/**
*
*
*/
@Schema(description = "")
private Long caId;
@ -172,7 +194,7 @@ public class WorkPlanEntity extends BaseEntity {
@Schema(description = "打印标记类型:1、生产过程")
private Short printType;
/**
*
*
*/
@Schema(description = "")
private Long subsidiaryTeam;
@ -202,7 +224,7 @@ public class WorkPlanEntity extends BaseEntity {
@Schema(description = "工艺文件编号/版本号")
private String papers;
/**
*
*
*/
@Schema(description = "")
private String referenceFile;

@ -67,4 +67,10 @@ public interface WorkOrderMapper extends BaseMapper<WorkOrderEntity> {
String getMaxByCodePattern(@Param("woCode") String woCode);
List<WorkOrderDto> selectSchedulingCount(WorkOrderDto workOrderDto);
List<String> selectTeam();
List<String> selectEquip();
}

@ -113,8 +113,9 @@
LEFT JOIN MES_WORK_PLAN e on a.wp_id = e.id
LEFT JOIN BS_PROCESS_SET f on e.pps_id = f.id
<where>
c.ts_name is not null and b.EQUIP_CODE is not null and a.is_deleted = 0
<if test="startTime !=null and startTime != ''">
and (to_char(b.start_time,'YYYY-MM-DD') = #{startTime} or b.end_time <![CDATA[ > ]]> to_date(CONCAT(#{startTime},' 00:00:00'),'YYYY-MM-DD HH24:MI:SS'))
and (to_char(b.start_time,'YYYY-MM-DD') = #{startTime} or (b.start_time <![CDATA[ < ]]> to_date(CONCAT(#{startTime},' 00:00:00'),'YYYY-MM-DD HH24:MI:SS') and b.end_time <![CDATA[ > ]]> to_date(CONCAT(#{startTime},' 23:59:59'),'YYYY-MM-DD HH24:MI:SS')))
</if>
<if test="woCode !=null and woCode != ''">
and a.wo_code = #{woCode}
@ -138,4 +139,37 @@
wo_code LIKE concat(#{woCode},'%')
</select>
<select id="selectSchedulingCount" resultType="org.springblade.scheduling.scheduling.dto.WorkOrderDto">
SELECT
b.WC_NAME AS "workCenterName",
a.WORK_CENTER_ID AS "workCenterId",
-- 统计待排产的数量
COUNT(CASE WHEN a.STATUS >= 3 THEN a.WORK_CENTER_ID END) AS "totalCount",
-- 统计已排产的数量
COUNT(CASE WHEN a.STATUS not in (3,6) THEN a.WORK_CENTER_ID END) AS "schedulingCount"
FROM MES_YIELD_ORDER a
LEFT JOIN BS_WORK_CENTER b ON a.WORK_CENTER_ID = b.ID
<where>
<if test="startTime !=null and startTime != ''">
and a.receive_time <![CDATA[ >= ]]> to_date(#{startTime},'YYYY-MM-DD HH24:MI:SS')
</if>
<if test="endTime !=null and endTime != ''">
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;
</select>
<select id="selectTeam" resultType="java.lang.String">
SELECT
ts_name as "name"
FROM BS_TEAM_SET
</select>
<select id="selectEquip" resultType="java.lang.String">
SELECT
device_name as "name"
FROM MES_EQUIPMENT
</select>
</mapper>

@ -78,4 +78,10 @@ public interface IWorkOrderService extends BaseService<WorkOrderEntity> {
* @param workOrderEntityList
*/
void sendWorkOrderToOldMes(List<WorkOrderEntity> workOrderEntityList);
List<WorkOrderDto> schedulingCount(WorkOrderDto workOrder);
List<String> selectTeam();
List<String> selectEquip();
}

@ -30,8 +30,10 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springblade.common.constant.YieldOrderConst;
import org.springblade.core.mp.base.BaseEntity;
@ -67,6 +69,7 @@ import java.util.stream.Collectors;
*/
@Service
@RequiredArgsConstructor
@Slf4j
public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkOrderEntity> implements IWorkOrderService {
private final IYieldOrderService yieldOrderService;
@ -110,11 +113,12 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
@Override
public void scheduling() {
//查询待排产订单,状态是3
List<YieldOrderEntity> list = yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().eq(BaseEntity::getStatus, YieldOrderConst.STATUS_APS));
List<YieldOrderEntity> list = yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().eq(BaseEntity::getStatus, YieldOrderConst.STATUS_APS).isNotNull(YieldOrderEntity::getWorkCenterId).isNotNull(YieldOrderEntity::getReleaseDate));
log.info("待排产订单数量为:" + list.size());
if (CollectionUtils.isNotEmpty(list)) {
//校验已排产订单
checkSchedulingOrder(list);
list = yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().eq(BaseEntity::getStatus, YieldOrderConst.STATUS_APS));
list = yieldOrderService.list(Wrappers.<YieldOrderEntity>lambdaQuery().eq(BaseEntity::getStatus, YieldOrderConst.STATUS_APS).isNotNull(YieldOrderEntity::getWorkCenterId).isNotNull(YieldOrderEntity::getReleaseDate));
//初始化人员能力
List<PersonAbilityEntity> personAbilityEntityList = personAbilityService.list(Wrappers.<PersonAbilityEntity>lambdaQuery().isNotNull(PersonAbilityEntity::getWorkCenterId).isNotNull(PersonAbilityEntity::getProcessId).isNotNull(PersonAbilityEntity::getCraftId));
Map<String, PersonAbilityEntity> personAbilityMap = new HashMap<>();
@ -140,7 +144,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
list1 -> {
// 排序逻辑:优先级升序 → CR值降序 → 数量降序 → 时间升序
list1.sort(Comparator.comparingInt(YieldOrderEntity::getPriorityAps).reversed()
//.thenComparing((e1, e2) -> e2.getCrValue().compareTo(e1.getCrValue()))
.thenComparing((e1, e2) -> e2.getCrValue().compareTo(e1.getCrValue()))
.thenComparingInt(YieldOrderEntity::getYpQty).reversed()
.thenComparing(YieldOrderEntity::getReleaseDate));
return list1;
@ -404,7 +408,32 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
}
}
void calculateCr(List<YieldOrderEntity> list) {
@Override
public List<WorkOrderDto> schedulingCount(WorkOrderDto workOrder) {
if(StringUtils.isNotEmpty(workOrder.getStartTime())){
workOrder.setStartTime(workOrder.getStartTime().concat(" 00:00:00"));
}
if(StringUtils.isNotEmpty(workOrder.getEndTime())){
workOrder.setEndTime(workOrder.getEndTime().concat(" 23:59:59"));
}
List<WorkOrderDto> list = baseMapper.selectSchedulingCount(workOrder);
list.forEach(item -> {
item.setSchedulingRate(String.format("%.2f", (double)item.getSchedulingCount()/item.getTotalCount()*100));
});
return list;
}
@Override
public List<String> selectTeam() {
return baseMapper.selectTeam();
}
@Override
public List<String> selectEquip() {
return baseMapper.selectEquip();
}
void calculateCr(List<YieldOrderEntity> list) {
//查询订单下的工序,计算cr值
for (YieldOrderEntity entity : list) {
List<YieldOrderCraftEntity> craftList = yieldOrderCraftService.list(Wrappers.<YieldOrderCraftEntity>lambdaQuery().eq(YieldOrderCraftEntity::getYoId, entity.getId()));
@ -439,290 +468,322 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
public void allocateResources(List<YieldOrderEntity> list,Map<String, PersonAbilityEntity> personAbilityMap,Map<Long, String> mainProducerMap,Map<String,List<WorkPlanEntity>> planMap) {
List<WorkOrderEntity> workOrderList = new ArrayList<>();
for (YieldOrderEntity order : list) {
//是否可以排产
Boolean isSchecuding = true;
List<WorkPlanEntity> workPlanList = new ArrayList<>();
//查询所有工序
List<YieldOrderCraftEntity> craftList = yieldOrderCraftService.list(Wrappers.<YieldOrderCraftEntity>lambdaQuery().eq(YieldOrderCraftEntity::getYoId, order.getId()).ne(YieldOrderCraftEntity::getCaId,27).orderByAsc(YieldOrderCraftEntity::getProcessNo));
List<Long> workCenterList = craftList.stream().filter(item -> item.getWorkCenterId() != null).map(YieldOrderCraftEntity::getWorkCenterId).collect(Collectors.toList());
if(workCenterList.size() != craftList.size()){
order.setErrorInfo("工序信息不完整,含有未匹配作业中心的工序");
order.setStatus(6);
yieldOrderService.updateById(order);
continue;
}
try {
//是否可以排产
Boolean isSchecuding = true;
List<WorkPlanEntity> workPlanList = new ArrayList<>();
//查询所有工序
List<YieldOrderCraftEntity> craftList = yieldOrderCraftService.list(Wrappers.<YieldOrderCraftEntity>lambdaQuery().eq(YieldOrderCraftEntity::getYoId, order.getId()).ne(YieldOrderCraftEntity::getCaId,27).orderByAsc(YieldOrderCraftEntity::getProcessNo));
List<Long> workCenterList = craftList.stream().filter(item -> item.getWorkCenterId() != null).map(YieldOrderCraftEntity::getWorkCenterId).collect(Collectors.toList());
if(workCenterList.size() != craftList.size()){
order.setErrorInfo("工序信息不完整,含有未匹配作业中心的工序");
order.setStatus(6);
yieldOrderService.updateById(order);
continue;
}
//上一道工序结束时间
LocalDateTime prevProcessEnd = LocalDateTime.now();
//判断是否有公共工序已经处理了,如果有则重新定义workPlanList,获取公共工序的最后结束时间和当前时间做比较,取大的作为上一道工序结束时间
if(planMap.containsKey(order.getYoCode())){
workPlanList = planMap.get(order.getYoCode());
prevProcessEnd = prevProcessEnd.compareTo(workPlanList.get(workPlanList.size()-1).getEndTime()) > 0 ? prevProcessEnd : workPlanList.get(workPlanList.size()-1).getEndTime();
}
for (int i = 0; i < craftList.size(); i++) {
YieldOrderCraftEntity craft = craftList.get(i);
if ("设备".equals(mainProducerMap.get(craft.getPpsId()))) {
//根据作业中心查询所有设备
List<EquipAbilityEntity> equipAbilityList = equipAbilityService.list(Wrappers.<EquipAbilityEntity>lambdaQuery().in(EquipAbilityEntity::getWorkCenterId, craft.getWorkCenterId()));
if(CollectionUtils.isEmpty(equipAbilityList)){
order.setErrorInfo("设备未匹配到对应的设备能力");
order.setStatus(6);
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}
Map<Integer,List<EquipAbilityEntity>> equipAbilityMap = equipAbilityList.stream().collect(Collectors.groupingBy(EquipAbilityEntity::getEquipOrder));
//匹配设备资源
//获取下一个整数点
LocalDateTime dateTime = getNextIntegerTime(prevProcessEnd);
for(Map.Entry<Integer,List<EquipAbilityEntity>> entry : equipAbilityMap.entrySet()){
//根据时间点获取所有设备资源
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)){
//上一道工序结束时间
LocalDateTime prevProcessEnd = LocalDateTime.now();
//判断是否有公共工序已经处理了,如果有则重新定义workPlanList,获取公共工序的最后结束时间和当前时间做比较,取大的作为上一道工序结束时间
if(planMap.containsKey(order.getYoCode())){
workPlanList = planMap.get(order.getYoCode());
prevProcessEnd = prevProcessEnd.compareTo(workPlanList.get(workPlanList.size()-1).getEndTime()) > 0 ? prevProcessEnd : workPlanList.get(workPlanList.size()-1).getEndTime();
}
for (int i = 0; i < craftList.size(); i++) {
YieldOrderCraftEntity craft = craftList.get(i);
if ("设备".equals(mainProducerMap.get(craft.getPpsId()))) {
//根据作业中心查询所有设备
List<EquipAbilityEntity> equipAbilityList = equipAbilityService.list(Wrappers.<EquipAbilityEntity>lambdaQuery().in(EquipAbilityEntity::getWorkCenterId, craft.getWorkCenterId()));
if(CollectionUtils.isEmpty(equipAbilityList)){
order.setErrorInfo("设备未匹配到对应的设备能力");
order.setStatus(6);
order.setErrorInfo("工序:"+craft+"未匹配到对应的设备资源");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}
//设备资源按照时间段分组并按时间排序,然后再每个组内按照剩余产能倒序排序
Map<LocalDateTime, List<EquipResourceEntity>> equipResourceMap = equipResourceList.stream()
.collect(Collectors.groupingBy(
EquipResourceEntity::getStartTime, // 分组字段:startTime
// 用TreeMap接收,指定startTime降序(分组的排序)
TreeMap::new,
// 组内收集器:按restCapacity降序排序
Collectors.collectingAndThen(
Collectors.toList(),
list1 -> list1.stream()
.sorted(Comparator.comparing(
EquipResourceEntity::getRestCapacity,
// restCapacity 降序比较器(BigDecimal专用)
Comparator.reverseOrder()
))
.collect(Collectors.toList())
)
));
//计算生产所需产能,需将m2换算成dm2
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(order.getYpQty()));
//需要判断设备额定生产能力是否满足订单总产能,如果不满足,则需要把总产能进行拆分
List<BigDecimal> capacityList = capacitySplit(equipResourceMap,sumCapacity);
for(BigDecimal capacity : capacityList){
for(Map.Entry<LocalDateTime, List<EquipResourceEntity>> entry1 : equipResourceMap.entrySet()){
Boolean isOccupied = false;
List<EquipResourceEntity> resourceList = entry1.getValue();
for (EquipResourceEntity equipResource : resourceList) {
//如果产能最大的设备都不满足,后面的设备就不需要判断了
if (equipResource.getRestCapacity().compareTo(capacity) < 0) {
break;
} else {
//生成车间订单
WorkPlanEntity workPlan = new WorkPlanEntity();
workPlan.setStartTime(equipResource.getStartTime());
if(entry.getKey() == 1){
workPlan.setEndTime(equipResource.getStartTime().plusMinutes(equipResource.getStandardTime().longValue()));
}else{
workPlan.setEndTime(equipResource.getEndTime());
Map<Integer,List<EquipAbilityEntity>> equipAbilityMap = equipAbilityList.stream().collect(Collectors.groupingBy(EquipAbilityEntity::getEquipOrder));
//匹配设备资源
//获取下一个整数点
LocalDateTime dateTime = getNextIntegerTime(prevProcessEnd);
for(Map.Entry<Integer,List<EquipAbilityEntity>> entry : equipAbilityMap.entrySet()){
//根据时间点获取所有设备资源
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(6);
order.setErrorInfo("工序:"+craft.getPpsId()+"未匹配到对应的设备资源");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}
//设备资源按照时间段分组并按时间排序,然后再每个组内按照剩余产能倒序排序
Map<LocalDateTime, List<EquipResourceEntity>> equipResourceMap = equipResourceList.stream()
.collect(Collectors.groupingBy(
EquipResourceEntity::getStartTime, // 分组字段:startTime
// 用TreeMap接收,指定startTime降序(分组的排序)
TreeMap::new,
// 组内收集器:按restCapacity降序排序
Collectors.collectingAndThen(
Collectors.toList(),
list1 -> list1.stream()
.sorted(Comparator.comparing(
EquipResourceEntity::getRestCapacity,
// restCapacity 降序比较器(BigDecimal专用)
Comparator.reverseOrder()
))
.collect(Collectors.toList())
)
));
//计算生产所需产能,需将m2换算成dm2
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(order.getYpQty()));
//需要判断设备额定生产能力是否满足订单总产能,如果不满足,则需要把总产能进行拆分
List<BigDecimal> capacityList = capacitySplit(equipResourceMap,sumCapacity);
for(BigDecimal capacity : capacityList){
for(Map.Entry<LocalDateTime, List<EquipResourceEntity>> entry1 : equipResourceMap.entrySet()){
Boolean isOccupied = false;
List<EquipResourceEntity> resourceList = entry1.getValue();
for (EquipResourceEntity equipResource : resourceList) {
//如果产能最大的设备都不满足,后面的设备就不需要判断了
if (equipResource.getRestCapacity().compareTo(capacity) < 0) {
break;
} else {
//生成车间订单
WorkPlanEntity workPlan = new WorkPlanEntity();
workPlan.setStartTime(equipResource.getStartTime());
if(entry.getKey() == 1){
workPlan.setEndTime(equipResource.getStartTime().plusMinutes(equipResource.getStandardTime().longValue()));
}else{
workPlan.setEndTime(equipResource.getEndTime());
}
workPlan.setWorkQty(order.getYpQty());
workPlan.setCaId(craft.getCaId());
workPlan.setPpsId(craft.getPpsId());
workPlan.setMakeTeam(equipResource.getTeamId());
workPlan.setWorkCenterId(craft.getWorkCenterId());
workPlan.setOrders(craft.getProcessNo());
workPlan.setWoId(order.getId());
workPlan.setOem("0");
workPlan.setTestQty(0);
workPlan.setQualifiedQty(0);
workPlan.setUnqualifiedQty(0);
workPlan.setScrapQty(0);
workPlan.setHourQuota(BigDecimal.valueOf(ChronoUnit.MINUTES.between(workPlan.getStartTime(), workPlan.getEndTime())));
workPlan.setEquipCode(equipResource.getEquipCode());
workPlan.setEquipName(equipResource.getEquipName());
workPlan.setEquipResourceId(equipResource.getId());
workPlanList.add(workPlan);
//更新剩余产能
equipResource.setRestCapacity(equipResource.getRestCapacity().subtract(capacity));
equipResource.setIsUsed("1");
//如果剩余产能占总产能不足20%,则修改为已占用
// if(equipResource.getRestCapacity().divide(equipResource.getTotalCapacity(),2,RoundingMode.HALF_UP).compareTo(BigDecimal.valueOf(0.2)) < 0){
//
// }
//同一个设备可能有多个工艺能力,同一时间只能做一个工艺能力的零件,所以需要把当前设备所有工艺能力的剩余产能都更新调
LambdaUpdateWrapper<EquipResourceEntity> equipWrapper = new LambdaUpdateWrapper<>();
equipWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
equipWrapper.eq(EquipResourceEntity::getDateTime,equipResource.getDateTime());
equipWrapper.eq(EquipResourceEntity::getPeriod,equipResource.getPeriod());
equipWrapper.eq(EquipResourceEntity::getStartTime,equipResource.getStartTime());
equipWrapper.eq(EquipResourceEntity::getEndTime,equipResource.getEndTime());
equipResourceService.update(equipResource,equipWrapper);
//该设备后续所有开始时间小于当前结束时间的时间段都变为不可用
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper();
updateWrapper.lt(EquipResourceEntity::getStartTime, equipResource.getEndTime());
updateWrapper.gt(EquipResourceEntity::getStartTime, equipResource.getStartTime());
updateWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
EquipResourceEntity equipResource1 = new EquipResourceEntity();
equipResource1.setIsUsed("1");
equipResourceService.update(equipResource1, updateWrapper);
//当前工序的结束时间作为下一工序的开始时间
prevProcessEnd = workPlan.getEndTime();
dateTime = workPlan.getEndTime();
isOccupied = true;
break;
}
workPlan.setWorkQty(order.getYpQty());
workPlan.setCaId(craft.getCaId());
workPlan.setPpsId(craft.getPpsId());
workPlan.setMakeTeam(equipResource.getTeamId());
workPlan.setWorkCenterId(craft.getWorkCenterId());
workPlan.setOrders(craft.getProcessNo());
workPlan.setWoId(order.getId());
workPlan.setOem("0");
workPlan.setTestQty(0);
workPlan.setQualifiedQty(0);
workPlan.setUnqualifiedQty(0);
workPlan.setScrapQty(0);
workPlan.setHourQuota(BigDecimal.valueOf(ChronoUnit.MINUTES.between(workPlan.getStartTime(), workPlan.getEndTime())));
workPlan.setEquipCode(equipResource.getEquipCode());
workPlan.setEquipName(equipResource.getEquipName());
workPlan.setEquipResourceId(equipResource.getId());
workPlanList.add(workPlan);
//更新剩余产能
equipResource.setRestCapacity(equipResource.getRestCapacity().subtract(capacity));
equipResource.setIsUsed("1");
//如果剩余产能占总产能不足20%,则修改为已占用
// if(equipResource.getRestCapacity().divide(equipResource.getTotalCapacity(),2,RoundingMode.HALF_UP).compareTo(BigDecimal.valueOf(0.2)) < 0){
//
// }
//同一个设备可能有多个工艺能力,同一时间只能做一个工艺能力的零件,所以需要把当前设备所有工艺能力的剩余产能都更新调
LambdaUpdateWrapper<EquipResourceEntity> equipWrapper = new LambdaUpdateWrapper<>();
equipWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
equipResourceService.update(equipResource,equipWrapper);
//该设备后续所有开始时间小于当前结束时间的时间段都变为不可用
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper();
updateWrapper.lt(EquipResourceEntity::getStartTime, equipResource.getEndTime());
updateWrapper.gt(EquipResourceEntity::getStartTime, equipResource.getStartTime());
updateWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
EquipResourceEntity equipResource1 = new EquipResourceEntity();
equipResource1.setIsUsed("1");
equipResourceService.update(equipResource1, updateWrapper);
//当前工序的结束时间作为下一工序的开始时间
prevProcessEnd = workPlan.getEndTime();
dateTime = workPlan.getEndTime();
isOccupied = true;
}
if (isOccupied) {
break;
}
}
if (isOccupied) {
break;
}
}
}
}
if(!isSchecuding){
break;
}
if(!isSchecuding){
break;
}
} else if ("人".equals(mainProducerMap.get(craft.getPpsId()))) {
//匹配人资源
/* String personAbility = craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId();
if (personAbilityMap.containsKey(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId())) {
} else if ("人".equals(mainProducerMap.get(craft.getPpsId()))) {
//匹配人资源
/* String personAbility = craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId();
if (personAbilityMap.containsKey(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId())) {
} else {
order.setStatus(6);
order.setErrorInfo("工序:"+personAbility+"未匹配到对应的人员能力");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}*/
WorkPlanEntity workPlan = new WorkPlanEntity();
BigDecimal totalTime = new BigDecimal(0);
PersonAbilityEntity ability = personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId());
//由于客户提供的数据不全,先判断有没有对应的能力,如果没有先不计算时间
if(ability != null){
totalTime = totalTime.add(BigDecimal.valueOf(order.getYpQty()).multiply(personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()).getStandardTime()).add(personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()).getPrepareTime()));
}
if(totalTime.compareTo(new BigDecimal(0)) > 0){
//通过加锁的方式保证每次查询到的人力资源都是最新的
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()).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;
}
} else {
order.setStatus(6);
order.setErrorInfo("工序:"+personAbility+"未匹配到对应的人员能力");
yieldOrderService.updateById(order);
isSchecuding = false;
break;
}*/
WorkPlanEntity workPlan = new WorkPlanEntity();
BigDecimal totalTime = new BigDecimal(0);
PersonAbilityEntity ability = personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId());
//由于客户提供的数据不全,先判断有没有对应的能力,如果没有先不计算时间
List<Long> ppsIds = Arrays.asList(Long.valueOf(10),Long.valueOf(21));
//镀后检验和镀后接收先按半小时计算
if(ability != null){
if(ppsIds.contains(craft.getPpsId())){
totalTime = BigDecimal.valueOf(30);
workPlan.setStartTime(prevProcessEnd);
workPlan.setEndTime(prevProcessEnd.plusMinutes(30));
if(craft.getPpsId() == 10){
workPlan.setMakeTeam(Long.valueOf(64));
}
if(isUsedIndex != -1){
personResourceList = personResourceList.subList(isUsedIndex + 1, personResourceList.size());
if(craft.getPpsId() == 21){
workPlan.setMakeTeam(Long.valueOf(65));
}
//如果size=0,说明最近3天的资源都排满了,就不需要排了
if(personResourceList.size() == 0){
}else{
totalTime = totalTime.add(BigDecimal.valueOf(order.getYpQty()).multiply(personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()).getStandardTime()).add(personAbilityMap.get(craft.getWorkCenterId() + "-" + craft.getPpsId() + "-" + craft.getCaId()).getPrepareTime()));
}
break;
}
//计算加工时间占几个人力片段
int period = totalTime.divide(BigDecimal.valueOf(30),0, RoundingMode.CEILING).intValue();
//占用时间段
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();
//通过加锁的方式保证每次查询到的人力资源都是最新的
/*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(j == period - 1){
endTime = personResource.getEndTime();
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);
if(j!=period-1){
personResourceIds.append(personResource.getId()).append(",");
}else{
personResourceIds.append(personResource.getId());
}
workPlan.setPersonResourceIds(personResource.getId().toString());
workPlan.setStartTime(personResource.getStartTime());
workPlan.setEndTime(personResource.getEndTime());
workPlan.setMakeTeam(personResourceList.get(0).getTeamId());
prevProcessEnd = personResource.getEndTime();
}
workPlan.setPersonResourceIds(personResourceIds.toString());
workPlan.setStartTime(startTime);
workPlan.setEndTime(endTime);
workPlan.setMakeTeam(personResourceList.get(0).getTeamId());
prevProcessEnd = endTime;
}
}finally {
craftLock.unlock(); // 释放本地锁
}finally {
craftLock.unlock(); // 释放本地锁
}*/
}
}
workPlan.setWoId(order.getId());
workPlan.setCaId(craft.getCaId());
workPlan.setPpsId(craft.getPpsId());
workPlan.setWorkQty(order.getYpQty());
workPlan.setHourQuota(totalTime);
workPlan.setWorkCenterId(craft.getWorkCenterId());
workPlan.setOrders(craft.getProcessNo());
workPlan.setOem("0");
workPlan.setTestQty(0);
workPlan.setQualifiedQty(0);
workPlan.setUnqualifiedQty(0);
workPlan.setScrapQty(0);
workPlanList.add(workPlan);
}else{
//未匹配到设备和人力资源,将工序状态改为6,标识为未排产
craft.setStatus(6);
yieldOrderCraftService.updateById(craft);
workPlan.setWoId(order.getId());
workPlan.setCaId(craft.getCaId());
workPlan.setPpsId(craft.getPpsId());
workPlan.setWorkQty(order.getYpQty());
workPlan.setHourQuota(totalTime);
workPlan.setWorkCenterId(craft.getWorkCenterId());
workPlan.setOrders(craft.getProcessNo());
workPlan.setOem("0");
workPlan.setTestQty(0);
workPlan.setQualifiedQty(0);
workPlan.setUnqualifiedQty(0);
workPlan.setScrapQty(0);
workPlanList.add(workPlan);
}else{
//未匹配到设备和人力资源,将工序状态改为6,标识为未排产
craft.setStatus(6);
yieldOrderCraftService.updateById(craft);
}
if(!isSchecuding){
break;
}
}
if(!isSchecuding){
break;
continue;
}
}
if(!isSchecuding){
continue;
}
if (CollectionUtils.isNotEmpty(workPlanList)) {
//为人员工序赋值开始结束时间
WorkPlanTimeCalculator(workPlanList);
//新增车间订单和车间计划
WorkOrderEntity workOrder = new WorkOrderEntity();
workOrder.setWoCode(this.nextCode(order.getYpCode()));
workOrder.setCardNo(order.getCardNo());
workOrder.setBatchNo(order.getBatchNo());
workOrder.setYoId(order.getId());
workOrder.setMakeQty(order.getYpQty());
workOrder.setPlanStartDate(workPlanList.get(0).getStartTime().truncatedTo(ChronoUnit.DAYS).toString().substring(0,10));
workOrder.setPlanEndDate(workPlanList.get(workPlanList.size()-1).getEndTime().truncatedTo(ChronoUnit.DAYS).toString().substring(0,10));
workOrder.setInventoryQty(0);
workOrder.setRunStatus(2);
workOrder.setPickingStatus(0);
workOrder.setOem("0");
workOrder.setPriority(order.getPriorityAps());
workOrder.setApprovalStatus(1);
workOrder.setScrapQty(0);
workOrder.setOemOut("0");
workOrder.setOemType(-1);
workOrder.setPrintFlag("0");
workOrder.setPushFlag("0");
workOrder.setQuotaExceptional("0");
workOrder.setReInStore("0");
workOrder.setPartCode(order.getPartCode());
this.save(workOrder);
workPlanList.forEach(workPlanEntity -> {
workPlanEntity.setWoId(workOrder.getId());
workPlanService.save(workPlanEntity);
});
workOrder.setWpId(workPlanList.get(0).getId());
this.updateById(workOrder);
//更新订单状态为已排产
order.setStatus(4);
yieldOrderService.updateById(order);
workOrderList.add(workOrder);
if (CollectionUtils.isNotEmpty(workPlanList)) {
//为人员工序赋值开始结束时间
WorkPlanTimeCalculator(workPlanList);
//新增车间订单和车间计划
WorkOrderEntity workOrder = new WorkOrderEntity();
workOrder.setWoCode(this.nextCode(order.getYpCode()));
workOrder.setCardNo(order.getCardNo());
workOrder.setBatchNo(order.getBatchNo());
workOrder.setYoId(order.getId());
workOrder.setMakeQty(order.getYpQty());
workOrder.setPlanStartDate(workPlanList.get(0).getStartTime() == null ? null :workPlanList.get(0).getStartTime().truncatedTo(ChronoUnit.DAYS).toString().substring(0,10));
workOrder.setPlanEndDate(workPlanList.get(workPlanList.size()-1).getEndTime() == null ? null : workPlanList.get(workPlanList.size()-1).getEndTime().truncatedTo(ChronoUnit.DAYS).toString().substring(0,10));
workOrder.setInventoryQty(0);
workOrder.setRunStatus(2);
workOrder.setPickingStatus(0);
workOrder.setOem("0");
workOrder.setPriority(order.getPriorityAps());
workOrder.setApprovalStatus(1);
workOrder.setScrapQty(0);
workOrder.setOemOut("0");
workOrder.setOemType(-1);
workOrder.setPrintFlag("0");
workOrder.setPushFlag("0");
workOrder.setQuotaExceptional("0");
workOrder.setReInStore("0");
workOrder.setPartCode(order.getPartCode());
this.save(workOrder);
workPlanList.forEach(workPlanEntity -> {
workPlanEntity.setWoId(workOrder.getId());
workPlanService.save(workPlanEntity);
});
workOrder.setWpId(workPlanList.get(0).getId());
this.updateById(workOrder);
//更新订单状态为已排产
order.setStatus(4);
order.setErrorInfo(null);
yieldOrderService.updateById(order);
workOrderList.add(workOrder);
}
} catch (Exception e) {
log.error("报错订单是:"+order.getId()+",报错信息是:"+e.getMessage());
throw new RuntimeException(e);
}
}
@ -927,11 +988,15 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
EquipResourceEntity equipResource = equipResourceService.getById(workPlan.getEquipResourceId());
equipResource.setIsUsed("0");
equipResource.setRestCapacity(equipResource.getRestCapacity().add(workPlan.getHourQuota()));
equipResourceService.updateById(equipResource);
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
updateWrapper.eq(EquipResourceEntity::getDateTime,equipResource.getDateTime());
updateWrapper.eq(EquipResourceEntity::getPeriod,equipResource.getPeriod());
equipResourceService.update(equipResource,updateWrapper);
}
//还原人力资源
if(workPlan.getPersonResourceIds() != null){
/*if(workPlan.getPersonResourceIds() != null){
List<PersonResourceEntity> personResourceList = personResourceService.list(Wrappers.<PersonResourceEntity>lambdaQuery().in(BaseEntity::getId,workPlan.getPersonResourceIds().split(",")));
if(CollectionUtils.isNotEmpty(personResourceList)){
personResourceList.forEach(item ->{
@ -939,7 +1004,7 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
personResourceService.updateById(item);
});
}
}
}*/
workPlanService.deleteLogic(Arrays.asList(workPlan.getId()));
}
@ -1029,6 +1094,9 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
List<WorkPlanEntity> workPlanList = new ArrayList<>();
//获取相关工序
YieldOrderCraftEntity craft = yieldOrderCraftService.getOne(Wrappers.<YieldOrderCraftEntity>lambdaQuery().eq(YieldOrderCraftEntity::getYoId,order.getId()).eq(YieldOrderCraftEntity::getCaId,equipAbility.getCraftId()));
if(craft == null){
continue;
}
//计算订单总产能
BigDecimal sumCapacity = order.getYpArea().multiply(BigDecimal.valueOf(100)).multiply(BigDecimal.valueOf(order.getYpQty()));
//计算需要占用几个时间段
@ -1100,4 +1168,35 @@ public class WorkOrderServiceImpl extends BaseServiceImpl<WorkOrderMapper, WorkO
return StringToFix;
}
public void restoreResource(List<WorkPlanEntity> list){
for(WorkPlanEntity workPlan : list){
//还原设备资源
if(workPlan.getEquipResourceId() != null){
EquipResourceEntity equipResource = equipResourceService.getById(workPlan.getEquipResourceId());
equipResource.setIsUsed("0");
equipResource.setRestCapacity(equipResource.getRestCapacity().add(workPlan.getHourQuota()));
LambdaUpdateWrapper<EquipResourceEntity> updateWrapper = new LambdaUpdateWrapper<>();
updateWrapper.eq(EquipResourceEntity::getEquipCode,equipResource.getEquipCode());
updateWrapper.eq(EquipResourceEntity::getDateTime,equipResource.getDateTime());
updateWrapper.eq(EquipResourceEntity::getPeriod,equipResource.getPeriod());
equipResourceService.update(equipResource,updateWrapper);
}
//还原人力资源
if(workPlan.getPersonResourceIds() != null){
List<PersonResourceEntity> personResourceList = personResourceService.list(Wrappers.<PersonResourceEntity>lambdaQuery().in(BaseEntity::getId,workPlan.getPersonResourceIds().split(",")));
if(CollectionUtils.isNotEmpty(personResourceList)){
personResourceList.forEach(item ->{
item.setIsUsed("0");
personResourceService.updateById(item);
});
}
}
if(workPlan.getId() != null){
workPlanService.deleteLogic(Arrays.asList(workPlan.getId()));
}
}
}
}

@ -68,9 +68,11 @@ public class WorkPlanServiceImpl extends BaseServiceImpl<WorkPlanMapper, WorkPla
workPlanUpdate.setId(id);
if (ObjectUtils.isNotEmpty(factStartTime)) {
workPlanUpdate.setFactStartTime(factStartTime);
workPlanUpdate.setStatus(WorkPlanEntity.STATUS_START);
}
if (ObjectUtils.isNotEmpty(factEndTime)) {
workPlanUpdate.setFactEndTime(factEndTime);
workPlanUpdate.setStatus(WorkPlanEntity.STATUS_COMPLETE);
}
this.updateById(workPlanUpdate);
}

@ -21,7 +21,7 @@ import org.springframework.stereotype.Component;
public class SchedulingJob {
private final IWorkOrderService workOrderService;
@Scheduled(cron = "* * 1 * * ?")
@Scheduled(cron = "0 0 8,12,16,20 * * ? ")
public void schedulingJob() {
workOrderService.scheduling();
}

@ -12,4 +12,5 @@ spring:
business:
oldMes:
url: 192.168.169.172:9000
# url: 127.0.0.1:32111
pushApsResult: /zhgd-rb/aiWebapi/pushApsResult

Loading…
Cancel
Save