guoyujie
2025-11-17 7fdc12195ab810476f01f6d332cbcd0a271effdb
提交部分报工存入redis功能实现
11个文件已修改
2个文件已添加
324 ■■■■ 已修改文件
north-glass-erp/pom.xml 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/ErpApplication.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/controller/pp/ReportingWorkController.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/dto/sd/OrderProcessSortDTO.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/mapper/sd/OrderProcessDetailMapper.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/service/pp/ReportingWorkService.java 109 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/tools/JacksonUtil.java 89 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/tools/netty/MyChannelHandlerPool.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/tools/netty/MyWebSocketHandler.java 15 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/java/com/example/erp/tools/netty/NettyServer.java 17 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/resources/application.yml 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/main/resources/mapper/sd/OrderProcessDetailMapper.xml 13 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
north-glass-erp/src/test/java/com/example/erp/ErpApplicationTests.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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");
    }
}