五楼柜体拆分区域下发柜体到工位功能
master
xins 7 months ago
parent 9b5d9912c3
commit a06e93e518

@ -87,4 +87,6 @@ public class MesConstants {
public static final String MES_ASSIGN_TASK_KEY = "fifth_floor_assign_task";//五楼分配柜体任务到具体工位的key
public static final String MES_ASSIGN_TASK_RESULT_KEY = "fifth_floor_assign_task_result";//五楼分配柜体任务到具体工位返库key
}

@ -0,0 +1,73 @@
package com.hw.common.core.utils;
import com.alibaba.fastjson2.JSONObject;
import java.io.*;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.nio.charset.StandardCharsets;
/**
* @Description:
* @ProjectName:HwMes
* @Author:xins
* @Date:2024-04-12 13:43
* @Version:1.0
*/
public class SocketUtils {
public static String sendAndReceive(String host,int port,int readTimeout,String sendMessage) {
Socket socket = null;
try {
socket = new Socket(host, port);
OutputStream outToServer = socket.getOutputStream();
byte[] sendMessageBytes = sendMessage.getBytes();
outToServer.write(sendMessageBytes);
outToServer.flush();
socket.setSoTimeout(readTimeout);
try {
// 获取Socket的输入流
InputStream inFromServer = socket.getInputStream();
// 创建一个足够大的缓冲区来接收数据
byte[] buffer = new byte[1024];
// 从输入流中读取数据
int bytesRead;
while ((bytesRead = inFromServer.read(buffer)) != -1) {
// 处理接收到的数据
String receivedMessage = new String(buffer, 0, bytesRead, StandardCharsets.UTF_8);
System.out.println("Received feedback from server: " + receivedMessage);
return receivedMessage;
}
} catch (SocketTimeoutException e) {
System.err.println("Reading from the socket timed out.");
}
} catch (IOException e) {
System.err.println("An I/O error occurred: " + e.getMessage());
} finally {
if (socket != null) {
try {
socket.close(); // 在异常情况下也尝试关闭
} catch (IOException e) {
System.err.println("Failed to close the socket: " + e.getMessage());
}
}
}
return "";
}
public static void main(String[] args) {
JSONObject assignTaskMessageJson = new JSONObject();
assignTaskMessageJson.put("stationNo", 3);
assignTaskMessageJson.put("time", System.currentTimeMillis());
assignTaskMessageJson.put("materialBarcode", "1111");
String host = "10.11.41.121";
int port = 5000;
int readTimeout = 5000; // 读取超时时间,单位:毫秒
sendAndReceive(host, port, readTimeout,assignTaskMessageJson.toString());
}
}

@ -0,0 +1,86 @@
//package com.hw.mes;
//
//import org.springframework.stereotype.Component;
//
//import javax.annotation.PostConstruct;
//import javax.annotation.PreDestroy;
//import java.io.IOException;
//import java.io.InputStream;
//import java.io.OutputStream;
//import java.net.Socket;
//
///**
// * @Description: Scoket客户端长连接
// * @ClassName: SocketClient
// * @Author : xins
// * @Date :2024-04-12 15:03
// * @Version :1.0
// */
//@Component
//public class SocketClient {
//
// private static final String SERVER_HOST = "10.11.41.121";
// private static final int SERVER_PORT = 5000;
// private Socket socket;
// private InputStream inFromServer;
// private OutputStream outToServer;
//
// @PostConstruct
// public void init() {
// try {
// System.out.println("ddddddssss");
// socket = new Socket(SERVER_HOST, SERVER_PORT);
// socket.setSoTimeout(5000); // 设置读取超时例如5秒
// socket.setKeepAlive(true); // 开启TCP KeepAlive有助于检测连接状态
//
// inFromServer = socket.getInputStream();
// outToServer = socket.getOutputStream();
// } catch (IOException e) {
// System.err.println("Error initializing socket client: " + e.getMessage());
// }
// }
//
// public String callApi(String request) {
// try {
// // 发送请求信息
// outToServer.write(request.getBytes());
// outToServer.flush();
//
// // 接收反馈信息
// byte[] buffer = new byte[1024];
// int bytesRead = inFromServer.read(buffer);
// if (bytesRead == -1) {
// throw new IOException("Connection closed while waiting for feedback");
// }
//
// String feedback = new String(buffer, 0, bytesRead);
// System.out.println("Received feedback from server: " + feedback);
//
// // 处理接收到的反馈信息
// handleServerFeedback(feedback);
//
// return feedback; // 返回接收到的反馈信息
// } catch (IOException e) {
// System.err.println("Error calling API: " + e.getMessage());
// // 根据实际情况处理异常,如重试、通知用户等
// return null; // 或返回一个默认值、错误信息等
// }
// }
//
// private void handleServerFeedback(String feedback) {
// // TODO: 实现处理服务器反馈的逻辑
// System.out.println("Handling server feedback: " + feedback);
// }
//
// //重连
// @PreDestroy
// public void cleanup() {
// try {
// if (socket != null && !socket.isClosed()) {
// socket.close();
// }
// } catch (IOException e) {
// System.err.println("Error closing socket: " + e.getMessage());
// }
// }
//}

@ -0,0 +1,55 @@
package com.hw.mes.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @Description:
* @ClassName: StationConfig
* @Author : xins
* @Date :2024-03-25 8:53
* @Version :1.0
*/
@Configuration
@ConfigurationProperties(prefix = "mes")
public class MesConfig
{
/**
* socket server host
*/
private String socketServerHost;
/**
* socket server port
*/
private int socketServerPort;
/**
*
*/
private int socketServerReadTimeOut;
public String getSocketServerHost() {
return socketServerHost;
}
public void setSocketServerHost(String socketServerHost) {
this.socketServerHost = socketServerHost;
}
public int getSocketServerPort() {
return socketServerPort;
}
public void setSocketServerPort(int socketServerPort) {
this.socketServerPort = socketServerPort;
}
public int getSocketServerReadTimeOut() {
return socketServerReadTimeOut;
}
public void setSocketServerReadTimeOut(int socketServerReadTimeOut) {
this.socketServerReadTimeOut = socketServerReadTimeOut;
}
}

@ -192,9 +192,8 @@ public class MesApiController extends BaseController {
*/
@Log(title = "柜体分配任务", businessType = BusinessType.ALLOCATE)
@PostMapping(("/assignTask"))
public AjaxResult assignTask(@RequestBody MesAssignTaskVo mesAssignTaskVo) {
productPlanService.assignTask(mesAssignTaskVo);
return success();
public AjaxResult assignTask(@RequestBody @Validated MesAssignTaskVo mesAssignTaskVo) {
return success(productPlanService.assignTask(mesAssignTaskVo));
}
}

@ -0,0 +1,67 @@
package com.hw.mes.domain;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.hw.common.core.annotation.Excel;
import com.hw.common.core.web.domain.BaseEntity;
/**
* mes_material_assign_info
*
* @author xins
* @date 2024-04-12
*/
public class MesMaterialAssignInfo extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 主键标识 */
private Long materialAssignInfoId;
/** 物料条码 */
@Excel(name = "物料条码")
private String materialBarcode;
/** 下发工位ID */
@Excel(name = "下发工位ID")
private Long stationId;
public void setMaterialAssignInfoId(Long materialAssignInfoId)
{
this.materialAssignInfoId = materialAssignInfoId;
}
public Long getMaterialAssignInfoId()
{
return materialAssignInfoId;
}
public void setMaterialBarcode(String materialBarcode)
{
this.materialBarcode = materialBarcode;
}
public String getMaterialBarcode()
{
return materialBarcode;
}
public void setStationId(Long stationId)
{
this.stationId = stationId;
}
public Long getStationId()
{
return stationId;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("materialAssignInfoId", getMaterialAssignInfoId())
.append("materialBarcode", getMaterialBarcode())
.append("stationId", getStationId())
.append("createBy", getCreateBy())
.append("createTime", getCreateTime())
.toString();
}
}

@ -16,9 +16,9 @@ import java.math.BigDecimal;
@Data
public class MesAssignTaskVo {
//工位序号,代表第几个工位
@NotNull(message = "工位序号必须输入")
private Integer stationNo;
//工位ID
@NotNull(message = "工位Id必须输入")
private Long stationId;
//物料条码
@NotBlank(message = "物料条码必须输入")

@ -0,0 +1,61 @@
package com.hw.mes.mapper;
import java.util.List;
import com.hw.mes.domain.MesMaterialAssignInfo;
/**
* Mapper
*
* @author xins
* @date 2024-04-12
*/
public interface MesMaterialAssignInfoMapper
{
/**
*
*
* @param materialAssignInfoId
* @return
*/
public MesMaterialAssignInfo selectMesMaterialAssignInfoByMaterialAssignInfoId(Long materialAssignInfoId);
/**
*
*
* @param mesMaterialAssignInfo
* @return
*/
public List<MesMaterialAssignInfo> selectMesMaterialAssignInfoList(MesMaterialAssignInfo mesMaterialAssignInfo);
/**
*
*
* @param mesMaterialAssignInfo
* @return
*/
public int insertMesMaterialAssignInfo(MesMaterialAssignInfo mesMaterialAssignInfo);
/**
*
*
* @param mesMaterialAssignInfo
* @return
*/
public int updateMesMaterialAssignInfo(MesMaterialAssignInfo mesMaterialAssignInfo);
/**
*
*
* @param materialAssignInfoId
* @return
*/
public int deleteMesMaterialAssignInfoByMaterialAssignInfoId(Long materialAssignInfoId);
/**
*
*
* @param materialAssignInfoIds
* @return
*/
public int deleteMesMaterialAssignInfoByMaterialAssignInfoIds(Long[] materialAssignInfoIds);
}

@ -127,6 +127,6 @@ public interface IMesProductPlanService
*
* @param mesAssignTaskVo
*/
public void assignTask(MesAssignTaskVo mesAssignTaskVo);
public int assignTask(MesAssignTaskVo mesAssignTaskVo);
}

@ -9,9 +9,12 @@ import com.alibaba.fastjson.JSONObject;
import com.hw.common.core.constant.MesConstants;
import com.hw.common.core.exception.ServiceException;
import com.hw.common.core.utils.DateUtils;
import com.hw.common.core.utils.SocketUtils;
import com.hw.common.core.utils.uuid.Seq;
import com.hw.common.security.utils.SecurityUtils;
import com.hw.mes.api.domain.MesBaseBarcodeInfo;
import com.hw.mes.config.MesConfig;
import com.hw.mes.domain.*;
import com.hw.mes.domain.vo.MesAssignTaskVo;
import com.hw.mes.domain.vo.MesMaterialScanVo;
@ -61,7 +64,10 @@ public class MesProductPlanServiceImpl implements IMesProductPlanService {
private MesBaseBarcodeInfoMapper mesBaseBarcodeInfoMapper;
@Autowired
private StringRedisTemplate redisTemplate;
private MesMaterialAssignInfoMapper mesMaterialAssignInfoMapper;
@Autowired
private MesConfig mesConfig;
/**
*
@ -373,16 +379,92 @@ public class MesProductPlanServiceImpl implements IMesProductPlanService {
/**
*
*
* @param mesAssignTaskVo
*/
@Override
public void assignTask(MesAssignTaskVo mesAssignTaskVo) {
//1、先发布信息设置超时时间如果超时需要删除此key避免重复读取
redisTemplate.convertAndSend(MesConstants.MES_ASSIGN_TASK_KEY, mesAssignTaskVo.getStationNo());
//2、订阅者读取此条信息后会给出反馈需要在程序已开始订阅此条反馈信息如果在10s内返回则成功如果10s内失败则失败
@Transactional(rollbackFor = Exception.class)
public int assignTask(MesAssignTaskVo mesAssignTaskVo) {
String materialBarcode = mesAssignTaskVo.getMaterialBarcode();
MesBaseBarcodeInfo mesBaseBarcodeInfo = mesBaseBarcodeInfoMapper.selectMesBaseBarcodeInfoByBarcodeInfo(materialBarcode);
if (mesBaseBarcodeInfo == null) {
throw new ServiceException("成品条码有误");
}
if (StringUtils.isEmpty(mesBaseBarcodeInfo.getBindBarcode())) {
throw new ServiceException("此成品条码未绑定柜体,不能下发");
}
MesMaterialAssignInfo queryMesMaterialAssignInfo = new MesMaterialAssignInfo();
queryMesMaterialAssignInfo.setMaterialBarcode(materialBarcode);
List<MesMaterialAssignInfo> mesMaterialAssignInfos = mesMaterialAssignInfoMapper.selectMesMaterialAssignInfoList(queryMesMaterialAssignInfo);
if (mesMaterialAssignInfos != null && !mesMaterialAssignInfos.isEmpty()) {
throw new ServiceException("此物料条码已经下发,无需重复下发");
}
System.out.println(redisTemplate.opsForValue().get(MesConstants.MES_ASSIGN_TASK_KEY));
// redisTemplate.c
Long stationId = mesAssignTaskVo.getStationId();
Date currentDate = new Date();
MesMaterialAssignInfo mesMaterialAssignInfo = new MesMaterialAssignInfo();
mesMaterialAssignInfo.setMaterialBarcode(materialBarcode);
mesMaterialAssignInfo.setStationId(stationId);
mesMaterialAssignInfo.setCreateBy(SecurityUtils.getUsername());
mesMaterialAssignInfo.setCreateTime(currentDate);
mesMaterialAssignInfoMapper.insertMesMaterialAssignInfo(mesMaterialAssignInfo);
Long stationNo = stationId % 10;
JSONObject assignTaskMessageJson = new JSONObject();
assignTaskMessageJson.put("stationNo", stationNo);
assignTaskMessageJson.put("time", currentDate.getTime());
assignTaskMessageJson.put("materialBarcode", materialBarcode);
//2、订阅者读取此条信息后会给出反馈直接写入redis如果在10s内返回则成功如果10s内失败则失败
String returnMsg = SocketUtils.
sendAndReceive(mesConfig.getSocketServerHost(), mesConfig.getSocketServerPort(), mesConfig.getSocketServerReadTimeOut(), assignTaskMessageJson.toString());
if (StringUtils.isEmpty(returnMsg)) {
throw new ServiceException("下发超时,请重试");
}
JSONObject returnMsgJson = JSONObject.parseObject(returnMsg);
boolean isFlag = returnMsgJson.getBoolean("isFlag");
if (!isFlag) {
String tipMessage = returnMsgJson.getString("message");
throw new ServiceException(tipMessage);
}
return 1;
}
// public String executeAssignTaskResultTask() {
// ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
// boolean running = true;
// AtomicInteger i = new AtomicInteger();
// Callable<String> task = () -> {
// String result = "";
// while (running) {
// i.getAndIncrement();
// result = redisTemplate.opsForValue().getAndDelete(MesConstants.MES_ASSIGN_TASK_RESULT_KEY);
// System.out.println("no:" + i.get());
// if (StringUtils.isNotEmpty(result)) {
// break;
// }
// }
// return result;
// };
//
//
// try {
// // 安排任务每秒执行一次
// ScheduledFuture<String> result = executor.schedule(task, 1, TimeUnit.SECONDS);
// executor.shutdown();
// executor.awaitTermination(Long.MAX_VALUE, TimeUnit.SECONDS);
// return result.get();
// } catch (InterruptedException e) {
// throw new RuntimeException(e);
// } catch (ExecutionException e) {
// throw new RuntimeException(e);
// }
// }
}

@ -0,0 +1,69 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hw.mes.mapper.MesMaterialAssignInfoMapper">
<resultMap type="MesMaterialAssignInfo" id="MesMaterialAssignInfoResult">
<result property="materialAssignInfoId" column="material_assign_info_id" />
<result property="materialBarcode" column="material_barcode" />
<result property="stationId" column="station_id" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
</resultMap>
<sql id="selectMesMaterialAssignInfoVo">
select material_assign_info_id, material_barcode, station_id, create_by, create_time from mes_material_assign_info
</sql>
<select id="selectMesMaterialAssignInfoList" parameterType="MesMaterialAssignInfo" resultMap="MesMaterialAssignInfoResult">
<include refid="selectMesMaterialAssignInfoVo"/>
<where>
<if test="materialBarcode != null and materialBarcode != ''"> and material_barcode = #{materialBarcode}</if>
<if test="stationId != null "> and station_id = #{stationId}</if>
</where>
</select>
<select id="selectMesMaterialAssignInfoByMaterialAssignInfoId" parameterType="Long" resultMap="MesMaterialAssignInfoResult">
<include refid="selectMesMaterialAssignInfoVo"/>
where material_assign_info_id = #{materialAssignInfoId}
</select>
<insert id="insertMesMaterialAssignInfo" parameterType="MesMaterialAssignInfo" useGeneratedKeys="true" keyProperty="materialAssignInfoId">
insert into mes_material_assign_info
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="materialBarcode != null and materialBarcode != ''">material_barcode,</if>
<if test="stationId != null">station_id,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="materialBarcode != null and materialBarcode != ''">#{materialBarcode},</if>
<if test="stationId != null">#{stationId},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
</trim>
</insert>
<update id="updateMesMaterialAssignInfo" parameterType="MesMaterialAssignInfo">
update mes_material_assign_info
<trim prefix="SET" suffixOverrides=",">
<if test="materialBarcode != null and materialBarcode != ''">material_barcode = #{materialBarcode},</if>
<if test="stationId != null">station_id = #{stationId},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
</trim>
where material_assign_info_id = #{materialAssignInfoId}
</update>
<delete id="deleteMesMaterialAssignInfoByMaterialAssignInfoId" parameterType="Long">
delete from mes_material_assign_info where material_assign_info_id = #{materialAssignInfoId}
</delete>
<delete id="deleteMesMaterialAssignInfoByMaterialAssignInfoIds" parameterType="String">
delete from mes_material_assign_info where material_assign_info_id in
<foreach item="materialAssignInfoId" collection="array" open="(" separator="," close=")">
#{materialAssignInfoId}
</foreach>
</delete>
</mapper>

@ -201,3 +201,13 @@ export function applyRawBack(data) {
data: data
})
}
// 下发柜体到具体工位
export function assignTask(data) {
return request({
url: '/mes/api/assignTask',
method: 'post',
data: data
})
}

@ -36,18 +36,18 @@
style="margin-left: 10px"
trigger="click"
width="400">
<el-form ref="form" :model="form2" label-width="80px">
<el-form-item label="名称">
<el-input v-model="form2.name"></el-input>
<el-form ref="assignTaskForm" :model="assignTaskForm" :rules="assignTaskRules" label-width="80px">
<el-form-item label="成品条码" prop="materialBarcode">
<el-input v-model="assignTaskForm.materialBarcode"></el-input>
</el-form-item>
<el-form-item label="特殊资源">
<el-radio-group v-model="form2.nowStation">
<el-radio v-for="i in stationData" :label="i.stationName" :value="i.stationId"></el-radio>
<el-form-item label="工位">
<el-radio-group v-model="assignTaskForm.stationId">
<el-radio v-for="i in stationData" :label="i.stationId" :value="i.stationId" :key="i.stationId">{{i.stationName}}</el-radio>
</el-radio-group>
</el-form-item>
</el-form>
<div style="float:right;margin-top: 8px">
<el-button type="primary" @click="completeStation"> </el-button>
<el-button type="primary" :loading="submitAssignLoading" @click="completeStation"> </el-button>
</div>
<el-button slot="reference" type="success">下发
</el-button>
@ -383,7 +383,8 @@ import {
getStockTotal,
getWarehouses,
bindBarcode,
applyRawBack
applyRawBack,
assignTask
} from "@/api/board";
const setState = (e) => {
@ -415,7 +416,20 @@ export default {
dialogVisible: false,
form: {},
form1: {},
form2: {},
assignTaskForm: {
materialBarcode: null,
stationId: null
},
assignTaskRules: {
materialBarcode: [
{ required: true, message: "物料条码不能为空", trigger: "blur" }
],
stationId: [
{ required: true, message: "工位不能为空", trigger: "change" }
],
},
submitAssignLoading: false,
tableData: [],
nowStation: null,
stationData: [
@ -702,11 +716,42 @@ export default {
stationChange(val) {
this.nowStation = val
},
//
resetAssignTask() {
this.assignTaskForm = {
materialBarcode: null,
stationNo:null
};
this.resetForm("assignTaskForm");
},
cancelAssignTask(){
this.assignModel = false;
this.submitAssignLoading = false;
this.resetAssignTask();
},
completeStation() {
alert(JSON.stringify(this.nowStation))
console.log(this.form2)
this.assignModel = false
this.submitAssignLoading = true;
this.$refs["assignTaskForm"].validate(valid => {
if (valid) {
assignTask(this.assignTaskForm).then(response => {
this.$modal.msgSuccess("下发成功");
this.cancelAssignTask();
}).catch(() => {
this.submitAssignLoading = false;
});
}
});
},
getInfo(e) {
this.$refs.chart1_1.setData({
series: [
@ -1171,8 +1216,6 @@ export default {
},
//
resetRawBack() {
this.rawBackForm = {

Loading…
Cancel
Save