package org.jeecg.modules.dry.service.impl; import cn.hutool.core.bean.BeanUtil; import com.alibaba.fastjson.JSONObject; import com.alibaba.fastjson.TypeReference; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import lombok.extern.slf4j.Slf4j; import org.apache.mina.core.service.IoAcceptor; import org.apache.mina.core.service.IoHandler; import org.apache.mina.core.session.IoSession; import org.jeecg.common.api.CommonAPI; import org.jeecg.common.api.vo.Result; import org.jeecg.common.config.TenantContext; import org.jeecg.common.config.mqtoken.UserTokenContext; import org.jeecg.common.constant.CommonConstant; import org.jeecg.common.system.util.JwtUtil; import org.jeecg.common.util.RedisUtil; import org.jeecg.common.util.SpringContextUtils; import org.jeecg.modules.dry.common.CacheConstants; import org.jeecg.modules.dry.entity.*; import org.jeecg.modules.dry.service.*; import org.jeecg.modules.dry.socket.ServerHandler; import org.jeecg.modules.dry.socket.SocketServerConfig; import org.jeecg.modules.dry.util.DryUtil; import org.jeecg.modules.dry.vo.*; import org.jetbrains.annotations.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.io.IOException; import java.io.ObjectOutputStream; import java.net.Socket; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Set; @Slf4j @Service public class DryRealTimeDataServiceImpl implements IDryRealTimeDataService { @Autowired private IDryOrderService dryOrderService; @Autowired private IDryOrderTrendService dryOrderTrendService; @Autowired private IDryHerbService herbService; @Autowired private IDryEquipmentService equipmentService; @Autowired private RedisUtil redisUtil; @Autowired private IDryProdRecordService prodRecordService; @Autowired private CommonAPI commonAPI; private String token; public String getTemporaryToken() { if (token == null) { RedisUtil redisUtil = SpringContextUtils.getBean(RedisUtil.class); // 模拟登录生成Token token = JwtUtil.sign("admin", "b668043e3ea4bc2d"); // 设置Token缓存有效时间为 5 分钟 redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, 5 * 60 * 1000); } return token; } @Override @Transactional public Result realTimeDataHandle(RealTimeDataVo realTimeDataVo) { TenantContext.setTenant(realTimeDataVo.getTenantid()+""); // log.info("实时数据:"+realTimeDataVo.toString()); // 1 查询或创建工单 // 1.1 从redis取出工单缓存 DryOrderVo orderVo = (DryOrderVo) redisUtil.hget(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode(), realTimeDataVo.getTenantid()+"_"+realTimeDataVo.getMachineid()); // 1.2 如果有缓存记录 if(orderVo != null && orderVo.getCode().equals(realTimeDataVo.getWorkorder())) { // 1.3 没有缓存记录再查询数据库 } else { // 根据租户id和工单号查询数据库是否有记录,有则返回,没有则新增一条再返回 orderVo = getOrSaveDryOrderVoDB(realTimeDataVo); } // 2 更新工单实时数据 // 2.1 将工单中的数据替换为最新数据 realTimeDataVo.setOrderId(orderVo.getId()); orderVo.setInitial(realTimeDataVo.getMoisture1()); orderVo.setDryTime(realTimeDataVo.getTime3()); orderVo.setDelay(realTimeDataVo.getDelay()); orderVo.setTurn(realTimeDataVo.getTurntime()); orderVo.setYield(realTimeDataVo.getWeight3()); orderVo.setStart(realTimeDataVo.getStart()); orderVo.setAuto(realTimeDataVo.getAuto()); orderVo.setPlcdisable(realTimeDataVo.getPlcdisable()); orderVo.setLowalarm(realTimeDataVo.getLowalarm()); orderVo.setWind(realTimeDataVo.getWind()); orderVo.setOriginWeight(realTimeDataVo.getWeight2()); orderVo.setWatt(realTimeDataVo.getWatt()); orderVo.setSteam(realTimeDataVo.getSteam()); orderVo.setEnvHum(realTimeDataVo.getEnvhum()); orderVo.setEnvTemp(realTimeDataVo.getEnvtemp()); orderVo.setRemain(realTimeDataVo.getAi_total_time()); orderVo.setCurRemain(realTimeDataVo.getAi_time()); orderVo.setState_fan(realTimeDataVo.getState_fan()); orderVo.setState_roller(realTimeDataVo.getState_roller()); orderVo.setState_auto(realTimeDataVo.getState_auto()); orderVo.setState_windbox(realTimeDataVo.getState_windbox()); orderVo.setState_valve(realTimeDataVo.getState_valve()); orderVo.setOrderStatus(realTimeDataVo.getWorkorder_status()); orderVo.setEqp_status(realTimeDataVo.getEqp_status()); orderVo.setEqp_state(realTimeDataVo.getEqp_state()); orderVo.setWarning(realTimeDataVo.getEqp_warning()); orderVo.setFault(realTimeDataVo.getEqp_fault()); orderVo.setLevel(realTimeDataVo.getLevel()); DryOrderTrendVo trendVo = new DryOrderTrendVo(realTimeDataVo); // 2.2 保存工单含水率变化 或 重量变化 if(realTimeDataVo.getReport_flag()) { DryProdRecord prodRecord = new DryProdRecord(); prodRecord.setReportHeadName(realTimeDataVo.getReport_head_name()); prodRecord.setReportHeadBatch(realTimeDataVo.getReport_head_batch()); prodRecord.setReportHeadNum(realTimeDataVo.getReport_head_num()); prodRecord.setReportHeadMachine(realTimeDataVo.getReport_head_machine()); prodRecord.setReportHeadAccepter(realTimeDataVo.getReport_head_accepter()); prodRecord.setReportHeadDate(realTimeDataVo.getReport_head_date()); prodRecord.setReportHeadLeader(realTimeDataVo.getReport_head_leader()); prodRecord.setReportHeadTecher(realTimeDataVo.getReport_head_techer()); prodRecord.setReportCheckField(realTimeDataVo.getReport_check_field()?1:0); prodRecord.setReportCheckFile(realTimeDataVo.getReport_check_file()?1:0); prodRecord.setReportCheckTag(realTimeDataVo.getReport_check_tag()?1:0); prodRecord.setReportCheckTool(realTimeDataVo.getReport_check_tool()?1:0); prodRecord.setReportCheckMan(realTimeDataVo.getReport_check_man()); prodRecord.setReportCheckStatus(realTimeDataVo.getReport_check_status()?1:0); prodRecord.setReportCheckQa(realTimeDataVo.getReport_check_qa()); prodRecord.setReportCheckRecord(realTimeDataVo.getReport_check_record()); prodRecord.setReportProductView(realTimeDataVo.getReport_product_view()?1:0); prodRecord.setReportProductWind(realTimeDataVo.getReport_product_wind()?1:0); prodRecord.setReportProductSun(realTimeDataVo.getReport_product_sun()?1:0); prodRecord.setReportProductLowDry(realTimeDataVo.getReport_product_low_dry()?1:0); prodRecord.setReportProductDry(realTimeDataVo.getReport_product_dry()?1:0); prodRecord.setReportProductStart(realTimeDataVo.getReport_product_start()); prodRecord.setReportProductEnd(realTimeDataVo.getReport_product_end()); prodRecord.setReportProductTotal(realTimeDataVo.getReport_product_total()); prodRecord.setReportProductCheck(realTimeDataVo.getReport_product_check()?1:0); prodRecord.setReportProductMan1(realTimeDataVo.getReport_product_man1()); prodRecord.setReportProductMan2(realTimeDataVo.getReport_product_man2()); prodRecord.setReportProductWeight(realTimeDataVo.getReport_product_weight()); prodRecord.setReportProductWaste(realTimeDataVo.getReport_product_waste()); prodRecord.setReportProductUse(realTimeDataVo.getReport_product_use()); prodRecord.setReportProductQa(realTimeDataVo.getReport_product_qa()); prodRecord.setReportCleanMachine(realTimeDataVo.getReport_clean_machine()?1:0); prodRecord.setReportCleanWaste(realTimeDataVo.getReport_clean_waste()?1:0); prodRecord.setReportCleanTool(realTimeDataVo.getReport_clean_tool()?1:0); prodRecord.setReportCleanDoor(realTimeDataVo.getReport_clean_door()?1:0); prodRecord.setReportCleanBox(realTimeDataVo.getReport_clean_box()?1:0); prodRecord.setReportCleanRecord(realTimeDataVo.getReport_clean_record()?1:0); prodRecord.setReportCleanDate(realTimeDataVo.getReport_clean_date()); prodRecord.setReportCleanMan(realTimeDataVo.getReport_clean_man()); prodRecord.setReportCleanConfirm(realTimeDataVo.getReport_clean_confirm()?1:0); prodRecord.setReportCleanQa(realTimeDataVo.getReport_clean_qa()); prodRecordService.save(prodRecord); } saveOrderTrendVo(trendVo, orderVo); orderVo.setTrendVo(trendVo); orderVo.getBellowsTemp().put(realTimeDataVo.getTime3(), realTimeDataVo.getTemp2()); // 2.3 更新到redis缓存 redisUtil.hset(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode(), realTimeDataVo.getTenantid()+"_"+realTimeDataVo.getMachineid(),orderVo, 600000); return Result.ok(); } /** * 根据租户id和工单号查询数据库是否有记录,有则返回,没有则新增一条 * @param realTimeDataVo * @return */ private DryOrderVo getOrSaveDryOrderVoDB(RealTimeDataVo realTimeDataVo) { DryOrderVo orderVo; LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryOrder::getCode, realTimeDataVo.getWorkorder()); queryWrapper.eq(DryOrder::getTenantId, realTimeDataVo.getTenantid()); // 1 查询数据库 DryOrder one = dryOrderService.getOne(queryWrapper); // 2 数据库有记录,更新到缓存 if (one != null) { // 转换为缓存数据结构 orderVo = BeanUtil.toBean(one, DryOrderVo.class); if (one.getTemps() != null) { Map map = JSONObject.parseObject(one.getTemps(), new TypeReference>(){}); orderVo.setBellowsTemp(map); } // 查询称重记录,添加到缓存数据结构 List trendVos = dryOrderTrendService.listByOrderId(one.getId()); if (trendVos != null && trendVos.size() > 0) { DryOrderTrendVo oldVo = trendVos.get(trendVos.size() - 1); orderVo.setTrendVo(oldVo); orderVo.setDetailList(trendVos); } // 3 数据库没有则新增一条数据 } else { orderVo = saveNewOrder(realTimeDataVo); } return orderVo; } /** * 保存新工单 * @param realTimeDataVo * @return */ @NotNull private DryOrderVo saveNewOrder(RealTimeDataVo realTimeDataVo) { DryOrderVo orderVo; // 查询药材 DryHerb herb = queryHerbByIndexTenant(realTimeDataVo); // 查询设备 DryEquipment equ = queryEquipmentByCodeTenant(realTimeDataVo); // 创建新工单 orderVo = new DryOrderVo(realTimeDataVo); orderVo.setHerbId(herb.getId()); orderVo.setEquId(equ.getId()); DryOrder dryOrder = BeanUtil.toBean(orderVo, DryOrder.class); boolean save = dryOrderService.save(dryOrder); return orderVo; } /** * 查询设备,新设备则添加到设备主数据 * @param realTimeDataVo * @return */ private DryEquipment queryEquipmentByCodeTenant(RealTimeDataVo realTimeDataVo) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryEquipment::getTenantId, realTimeDataVo.getTenantid()); queryWrapper.eq(DryEquipment::getCode, realTimeDataVo.getMachineid()); DryEquipment one = equipmentService.getOne(queryWrapper); if (one == null) { one = new DryEquipment(realTimeDataVo); equipmentService.save(one); } return one; } /** * 查询药材,新药材添加到数据库 * @param realTimeDataVo * @return */ private DryHerb queryHerbByIndexTenant(RealTimeDataVo realTimeDataVo) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryHerb::getTenantId, realTimeDataVo.getTenantid()); queryWrapper.eq(DryHerb::getCode, realTimeDataVo.getIndex()); DryHerb one = herbService.getOne(queryWrapper); if (one == null) { one = new DryHerb(realTimeDataVo); herbService.save(one); } return one; } /** * 保存含水率变化记录 * @param trendVo * @param orderVo */ private void saveOrderTrendVo(DryOrderTrendVo trendVo, DryOrderVo orderVo) { //判断 实时含水率 或 实时重量有没有变化,有变化则更新 if(orderVo.getTrendVo() == null || trendVo.getWeight() < orderVo.getTrendVo().getWeight() ) { DryOrder byId = dryOrderService.getById(orderVo.getId()); // 将最新结果更新到工单 if (byId != null) { BeanUtil.copyProperties(orderVo, byId); byId.setTemps(JSONObject.toJSONString(orderVo.getBellowsTemp())); dryOrderService.updateById(byId); } // 保存含水率变化 orderVo.getDetailList().add(trendVo); DryOrderTrend dryOrderTrend = BeanUtil.toBean(trendVo, DryOrderTrend.class); dryOrderTrendService.save(dryOrderTrend); } } /** * 查询机台实时数据 * @param realTimeDataVo * @return */ @Override public Result queryMachineRealTImeData(RealTimeDataVo realTimeDataVo) { TenantContext.setTenant(realTimeDataVo.getTenantid()+""); LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryEquipment::getTenantId, realTimeDataVo.getTenantid()); queryWrapper.eq(DryEquipment::getEnable, "Y"); List dryEquipments = equipmentService.list(queryWrapper); List list = new ArrayList<>(); List dList = new ArrayList<>(); DryOrderVo orderVo = (DryOrderVo) redisUtil.hget(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode(), realTimeDataVo.getTenantid() + "_" + realTimeDataVo.getMachineid()); try { if (dryEquipments != null && dryEquipments.size() > 0) { dryEquipments.stream().forEach(item -> { DryOrderVo order = (DryOrderVo) redisUtil.hget(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode(), realTimeDataVo.getTenantid() + "_" + item.getCode()); if (order != null) { double v = order.getOriginWeight() - order.getYield(); list.add(item.getName().substring(0, item.getName().indexOf('#')+1)); if (v > 0 && order.getDryTime()>0) { DecimalFormat df = new DecimalFormat("#.00"); dList.add(Double.valueOf(df.format(v / order.getDryTime() * 60))); } else { dList.add(50d); } } }); } if (orderVo != null) { orderVo.setCompEqpNum(list); orderVo.setCompEqpEffic(dList); } }catch (Exception e) { e.printStackTrace(); } return Result.ok(orderVo); } @Override public Result sendSocketMsg(CommandMessageVo msgVo) { DryEquipment dryEquipment = equipmentService.selectByTenantIdEquipmentId(msgVo.getTenantId() + "", msgVo.getMachineId()); log.info("获取设备:" + dryEquipment.toString()); // managedSessions.keySet().forEach(addr -> { // ObjectOutputStream oos = null; try { // Socket socket = SocketServerConfig.clientMap.get(addr); IoSession session = ServerHandler.clientSocket.get(dryEquipment.getIp()); if (session == null) { return Result.error("未获取到session,请检查客户端配置或设备ip配置是否正常"); } SocketMsgVo smv = new SocketMsgVo(msgVo); session.write(JSONObject.toJSONString(smv)); // oos = new ObjectOutputStream(socket.getOutputStream()); // String s = JSONObject.toJSONString(new SocketMsgVo(msgVo)); // oos.writeUTF(s); // oos.flush(); } catch (Exception e) { throw new RuntimeException(e); } finally { } // }); return Result.OK(); } @Override public Result queryWorkshopStatistics(RealTimeDataVo realTimeDataVo) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(DryEquipment::getTenantId, realTimeDataVo.getTenantid()); queryWrapper.eq(DryEquipment::getEnable, "Y"); List dryEquipments = equipmentService.list(queryWrapper); DryOrderVo orderVo = new DryOrderVo(); if (dryEquipments != null && dryEquipments.size() > 0) { dryEquipments.stream().forEach(item -> { DryOrderVo order = (DryOrderVo) redisUtil.hget(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode(), realTimeDataVo.getTenantid() + "_" + item.getCode()); if (order != null) { orderVo.setEnvHum(order.getEnvHum()); orderVo.setEnvTemp(order.getEnvTemp()); double watt = order.getWatt() - order.getDetailList().get(0).getWatt(); orderVo.setWatt(orderVo.getWatt()==null? watt : orderVo.getWatt() + watt); double steam = order.getSteam() - order.getDetailList().get(0).getSteam(); orderVo.setSteam(orderVo.getSteam()==null? steam : orderVo.getSteam() + steam); orderVo.setOriginWeight(orderVo.getOriginWeight()==null? order.getOriginWeight(): orderVo.getOriginWeight() + order.getOriginWeight()); double yield = order.getOriginWeight()*(1-(order.getInitial()/100))/(1-(order.getTarget()/100)); orderVo.setYield(orderVo.getYield()==null? yield: orderVo.getYield() + yield); double sub = order.getOriginWeight() - order.getYield(); orderVo.setReduce(orderVo.getReduce()==null? sub: orderVo.getReduce() + sub); } }); } //redisUtil.get(CacheConstants.RedisKeyEnum.WORK_ORDER.getCode() return Result.OK(orderVo); } }