优化流利架入出库逻辑,修改日志级别

This commit is contained in:
liuhanqing
2025-08-07 14:44:15 +08:00
parent 37e026adb7
commit 689792e285
19 changed files with 442 additions and 262 deletions

View File

@@ -20,20 +20,20 @@ public class ToWcsApiController {
/**
* 推送CTU出库任务
*/
*//*
//@PostMapping("/pushOutMydoJob")
@Scheduled(fixedDelay=10000)
public void pushOutMydoJob() {
toWcsService.pushOutMydoJob();
}
/**
*//**
* 推送CTU流利架空料箱入库任务
*/
*//*
@Scheduled(fixedDelay=10000)
public void pushInMydoJob() {
toWcsService.pushInMydoJob();
}
}*/
/**
* 推送agv搬运作业

View File

@@ -12,6 +12,10 @@ import com.ruoyi.log.service.IRequestLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* 作业统计 Controller
*/
@@ -109,4 +113,20 @@ public class ToWmsApiController {
requestLogService.insertRequestLog(requestLog);
return ajaxResult;
}
/**
* ctu取完箱子反馈
* @param map{
* "lljCode"
* }
* @return
*/
@PostMapping("/takeCompleted")
public AjaxResult takeCompleted(@RequestBody Map<String, Object> map) {
AjaxResult ajaxResult = toWmsService.takeCompleted(map);
RequestLog requestLog = requestLogService.getRequestLog(JSONUtil.toJsonStr(map), "takeCompleted",ajaxResult);
requestLogService.insertRequestLog(requestLog);
return ajaxResult;
}
}

View File

@@ -23,4 +23,6 @@ public interface IToWmsService {
AjaxResult getJob(MydoJob mydoJob);
AjaxResult startSignal(MydoJob mydoJob);
AjaxResult takeCompleted(Map<String, Object> map);
}

View File

@@ -43,8 +43,8 @@ public class ToWcsServiceImpl implements IToWcsService {
private IMydoJobService mydoJobService;
public static final String PUSH_OUT_MYDO_JOB = "http://localhost:8081/wcs2Wms/api/receiveOutMydoJob";
public static final String PUSH_IN_MYDO_JOB = "http://localhost:8081/agv/wcs2Wms/api/receiveInMydoJob";
public static final String PUSH_AGV_MOVE_JOB = "http://localhost:8081/api/receiveAgvMoveJob";
public static final String PUSH_IN_MYDO_JOB = "http://localhost:8081/wcs2Wms/api/receiveInMydoJob";
public static final String PUSH_AGV_MOVE_JOB = "http://localhost:8081/agv/api/receiveAgvMoveJob";
public static final String OUT_MYDOJOB_MS = "http://localhost:8081/wcs2Wms/api/outMydojobMakesure";
public static final String CANCEL_MYDOJOB = "http://localhost:8081/wcs2Wms/api/cancelMydoJob";
@@ -84,7 +84,6 @@ public class ToWcsServiceImpl implements IToWcsService {
MydoJob mydoJobParam = new MydoJob();
mydoJobParam.setInOrOut("1");
mydoJobParam.setStatus("1");
mydoJobParam.setExitId("fluent");
mydoJobParam.setEntranceId("fluent");
List<MydoJob> mydoJobs = mydoJobService.selectMydoJobListApi(mydoJobParam);
if (CollUtil.isNotEmpty(mydoJobs)){

View File

@@ -1,50 +1,32 @@
package com.ruoyi.api.service.impl;
import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import com.ruoyi.api.domain.WmsJobRequest;
import com.ruoyi.api.mapper.JobStatisticsMapper;
import com.ruoyi.api.service.IJobStatisticsService;
import com.ruoyi.api.service.IToWmsService;
import com.ruoyi.bas.cargoSpace.domain.BasCargoSpace;
import com.ruoyi.bas.cargoSpace.mapper.BasCargoSpaceMapper;
import com.ruoyi.bas.cargoSpace.service.IBasCargoSpaceService;
import com.ruoyi.bas.container.domain.BasContainer;
import com.ruoyi.bas.container.service.IBasContainerService;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.bas.taskNo.service.IBasTaskNoService;
import com.ruoyi.bas.warehouse.domain.BasWarehouse;
import com.ruoyi.bas.warehouse.service.IBasWarehouseService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.MessageUtils;
import com.ruoyi.job.mydojob.domain.MydoJob;
import com.ruoyi.job.mydojob.mapper.MydoJobMapper;
import com.ruoyi.job.mydojob.service.IMydoJobService;
import com.ruoyi.job.mydojobdetail.domain.MydoJobDetail;
import com.ruoyi.job.mydojobdetail.service.IMydoJobDetailService;
import com.ruoyi.log.domain.RequestLog;
import com.ruoyi.log.service.IRequestLogService;
import com.ruoyi.out.outStockout.service.IOutStockoutService;
import com.ruoyi.out.outStockoutDetail.domain.OutStockoutDetail;
import com.ruoyi.out.outStockoutDetail.service.IOutStockoutDetailService;
import com.ruoyi.out.tagTask.domain.TagTask;
import com.ruoyi.out.tagTask.service.ITagTaskService;
import com.ruoyi.out.tagTask.thread.TagOutReadThread;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.bridge.Message;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -178,6 +160,8 @@ public class ToWmsServiceImpl implements IToWmsService {
tagTask.setFloor("0");
tagTaskService.insertTagTask(tagTask);
}
//开启线程
new Thread(new TagOutReadThread(basTag)).start();
}
break;
case "3":
@@ -269,4 +253,17 @@ public class ToWmsServiceImpl implements IToWmsService {
return AjaxResult.success();
}
}
@Override
public AjaxResult takeCompleted(Map<String, Object> map) {
String lljCode = Convert.toStr(map.get("lljCode"));
BasTag basTagParam = new BasTag();
basTagParam.setPickAdd(lljCode);
List<BasTag> basTags = iBasTagService.selectBasTagList(basTagParam);
for (BasTag basTag : basTags) {
basTag.setSpare2("2");
iBasTagService.updateBasTag(basTag);
}
return AjaxResult.success();
}
}

View File

@@ -7,7 +7,7 @@ import com.ruoyi.common.core.domain.BaseEntity;
/**
* 电子标签对象 bas_tag
*
*
* @author ruoyi
* @date 2025-07-11
*/
@@ -50,92 +50,92 @@ public class BasTag extends BaseEntity
@Excel(name = "备用3")
private String spare3;
public void setId(Long id)
public void setId(Long id)
{
this.id = id;
}
public Long getId()
public Long getId()
{
return id;
}
public void setIp(String ip)
public void setIp(String ip)
{
this.ip = ip;
}
public String getIp()
public String getIp()
{
return ip;
}
public void setPickAdd(String pickAdd)
public void setPickAdd(String pickAdd)
{
this.pickAdd = pickAdd;
}
public String getPickAdd()
public String getPickAdd()
{
return pickAdd;
}
public void setTrayCode(String trayCode)
public void setTrayCode(String trayCode)
{
this.trayCode = trayCode;
}
public String getTrayCode()
public String getTrayCode()
{
return trayCode;
}
public void setCurNum(String curNum)
public void setCurNum(String curNum)
{
this.curNum = curNum;
}
public String getCurNum()
public String getCurNum()
{
return curNum;
}
public void setSendCompleted(String sendCompleted)
public void setSendCompleted(String sendCompleted)
{
this.sendCompleted = sendCompleted;
}
public String getSendCompleted()
public String getSendCompleted()
{
return sendCompleted;
}
public void setSpare1(String spare1)
public void setSpare1(String spare1)
{
this.spare1 = spare1;
}
public String getSpare1()
public String getSpare1()
{
return spare1;
}
public void setSpare2(String spare2)
public void setSpare2(String spare2)
{
this.spare2 = spare2;
}
public String getSpare2()
public String getSpare2()
{
return spare2;
}
public void setSpare3(String spare3)
public void setSpare3(String spare3)
{
this.spare3 = spare3;
}
public String getSpare3()
public String getSpare3()
{
return spare3;
}

View File

@@ -12,6 +12,7 @@ import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.api.service.IToWcsService;
import com.ruoyi.bas.BasProduct.domain.BasProduct;
import com.ruoyi.bas.BasProduct.service.IBasProductService;
import com.ruoyi.bas.basJobId.service.IBasJobIdService;
@@ -58,6 +59,8 @@ public class CheckStockinServiceImpl implements ICheckStockinService
private IBasProductService productService;
@Autowired
private IBasStockService basStockService;
@Autowired
private IToWcsService iToWcsService;
/**
* 查询盘库单据主信息
@@ -236,6 +239,7 @@ public class CheckStockinServiceImpl implements ICheckStockinService
HashMap<String, String> map = new HashMap<>();
map.put("v_stock_check_id", currentCheckStock.getStockCheckId());
checkStockinMapper.autoAllot(map);
iToWcsService.pushOutMydoJob();
if ("10".equals(map.get("v_result"))){
return AjaxResult.success();
}else {

View File

@@ -480,7 +480,7 @@ public class MydoJobServiceImpl implements IMydoJobService {
insertHistory(jobId);
//通知wcs
AjaxResult ajaxResult = iToWcsService.cancelTaskByTaskNo(job.getTaskNo());
if (!ajaxResult.isSuccess()){
if (ajaxResult.isSuccess()){
return AjaxResult.success();
}else {
throw new RuntimeException(Convert.toStr(ajaxResult.get("msg")));
@@ -504,6 +504,7 @@ public class MydoJobServiceImpl implements IMydoJobService {
map.put("v_stock_id", stockId);
map.put("v_exit_id", exitId);
mydoJobMapper.pointOut(map);
iToWcsService.pushOutMydoJob();
String result = map.get("v_result").toString();
if ("10".equals(result)) {
msg = "操作成功!";

View File

@@ -66,7 +66,6 @@ public class RequestLogServiceImpl implements IRequestLogService
if (requestLog.getIsSuccessful().equals("1")){
return requestLogMapper.insertRequestLog(requestLog);
}else {
log.error("请求失败:" + requestLog.getErrorDetails());
return 0;
}
}

View File

@@ -7,6 +7,7 @@ import java.util.HashMap;
import java.util.List;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.api.service.IToWcsService;
import com.ruoyi.bas.basJobId.service.IBasJobIdService;
import com.ruoyi.common.annotation.DataScope;
import com.ruoyi.common.core.domain.AjaxResult;
@@ -42,6 +43,8 @@ public class OutStockoutServiceImpl implements IOutStockoutService
private OutStockoutDetailMapper outStockoutDetailMapper;
@Autowired
private IOutStockoutDetailService outStockoutDetailService;
@Autowired
private IToWcsService toWcsService;
/**
* 查询出库主单
@@ -178,6 +181,7 @@ public class OutStockoutServiceImpl implements IOutStockoutService
if (detail.getAllotQuantity().compareTo(detail.getQuantity()) < 0){
map.put("v_stockout_detail_id", detail.getStockoutDetailId());
outStockoutMapper.autoAllot(map);
toWcsService.pushOutMydoJob();
if (!"10".equals(map.get("v_result"))){
stringBuilder.append(",").append(map.get("v_resultString"));
}

View File

@@ -108,12 +108,13 @@ public class TagTaskController extends BaseController
/**
* 传入电子标签信息
*/
@Scheduled(fixedDelay = 2000)
//@Scheduled(fixedDelay = 2000)
public void tagOutManager() throws IOException {
tagTaskService.tagOutManager();
}
@Scheduled(fixedDelay = 2000)
public void tagInManager(){
tagTaskService.tagInManager();
}

View File

@@ -1,7 +1,24 @@
package com.ruoyi.out.tagTask.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.job.mydojob.domain.MydoJob;
import com.ruoyi.job.mydojob.service.IMydoJobService;
import com.ruoyi.out.tagTask.domain.TagTask;
import com.ruoyi.out.tagTask.mapper.TagTaskMapper;
import com.ruoyi.out.tagTask.service.ITagTaskService;
import com.ruoyi.out.tagTask.thread.TagInReadThread;
import com.ruoyi.out.tagTask.util.ElectronicTagClient;
import com.ruoyi.pda.domain.TrayCodeMsg;
import com.ruoyi.pda.service.PdaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
@@ -9,28 +26,6 @@ import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.IdUtil;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.job.mydojob.domain.MydoJob;
import com.ruoyi.job.mydojob.service.IMydoJobService;
import com.ruoyi.out.tagTask.thread.TagReadThread;
import com.ruoyi.out.tagTask.util.ElectronicTagClient;
import com.ruoyi.pda.domain.TrayCodeMakeSure;
import com.ruoyi.pda.domain.TrayCodeMsg;
import com.ruoyi.pda.service.PdaService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.out.tagTask.mapper.TagTaskMapper;
import com.ruoyi.out.tagTask.domain.TagTask;
import com.ruoyi.out.tagTask.service.ITagTaskService;
import static io.netty.util.internal.StringUtil.byteToHexString;
/**
* 电子标签任务Service业务层处理
*
@@ -148,7 +143,7 @@ public class TagTaskServiceImpl implements ITagTaskService {
tagTaskMapper.updateTagTask(tagTask);
log.info("下发电子标签:ip:" + basTag.getIp() + ",id:" + basTag.getId() + "数量:" + basTag.getCurNum());
//开线程一直读取电子标签数据
new Thread(new TagReadThread(tagTaskMapper,basTagService,pdaService)).start();
}
} catch (Exception e) {
log.info(e.getMessage(), e.getMessage());
@@ -164,46 +159,11 @@ public class TagTaskServiceImpl implements ITagTaskService {
@Override
public void tagInManager() {
BasTag param = new BasTag();
param.setSendCompleted("0");
param.setSpare3("2");
List<BasTag> basTags = basTagService.selectBasTagList(param);
for (BasTag basTag : basTags) {
Socket socket = getSocket(basTag);
try {
/** 接收电子标签指令 */
String content = null;//receiveResponse(socket);//读取值
if (!content.isEmpty()) {
log.info("读取电子标签值:" + content);
}
//将拍灯指令整理成数组
String[] split = content.split("5a");
for (String s : split) {
if (s.length() == 10) {
String type = s.substring(4, 6);//指令类型 01是下发成功反馈 12是拍灭绿灯指令
if ("12".equals(type)) {
//12为 绿色拍灯指令
MydoJob mydoJobParam = new MydoJob();
mydoJobParam.setInOrOut("1");
mydoJobParam.setExitId("fluent");
List<MydoJob> mydoJobs = mydoJobService.selectMydoJobList(mydoJobParam);
if (CollUtil.isEmpty(mydoJobs)){
//生成agv空料箱入库作业
TrayCodeMsg trayCodeMsg = new TrayCodeMsg();
trayCodeMsg.setTrayCode(IdUtil.fastSimpleUUID());
trayCodeMsg.setWarehouseId("02");
trayCodeMsg.setEntranceId(basTag.getPickAdd());
pdaService.emptyBoxIn(trayCodeMsg);
}else {
MydoJob mydoJob = mydoJobs.get(0);
mydoJob.setEntranceId(basTag.getPickAdd());
mydoJobService.updateMydoJob(mydoJob);
}
}
}
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
new Thread(new TagInReadThread(basTag.getId())).start();
}
}
@@ -244,7 +204,7 @@ public class TagTaskServiceImpl implements ITagTaskService {
public boolean sendMsgDzbq( BasTag basTag ,TagTask tagTask) throws IOException {
try (Socket socket = new Socket(basTag.getIp(), 20108)
){
socket.setSoTimeout(5000);
//socket.setSoTimeout(5000);
String green = String.format("%04x", Convert.toInt(tagTask.getNum()));
String red = String.format("%04x", 0);
String greenFirst2 = green.substring(0, 2);

View File

@@ -0,0 +1,131 @@
package com.ruoyi.out.tagTask.thread;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.ruoyi.api.service.impl.ToWcsServiceImpl;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.job.mydojob.domain.MydoJob;
import com.ruoyi.job.mydojob.service.IMydoJobService;
import com.ruoyi.out.tagTask.mapper.TagTaskMapper;
import com.ruoyi.out.tagTask.service.ITagTaskService;
import com.ruoyi.out.tagTask.util.ElectronicTagClient;
import com.ruoyi.pda.domain.TrayCodeMsg;
import com.ruoyi.pda.service.PdaService;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
import java.util.List;
import static com.ruoyi.out.tagTask.util.ElectronicTagClient.getSocket;
@Slf4j
public class TagInReadThread implements Runnable {
private TagTaskMapper tagTaskMapper;
private IMydoJobService mydoJobService;
private ITagTaskService tagTaskService;
private IBasTagService basTagService;
private PdaService pdaService;
private ToWcsServiceImpl toWcsService;
private Long tagId;
public TagInReadThread(Long tagId) {
this.tagTaskMapper = SpringUtils.getBean(TagTaskMapper.class);
this.mydoJobService = SpringUtils.getBean(IMydoJobService.class);
this.tagTaskService = SpringUtils.getBean(ITagTaskService.class);
this.basTagService = SpringUtils.getBean(IBasTagService.class);
this.pdaService = SpringUtils.getBean(PdaService.class);
this.toWcsService = SpringUtils.getBean(ToWcsServiceImpl.class);
this.tagId = tagId;
}
@Override
public void run() {
BasTag basTag = basTagService.selectBasTagById(tagId);
basTag.setSendCompleted("1");
basTagService.updateBasTag(basTag);
while (true) {
try (Socket socket = getSocket(basTag.getIp(), 20108)) {
basTag = basTagService.selectBasTagById(tagId);
if (basTag == null) {
break;
}
switch (basTag.getSpare2()) {
case "0":
String content = ElectronicTagClient.receiveHexData(socket, 0);
if (StrUtil.isNotEmpty(content)) {
//将拍灯指令整理成数组
String[] split = content.split("5A");
for (String s : split) {
if (s.length() == 10) {
String type = s.substring(4, 6);//指令类型 01是下发成功反馈 12是拍灭绿灯指令
if ("12".equals(type)) {
int address = new BigInteger(s.substring(2, 4), 16).intValue();
if (address == basTag.getId()) {
//12为 绿色拍灯指令
MydoJob mydoJobParam = new MydoJob();
mydoJobParam.setInOrOut("1");
mydoJobParam.setExitId("fluent");
mydoJobParam.setStatus("1");
List<MydoJob> mydoJobs = mydoJobService.selectMydoJobListApi(mydoJobParam);
if (CollUtil.isEmpty(mydoJobs)){
//生成agv空料箱入库作业
TrayCodeMsg trayCodeMsg = new TrayCodeMsg();
trayCodeMsg.setTrayCode(IdUtil.fastSimpleUUID());
trayCodeMsg.setWarehouseId("02");
trayCodeMsg.setEntranceId(basTag.getPickAdd());
pdaService.emptyBoxIn(trayCodeMsg);
toWcsService.pushInMydoJob();
}else {
MydoJob mydoJob = mydoJobs.get(0);
mydoJob.setEntranceId(basTag.getPickAdd());
mydoJobService.updateMydoJob(mydoJob);
toWcsService.pushInMydoJob();
}
//ctu 取货完成,灭灯
boolean b1 = ElectronicTagClient.sendDzbqOff(socket, Convert.toInt(basTag.getId()));
if (b1) {
basTag.setSpare2("1");
basTagService.updateBasTag(basTag);
log.info("灭灯提示空料箱任务已下发");
}
}
}
}
}
}
break;
case "1":
//ctu 取货阶段
Thread.sleep(2000);
break;
case "2":
//亮灯 下发ctu入库任务
boolean b = ElectronicTagClient.sendMsgDzbq(socket, Convert.toInt(basTag.getId()), 1, 0);
if (b) {
basTag.setSpare2("0");
basTagService.updateBasTag(basTag);
log.info("亮灯提示空料箱任务已完成,下发电子标签:ip:{},id:{}", basTag.getIp(), basTag.getId());
}
break;
}
} catch (IOException | InterruptedException e) {
log.error(e.getMessage(), e);
}
}
}
}

View File

@@ -0,0 +1,124 @@
package com.ruoyi.out.tagTask.thread;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.out.tagTask.domain.TagTask;
import com.ruoyi.out.tagTask.mapper.TagTaskMapper;
import com.ruoyi.out.tagTask.util.ElectronicTagClient;
import com.ruoyi.pda.domain.TrayCodeMakeSure;
import com.ruoyi.pda.service.PdaService;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
import java.util.List;
import java.util.Optional;
import static com.ruoyi.out.tagTask.util.ElectronicTagClient.*;
@Slf4j
public class TagOutReadThread implements Runnable {
private TagTaskMapper tagTaskMapper;
private IBasTagService basTagService;
private PdaService pdaService;
private BasTag basTag;
public TagOutReadThread(BasTag bastag) {
this.tagTaskMapper = SpringUtils.getBean(TagTaskMapper.class);
this.basTagService = SpringUtils.getBean(IBasTagService.class);
this.pdaService = SpringUtils.getBean(PdaService.class);
this.basTag = bastag;
}
@Override
public void run() {
//查询所有下发的任务
TagTask tagTaskParam = new TagTask();
tagTaskParam.setTagId(basTag.getId());
List<TagTask> allTagTasks = null;
try (Socket socket = getSocket(basTag.getIp(), 20108)) {
while (true) {
allTagTasks = tagTaskMapper.selectTagTaskList(tagTaskParam);
if (allTagTasks.stream().allMatch(x -> "2".equals(x.getStatus()))) {
//全部拣选完成 灭灯逻辑
//灭灯
boolean b = sendDzbqOff(socket, Convert.toInt(basTag.getId()));
if (b) {
//出库确认
TrayCodeMakeSure trayCodeMakeSure = new TrayCodeMakeSure();
trayCodeMakeSure.setTrayCode(basTag.getTrayCode());
AjaxResult ajaxResult = pdaService.outMakeSure(trayCodeMakeSure);
if (ajaxResult.isSuccess()) {
//删除标签绑定信息
basTag.setSendCompleted("0");
basTag.setTrayCode("");
basTagService.updateBasTag(basTag);
//删除tagList
tagTaskMapper.deleteTagTaskByIds(allTagTasks.stream().map(TagTask::getId).toArray(Long[]::new));
log.info("下发电子标签灭灯:ip:{},id:{}", basTag.getIp(), basTag.getId());
break;
}
}
} else {
if (allTagTasks.stream().anyMatch(x -> "1".equals(x.getStatus()))) {
Optional<TagTask> first = allTagTasks.stream().filter(x -> "1".equals(x.getStatus())).findFirst();
if (first.isPresent()) {
TagTask tagTask = first.get();
/* 接收电子标签指令 */
String content = ElectronicTagClient.receiveHexData(socket, 0);//读取值
if (!content.isEmpty()) {
log.info("读取电子标签值:{}", content);
}
//将拍灯指令整理成数组
String[] split = content.split("5A");
for (String s : split) {
if (s.length() == 10) {
String type = s.substring(4, 6);//指令类型 01是下发成功反馈 12是拍灭绿灯指令
if ("12".equals(type)) {
//12为 绿色拍灯指令
int address = new BigInteger(s.substring(2, 4), 16).intValue();
if (address == basTag.getId()) {
//更新当前子任务状态
tagTask.setStatus("2");
tagTaskMapper.updateTagTask(tagTask);
log.info("更新任务状态:{},id:{}", tagTask.getProductId(), tagTask.getId());
}
}
}
}
}
} else {
Optional<TagTask> first = allTagTasks.stream().filter(x -> "0".equals(x.getStatus())).findFirst();
if (first.isPresent()) {
TagTask tagTask = first.get();
boolean b = sendMsgDzbq(socket, Convert.toInt(basTag.getId()), Convert.toInt(tagTask.getNum()), Convert.toInt(tagTask.getNum()));
if (b) {
basTag.setSendCompleted("1");
basTag.setCurNum(tagTask.getNum());
basTagService.updateBasTag(basTag);
tagTask.setStatus("1");
tagTaskMapper.updateTagTask(tagTask);
log.info("下发电子标签:ip:{},id:{}数量:{}", basTag.getIp(), basTag.getId(), tagTask.getNum());
}
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -1,130 +0,0 @@
package com.ruoyi.out.tagTask.thread;
import cn.hutool.core.collection.CollUtil;
import com.ruoyi.bas.tag.domain.BasTag;
import com.ruoyi.bas.tag.service.IBasTagService;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.out.tagTask.domain.TagTask;
import com.ruoyi.out.tagTask.mapper.TagTaskMapper;
import com.ruoyi.out.tagTask.util.ElectronicTagClient;
import com.ruoyi.pda.domain.TrayCodeMakeSure;
import com.ruoyi.pda.service.PdaService;
import java.io.IOException;
import java.math.BigInteger;
import java.net.Socket;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class TagReadThread implements Runnable{
private TagTaskMapper tagTaskMapper;
private IBasTagService basTagService;
private PdaService pdaService;
public TagReadThread(TagTaskMapper tagTaskMapper, IBasTagService basTagService,PdaService pdaService) {
this.tagTaskMapper = tagTaskMapper;
this.basTagService = basTagService;
this.pdaService = pdaService;
}
@Override
public void run() {
//查询所有下发的任务
TagTask tagTaskParam = new TagTask();
tagTaskParam.setStatus("1");
List<TagTask> allTagTasks = tagTaskMapper.selectTagTaskList(tagTaskParam);
if (CollUtil.isNotEmpty(allTagTasks)) {
Map<Long, List<TagTask>> tagGroup = allTagTasks.stream().collect(Collectors.groupingBy(TagTask::getTagId));
for (Long tagId : tagGroup.keySet()) {
BasTag basTag = basTagService.selectBasTagById(tagId);
try (Socket socket = getSocket(basTag)){
while (true){
/** 接收电子标签指令 */
String content = ElectronicTagClient.receiveHexData(socket,0);//读取值
if (!content.isEmpty()) {
System.out.println("读取电子标签值:" + content);
}
for (TagTask tagTask : tagGroup.get(tagId)) {
//将拍灯指令整理成数组
String[] split = content.split("5A");
for (String s : split) {
if (s.length() == 10) {
String type = s.substring(4, 6);//指令类型 01是下发成功反馈 12是拍灭绿灯指令
if ("12".equals(type)) {
//12为 绿色拍灯指令
int address = new BigInteger(s.substring(2, 4), 16).intValue();
if (address == basTag.getId()) {
//更新当前子任务状态
tagTask.setStatus("2");
tagTaskMapper.updateTagTask(tagTask);
System.out.println("更新任务状态:" + tagTask.getProductId() + ",id:" + tagTask.getId());
TagTask param = new TagTask();
param.setTagId(tagId);
List<TagTask> tagTasks = tagTaskMapper.selectTagTaskList(param);
if (CollUtil.isNotEmpty(tagTasks)){
if (tagTasks.stream().allMatch(x-> "2".equals(x.getStatus()))){
//全部拣选完成 灭灯逻辑
//灭灯
boolean b = sendDzbqOff(basTag);
if (b) {
//出库确认
TrayCodeMakeSure trayCodeMakeSure = new TrayCodeMakeSure();
trayCodeMakeSure.setTrayCode(basTag.getTrayCode());
AjaxResult ajaxResult = pdaService.outMakeSure(trayCodeMakeSure);
if (ajaxResult.isSuccess()){
//删除标签绑定信息
basTag.setSendCompleted("0");
basTag.setTrayCode("");
basTagService.updateBasTag(basTag);
//删除tagList
tagTaskMapper.deleteTagTaskByIds(tagTasks.stream().map(TagTask::getId).toArray(Long[]::new));
break;
}
}
}
}
}
}
}
}
}
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
}
/**
* 获取socket
*
* @param basTag
* @return
*/
private Socket getSocket(BasTag basTag) {
try {
return new Socket(basTag.getIp(), 20108);
}catch (Exception e){
System.out.println(e.getMessage());
}
return null;
}
/**
* 灭灯
*
* @param basTag
*/
public boolean sendDzbqOff(BasTag basTag) throws IOException {
int address = Convert.toInt(basTag.getId());
Socket socket = getSocket(basTag);
int x7 = (address + 0x10 + 0x03 + 0xe8 + 0x03 + 0xe8) % 256;//累加 校验
return ElectronicTagClient.sendHexData( socket,"FA " + String.format("%02x", address) + " 10 00 03 e8 03 e8 " + String.format("%02x", x7) + " AF");
}
}

View File

@@ -1,13 +1,20 @@
package com.ruoyi.out.tagTask.util;
import lombok.extern.slf4j.Slf4j;
import javax.xml.bind.DatatypeConverter;
import java.io.*;
import java.net.*;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Arrays;
@Slf4j
public class ElectronicTagClient {
public static void main(String[] args) {
/*public static void main(String[] args) {
final String SERVER_IP = "192.168.0.7";
final int SERVER_PORT = 20108;
final String hexData = "FA0111000001000114AF";
@@ -29,11 +36,12 @@ public class ElectronicTagClient {
} finally {
System.out.println("连接已关闭");
}
}
}*/
/**
* 发送16进制数据
* @param socket 已建立的Socket连接
*
* @param socket 已建立的Socket连接
* @param hexData 要发送的16进制字符串
* @throws IOException 如果发生I/O错误
*/
@@ -47,7 +55,6 @@ public class ElectronicTagClient {
byte[] sendBytes = hexStringToByteArray(hexData);
System.out.println("发送字节: " + Arrays.toString(sendBytes));
OutputStream output = socket.getOutputStream();
output.write(sendBytes);
output.flush();
@@ -56,15 +63,14 @@ public class ElectronicTagClient {
/**
* 接收16进制响应数据
* @param socket 已建立的Socket连接
*
* @param socket 已建立的Socket连接
* @param timeoutMillis 超时时间(毫秒)
* @return 接收到的16进制字符串
* @throws IOException 如果发生I/O错误或超时
*/
public static String receiveHexData(Socket socket, int timeoutMillis) throws IOException {
//socket.setSoTimeout(timeoutMillis);
InputStream input = socket.getInputStream();
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
byte[] temp = new byte[1024];
int bytesRead;
@@ -92,4 +98,56 @@ public class ElectronicTagClient {
private static String byteArrayToHexString(byte[] bytes) {
return DatatypeConverter.printHexBinary(bytes).toUpperCase();
}
/**
* 下发电子标签
*
* @param socket 连接
* @param sid 标签id 数字
* @param greenNum 绿色数字
* @param redNum 红色数字
*/
public static boolean sendMsgDzbq(Socket socket, int sid, int greenNum, int redNum) {
try {
String green = String.format("%04x", greenNum);
String red = String.format("%04x", redNum);
String greenFirst2 = green.substring(0, 2);
String greenLast2 = green.substring(2);
String redFirst2 = red.substring(0, 2);
String redLast2 = red.substring(2);
int x3 = Integer.parseInt(greenFirst2, 16);//绿色数值
int x4 = Integer.parseInt(greenLast2, 16);//绿色数值
int x5 = Integer.parseInt(redFirst2, 16);//红色数值
int x6 = Integer.parseInt(redLast2, 16);//红色数值
int x7 = (sid + 0x02 + 0x80 + x3 + x4 + x5 + x6) % 256;//累加 校验
String value = "FA" + String.format("%02x", sid) + String.format("%02x", 0x02) + String.format("%02x", 0x80) + greenFirst2 +
greenLast2 + redFirst2 + redLast2 + String.format("%02x", x7) + "AF";
return ElectronicTagClient.sendHexData(socket, value);
} catch (Exception e) {
log.error("e: ", e);
}
return false;
}
/**
* 灭灯
*/
public static boolean sendDzbqOff(Socket socket, int id) throws IOException {
int x7 = (id + 0x10 + 0x03 + 0xe8 + 0x03 + 0xe8) % 256;//累加 校验
return ElectronicTagClient.sendHexData(socket, "FA " + String.format("%02x", id) + " 10 00 03 e8 03 e8 " + String.format("%02x", x7) + " AF");
}
/**
* 获取socket
*/
public static Socket getSocket(String ip, int port) {
try {
Socket socket = new Socket(ip, port);
return socket;
} catch (Exception e) {
System.out.println(e.getMessage());
}
return null;
}
}

View File

@@ -2,6 +2,7 @@ package com.ruoyi.pda.service;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
@@ -303,10 +304,13 @@ public class PdaServiceImp implements PdaService {
//修改单据实际数量
String inOrOutDId = mydoJobDetail.getInOrOutDId();
OutStockoutDetail outStockoutDetail = outStockoutDetailService.selectOutStockoutDetailByStockoutDetailId(inOrOutDId);
outStockoutDetail.setAssignNum(outStockoutDetail.getAssignNum().add(Convert.toBigDecimal(mydoJobDetail.getPickQuantity())));
outStockoutDetailService.updateOutStockoutDetail(outStockoutDetail);
if (ObjUtil.isNotNull(outStockoutDetail)){
outStockoutDetail.setAssignNum(outStockoutDetail.getAssignNum().add(Convert.toBigDecimal(mydoJobDetail.getPickQuantity())));
outStockoutDetailService.updateOutStockoutDetail(outStockoutDetail);
}
//修改电子标签
updateTagTaskStatus(mydoJobDetail, basWarehouse);
}
//判断拣选数量是否等于出库数量
MydoJobDetail mydoJobDetailParam = new MydoJobDetail();
@@ -318,6 +322,7 @@ public class PdaServiceImp implements PdaService {
map.put("v_tray_code", trayCodeMakeSure.getTrayCode());
map.put("v_type", "1");
pdaMapper.outMakeSure(map);
iToWcsService.pushInMydoJob();
String result = map.get("v_result").toString();
if ("10".equals(result)) {
//通知wcs 出库确认
@@ -377,8 +382,10 @@ public class PdaServiceImp implements PdaService {
//修改单据实际数量
String inOrOutDId = mydoJobDetail.getInOrOutDId();
OutStockoutDetail outStockoutDetail = outStockoutDetailService.selectOutStockoutDetailByStockoutDetailId(inOrOutDId);
outStockoutDetail.setAssignNum(outStockoutDetail.getAssignNum().add(Convert.toBigDecimal(mydoJobDetail.getPickQuantity())));
outStockoutDetailService.updateOutStockoutDetail(outStockoutDetail);
if (ObjUtil.isNotNull(outStockoutDetail)){
outStockoutDetail.setAssignNum(outStockoutDetail.getAssignNum().add(Convert.toBigDecimal(mydoJobDetail.getPickQuantity())));
outStockoutDetailService.updateOutStockoutDetail(outStockoutDetail);
}
//修改电子标签
updateTagTaskStatus(mydoJobDetail, basWarehouse);
@@ -397,6 +404,7 @@ public class PdaServiceImp implements PdaService {
map.put("v_tray_code", trayCodeMakeSure.getTrayCode());
map.put("v_type", "1");
pdaMapper.outMakeSure(map);
iToWcsService.pushInMydoJob();
String result = map.get("v_result").toString();
if ("10".equals(result)) {
deleteTagTask(trayCodeMakeSure, basWarehouse,mydoJob);
@@ -446,6 +454,7 @@ public class PdaServiceImp implements PdaService {
HashMap<String, Object> map = new HashMap<>();
map.put("v_tray_code", trayCodeMakeSure.getTrayCode());
pdaMapper.checkMakeSure(map);
iToWcsService.pushInMydoJob();
String result = map.get("v_result").toString();
if ("10".equals(result)) {
return AjaxResult.success(map.get("v_resultmsg").toString());
@@ -547,6 +556,7 @@ public class PdaServiceImp implements PdaService {
map.put("v_tray_code", trayCodeMakeSure.getTrayCode());
map.put("v_type", "1");
pdaMapper.outMakeSureException(map);
iToWcsService.pushInMydoJob();
String result = map.get("v_result").toString();
if ("10".equals(result)) {
//自动分配

View File

@@ -34,7 +34,7 @@ server:
# 日志配置
logging:
level:
com.ruoyi: debug
com.ruoyi: info
org.springframework: warn
# 用户配置

View File

@@ -11,7 +11,7 @@
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-info.log</file>
@@ -34,7 +34,7 @@
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
@@ -56,7 +56,7 @@
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 用户访问日志输出 -->
<appender name="sys-user" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/sys-user.log</file>
@@ -70,7 +70,7 @@
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.ruoyi" level="info" />
<!-- Spring日志级别控制 -->
@@ -79,15 +79,15 @@
<root level="info">
<appender-ref ref="console" />
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info" />
<appender-ref ref="file_error" />
</root>
<!--系统用户操作日志-->
<logger name="sys-user" level="info">
<appender-ref ref="sys-user"/>
</logger>
</configuration>
</configuration>