north-glass-erp/pom.xml
@@ -114,11 +114,13 @@ <!-- <artifactId>spring-boot-starter-websocket</artifactId>--> <!-- </dependency>--> <!-- <dependency> <groupId>io.netty</groupId> <artifactId>netty-all</artifactId> <version>4.1.36.Final</version> </dependency> --> <dependency> <groupId>com.alibaba</groupId> @@ -167,6 +169,30 @@ <version>21.11</version> </dependency> <!--redis--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version>2.5.9</version> </dependency> <!--redis连接池依赖--> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> </dependency> <!--jackson json工具--> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.12.6</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> <version>2.12.6</version> </dependency> </dependencies> north-glass-erp/src/main/java/com/example/erp/ErpApplication.java
@@ -3,11 +3,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCaching; import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.transaction.annotation.EnableTransactionManagement; //springboot 启动入口 @SpringBootApplication @EnableCaching @EnableScheduling @EnableTransactionManagement//事务注解 //@Transactional//在service里面有多表操作,开启事务注解 public class ErpApplication { north-glass-erp/src/main/java/com/example/erp/controller/pp/ReportingWorkController.java
@@ -9,6 +9,7 @@ import com.example.erp.exception.ServiceException; import com.example.erp.service.pp.ReportingWorkService; import com.example.erp.service.userInfo.LogService; import com.fasterxml.jackson.core.JsonProcessingException; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; @@ -160,6 +161,17 @@ throw new ServiceException(Constants.Code_600, "上工序已完工数量小于本工序报工数量,请检查"); } } @ApiOperation("mes报工接口测试") @PostMapping ("/mesReportingWork1") public Result mesReportingWork1(@RequestBody Map<String,Object> reportingWork) throws JsonProcessingException { return reportingWorkService.mesReportingWorkSv1(reportingWork); // if(aBoolean){ // return Result.success(aBoolean); // }else{ // throw new ServiceException(Constants.Code_600, "上工序已完工数量小于本工序报工数量,请检查"); // } } @ApiOperation("mes报工次破新增") @PostMapping ("/mesSaveReportingWorkWorn") public Result mesSaveReportingWorkWorn(@RequestBody Map<String,Object> reportingWork) { north-glass-erp/src/main/java/com/example/erp/dto/sd/OrderProcessSortDTO.java
New file @@ -0,0 +1,12 @@ package com.example.erp.dto.sd; import lombok.Data; @Data public class OrderProcessSortDTO { private String sort; private String process; //判断是否是复合工序 private String recombination; } north-glass-erp/src/main/java/com/example/erp/mapper/sd/OrderProcessDetailMapper.java
@@ -2,6 +2,7 @@ import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.erp.dto.sd.OrderProcessSortDTO; import com.example.erp.entity.pp.ReportingWorkDetail; import com.example.erp.entity.sd.OrderProcessDetail; import org.apache.ibatis.annotations.Mapper; @@ -38,4 +39,6 @@ String getBehindProcess(String processId, String orderNumber, String technologyNumber, String thisProcess,String orderId); List<OrderProcessDetail> selectProcessCardProgressSv(String orderId, String processId, String orderNumber, String technologyNumber, String process); List<OrderProcessSortDTO> selectProcessSort(String orderId, String processId, String orderNumber, String technologyNumber); } north-glass-erp/src/main/java/com/example/erp/service/pp/ReportingWorkService.java
@@ -3,40 +3,45 @@ import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import com.aspose.cad.internal.I.S; import com.baomidou.dynamic.datasource.annotation.DS; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper; import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper; import com.example.erp.common.AsyncQueryExecutor; import com.example.erp.common.Constants; import com.example.erp.common.Result; import com.example.erp.dto.pp.OrderNumberTransferDTO; import com.example.erp.dto.sd.OrderProcessSortDTO; import com.example.erp.entity.pp.*; import com.example.erp.entity.sd.*; import com.example.erp.entity.sd.BasicData; import com.example.erp.entity.sd.Order; import com.example.erp.entity.sd.OrderDetail; import com.example.erp.entity.sd.OrderProcessDetail; import com.example.erp.entity.userInfo.Log; import com.example.erp.entity.userInfo.SysError; import com.example.erp.exception.ServiceException; import com.example.erp.mapper.mm.FinishedOperateLogMapper; import com.example.erp.mapper.pp.*; import com.baomidou.dynamic.datasource.annotation.DS; import com.example.erp.mapper.sd.*; import com.example.erp.mapper.userInfo.LogMapper; import com.example.erp.service.mm.FinishedGoodsInventoryService; import com.example.erp.service.sd.OrderProcessDetailService; import com.example.erp.service.userInfo.LogService; import com.example.erp.service.userInfo.SysErrorService; import com.example.erp.tools.JacksonUtil; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import com.github.yulichang.wrapper.MPJLambdaWrapper; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpEntity; import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.web.client.RestTemplate; import javax.annotation.PreDestroy; import javax.annotation.Resource; import java.text.SimpleDateFormat; import java.time.LocalDate; @@ -45,6 +50,7 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.concurrent.TimeUnit; @Service @DS("pp") @@ -58,13 +64,9 @@ private final ReportingWorkDetailMapper reportingWorkDetailMapper; private final OrderMapper orderMapper; private final OrderDetailMapper orderDetailMapper; private final FlowCardMapper flowCardMapper; private final OrderProcessDetailService orderProcessDetailService; private final LogService logService; private final LogMapper logMapper; private final OrderGlassDetailMapper orderGlassDetailMapper; private final SysErrorService sysErrorService; @@ -74,6 +76,7 @@ private final ReworkMapper reworkMapper; private final BasicDataMapper basicDataMapper; private final FinishedGoodsInventoryService finishedGoodsInventoryService; private final StringRedisTemplate stringRedisTemplate; @Resource private AsyncQueryExecutor asyncExecutor; @@ -1114,7 +1117,9 @@ List<ReportingWork> ReportingWorks = reportingWorkMapper.selectJoinList(ReportingWork.class, new MPJLambdaWrapper<ReportingWork>() .select(ReportingWork::getReportingWorkId) .leftJoin(ReportingWorkDetail.class, ReportingWorkDetail::getReportingWorkId, ReportingWork::getReportingWorkId) .leftJoin(ReportingWorkDetail.class, ReportingWorkDetail::getReportingWorkId, ReportingWork::getReportingWorkId) .eq(ReportingWork::getProcessId,reportingWork.getProcessId()) .eq(ReportingWork::getThisProcess,reportingWork.getThisProcess()) .eq(ReportingWork::getDeviceName,reportingWork.getDeviceName()) @@ -1197,7 +1202,7 @@ //将异常传入数据库 SysError sysError = new SysError(); sysError.setError(e +Arrays.toString(e.getStackTrace())); sysError.setFunc("汉玻mes报工"); sysError.setFunc("mes报工"); sysErrorService.insert(sysError); throw new ServiceException(Constants.Code_500, "数据请求异常,请检查"); @@ -1584,4 +1589,80 @@ map.put("breakageReason", reportingWorkMapper.selectBasicNameByType("breakagereason")); return map; } //@Transactional(rollbackFor = Exception.class , noRollbackFor = ServiceException.class) public Result mesReportingWorkSv1(Map<String, Object> reportingWorkMap) throws JsonProcessingException { //设置回滚点 //Object savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint(); //接收解析主附表信息 String titleJson = JacksonUtil.writeValueAsString(reportingWorkMap.get("title")); String detailJson = JacksonUtil.writeValueAsString(reportingWorkMap.get("detail")); ReportingWork reportingWork = JacksonUtil.readValue(titleJson, ReportingWork.class); ReportingWorkDetail reportingWorkDetail = JacksonUtil.readValue(detailJson, ReportingWorkDetail.class); String Base_KEY = reportingWork.getProcessId()+":"+reportingWork.getThisProcess()+":"+reportingWork.getDeviceName(); String reportingWork_KEY = Base_KEY+":title"; String reportingWorkDetail_KEY = Base_KEY+":detail:"+reportingWorkDetail.getOrderNumber()+":"+reportingWorkDetail.getTechnologyNumber(); String process_KEY = reportingWork.getProcessId()+":process:"+reportingWorkDetail.getOrderNumber()+":"+reportingWorkDetail.getTechnologyNumber(); //判断工序是否存在redis中 if(!Boolean.TRUE.equals(stringRedisTemplate.hasKey(process_KEY+":"+reportingWork.getThisProcess()))){ List<OrderProcessSortDTO> orderProcessSortDTOList = orderProcessDetailMapper.selectProcessSort( reportingWork.getOrderId(), reportingWork.getProcessId(), reportingWorkDetail.getOrderNumber(), reportingWorkDetail.getTechnologyNumber() ); if (orderProcessSortDTOList.isEmpty()){ throw new ServiceException(Constants.Code_600, "未检测到流程卡信息,请检查"); } orderProcessSortDTOList.forEach(orderProcessSortDTO -> { Map<String, String> map = new HashMap<>(); map.put("sort",orderProcessSortDTO.getSort()); map.put("recombination",orderProcessSortDTO.getRecombination()); stringRedisTemplate.opsForHash().putAll(process_KEY+":"+orderProcessSortDTO.getProcess(), map); }); } String recombination = (String) stringRedisTemplate.opsForHash().get(process_KEY+":"+reportingWork.getThisProcess(),"recombination"); if (!recombination.isEmpty()){ throw new ServiceException(Constants.Code_600, "复合工序请到ERP中进行报工"); } //判断是否redis此报工编号key是否存在 if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(reportingWork_KEY))){ stringRedisTemplate.opsForHash().increment( reportingWork_KEY, "thisCompletedQuantity", reportingWork.getThisCompletedQuantity() ); } else{ stringRedisTemplate.opsForHash().putAll( reportingWork_KEY, JacksonUtil.readValueObjectToString(reportingWork,new TypeReference<Map<String, String>>() {}) ); } //判断是否redis此报工明细中key是否存在 if(Boolean.TRUE.equals(stringRedisTemplate.hasKey(reportingWorkDetail_KEY))){ stringRedisTemplate.opsForHash().increment( reportingWorkDetail_KEY, "completedQuantity", reportingWorkDetail.getCompletedQuantity() ); }else { stringRedisTemplate.opsForHash().putAll( reportingWorkDetail_KEY, JacksonUtil.readValueObjectToString(reportingWorkDetail,new TypeReference<Map<String, String>>() {}) ); } return Result.success("提交成功"); } } north-glass-erp/src/main/java/com/example/erp/tools/JacksonUtil.java
New file @@ -0,0 +1,89 @@ package com.example.erp.tools; import com.fasterxml.jackson.core.JacksonException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import org.springframework.boot.json.JsonParseException; import java.util.List; import java.util.concurrent.Callable; // 将繁琐的异常处理进行了解决 public class JacksonUtil { /** * 工具类不需要创建实例对象 */ private JacksonUtil(){ } /** * 给ObjectMapper进行单例模式,由于ObjectMapper 是线程安全的,可以复用,放置重复创建影响性能 */ private static final ObjectMapper objectMapper; static { objectMapper = new ObjectMapper(); objectMapper.registerModule(new JavaTimeModule()); } public static ObjectMapper getObjectMapper(){ return objectMapper; } public static final <T> T tryParse(Callable<T> parser) { return JacksonUtil.tryParse(parser, JacksonException.class); } public static final <T> T tryParse(Callable<T> parser, Class<? extends Exception> check) { try { return parser.call(); } catch (Exception ex) { if (check.isAssignableFrom(ex.getClass())) { throw new JsonParseException(ex); } throw new IllegalStateException(ex); } } // 普通对象和List对象共同使用 public static String writeValueAsString(Object object){ return JacksonUtil.tryParse(()->{ return JacksonUtil.getObjectMapper().writeValueAsString(object); }); } // 普通对象的反序列化 public static <T> T readValue(String str,Class<T> valueType){ return JacksonUtil.tryParse(()->{ return JacksonUtil.getObjectMapper().readValue(str,valueType); }); } public static <T> T readValueObjectToString(Object object,TypeReference<T> valueType){ String str = JacksonUtil.tryParse(()->{ return JacksonUtil.getObjectMapper().writeValueAsString(object); }); return JacksonUtil.tryParse(()->{ return JacksonUtil.getObjectMapper().readValue(str,valueType); }); } // List类型的反序列化 public static <T> T readListValue(String str,Class<?> valueType){ JavaType javaType = JacksonUtil.getObjectMapper().getTypeFactory().constructParametricType(List.class,valueType); return JacksonUtil.tryParse(()->{ return JacksonUtil.getObjectMapper().readValue(str,javaType); }); } } north-glass-erp/src/main/java/com/example/erp/tools/netty/MyChannelHandlerPool.java
@@ -2,9 +2,7 @@ import io.netty.channel.group.ChannelGroup; import io.netty.channel.group.DefaultChannelGroup; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import io.netty.util.concurrent.GlobalEventExecutor; import org.springframework.context.annotation.Bean; /** * MyChannelHandlerPool @@ -18,9 +16,9 @@ public static ChannelGroup channelGroup = new DefaultChannelGroup(GlobalEventExecutor.INSTANCE); public void sendMsg(String message){ /*public void sendMsg(String message){ channelGroup.writeAndFlush(new TextWebSocketFrame(message)); } }*/ } north-glass-erp/src/main/java/com/example/erp/tools/netty/MyWebSocketHandler.java
@@ -1,15 +1,8 @@ package com.example.erp.tools.netty; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.websocketx.TextWebSocketFrame; import java.util.HashMap; import java.util.Map; public class MyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { public class MyWebSocketHandler { // public class MyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> { /* @Override public void channelActive(ChannelHandlerContext ctx) throws Exception { System.out.println("与客户端建立连接,通道开启!"); @@ -77,6 +70,6 @@ }else{ return map; } } }*/ } north-glass-erp/src/main/java/com/example/erp/tools/netty/NettyServer.java
@@ -1,18 +1,5 @@ package com.example.erp.tools.netty; import io.netty.bootstrap.ServerBootstrap; 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.NioServerSocketChannel; import io.netty.handler.codec.http.HttpObjectAggregator; import io.netty.handler.codec.http.HttpServerCodec; import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler; import io.netty.handler.stream.ChunkedWriteHandler; /** * NettyServer Netty服务器配置 * @author zhengkai.blog.csdn.net @@ -25,7 +12,7 @@ this.port = port; } public void start() throws Exception { /*public void start() throws Exception { EventLoopGroup bossGroup = new NioEventLoopGroup(); EventLoopGroup group = new NioEventLoopGroup(); @@ -56,7 +43,7 @@ group.shutdownGracefully().sync(); // 释放线程池资源 bossGroup.shutdownGracefully().sync(); } } }*/ } north-glass-erp/src/main/resources/application.yml
@@ -18,6 +18,17 @@ multipart: max-file-size: 50MB max-request-size: 50MB redis: host: ${ip} database: 15 port: 6379 password: 123456 lettuce: pool: max-active: 8 #最大连接 max-idle: 8 #最大空闲连接 min-idle: 0 #最小空闲连接 max-wait: 1000ms #获取连接的最大等待时间 datasource: dynamic: primary: user_info #设置默认的数据源或者数据源组,默认值即为master north-glass-erp/src/main/resources/mapper/sd/OrderProcessDetailMapper.xml
@@ -292,4 +292,17 @@ </if> </select> <select id="selectProcessSort"> select a.process, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS sort, ifnull(b.nickname,"") as recombination from sd.order_process_detail as a inner join sd.basic_data as b on a.process = b.basic_name and b.basic_category = 'process' where a.order_id = #{orderId} and a.process_id = #{processId} and a.order_number =#{orderNumber} and a.technology_number =#{technologyNumber} </select> </mapper> north-glass-erp/src/test/java/com/example/erp/ErpApplicationTests.java
@@ -1,10 +1,16 @@ package com.example.erp; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.StringRedisTemplate; import static org.apache.tomcat.jni.Lock.trylock; @SpringBootTest class ErpApplicationTests { @Autowired private StringRedisTemplate stringRedisTemplate; @Test void contextLoads() { @@ -13,7 +19,8 @@ @Test void test() { // stringRedisTemplate.opsForValue().set("test", "test"); // Object test = stringRedisTemplate.opsForValue().get("test"); } }