diff --git a/src/main/java/com/dsic/gj_erp/pc/DataFactory.java b/src/main/java/com/dsic/gj_erp/pc/DataFactory.java index 03a4562..f8907f8 100644 --- a/src/main/java/com/dsic/gj_erp/pc/DataFactory.java +++ b/src/main/java/com/dsic/gj_erp/pc/DataFactory.java @@ -30,6 +30,7 @@ import java.io.OutputStream; import java.util.*; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.stream.Collectors; import static com.dsic.gj_erp.pc.Constant.工序CD; @@ -40,6 +41,7 @@ public class DataFactory { public static void 排产2() { 套料图所占工序的资源.clear(); + Manager.排产结果=new ArrayList<>(); List<钢料需求> list=读取钢料需求(); list.forEach(钢料需求 -> { @@ -65,6 +67,7 @@ public class DataFactory { throw new RuntimeException(e); } }); + System.out.println(Manager.排产结果.size()); //清理冗余数据 list.forEach(钢料需求->{ 钢料需求.getBomList().forEach(bom -> { @@ -79,10 +82,8 @@ public class DataFactory { } public static List<钢料需求> 读取钢料需求(){ - List<钢料需求> list=new ArrayList<>(); List 按需求日期排序的钢料需求 = getBean(DmSygdxqService.class).getXqWithBom(from, to); - 按需求日期排序的钢料需求.forEach(item-> list.add(钢料需求.of(item))); - return list; + return 按需求日期排序的钢料需求.stream().map(钢料需求::of).collect(Collectors.toList()); } public static void 排产() { @@ -190,6 +191,9 @@ public class DataFactory { return 资源池.values().stream().filter(资源->{ 工序产能 工序产能 = 资源.get工序产能MAP().get(工序); Date 资源日期=DateUtil.parse(资源.getDate(),"yyyy/MM/dd"); + if (工序产能==null){ + return false; + } return 工序产能.判断是否可以占用(需求数量)&&资源日期.after(搜索起始日期)&&资源日期.before(搜索截止日期); }).findFirst(); } diff --git a/src/main/java/com/dsic/gj_erp/pc/Manager.java b/src/main/java/com/dsic/gj_erp/pc/Manager.java index 2ff3980..023a28f 100644 --- a/src/main/java/com/dsic/gj_erp/pc/Manager.java +++ b/src/main/java/com/dsic/gj_erp/pc/Manager.java @@ -2,6 +2,7 @@ package com.dsic.gj_erp.pc; import com.dsic.gj_erp.bean.jcsj.EmGcrl; import com.dsic.gj_erp.bean.jcsj.EmSbjbb; +import com.dsic.gj_erp.pc.dto.data.Bom; import com.dsic.gj_erp.pc.dto.data.钢料需求; import com.dsic.gj_erp.pc.dto.资源; @@ -24,7 +25,7 @@ public class Manager { public static final ExecutorService es; - public static List<钢料需求> 排产结果; + public static List 排产结果; static { int poolSize =Runtime.getRuntime().availableProcessors() * 2; diff --git a/src/main/java/com/dsic/gj_erp/pc/dto/data/Bom.java b/src/main/java/com/dsic/gj_erp/pc/dto/data/Bom.java index acfd966..d2d4ee7 100644 --- a/src/main/java/com/dsic/gj_erp/pc/dto/data/Bom.java +++ b/src/main/java/com/dsic/gj_erp/pc/dto/data/Bom.java @@ -1,12 +1,16 @@ package com.dsic.gj_erp.pc.dto.data; import cn.hutool.core.bean.BeanUtil; +import com.alibaba.fastjson.JSONObject; import com.dsic.gj_erp.bean.jcsj.DmBom; +import com.dsic.gj_erp.pc.Constant; import com.dsic.gj_erp.pc.dto.设备; import com.dsic.gj_erp.pc.dto.资源; import lombok.Getter; import lombok.Setter; +import java.util.ArrayList; +import java.util.List; import java.util.Map; @Getter @@ -28,12 +32,18 @@ public class Bom { private Map degs; private 设备 所在设备; private 资源 所在资源; + private List 已排工序; public static Bom of(String xzxq, String dzxq, DmBom bom){ Bom _bom = new Bom(); BeanUtil.copyProperties(bom,_bom); _bom.xzglxq=xzxq; _bom.dzglxq=dzxq; + _bom.已排工序 =new ArrayList<>(); return _bom; } + + public String toString() { + return JSONObject.toJSONString(this); + } } diff --git a/src/main/java/com/dsic/gj_erp/pc/dto/套料图工序.java b/src/main/java/com/dsic/gj_erp/pc/dto/套料图工序.java index 0869a1b..e191c3a 100644 --- a/src/main/java/com/dsic/gj_erp/pc/dto/套料图工序.java +++ b/src/main/java/com/dsic/gj_erp/pc/dto/套料图工序.java @@ -5,6 +5,7 @@ import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.ObjUtil; import cn.hutool.core.util.StrUtil; import com.dsic.gj_erp.pc.Constant; +import com.dsic.gj_erp.pc.Manager; import com.dsic.gj_erp.pc.dto.data.Bom; import com.dsic.gj_erp.pc.dto.data.钢料需求; import com.dsic.gj_erp.pc.service.套料图工序接口; @@ -20,7 +21,6 @@ import static com.dsic.gj_erp.pc.Constant.工序CD; import static com.dsic.gj_erp.pc.DataFactory.提取资源; import static com.dsic.gj_erp.pc.DataFactory.搜索可用资源; import static com.dsic.gj_erp.pc.Manager.from; -import static com.dsic.gj_erp.pc.Manager.套料图所占工序的资源; @Getter @Setter @@ -41,18 +41,26 @@ public abstract class 套料图工序 implements 套料图工序接口 { this._需求日期 = DateUtil.parse(this.需求日期, "yyyy/MM/dd"); double 需求数量 = 1; this.工序.forEach(_工序 -> { - if (!this.已占资源(_工序)&&!this.占用资源(_工序,需求数量)){ - if (bom.get所在资源() == null) { - Optional<资源> 可用资源 = 搜索可用资源(_工序, DateUtil.parse(from, "yyyy/MM/dd"), this._需求日期, 需求数量); - 可用资源.ifPresent(_资源 -> { - _资源.占用资源(_工序,this.bom,需求数量); - }); + if (!this.占用资源(_工序,需求数量)){ + if (bom.get已排工序().size()==0||bom.get已排工序().get(0) != _工序) { + //可用资源最大前推日期设置为N天,最大前推日期意味从上料开始最小施工周期 + //fixme 这里应该安装工序设置,暂时写死一个日期 + Optional<资源> 可用资源 = 搜索可用资源(_工序, DateUtil.parse(from, "yyyy/MM/dd"), DateUtil.offsetDay(this._需求日期,0), 需求数量); + if (可用资源!=null){ + 可用资源.ifPresent(_资源 -> { + if (_资源.占用资源(_工序,this.bom,需求数量)){ + this.bom.set所在资源(_资源); + this.bom.get已排工序().add(0,_工序); + } + }); + } } - //没有可用资源放入月末(强占),待手工调整 - if (bom.get所在资源() == null) { - 资源 _资源 = 提取资源(DateUtil.endOfMonth(DateUtil.parse(this.需求日期, "yyyy/MM/dd"))); - _资源.强占资源(_工序,this.bom,需求数量); + if (bom.get已排工序().size()==0||bom.get已排工序().get(0) != _工序) { + if (_工序 == Constant.工序.上料){ + Manager.排产结果.add(this.bom); + System.out.println(this.bom.toString()); + } } } }); @@ -64,18 +72,20 @@ public abstract class 套料图工序 implements 套料图工序接口 { 资源 _资源 = 提取资源(dateTime); AtomicBoolean 占用成功=new AtomicBoolean(false); try { - _资源.占用资源(_工序,this.bom,需求数量); - this.bom.set所在资源(_资源); - 占用成功.set(true); + if (_资源.占用资源(_工序,this.bom,需求数量)){ + this.bom.set所在资源(_资源); + this.bom.get已排工序().add(0,_工序); + 占用成功.set(true); + } }catch (Exception e){ - + e.printStackTrace(); } return 占用成功.get(); } - protected boolean 已占资源(Constant.工序 _工序){ - 资源 已占资源 = this.获取所在资源(); + protected boolean 已占资源(Constant.工序 _工序,String 套料图){ + 资源 已占资源 = 资源.读取套料图所在资源(套料图); 工序产能 工序产能 = null; if (已占资源 != null) { 工序产能 = 已占资源.get工序产能MAP().get(_工序); @@ -89,10 +99,6 @@ public abstract class 套料图工序 implements 套料图工序接口 { return false; } - protected 资源 获取所在资源() { - return 套料图所占工序的资源.get(this.bom.getTzbh()); - } - @Override public 套料图工序 钢料需求(钢料需求 _钢料需求) { this._钢料需求=_钢料需求; diff --git a/src/main/java/com/dsic/gj_erp/pc/dto/工序产能.java b/src/main/java/com/dsic/gj_erp/pc/dto/工序产能.java index b3716d2..d2459e6 100644 --- a/src/main/java/com/dsic/gj_erp/pc/dto/工序产能.java +++ b/src/main/java/com/dsic/gj_erp/pc/dto/工序产能.java @@ -70,8 +70,7 @@ public abstract class 工序产能 implements 工序排产处理接口 { } public Optional<设备> 获取可占用设备(double 所需产能){ - return this.设备.values().stream() - .filter(item -> this.判断设备是否可以占用(item.设备编号, 所需产能)).findFirst(); + return this.设备.values().stream().findAny(); } public boolean 判断设备是否可以占用(String 设备编号,double 所需产能){ diff --git a/src/main/java/com/dsic/gj_erp/pc/dto/资源.java b/src/main/java/com/dsic/gj_erp/pc/dto/资源.java index e6bb51b..fab4a0a 100644 --- a/src/main/java/com/dsic/gj_erp/pc/dto/资源.java +++ b/src/main/java/com/dsic/gj_erp/pc/dto/资源.java @@ -7,6 +7,10 @@ import lombok.Setter; import java.util.Map; import java.util.Optional; +import java.util.concurrent.Semaphore; +import java.util.concurrent.atomic.AtomicBoolean; + +import static com.dsic.gj_erp.pc.Manager.套料图所占工序的资源; @Getter @Setter @@ -24,14 +28,17 @@ public class 资源 { }); } - public void 占用资源(Constant.工序 工序, Bom bom, double 产能消耗){ + public boolean 占用资源(Constant.工序 工序, Bom bom, double 产能消耗){ + AtomicBoolean atomicBoolean = new AtomicBoolean(false); 工序产能 工序产能 = 工序产能MAP.get(工序); - Optional.of(工序产能).ifPresent(it->{ + Optional.ofNullable(工序产能).ifPresent(it->{ if (it.判断是否可以占用(产能消耗)){ it.占用资源(产能消耗,bom); 设置套料图所在资源(bom.getTzbh()); + atomicBoolean.set(true); } }); + return atomicBoolean.get(); } public void 强占资源(Constant.工序 工序,Bom bom,double 产能消耗){ @@ -42,8 +49,28 @@ public class 资源 { }); } + private static Semaphore semaphore = new Semaphore(1); + + protected static 资源 读取套料图所在资源(String 套料图号) { + try { + semaphore.acquire(); + return 套料图所占工序的资源.get(套料图号); + } catch (InterruptedException e) { + throw new RuntimeException(e); + }finally { + semaphore.release(); + } + } + protected void 设置套料图所在资源(String 套料图号) { - //套料图所占工序的资源.put(套料图号,this); + try { + semaphore.acquire(); + 套料图所占工序的资源.put(套料图号,this); + } catch (InterruptedException e) { + throw new RuntimeException(e); + }finally { + semaphore.release(); + } } public static 资源 of(String date,Map 工序产能MAP){