rev:修改多层子流程时透传函数套娃问题;

add:网关添加自动功能作为空节点使用
This commit is contained in:
zhangzq
2024-07-08 15:14:19 +08:00
parent 9a16d8be85
commit 7607eeb6f4
32 changed files with 522 additions and 55 deletions

View File

@@ -41,8 +41,8 @@ public class AppRun implements CommandLineRunner {
}
@Override
public void run(String... args) throws Exception {
System.out.println(111);
public void run(String... args) {
System.out.println("--------项目启动完成--------");
}
// @Bean

View File

@@ -26,13 +26,13 @@ public enum StatusEnum {
/**
* 单据状态
*/
FORM_STATUS(ForkMap.of("生成", "10",null,"已分配", "13", null,"执行中", "20",null,"暂停", "30",null,"完成", "80",null,"取消", "90",null)),
FORM_STATUS(ForkMap.of("生成", "10",null,"已分配", "13", null,"下发", "15", null,"执行中", "20",null,"暂停", "30",null,"完成", "80",null,"取消", "90",null)),
/**
* 出入库单据类型
*/
IOBILL_TYPE_IN(ForkMap.of("生产入库", "10","inStorageTask", "调拨入库", "11","inStorageTask", "退货入库", "12","inStorageTask","拣选回库", "13","inStorageTask","盘点入库", "14","inStorageTask","托盘入库", "30","inStorageTask")),
IOBILL_TYPE_OUT(ForkMap.of("销售出库", "20","outStorageTask","生产出库", "21","outStorageTask", "调拨出库", "22","outStorageTask","拣选出库", "23","conveyorOutStorageTask","盘点出库", "24","outStorageTask", "托盘出库", "40","outStorageTask")),
IOBILL_TYPE_OUT(ForkMap.of("销售出库", "20","outStorageTask","生产出库", "21","outStorageTask", "调拨出库", "22","outStorageTask","拣选出库", "23","conveyorOutStorageTask","盘点出库", "24","outStorageTask","出库拣选", "25","toPickPlatformTask","托盘出库", "40","outStorageTask")),
IOBILL_TYPE_MOVE(ForkMap.of("移库", "50","moveStorageTask")),
profit_loss(ForkMap.of("盘亏", "0",null,"盘盈", "1",null,"实盘", "2",null)),

View File

@@ -14,16 +14,18 @@ import java.util.function.Supplier;
* @Date 2024/6/19 17:44
*/
@FunctionalInterface
public interface PermeateFunction<T,U > {
public interface PermeateFunction<T,U >{
PermeateFunction[] Ext_PF = new PermeateFunction[1];
void accept(T t,U u);
//函数透传方式
default PermeateFunction<T,U> andThen(Supplier<U> middle) {
PermeateFunction permeateFunction = Ext_PF[0];
if (permeateFunction==null){
Ext_PF[0]=this;
}
Objects.requireNonNull(middle);
return (inst_id,vehicle)->{
accept(inst_id,middle.get());
};
U extU = middle.get();
return (t, u) -> Ext_PF[0].accept(t, extU);
}
}

View File

@@ -35,6 +35,7 @@ public class InterationUtil {
String url = acsUrl + api;
try {
String resultMsg = HttpRequest.post(url)
.timeout(1000)
.body(String.valueOf(param))
.execute().body();
JSONObject response = JSONObject.parseObject(resultMsg);

View File

@@ -27,13 +27,13 @@ public class SpelUtil {
private static SpelExpressionParser SPEL_PARSER = new SpelExpressionParser();
public static void main2(String[] args) {
public static void main(String[] args) {
JSONObject source = new JSONObject();
JSONObject model = new JSONObject();
JSONObject FBillType = new JSONObject();
JSONArray FARRAY = new JSONArray();
source.put("FID","120222");
source.put("FID","");
source.put("Model",model);
model.put("FDATA", DateUtil.now());
model.put("FCODE", IdUtil.getStringId());
@@ -42,8 +42,11 @@ public class SpelUtil {
model.put("FARRAY", FARRAY);
FARRAY.add(MapOf.of("ARR1","子子子数字"));
FARRAY.add(MapOf.of("ARR2","子子子数字2"));
Map parse = SpelUtil.parse(source, MapOf.of("FID", "#M['FID']", "SSD", "#M['Model']['FDATA']","ARR1", "#M['Model']['FARRAY2'][1]['ARR2']"));
System.out.println(parse.toString());
Map parse = SpelUtil.parse(source, MapOf.of("FID", "#M['FID']"));
Boolean parse1 = SpelUtil.parse(source, "#M['FID'] != 'true'", Boolean.class);
Boolean parse2 = SpelUtil.parse(source, "#M['']", Boolean.class);
System.out.println(parse2);
System.out.println(parse1);
/*
{
"FID": "120222",
@@ -105,7 +108,7 @@ public class SpelUtil {
}
}
public static void main(String[] args) {
public static void main2(String[] args) {
String a= "{\"item\":[{\"t\":{\"stor_code\":\"FStockId\",\"create_time\":\"2024-06-19 11:13:06\",\"task_code\":\"28510\",\"material_spec\":\"45CCL1 1/8\",\"form_data\":{},\"group_id\":\"1803264719126138880\",\"qty\":120,\"proc_inst_id\":\"1803320414961799168\",\"is_lock\":false,\"pcsn\":\"11\",\"material_id\":\"FMaterialId\",\"id\":\"1803264718849314816\",\"has_child\":false,\"frozen_qty\":0,\"vehicle_code\":\"D00012\",\"source_form_id\":\"1803264490947612672\",\"unit_id\":\"16\",\"material_name\":\"A345度等径承插口弯头45CCL1 1/8USNA0131010\",\"source_form_type\":\"st_ivt_iostorinvdtl\",\"create_name\":\"管理员\",\"material_code\":\"24001097S\"},\"form_id\":\"1803264718849314816\",\"form_type\":\"md_pb_vehicleMater\",\"source_form_id\":\"1803264490947612672\",\"source_form_type\":\"st_ivt_iostorinvdtl\"}],\"t\":{\"code\":\"ZP20240619023\",\"stor_code\":\"FStockId\",\"create_time\":\"2024-06-19 11:13:06\",\"update_name\":\"管理员\",\"update_time\":\"2024-06-19 11:15:31\",\"form_data\":{},\"id\":\"1803264719126138880\",\"vehicle_code\":\"D00012\",\"source_form_id\":\"1803264490947612672\",\"struct_code\":\"L03-03-01\",\"source_form_type\":\"st_ivt_iostorinvdtl\",\"status\":\"10\",\"create_name\":\"管理员\"},\"form_id\":\"1803264719126138880\",\"form_type\":\"md_group_dick\",\"source_form_id\":\"1803264490947612672\",\"source_form_type\":\"st_ivt_iostorinvdtl\"}";
JSONObject jsonObject = JSONObject.parseObject(a);
String parse = SpelUtil.parse(jsonObject.getJSONObject("t"),"#M['stor_code'] == 'FStockId'", String.class);

View File

@@ -0,0 +1,72 @@
package org.nl.common.websocket.heartSocket.clientSocket;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.Future;
import org.nl.config.lucene.remote.AbstraceServer;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/*
* @author ZZQ
* @Date 2024/7/5 14:53
*/
public class HeartClientServer extends AbstraceServer {
private static EventLoopGroup group = new NioEventLoopGroup();
public HeartClientServer(SocketAddress address) {
super(address);
}
@Override
public void doOpen() {
server = new Bootstrap();
server.group(group)
// .option(ChannelOption.SO_KEEPALIVE, true)
.channel(NioSocketChannel.class);
server.handler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline()
.addLast("client-idle-handler", new IdleStateHandler(0, 5,0 , TimeUnit.SECONDS))
.addLast( new StringEncoder())
.addLast( new StringDecoder())
.addLast( new HeartConsumerHandler());
}
});
}
@Override
public void doClose() {
super.doClose();
Future<?> bossGroupShutdownFuture = group.shutdownGracefully();
bossGroupShutdownFuture.syncUninterruptibly();
}
@Override
public void doConnect() {
try {
ChannelFuture connect = ((Bootstrap) server).connect(address);
connect.syncUninterruptibly();
channel = connect.channel();
} catch (Throwable t) {
this.doClose();
throw t;
}
}
}

View File

@@ -0,0 +1,50 @@
package org.nl.common.websocket.heartSocket.clientSocket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import org.nl.config.lucene.remote.RemoteLogServer;
/*
* @author ZZQ
* @Date 2024/1/22 10:24
*/
public class HeartConsumerHandler extends SimpleChannelInboundHandler {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("断开连接---");
//重新建立
super.channelInactive(ctx);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("连接");
super.channelActive(ctx);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("接收到消息"+msg.toString());
super.channelRead(ctx, msg);
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent){
IdleStateEvent stateEvent = (IdleStateEvent) evt;
if (stateEvent.state() == IdleState.WRITER_IDLE) {
//如果五秒内写失败,说明服务网络异常
}
}
super.userEventTriggered(ctx, evt);
}
}

View File

@@ -0,0 +1,26 @@
package org.nl.common.websocket.heartSocket.clientSocket;
import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.util.CharsetUtil;
import org.nl.common.websocket.heartSocket.serverSocket.HeartServer;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
/*
* @author ZZQ
* @Date 2024/7/5 15:15
*/
public class RunClientHeartMain {
public static void main(String[] args) throws InterruptedException {
HeartClientServer heartServer = new HeartClientServer(new InetSocketAddress("127.0.0.1", 20889));
while (true){
Thread.sleep(2000);
System.out.println("-----chilend-------");
ByteBuf log = Unpooled.copiedBuffer("ping--333-", CharsetUtil.UTF_8);
heartServer.channel.writeAndFlush(log);
}
}
}

View File

@@ -0,0 +1,88 @@
package org.nl.common.websocket.heartSocket.serverSocket;
import io.netty.bootstrap.Bootstrap;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;
import io.netty.util.concurrent.Future;
import org.nl.common.websocket.heartSocket.clientSocket.HeartConsumerHandler;
import org.nl.config.lucene.remote.AbstraceServer;
import org.nl.config.lucene.remote.coder.LogProviderHandler;
import java.net.SocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
/*
* @author ZZQ
* @Date 2024/7/5 14:53
*/
public class HeartServer extends AbstraceServer {
public static Map<String, Channel> Heart_Connection = new HashMap();
private static EventLoopGroup boss = new NioEventLoopGroup();
private static EventLoopGroup worker = new NioEventLoopGroup();
public HeartServer(SocketAddress address) {
super(address);
}
// 非阻塞IO线程组
@Override
public void doOpen() {
ServerBootstrap bootstrap = new ServerBootstrap();
bootstrap
.group(boss, worker)
.channel(NioServerSocketChannel.class)
// .childOption(ChannelOption.SO_KEEPALIVE, Boolean.TRUE)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
protected void initChannel(SocketChannel ch) throws Exception {
ch.pipeline()
.addLast("client-idle-handler", new IdleStateHandler(4, 0, 0, TimeUnit.SECONDS))
.addLast( new StringEncoder())
.addLast( new StringDecoder())
.addLast(new HeartServerHandler());
}
});
server = bootstrap;
}
@Override
public void doClose(){
Future<?> bossGroupShutdownFuture = boss.shutdownGracefully();
Future<?> workerGroupShutdownFuture = worker.shutdownGracefully();
bossGroupShutdownFuture.syncUninterruptibly();
workerGroupShutdownFuture.syncUninterruptibly();
}
@Override
public void doConnect() {
ChannelFuture future = server.bind(address);
boolean ret = future.awaitUninterruptibly(3000, MILLISECONDS);
if (ret && future.isSuccess()) {
Channel newChannel = future.channel();
if (channel != null) {
channel.close();
channel = newChannel;
}
} else if (future.cause() != null) {
Throwable cause = future.cause();
cause.printStackTrace();
}
}
}

View File

@@ -0,0 +1,55 @@
package org.nl.common.websocket.heartSocket.serverSocket;
import com.alibaba.fastjson.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.CharsetUtil;
import org.nl.config.lucene.remote.RemoteLogServer;
/*
* @author ZZQ
* @Date 2024/1/22 10:24
*/
public class HeartServerHandler extends SimpleChannelInboundHandler {
@Override
public void channelInactive(ChannelHandlerContext ctx) throws Exception {
System.out.println("服务端断开连接-----");
HeartServer.Heart_Connection.remove(ctx.channel().id().asLongText());
//重新建立
super.channelInactive(ctx);
}
@Override
public void channelActive(ChannelHandlerContext ctx) throws Exception {
System.out.println("服务端收到连接-----连接");
HeartServer.Heart_Connection.put(ctx.channel().id().asLongText(),ctx.channel());
super.channelActive(ctx);
}
@Override
protected void channelRead0(ChannelHandlerContext ctx, Object msg) throws Exception {
System.out.println("接收到消息"+msg.toString());
}
@Override
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
if (evt instanceof IdleStateEvent){
IdleStateEvent stateEvent = (IdleStateEvent) evt;
System.out.println(stateEvent.state());
if (stateEvent.state() == IdleState.READER_IDLE) {
//向服务端发送消息
// ctx.writeAndFlush("ping")
// .addListener(ChannelFutureListener.CLOSE_ON_FAILURE);
}
}
super.userEventTriggered(ctx, evt);
}
}

View File

@@ -0,0 +1,28 @@
package org.nl.common.websocket.heartSocket.serverSocket;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.util.CharsetUtil;
import org.nl.common.websocket.heartSocket.serverSocket.HeartServer;
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
/*
* @author ZZQ
* @Date 2024/7/5 15:15
*/
public class RunHeartMain {
public static void main(String[] args) throws InterruptedException {
HeartServer heartServer = new HeartServer(new InetSocketAddress("127.0.0.1", 20889));
// while (true){
// Thread.sleep(5000);
// for (Channel value : HeartServer.Heart_Connection.values()) {
// System.out.println("-----server-------");
// ByteBuf log = Unpooled.copiedBuffer("ping--2222-", CharsetUtil.UTF_8);
// value.writeAndFlush(log);
// }
// }
}
}

View File

@@ -54,7 +54,7 @@ public class DruidFilter extends FilterEventAdapter {
}
executeSql = SQLUtils.format(executeSql, JdbcUtils.MYSQL, params);
}
log.info("[----SQL----][update][ SQL: {} ]", executeSql);
// log.info("[----SQL----][update][ SQL: {} ]", executeSql);
}
super.statementExecuteAfter(statement, sql, result);
}
@@ -81,7 +81,7 @@ public class DruidFilter extends FilterEventAdapter {
}catch (Exception ex){
log.warn("[-SQL解析异常-][{}]",ex.getMessage());
}
log.info("[----SQL----][select][执行结果:{}][ SQL: {} ]",result, executeSql);
// log.info("[----SQL----][select][执行结果:{}][ SQL: {} ]",result, executeSql);
}
return rs;
}

View File

@@ -4,6 +4,7 @@ package org.nl.wms.base_manage.bsrealstorattr.controller;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import org.nl.common.domain.entity.PageQuery;
import org.nl.common.utils.IdUtil;
import org.nl.wms.base_manage.bsrealstorattr.service.IStIvtBsrealstorattrService;
@@ -20,7 +21,10 @@ import org.springframework.web.bind.annotation.*;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.function.Function;
/**
* <p>
@@ -101,7 +105,7 @@ public class StIvtBsrealstorattrController {
attr.setStor_code(stor_code);
String ny = (y < 10) ? "0" + y : "" + y;
String nz = (z < 10) ? "0" + z : "" + z;
attr.setStruct_code("T0"+x+"-"+ny+"-"+nz);
attr.setStruct_code("L0"+x+"-"+ny+"-"+nz);
attr.setStruct_name(x+""+y+""+z+"");
attr.setCreate_id("1");
attr.setRow_num(x);
@@ -112,11 +116,17 @@ public class StIvtBsrealstorattrController {
attr.setCreate_name("Admin");
attr.setIs_temp(false);
attr.setIs_used(true);
System.out.println(attr.toString());
list.add(attr);
}
}
}
iStIvtStructattrService.saveBatch(list);
Lists.partition(list,1000).stream().map((Function<List<StIvtStructattr>, CompletableFuture>) o->CompletableFuture.runAsync(() -> {
for (StIvtStructattr stIvtStructattr : o) {
iStIvtStructattrService.save(stIvtStructattr);
}
})).parallel().forEach(CompletableFuture::join);
return new ResponseEntity<>(HttpStatus.OK);
}

View File

@@ -2,12 +2,14 @@ package org.nl.wms.decision_manage.handler.decisioner;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.utils.SpringContextHolder;
import org.nl.wms.decision_manage.service.IStStrategyConfigService;
import org.nl.wms.decision_manage.service.dao.StStrategyConfig;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ResolvableType;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@@ -28,6 +30,9 @@ public abstract class Decisioner<T,P> implements InitializingBean {
public void afterPropertiesSet(){
String type = SpringContextHolder.getApplicationContext().getBeanNamesForType(ResolvableType.forClass(this.getClass()))[0];
this.strategyConfig =iStStrategyConfigService.getOne(new QueryWrapper<StStrategyConfig>().eq("strategy_code",type));
if (this.strategyConfig == null){
throw new BadRequestException("启动失败:当前策略"+type+"没有实例信息");
}
}
}

View File

@@ -22,7 +22,6 @@ import java.util.List;
@Service("nearby")
public class NearbyRuleHandler extends Decisioner<StIvtStructattr, JSONObject> {
//每个策略的配置信息
private static StStrategyConfig stStrategyConfig;
/**
* 出入库明细服务
*/

View File

@@ -0,0 +1,106 @@
package org.nl.wms.dispatch_manage.task.handler.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.constant.DictConstantPool;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.enums.StatusEnum;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.IdUtil;
import org.nl.common.utils.SecurityUtils;
import org.nl.wms.dispatch_manage.task.handler.AbstractTask;
import org.nl.wms.dispatch_manage.task.service.ISchBaseTaskService;
import org.nl.wms.dispatch_manage.task.service.dao.SchBaseTask;
import org.nl.wms.md_manage.vehicleMater.service.IMdPbVehicleMaterService;
import org.nl.wms.md_manage.vehicleMater.service.dao.MdPbVehicleMater;
import org.nl.wms.stor_manage.struct.service.IStIvtStructattrService;
import org.nl.wms.stor_manage.struct.service.dao.StIvtStructattr;
import org.nl.wms.system_manage.service.param.ISysParamService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.stream.Collectors;
/*
* @author ZZQ
* @Date 2024/5/6 14:34
* 出库任务入库任务
*/
@Service
public class ToPickPlatformTask extends AbstractTask {
@Autowired
private ISchBaseTaskService taskService;
@Autowired
private ISysParamService iSysParamService;
@Autowired
private IStIvtStructattrService iStIvtStructattrService;
@Autowired
private IMdPbVehicleMaterService iMdPbVehicleMaterService;
@Override
@Transactional
public JSONObject createTask(JSONObject from) {
String vehicle_code = from.getString("vehicle_code");
String target_point = from.getString("target_point");
//通过全局变量获取目标位置
if (StringUtils.isEmpty(vehicle_code) ||StringUtils.isEmpty(target_point)){
throw new BadRequestException("创建任务失败:方法请求参数不能为空");
}
List<SchBaseTask> list = taskService.list(new QueryWrapper<SchBaseTask>().eq("vehicle_code", vehicle_code)
.ne("status", StatusEnum.FORM_STATUS.code("完成")));
if (!CollectionUtils.isEmpty(list)){
throw new BadRequestException("当前载具存在任务:"+list.stream().map(SchBaseTask::getTask_code).collect(Collectors.joining(",")));
}
StIvtStructattr struct = iStIvtStructattrService.getOne(new QueryWrapper<StIvtStructattr>().eq("vehicle_code", vehicle_code));
SchBaseTask task = new SchBaseTask();
task.setId(IdUtil.getStringId());
task.setTask_code(CodeUtil.getNewCode("TASK_CODE"));
task.setStatus(StatusEnum.FORM_STATUS.code("生成"));
task.setHandle_class(this.getClass().getName());
task.setAcs_type(StatusEnum.ACS_TYPE.code("立库"));
task.setCreate_time(DateUtil.now());
task.setCreate_name(SecurityUtils.getCurrentNickName());
task.setTask_type(from.getString("task_type"));
task.setVehicle_code(vehicle_code);
task.setPoint_code1(struct.getStruct_code());
task.setPoint_code2(target_point);
taskService.save(task);
iMdPbVehicleMaterService.update(new LambdaUpdateWrapper<MdPbVehicleMater>()
.set(MdPbVehicleMater::getTask_code,task.getTask_code())
.eq(MdPbVehicleMater::getVehicle_code,task.getVehicle_code()));
//TODO:是否下发
Boolean isSend = from.getBoolean("is_send");
if (isSend){
//参数封装调acs接口
}
return (JSONObject)JSON.toJSON(task);
}
@Override
@Transactional
public void updateStatus(JSONObject data) {
this.updateTask(data);
}
@Override
public void finish(JSONObject data) {
this.updateTask(data);
SchBaseTask schBaseTask = taskService.getOne(new QueryWrapper<SchBaseTask>().eq("task_code", data.getString("task_code")));
iStIvtStructattrService.changeStruct(schBaseTask.getPoint_code1(),schBaseTask.getVehicle_code(),schBaseTask.getTask_type(), null,Boolean.FALSE);
}
@Override
public void cancel(JSONObject data) {
this.updateTask(data);
}
}

View File

@@ -6,7 +6,6 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.conditions.update.UpdateChainWrapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
@@ -14,7 +13,6 @@ import org.nl.common.TableDataInfo;
import org.nl.common.enums.StatusEnum;
import org.nl.wms.dispatch_manage.task.service.dao.SchBaseTask;
import org.nl.wms.external_system.acs.service.WmsToAcsService;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
@@ -35,7 +33,7 @@ public class TaskScheduleService {
private ReentrantLock lock = new ReentrantLock();
@Autowired
private ISchBaseTaskService taskService;
private ISchBaseTaskService iSchBaseTaskService;
@Autowired
private WmsToAcsService wmsToAcsService;
@@ -46,22 +44,29 @@ public class TaskScheduleService {
try {
if (islock){
//查询所有自动下发的任务
List<SchBaseTask> list = taskService.list(new QueryWrapper<SchBaseTask>().eq("is_send", true)
List<SchBaseTask> list = iSchBaseTaskService.list(new QueryWrapper<SchBaseTask>().eq("is_send", true)
.eq("status", StatusEnum.FORM_STATUS.code("生成")));
if (!CollectionUtils.isEmpty(list)){
List<String> taskCodes = list.stream().map(SchBaseTask::getTask_code).collect(Collectors.toList());
TableDataInfo response = wmsToAcsService.interationToExt(list, "createTask");
if (response.getCode().equals(String.valueOf(HttpStatus.HTTP_BAD_REQUEST))){
if (!response.getCode().equals(String.valueOf(HttpStatus.HTTP_OK))){
JSONArray results = (JSONArray)JSON.toJSON(response.getData());
if (!CollectionUtils.isEmpty(results)){
for (Object result : results) {
Map resultM = (Map) result;
taskService.update(new UpdateWrapper<SchBaseTask>()
taskCodes.remove(resultM.get("task_code"));
iSchBaseTaskService.update(new UpdateWrapper<SchBaseTask>()
.eq("task_code",resultM.get("task_code"))
.set("status",StatusEnum.FORM_STATUS.code("暂停"))
.set("update_time", DateUtil.now()).set("remark",resultM.get("error")));
}
}
}
if (!CollectionUtils.isEmpty(taskCodes)){
iSchBaseTaskService.update(new UpdateWrapper<SchBaseTask>()
.set("status",StatusEnum.FORM_STATUS.code("下发"))
.in("task_code",taskCodes));
}
}
}
}finally {

View File

@@ -103,7 +103,7 @@ public class ExecutionController {
@GetMapping(value = "/confirm/{proc_inst_id}")
public ResponseEntity<Object> flowConfirm(@PathVariable String proc_inst_id) {
return new ResponseEntity<>(flowOperationService.flowConfirm(proc_inst_id, null, null), HttpStatus.OK);
return new ResponseEntity<>(flowOperationService.flowConfirm(proc_inst_id, null, null, null), HttpStatus.OK);
}
@GetMapping(value = "/queryByParentId/{id}")

View File

@@ -109,7 +109,9 @@ public abstract class FlowNodeActivityBehavior<T> {
}
}
if (flowElement instanceof SequenceFlow){
CommandExecutor.getAgenda().planOperation(new SequenceFlowOperation(entity));
if (((SequenceFlow)flowElement).getPassNode()){
CommandExecutor.getAgenda().planOperation(new SequenceFlowOperation(entity));
}
}
}

View File

@@ -3,6 +3,7 @@ package org.nl.wms.flow_manage.flow.framework.engine.behavior.impl;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.utils.ListOf;
import org.nl.common.utils.MapOf;
@@ -37,9 +38,14 @@ public class GateWayActivityBehavior extends FlowNodeActivityBehavior<JSONObject
FlowElement element = entity.getCurrentFlowElement();
GateWay gateWay = (GateWay) element;
Boolean passNode = gateWay.getPassNode();
SequenceFlow targetSequence = null;
for (SequenceFlow sequenceFlow : gateWay.getOutgoingFlows()) {
String skipExpression = sequenceFlow.getSkipExpression();
if (StringUtils.isEmpty(skipExpression)){
targetSequence = sequenceFlow;
break;
}
Boolean parse = SpelUtil.parse(entity.getT().getJSONObject("t"),skipExpression, Boolean.class);
if (parse){
System.out.println(Thread.currentThread().getName()+"_执行网关判断:"+skipExpression+"_"+sequenceFlow.getName());
@@ -50,6 +56,7 @@ public class GateWayActivityBehavior extends FlowNodeActivityBehavior<JSONObject
if (targetSequence == null){
throw new BadRequestException("当前网关没有满足的流程线");
}
targetSequence.setPassNode(passNode);
//手动保存网关调用
IActHiExecutionService history = SpringContextHolder.getBean(IActHiExecutionService.class);
ActHiExecution historyEntity = new ActHiExecution();

View File

@@ -104,7 +104,8 @@ public class SubProcessActivityBehavior extends FlowNodeActivityBehavior<JSONObj
subEntity.setAuxParam(subAuxParam);
subEntity.setCurrentFlowElement(startEvent);
if (subProcess.getPermeate()){
subEntity.setCallback(entity.getCallback().andThen(() -> ((JSONObject) o).getJSONObject("t").getString("vehicle_code")));
String vehicle_code = ((JSONObject) o).getJSONObject("t").getString("vehicle_code");
subEntity.setCallback(entity.getCallback().andThen(() -> vehicle_code));
}
subEntity.setT(o);
//在endEvent中有个所有子流程结束的判断如果判断成功会触发父流程startEvent暂时通过等待处理防止自动流程导致endEvent判断出错

View File

@@ -24,6 +24,7 @@ public abstract class FlowElement extends BaseElement {
protected String type;
protected String name;
protected String documentation;
/**
* 是否自动触发下个节点
*/

View File

@@ -29,6 +29,9 @@ public class SequenceFlow extends FlowElement {
protected FlowNode targetFlowElement;
protected Boolean passNode = Boolean.TRUE;
/**
* Graphical information: a list of waypoints: x1, y1, x2, y2, x3, y3, ..
*

View File

@@ -5,9 +5,6 @@ import com.alibaba.fastjson.JSONObject;
import org.nl.common.function.PermeateFunction;
import org.nl.wms.flow_manage.flow.framework.entity.ExecutionDto;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/**
* @program: flow
* @description: 表单流程操作类
@@ -19,5 +16,5 @@ public interface IFlowOperationService {
String startUp(String model_key, PermeateFunction callback, ExecutionDto dto, JSONObject auxParam);
Boolean flowConfirm(String proc_inst_id,JSONObject auxParam,ExecutionDto dto);
Boolean flowConfirm(String proc_inst_id,PermeateFunction callback,JSONObject auxParam,ExecutionDto dto);
}

View File

@@ -27,8 +27,6 @@ import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
/*
* @author ZZQ
@@ -83,7 +81,7 @@ public class FlowOperationServiceImpl implements IFlowOperationService {
@Override
public Boolean flowConfirm(String proc_inst_id, JSONObject auxParam, ExecutionDto dto) {
public Boolean flowConfirm(String proc_inst_id, PermeateFunction callback, JSONObject auxParam, ExecutionDto dto) {
if (StringUtils.isNotEmpty(proc_inst_id)){
//当前流程
ActRuExecution execution = iActRuExecutionService.getOne(new QueryWrapper<ActRuExecution>()
@@ -111,6 +109,7 @@ public class FlowOperationServiceImpl implements IFlowOperationService {
FlowNode flowNode = bpmnModel.getProcesses().get(execution.getActivity_id());
ExecutionEntity entity = new ExecutionEntity();
entity.setCurrentFlowElement(flowNode);
entity.setCallback(callback);
entity.setProc_inst_id(execution.getProc_inst_id());
entity.setParent_id(execution.getParent_id());
entity.setAuxParam(execution.getAux_param());

View File

@@ -5,7 +5,6 @@ import lombok.extern.slf4j.Slf4j;
import org.nl.common.publish.AbstraceListener;
import org.nl.wms.flow_manage.flow.service.execution.IFlowOperationService;
import org.nl.wms.flow_manage.monitor.event.FlowContinueEvent;
import org.nl.wms.flow_manage.monitor.event.FlowStartEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@@ -24,7 +23,7 @@ public class FlowContinueEventListener extends AbstraceListener<FlowContinueEven
protected String doEvent(FlowContinueEvent event) {
String s = JSON.toJSONString(event.getDto());
log.info("触发流程"+ s);
flowOperationService.flowConfirm(event.getProc_inst_id(), event.getAuxParam(),event.getDto());
flowOperationService.flowConfirm(event.getProc_inst_id(), event.getFlowStartCallback(), event.getAuxParam(),event.getDto());
return "";
}
}

View File

@@ -9,6 +9,7 @@ import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.domain.exception.BadRequestException;
import org.nl.common.enums.StatusEnum;
import org.nl.common.function.PermeateFunction;
import org.nl.common.publish.BussEventMulticaster;
import org.nl.common.utils.CodeUtil;
import org.nl.common.utils.IdUtil;
@@ -75,7 +76,7 @@ public class PickingService {
vehicleCodes.remove(one.getVehicle_code());
int mCode = iMdPbVehicleMaterService.count(new QueryWrapper<MdPbVehicleMater>().in("vehicle_code", vehicleCodes));
if (mCode>0){
throw new BadRequestException("当前载具以存在载具物料信息");
throw new BadRequestException("当前载具"+vehicleCodes.toString()+"以存在载具物料信息");
}
String now = DateUtil.now();
String user = SecurityUtils.getCurrentNickName();
@@ -131,8 +132,9 @@ public class PickingService {
dto.setSource_form_id(mst.getSource_form_id());
dto.setT(mstJ);
dto.setItem(packageT(mstJ,"id"));
FlowContinueEvent continueEvent = new FlowContinueEvent(mst.getProc_inst_id(), null,null)
//只有透传才有vehicle_code参数否则只有inst_id
FlowContinueEvent continueEvent = new FlowContinueEvent(mst.getProc_inst_id(), (PermeateFunction<String, String>) (inst_id, vehicle_code) -> iMdPbVehicleMaterService.update(new UpdateWrapper<MdPbVehicleMater>()
.set("proc_inst_id",inst_id).eq("vehicle_code",vehicle_code)), null)
.setDto(dto);
continueEvent.setCallback(emp->{
iFormDataService.update(new UpdateWrapper<PmFormData>()

View File

@@ -1,6 +1,11 @@
server:
port: 8012
max-http-header-size: 65536
tomcat:
accept-count: 300
threads:
max: 300
min-spare: 30
#配置数据源
spring:
datasource:
@@ -8,6 +13,7 @@ spring:
db-type: com.alibaba.druid.pool.DruidDataSource
driverClassName: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://${DB_HOST:192.168.81.251}:${DB_PORT:3306}/${DB_NAME:wms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
# url: jdbc:mysql://${DB_HOST:127.0.0.1}:${DB_PORT:3306}/${DB_NAME:wms}?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&useOldAliasMetadataBehavior=true&allowPublicKeyRetrieval=true&useSSL=false
username: ${DB_USER:root}
password: ${DB_PWD:123456}
@@ -20,7 +26,7 @@ spring:
# 是否自动回收超时连接
remove-abandoned: true
# 超时时间(以秒数为单位)
remove-abandoned-timeout: 180
remove-abandoned-timeout: 10
# 获取连接超时时间
max-wait: 9000
# 连接有效性检测时间

View File

@@ -12,7 +12,7 @@
>
<el-form-item label="所属仓库">
<el-select
v-model="query.stor_id"
v-model="query.stor_code"
clearable
class="filter-item"
placeholder="所属仓库"
@@ -20,9 +20,9 @@
>
<el-option
v-for="item in tableEnum.st_ivt_bsrealstorattr"
:key="item.value"
:label="item.label"
:value="item.value"
:key="item.stor_code"
:label="item.stor_name"
:value="item.stor_code"
/>
</el-select>
</el-form-item>
@@ -71,17 +71,17 @@
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="归属仓库" prop="id">
<el-form-item label="归属仓库" prop="stor_code">
<el-select
v-model="form.id"
v-model="form.stor_code"
placeholder=""
style="width: 200px"
>
<el-option
v-for="item in tableEnum.st_ivt_bsrealstorattr"
:key="item.id"
:key="item.stor_code"
:label="item.stor_name"
:value="item.id"
:value="item.stor_code"
/>
</el-select>
</el-form-item>
@@ -231,7 +231,7 @@ const defaultForm = {
export default {
name: 'Sectattr',
dicts: ['st_sect_type', 'is_used'],
tableEnums: [ 'st_ivt_bsrealstorattr#stor_name#id' ],
tableEnums: [ 'st_ivt_bsrealstorattr#stor_name#stor_code' ],
components: { pagination, crudOperation, rrOperation, udOperation },
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {

View File

@@ -11,7 +11,7 @@
>
<el-form-item label="所属仓库">
<el-select
v-model="query.stor_id"
v-model="query.stor_code"
clearable
class="filter-item"
placeholder="所属仓库"
@@ -322,7 +322,7 @@ export default {
name: 'Structattr',
dicts: ['ST_HEIGHT_TYPE', 'is_used', 'd_lock_type', 'SCH_TASK_TYPE_DTL', 'placement_type'],
statusEnums: ['LOCK'],
tableEnums: [ 'st_ivt_bsrealstorattr#stor_name#id' ],
tableEnums: [ 'st_ivt_bsrealstorattr#stor_name#stor_code' ],
components: { pagination, crudOperation, rrOperation, udOperation },
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {

View File

@@ -88,7 +88,7 @@
style="width: 100%;"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="proc_inst_id" show-overflow-tooltip show-tooltip-when-overflow width="220" label="流程实例">
<el-table-column prop="proc_inst_id" show-overflow-tooltip show-tooltip-when-overflow width="260" label="流程实例">
<template slot-scope="scope">
<el-link type="warning" @click="toView(scope.row)">{{ scope.row.proc_inst_id }}</el-link>
</template>

View File

@@ -191,7 +191,7 @@
<el-table-column width="130" show-overflow-tooltip v-for="(item, index) in disCols" :key="item.value"
:label="item.lable">
<template slot-scope="scope">
<el-switch v-if="item.value == 'is_artificiality'"
<el-switch v-if="item.value == 'is_move'"
v-model="tabledis[scope.$index].form_data[item.value]"
active-color="#409EFF"
inactive-color="#F56C6C"