廖井涛
2025-11-19 a60803afc8981d10cfea1da44c26c4e50f0f6d82
north-glass-erp/src/main/java/com/example/erp/service/pp/ReportingWorkService.java
@@ -3,40 +3,44 @@
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.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.RedisCallback;
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 +49,8 @@
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
@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;
@@ -270,19 +273,7 @@
        List<ReportingWorkDetail> reportingWorkDetails = JSONArray.parseArray(
                JSONObject.toJSONString(reportingWorkJson.get("detail")), ReportingWorkDetail.class);
        // 报工编号
        Integer maxId = reportingWorkMapper.selectMaxReportingWorkId();
        if (maxId == null) {
            maxId = 0;
        }
        String formattedNumber = String.format("%04d", maxId + 1);
        // 格式化当前日期
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        String formattedDate = dateFormat.format(currentDate);
        String reportingWorkId = "BG" + formattedDate + formattedNumber;
        reportingWork.setReportingWorkId(reportingWorkId);
        // 处理工序 ID
        String[] processIdStr = reportingWork.getProcessId() != null
@@ -306,9 +297,23 @@
            reportingWork.setReportingWorkTime(LocalDateTime.now());
        }
        // 是否线补 1现补 0未现补
        // 是否现补 1现补 0未现补
        int isPatch = reportingWorkJson.getInteger("isPatch") != null
                ? reportingWorkJson.getInteger("isPatch") : 0;
        // 报工编号
        Integer maxId = reportingWorkMapper.selectMaxReportingWorkId();
        if (maxId == null) {
            maxId = 0;
        }
        String formattedNumber = String.format("%04d", maxId + 1);
        // 格式化当前日期
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        String formattedDate = dateFormat.format(currentDate);
        String reportingWorkId = "BG" + formattedDate + formattedNumber;
        reportingWork.setReportingWorkId(reportingWorkId);
        // 主表插入
        reportingWorkMapper.insert(reportingWork);
@@ -433,7 +438,7 @@
                reportingWorkDetailMapper.insert(reportingWorkDetail);
            }
            // 更新流程卡报工数量
            // 判断最后一道工序,更新流程卡报工数量
            if (reportingWork.getNextProcess() == null || reportingWork.getNextProcess().isEmpty()) {
                LambdaUpdateWrapper<FlowCard> flowCardLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                flowCardLambdaUpdateWrapper
@@ -649,22 +654,22 @@
        String nowDate = LocalDate.now().toString();
        //获取报工工序是否为复合工程
        String laminating = reportingWorkMapper.getProcessLaminating(thisProcess);
//合片工序
if (laminating.indexOf("step")!=-1){
    LambdaUpdateWrapper
                <ReportingWork> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper
                .eq(ReportingWork::getProcessId, processIdStr[0])
                .eq(ReportingWork::getThisProcess, reportingWork.get("process"))
                .eq(ReportingWork::getReviewedState, 0)
                .setSql("reviewed_state =1")
                .set(ReportingWork::getReviewed, userName)
                .set(ReportingWork::getExamineTime, nowDate);
        reportingWorkMapper.update(null, updateWrapper);
}else {
    reportingWorkMapper.ReviewReportingWorkMp(processIdStr[0],reportingWork.get("process"),technologyStr,userName);
        //合片工序
        if (laminating.indexOf("step")!=-1){
            LambdaUpdateWrapper
                        <ReportingWork> updateWrapper = new LambdaUpdateWrapper<>();
                updateWrapper
                        .eq(ReportingWork::getProcessId, processIdStr[0])
                        .eq(ReportingWork::getThisProcess, reportingWork.get("process"))
                        .eq(ReportingWork::getReviewedState, 0)
                        .setSql("reviewed_state =1")
                        .set(ReportingWork::getReviewed, userName)
                        .set(ReportingWork::getExamineTime, nowDate);
                reportingWorkMapper.update(null, updateWrapper);
        }else {
            reportingWorkMapper.ReviewReportingWorkMp(processIdStr[0],reportingWork.get("process"),technologyStr,userName);
}
        }
        return true;
    }
@@ -1112,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())
@@ -1127,12 +1134,7 @@
            //判断报工表是否存在,不存在则新增报工主副表数据,存在则修改副表数据
            if(ReportingWorks.isEmpty()){
                //获取当前最大报工单号生成报工单号
                String formattedNumber = String.format("%04d", reportingWorkMapper.selectMaxReportingWorkId() + 1);
                //格式化当前日期
                Date currentDate = new Date();
                SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
                String formattedDate = dateFormat.format(currentDate);
                String reportingWorkId = "BG" + formattedDate + formattedNumber;
                String reportingWorkId = this.getTodayMaxReportingId();
                reportingWork.setReportingWorkId(reportingWorkId);
                reportingWorkDetail.setReportingWorkId(reportingWorkId);
@@ -1195,7 +1197,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, "数据请求异常,请检查");
@@ -1560,13 +1562,13 @@
    public List<BasicDataProduce> selectEquipmentByProcessSv(String process) {
           return reportingWorkMapper.SelectWorkBasicDeviceMp(process);
        }
    }
    public String saveWorkStorage(Map<String, Object> object) {
            //List<Map<String, Object>> flowCard = reportingWorkMapper.getStorageData();
            //finishedGoodsInventoryService.addSelectWarehousing(object);
            return null;
        }
    }
    public Map<String, Object> mesBasicDataSv() {
        Map<String, Object> map = new HashMap<>();
@@ -1582,4 +1584,204 @@
        map.put("breakageReason", reportingWorkMapper.selectBasicNameByType("breakagereason"));
        return map;
    }
    //@Transactional(rollbackFor = Exception.class , noRollbackFor = ServiceException.class)
    public Result mesReportingWorkSvToRedis(Map<String, Object> reportingWorkMap) throws JsonProcessingException, InterruptedException {
        //设置回滚点
        //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:"+reportingWork.getProcessId()+"/"+reportingWorkDetail.getTechnologyNumber()+":"+reportingWork.getThisProcess()+":"+reportingWork.getDeviceName();
        String reportingWork_KEY = Base_KEY+":title";
        String reportingWorkDetail_KEY = Base_KEY+":detail:"+reportingWorkDetail.getOrderNumber();
        String process_KEY = "reportingWork:"+reportingWork.getProcessId()+"/"+reportingWorkDetail.getTechnologyNumber()+":process";
        //判断锁是否存在,存在等待5秒
        if(Boolean.TRUE.equals(stringRedisTemplate.hasKey("lock:reportingWork"))){
            Thread.sleep(5*1000);
            if(Boolean.TRUE.equals(stringRedisTemplate.hasKey("lock:reportingWork"))){
                throw new ServiceException(Constants.Code_600, "当前服务器正在处理报工数据,请稍后重试!");
            }
        }
        //判断工序是否存在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("提交成功");
    }
    public void redisToMysqlReportingWork() throws InterruptedException {
        if(Boolean.TRUE.equals(stringRedisTemplate.hasKey("lock:reportingWork"))){
            throw new ServiceException(Constants.Code_600, "定时任务:当前服务器正在处理报工数据,请稍后重试!");
        }
        //获取所有key
        String pattern = "reportingWork:*";
        Set<String> keys = stringRedisTemplate.keys(pattern);
        //判断redis中是否存在报工数据,存在则添加锁 并且修改key转移到上传mysql的key中
        if (keys != null && !keys.isEmpty()) {
            //添加锁
            stringRedisTemplate.opsForValue().set("lock:reportingWork","1",60, TimeUnit.SECONDS);
            if(Boolean.FALSE.equals(stringRedisTemplate.hasKey("upload:*" ))){
                keys.forEach(key -> {
                    stringRedisTemplate.rename(key, "upload:" + key);
                });
            }
        }
        //添加暂停时间,方式获取map时,redis中数据还在变化
        Thread.sleep(200);
        // 保存日志,把redis中的数据保存到日志中
        Map<String, Map<Object, Object>> map = this.getAllHashesByPattern("upload:reportingWork:*");
        Log log = new Log();
        log.setContent(JacksonUtil.writeValueAsString(map));
        log.setFunction("reportingWorkRedisToMysql");
        log.setOperator("自动定时报工");
        logService.saveLog(log);
        //删除锁,让接口继续接收报工
        stringRedisTemplate.delete("lock:reportingWork");
        //获取到所有参数后清空redis库
        // stringRedisTemplate.getConnectionFactory().getConnection().flushDb();
        //从redis中获取所有报工主表数据
        String titleKeyString = "upload:reportingWork:*:title";
        Set<String> titleKeys = stringRedisTemplate.keys(titleKeyString);
        if (titleKeys != null) {
            titleKeys.forEach(titleKey -> {
                ReportingWork reportingWork = JSON.parseObject(
                        JSONObject.toJSONString(stringRedisTemplate.opsForHash().entries(titleKey))
                        , ReportingWork.class
                );
                //获取当天一共有多少个报工编号
                String reportingWorkId = this.getTodayMaxReportingId();
                //添加报工编号
                reportingWork.setReportingWorkId(reportingWorkId);
                //往主表插入报工主数据
                reportingWorkMapper.insert(reportingWork);
                String detailKeyString = titleKey.replace(":title", ":detail:*");
                Set<String> detailKeys = stringRedisTemplate.keys(detailKeyString);
                if (detailKeys != null) {
                    detailKeys.forEach(detailKey -> {
                        ReportingWorkDetail reportingWorkDetail = JSON.parseObject(
                                JSONObject.toJSONString(stringRedisTemplate.opsForHash().entries(detailKey))
                                , ReportingWorkDetail.class
                        );
                        reportingWorkDetail.setReportingWorkId(reportingWorkId);
                        reportingWorkDetailMapper.insert(reportingWorkDetail);
                        //根据订单id,订单序号,以及小片序号 更新小片流程的完工数量以及刺破数量
                        LambdaUpdateWrapper<OrderProcessDetail> updateWrapper = new LambdaUpdateWrapper<>();
                        updateWrapper.eq(OrderProcessDetail::getOrderNumber, reportingWorkDetail.getOrderNumber())
                                .eq(OrderProcessDetail::getProcessId, reportingWork.getProcessId())
                                .eq(OrderProcessDetail::getOrderId, reportingWork.getOrderId())
                                .eq(OrderProcessDetail::getProcess, reportingWork.getThisProcess())
                                .eq(OrderProcessDetail::getTechnologyNumber, reportingWorkDetail.getTechnologyNumber())
                                .setSql("reporting_work_num_count = reporting_work_num_count +" + reportingWorkDetail.getCompletedQuantity())
                                .setSql("reporting_work_num =reporting_work_num +" + reportingWorkDetail.getCompletedQuantity());
                        orderProcessDetailMapper.update(null, updateWrapper);
                    });
                }
            });
        }
        Set<String> uploadKeys = stringRedisTemplate.keys("upload:reportingWork:*");
        if (uploadKeys != null) {
            stringRedisTemplate.delete(uploadKeys);
        }
    }
    public String getTodayMaxReportingId() {
        String formattedNumber = String.format("%04d", reportingWorkMapper.selectMaxReportingWorkId() + 1);
        //格式化当前日期
        Date currentDate = new Date();
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyMMdd");
        String formattedDate = dateFormat.format(currentDate);
        return "BG" + formattedDate + formattedNumber;
    }
/*获取所有的参数转*/
    public Map<String, Map<Object, Object>> getAllHashesByPattern(String pattern) {
        Set<String> keys = stringRedisTemplate.keys(pattern);
        Map<String, Map<Object, Object>> result = new HashMap<>();
        if (keys != null) {
            for (String key : keys) {
                Map<Object, Object> hashData = stringRedisTemplate.opsForHash().entries(key);
                result.put(key, hashData);
            }
        }
        return result;
    }
}