Commit 16798e04 authored by 耿迪迪's avatar 耿迪迪

生产车间及贴片车间出入库接口开发

parent 0f399e4c
package com.zehong.web.controller.shelf;
import com.zehong.common.annotation.Log;
import com.zehong.common.core.controller.BaseController;
import com.zehong.common.core.domain.AjaxResult;
import com.zehong.common.core.page.TableDataInfo;
import com.zehong.common.enums.BusinessType;
import com.zehong.common.utils.poi.ExcelUtil;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
import com.zehong.system.service.shelf.ITPlatformDockingTaskService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* 平台对接任务Controller
*
* @author zehong
* @date 2025-09-22
*/
@RestController
@RequestMapping("/shelf/docking")
public class TPlatformDockingTaskController extends BaseController
{
@Autowired
private ITPlatformDockingTaskService tPlatformDockingTaskService;
/**
* 查询平台对接任务列表
*/
@GetMapping("/list")
public TableDataInfo list(TPlatformDockingTask tPlatformDockingTask)
{
startPage();
List<TPlatformDockingTask> list = tPlatformDockingTaskService.selectTPlatformDockingTaskList(tPlatformDockingTask);
return getDataTable(list);
}
/**
* 导出平台对接任务列表
*/
@Log(title = "平台对接任务", businessType = BusinessType.EXPORT)
@GetMapping("/export")
public AjaxResult export(TPlatformDockingTask tPlatformDockingTask)
{
List<TPlatformDockingTask> list = tPlatformDockingTaskService.selectTPlatformDockingTaskList(tPlatformDockingTask);
ExcelUtil<TPlatformDockingTask> util = new ExcelUtil<TPlatformDockingTask>(TPlatformDockingTask.class);
return util.exportExcel(list, "平台对接任务数据");
}
/**
* 获取平台对接任务详细信息
*/
@GetMapping(value = "/{fId}")
public AjaxResult getInfo(@PathVariable("fId") Long fId)
{
return AjaxResult.success(tPlatformDockingTaskService.selectTPlatformDockingTaskById(fId));
}
/**
* 新增平台对接任务
*/
@Log(title = "平台对接任务", businessType = BusinessType.INSERT)
@PostMapping
public AjaxResult add(@RequestBody TPlatformDockingTask tPlatformDockingTask)
{
return toAjax(tPlatformDockingTaskService.insertTPlatformDockingTask(tPlatformDockingTask));
}
/**
* 修改平台对接任务
*/
@Log(title = "平台对接任务", businessType = BusinessType.UPDATE)
@PutMapping
public AjaxResult edit(@RequestBody TPlatformDockingTask tPlatformDockingTask)
{
return toAjax(tPlatformDockingTaskService.updateTPlatformDockingTask(tPlatformDockingTask));
}
/**
* 删除平台对接任务
*/
@Log(title = "平台对接任务", businessType = BusinessType.DELETE)
@DeleteMapping("/{fIds}")
public AjaxResult remove(@PathVariable Long[] fIds)
{
return toAjax(tPlatformDockingTaskService.deleteTPlatformDockingTaskByIds(fIds));
}
}
package com.zehong.web.controller.shelf;
import com.alibaba.fastjson.JSONObject;
import com.zehong.common.annotation.Log;
import com.zehong.common.core.controller.BaseController;
import com.zehong.common.core.domain.AjaxResult;
import com.zehong.common.core.page.TableDataInfo;
import com.zehong.common.enums.BusinessType;
import com.zehong.common.exception.CustomException;
import com.zehong.common.utils.poi.ExcelUtil;
import com.zehong.system.domain.shelf.TShelfStorageLocation;
import com.zehong.system.service.shelf.ITShelfApiService;
import com.zehong.system.service.shelf.ITShelfStorageLocationService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.text.ParseException;
import java.util.List;
/**
......@@ -26,6 +30,9 @@ public class TShelfStorageLocationController extends BaseController
@Autowired
private ITShelfStorageLocationService tShelfStorageLocationService;
@Autowired
private ITShelfApiService shelfApiService;
/**
* 查询储位信息列表
*/
......@@ -96,4 +103,28 @@ public class TShelfStorageLocationController extends BaseController
{
return toAjax(tShelfStorageLocationService.deleteTShelfStorageLocationByIds(fShelfStorageLocationIds));
}
/**
* 出入库
* @param param 参数
* @return
*/
@PostMapping("/rackInOutput")
public AjaxResult rackInOutput(@RequestBody String param) {
String result = shelfApiService.rackInOutput(param);
JSONObject resultJson = JSONObject.parseObject(result);
if("1".equals(resultJson.getString("FLAG"))) {
return AjaxResult.error(resultJson.getString("MESSAGE"));
}
return AjaxResult.success();
}
@PostMapping("/receiveFeedBackInfo")
public AjaxResult receiveFeedBackInfo(@RequestBody JSONObject request){
try {
return AjaxResult.success(shelfApiService.receiveFeedBackInfo(request));
} catch (ParseException e) {
return AjaxResult.error("反馈接口调用失败");
}
}
}
......@@ -94,4 +94,7 @@ zehong:
# 获取ip地址开关
addressEnabled: false
# 验证码类型 math 数组计算 char 字符验证
captchaType: math
\ No newline at end of file
captchaType: math
shelf:
apiUrl: http://127.0.0.1/
\ No newline at end of file
......@@ -119,6 +119,12 @@
<artifactId>javax.servlet-api</artifactId>
</dependency>
<!-- websocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zehong.common.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.server.standard.ServerEndpointExporter;
@Configuration
@EnableWebSocket
public class WebSocketConfig {
@Bean
public ServerEndpointExporter serverEndpointExporter(){
return new ServerEndpointExporter();
}
}
......@@ -97,7 +97,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
// 过滤请求
.authorizeRequests()
// 对于登录login 验证码captchaImage 允许匿名访问
.antMatchers("/login", "/captchaImage").anonymous()
.antMatchers("/login", "/captchaImage","/shelf/location/receiveFeedBackInfo").anonymous()
.antMatchers("/ws/**").permitAll()
.antMatchers(
HttpMethod.GET,
"/*.html",
......
......@@ -23,6 +23,11 @@
<artifactId>smart-rack-base-common</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
package com.zehong.system.domain.shelf;
import java.util.Date;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.apache.commons.lang3.builder.ToStringStyle;
import com.zehong.common.annotation.Excel;
import com.zehong.common.core.domain.BaseEntity;
/**
* 平台对接任务对象 t_platform_docking_task
*
* @author zehong
* @date 2025-09-22
*/
public class TPlatformDockingTask extends BaseEntity
{
private static final long serialVersionUID = 1L;
/** 自增主键ID */
private Long fId;
/** 任务号,对应请求体中的ID */
@Excel(name = "任务号,对应请求体中的ID")
private String fTaskId;
/** 操作类型,对应OPTYPE:N/I/O/C/S/D */
@Excel(name = "操作类型,对应OPTYPE:N/I/O/C/S/D")
private String fOpType;
/** 料架号,对应SHELF */
@Excel(name = "料架号,对应SHELF")
private String fShelf;
/** 颜色标识,对应COLOR */
@Excel(name = "颜色标识,对应COLOR")
private String fColor;
/** 接口类型-(0-调用料架系统接口;1-客户接口返回) */
@Excel(name = "接口类型-(0-调用料架系统接口;1-客户接口返回)")
private Integer fType;
/** 储位编号 */
@Excel(name = "储位编号")
private String fLocation;
/** 料盘唯一码 */
@Excel(name = "料盘唯一码")
private String fRid;
/** 操作时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "操作时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date fOperateDate;
/** 操作人,对应USERNAME */
@Excel(name = "操作人,对应USERNAME")
private String fUsername;
/** 料盘与储位信息集合,对应TOTALINFO */
@Excel(name = "料盘与储位信息集合,对应TOTALINFO")
private String fTotalInfo;
/** 任务请求时间 */
@JsonFormat(pattern = "yyyy-MM-dd")
@Excel(name = "任务请求时间", width = 30, dateFormat = "yyyy-MM-dd")
private Date fRequestTime;
/** 返回信息,返回结果 */
@Excel(name = "返回信息,返回结果")
private String fResponseInfo;
public void setfId(Long fId)
{
this.fId = fId;
}
public Long getfId()
{
return fId;
}
public void setfTaskId(String fTaskId)
{
this.fTaskId = fTaskId;
}
public String getfTaskId()
{
return fTaskId;
}
public void setfOpType(String fOpType)
{
this.fOpType = fOpType;
}
public String getfOpType()
{
return fOpType;
}
public void setfShelf(String fShelf)
{
this.fShelf = fShelf;
}
public String getfShelf()
{
return fShelf;
}
public void setfColor(String fColor)
{
this.fColor = fColor;
}
public String getfColor()
{
return fColor;
}
public void setfType(Integer fType)
{
this.fType = fType;
}
public Integer getfType()
{
return fType;
}
public void setfLocation(String fLocation)
{
this.fLocation = fLocation;
}
public String getfLocation()
{
return fLocation;
}
public void setfRid(String fRid)
{
this.fRid = fRid;
}
public String getfRid()
{
return fRid;
}
public void setfOperateDate(Date fOperateDate)
{
this.fOperateDate = fOperateDate;
}
public Date getfOperateDate()
{
return fOperateDate;
}
public void setfUsername(String fUsername)
{
this.fUsername = fUsername;
}
public String getfUsername()
{
return fUsername;
}
public void setfTotalInfo(String fTotalInfo)
{
this.fTotalInfo = fTotalInfo;
}
public String getfTotalInfo()
{
return fTotalInfo;
}
public void setfRequestTime(Date fRequestTime)
{
this.fRequestTime = fRequestTime;
}
public Date getfRequestTime()
{
return fRequestTime;
}
public void setfResponseInfo(String fResponseInfo)
{
this.fResponseInfo = fResponseInfo;
}
public String getfResponseInfo()
{
return fResponseInfo;
}
@Override
public String toString() {
return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
.append("fId", getfId())
.append("fTaskId", getfTaskId())
.append("fOpType", getfOpType())
.append("fShelf", getfShelf())
.append("fColor", getfColor())
.append("fType", getfType())
.append("fLocation", getfLocation())
.append("fRid", getfRid())
.append("fOperateDate", getfOperateDate())
.append("fUsername", getfUsername())
.append("fTotalInfo", getfTotalInfo())
.append("fRequestTime", getfRequestTime())
.append("fResponseInfo", getfResponseInfo())
.toString();
}
}
package com.zehong.system.mapper.shelf;
import java.util.List;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
/**
* 平台对接任务Mapper接口
*
* @author zehong
* @date 2025-09-22
*/
public interface TPlatformDockingTaskMapper
{
/**
* 查询平台对接任务
*
* @param fId 平台对接任务ID
* @return 平台对接任务
*/
public TPlatformDockingTask selectTPlatformDockingTaskById(Long fId);
/**
* 查询平台对接任务列表
*
* @param tPlatformDockingTask 平台对接任务
* @return 平台对接任务集合
*/
public List<TPlatformDockingTask> selectTPlatformDockingTaskList(TPlatformDockingTask tPlatformDockingTask);
/**
* 新增平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
public int insertTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask);
/**
* 修改平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
public int updateTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask);
/**
* 删除平台对接任务
*
* @param fId 平台对接任务ID
* @return 结果
*/
public int deleteTPlatformDockingTaskById(Long fId);
/**
* 批量删除平台对接任务
*
* @param fIds 需要删除的数据ID
* @return 结果
*/
public int deleteTPlatformDockingTaskByIds(Long[] fIds);
}
......@@ -19,6 +19,14 @@ public interface TShelfInfoMapper
*/
public TShelfInfo selectTShelfInfoById(Long fShelfId);
/**
* 根据料架名称获取料架信息
* @param shelf 料架名称
* @return
*/
TShelfInfo selectTShelfInfoByShelf(String shelf);
/**
* 查询料架信息列表
*
......
......@@ -58,4 +58,11 @@ public interface TShelfStorageLocationMapper
* @return 结果
*/
public int deleteTShelfStorageLocationByIds(Long[] fShelfStorageLocationIds);
/**
* 根据位置更新储位信息
* @param tShelfStorageLocation
* @return
*/
int updateTShelfStorageLocationByLocationAndShelfId(TShelfStorageLocation tShelfStorageLocation);
}
package com.zehong.system.service.impl.shelf;
import com.alibaba.fastjson.JSONObject;
import com.zehong.system.service.impl.shelf.annotation.DockingTaskType;
import com.zehong.system.service.impl.shelf.annotation.PlatformDockingTaskLog;
import com.zehong.system.service.impl.shelf.annotation.SendNotification;
import com.zehong.common.exception.CustomException;
import com.zehong.common.utils.StringUtils;
import com.zehong.common.utils.http.HttpUtils;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
import com.zehong.system.domain.shelf.TShelfInfo;
import com.zehong.system.domain.shelf.TShelfStorageLocation;
import com.zehong.system.mapper.shelf.TPlatformDockingTaskMapper;
import com.zehong.system.mapper.shelf.TShelfInfoMapper;
import com.zehong.system.mapper.shelf.TShelfStorageLocationMapper;
import com.zehong.system.service.shelf.ITShelfApiService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
/**
* 货架第三方接口
*/
@Service
public class ITShelfApiServiceImpl implements ITShelfApiService{
@Resource
private TShelfStorageLocationMapper shelfStorageLocationMapper;
@Resource
private TShelfInfoMapper shelfInfoMapper;
/**
* 获取料架状态接口
*/
private final static String RACK_STATUS_URL = "/api/TyChargingData/RackStatus";
/**
* 料架出入库接口
*/
private final static String RACK_IN_OUT_PUT_URL = "/api/TyChargingData/RackInOutput";
/**
* 获取料架所有储位信息
*/
private final static String LOOK_ALL_LOCATION_URL = "/api/TyChargingData/LookAllLocation";
@Value("${shelf.apiUrl}")
private String shelfApiUrl;
/**
* 获取料架状态
* @param param 请求参数
*/
@Override
public JSONObject getRackStatus(String param) {
String result = HttpUtils.sendPost(shelfApiUrl + RACK_STATUS_URL,param);
if(StringUtils.isEmpty(result)) throw new CustomException("获取料架状态信息失败");
return JSONObject.parseObject(result);
}
/**
* 料架出库入库接口
* @param param 入参
*/
@Override
@PlatformDockingTaskLog(type = DockingTaskType.CALL_RACK_SYSTEM)
public String rackInOutput(String param){
String result = HttpUtils.sendPost(shelfApiUrl + RACK_IN_OUT_PUT_URL,param);
if(StringUtils.isEmpty(result)) throw new CustomException("料架出入库接口错误");
return result;
}
/**
* 获取料架所有储位信息
* @param param 请求参数
*/
@Override
public JSONObject lookAllLocation(String param){
String result = HttpUtils.sendPost(shelfApiUrl + LOOK_ALL_LOCATION_URL,param);
if(StringUtils.isEmpty(result)) throw new CustomException("获取料架所有储位信息错误");
return JSONObject.parseObject(result);
}
/**
* 获取储出储成功后反馈
* @param request 入参
*/
@Override
@SendNotification
@PlatformDockingTaskLog(type = DockingTaskType.RECEIVE_RACK_SYSTEM_INFO)
@Transactional(rollbackFor = Exception.class)
public JSONObject receiveFeedBackInfo(JSONObject request) {
try {
JSONObject result = new JSONObject();
TShelfInfo shelfInfo = shelfInfoMapper.selectTShelfInfoByShelf(request.getString("SHELF"));
request.put("SHELFID",shelfInfo.getfShelfId());
//更新位置状态
TShelfStorageLocation tShelfStorageLocation = new TShelfStorageLocation();
tShelfStorageLocation.setLocation(request.getString("LOCATION"));
tShelfStorageLocation.setShelfId(shelfInfo.getfShelfId());
if("I".equals(request.getString("OPTYPE"))){
tShelfStorageLocation.setInboundTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(request.getString("OPERATEDATE")));
tShelfStorageLocation.setRid(request.getString("RID"));
}
if("O".equals(request.getString("OPTYPE"))){
tShelfStorageLocation.setOutboundTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(request.getString("OPERATEDATE")));
}
shelfStorageLocationMapper.updateTShelfStorageLocationByLocationAndShelfId(tShelfStorageLocation);
result.put("FLAG","0");
result.put("MESSAGE","");
result.put("ERRORCODE","");
return result;
} catch (ParseException e) {
throw new CustomException("储出储成功后反馈接口错误");
}
}
}
package com.zehong.system.service.impl.shelf;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.concurrent.ConcurrentHashMap;
@ServerEndpoint("/ws/notifications")
@Component
public class NotificationWebSocket {
private static final ConcurrentHashMap<String, Session> sessions = new ConcurrentHashMap<>();
@OnOpen
public void onOpen(Session session) {
sessions.put(session.getId(), session);
sendMessage(session, "{\"type\":\"SYSTEM\",\"content\":\"WebSocket连接已建立\",\"timestamp\":" + System.currentTimeMillis() + "}");
System.out.println("新的WebSocket连接: " + session.getId());
}
@OnClose
public void onClose(Session session) {
sessions.remove(session.getId());
System.out.println("WebSocket连接关闭: " + session.getId());
}
@OnError
public void onError(Session session, Throwable error) {
System.err.println("WebSocket错误: " + session.getId() + " - " + error.getMessage());
}
@OnMessage
public void onMessage(String message, Session session) {
System.out.println("收到消息: " + message + " from " + session.getId());
}
private void sendMessage(Session session, String message) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println("发送消息失败: " + e.getMessage());
}
}
// 广播消息给所有客户端
public static void broadcast(String message) {
sessions.forEach((id, session) -> {
if (session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println("广播消息失败: " + e.getMessage());
}
}
});
}
// 发送消息给特定客户端
public static void sendToSession(String sessionId, String message) {
Session session = sessions.get(sessionId);
if (session != null && session.isOpen()) {
try {
session.getBasicRemote().sendText(message);
} catch (IOException e) {
System.err.println("发送消息到会话失败: " + e.getMessage());
}
}
}
// 获取当前连接数
public static int getConnectionCount() {
return sessions.size();
}
}
\ No newline at end of file
package com.zehong.system.service.impl.shelf;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zehong.system.mapper.shelf.TPlatformDockingTaskMapper;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
import com.zehong.system.service.shelf.ITPlatformDockingTaskService;
/**
* 平台对接任务Service业务层处理
*
* @author zehong
* @date 2025-09-22
*/
@Service
public class TPlatformDockingTaskServiceImpl implements ITPlatformDockingTaskService
{
@Autowired
private TPlatformDockingTaskMapper tPlatformDockingTaskMapper;
/**
* 查询平台对接任务
*
* @param fId 平台对接任务ID
* @return 平台对接任务
*/
@Override
public TPlatformDockingTask selectTPlatformDockingTaskById(Long fId)
{
return tPlatformDockingTaskMapper.selectTPlatformDockingTaskById(fId);
}
/**
* 查询平台对接任务列表
*
* @param tPlatformDockingTask 平台对接任务
* @return 平台对接任务
*/
@Override
public List<TPlatformDockingTask> selectTPlatformDockingTaskList(TPlatformDockingTask tPlatformDockingTask)
{
return tPlatformDockingTaskMapper.selectTPlatformDockingTaskList(tPlatformDockingTask);
}
/**
* 新增平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
@Override
public int insertTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask)
{
return tPlatformDockingTaskMapper.insertTPlatformDockingTask(tPlatformDockingTask);
}
/**
* 修改平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
@Override
public int updateTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask)
{
return tPlatformDockingTaskMapper.updateTPlatformDockingTask(tPlatformDockingTask);
}
/**
* 批量删除平台对接任务
*
* @param fIds 需要删除的平台对接任务ID
* @return 结果
*/
@Override
public int deleteTPlatformDockingTaskByIds(Long[] fIds)
{
return tPlatformDockingTaskMapper.deleteTPlatformDockingTaskByIds(fIds);
}
/**
* 删除平台对接任务信息
*
* @param fId 平台对接任务ID
* @return 结果
*/
@Override
public int deleteTPlatformDockingTaskById(Long fId)
{
return tPlatformDockingTaskMapper.deleteTPlatformDockingTaskById(fId);
}
}
......@@ -7,6 +7,8 @@ import com.zehong.system.mapper.shelf.TShelfInfoMapper;
import com.zehong.system.domain.shelf.TShelfInfo;
import com.zehong.system.service.shelf.ITShelfInfoService;
import javax.annotation.Resource;
/**
* 料架信息Service业务层处理
*
......@@ -16,7 +18,7 @@ import com.zehong.system.service.shelf.ITShelfInfoService;
@Service
public class TShelfInfoServiceImpl implements ITShelfInfoService
{
@Autowired
@Resource
private TShelfInfoMapper tShelfInfoMapper;
/**
......
package com.zehong.system.service.impl.shelf.annotation;
/**
* 台对接任务类型
*/
public enum DockingTaskType {
//调用料架系统
CALL_RACK_SYSTEM,
//料架系统返回信息
RECEIVE_RACK_SYSTEM_INFO
}
package com.zehong.system.service.impl.shelf.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 平台对接任务消息持久化
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface PlatformDockingTaskLog {
DockingTaskType type() default DockingTaskType.CALL_RACK_SYSTEM;
}
package com.zehong.system.service.impl.shelf.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 料架第三方反馈通知前台
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SendNotification {
String value() default "";
}
package com.zehong.system.service.impl.shelf.aspectj;
import com.alibaba.fastjson.JSONObject;
import com.zehong.system.service.impl.shelf.NotificationWebSocket;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
/**
* 料架第三方反馈通知前台切面
*/
@Aspect
@Component
public class NotificationAspect {
// 定义切点:拦截带有@SendNotification注解的方法
@Pointcut("@annotation(com.zehong.system.service.impl.shelf.annotation.SendNotification)")
public void notificationPointcut() {}
// 后置通知:在方法执行后发送通知
@AfterReturning(pointcut = "notificationPointcut()")
public void sendAfterNotification(JoinPoint joinPoint) {
JSONObject param = (JSONObject) joinPoint.getArgs()[0];
NotificationWebSocket.broadcast(param.toJSONString());
}
}
\ No newline at end of file
package com.zehong.system.service.impl.shelf.aspectj;
import com.alibaba.fastjson.JSONObject;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
import com.zehong.system.mapper.shelf.TPlatformDockingTaskMapper;
import com.zehong.system.service.impl.shelf.annotation.DockingTaskType;
import com.zehong.system.service.impl.shelf.annotation.PlatformDockingTaskLog;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 平台对接任务消息持久化切面
*/
@Aspect
@Component
public class PlatformDockingTaskAspect {
private static final Logger log = LoggerFactory.getLogger(PlatformDockingTaskAspect.class);
@Resource
private TPlatformDockingTaskMapper platformDockingTaskMapper;
// 定义切点:拦截带有@PlatformDockingTaskLog注解的方法
@Pointcut("@annotation(platformDockingTaskLog)")
public void platformDockingTaskPointcut(PlatformDockingTaskLog platformDockingTaskLog) {}
// 后置通知:在方法执行后发送通知
@AfterReturning(pointcut="platformDockingTaskPointcut(platformDockingTaskLog)",returning = "result")
public void insertPlatformDockingTaskLog(JoinPoint joinPoint,PlatformDockingTaskLog platformDockingTaskLog, Object result) {
DockingTaskType type = platformDockingTaskLog.type();
if(DockingTaskType.CALL_RACK_SYSTEM.equals(type)){
insertCallRackSystemLog(joinPoint,result);
}
if(DockingTaskType.RECEIVE_RACK_SYSTEM_INFO.equals(type)){
insertReceiveRackSystemInfo(joinPoint);
}
}
/**
* 调用料架系统记录
* @param joinPoint 请求参数
* @param result 返回结果
*/
private void insertCallRackSystemLog(JoinPoint joinPoint,Object result){
String param = (String) joinPoint.getArgs()[0];
JSONObject paramJson = JSONObject.parseObject(param);
//插入日志
TPlatformDockingTask tPlatformDockingTask = new TPlatformDockingTask();
tPlatformDockingTask.setfTaskId(paramJson.getString("ID"));
tPlatformDockingTask.setfOpType(paramJson.getString("OPTYPE"));
tPlatformDockingTask.setfShelf(paramJson.getString("SHELF"));
tPlatformDockingTask.setfColor(paramJson.getString("COLOR"));
tPlatformDockingTask.setfUsername(paramJson.getString("USERNAME"));
tPlatformDockingTask.setfType(0);
tPlatformDockingTask.setfTotalInfo(paramJson.getString("TOTALINFO"));
tPlatformDockingTask.setfRequestTime(new Date());
tPlatformDockingTask.setfResponseInfo((String) result);
platformDockingTaskMapper.insertTPlatformDockingTask(tPlatformDockingTask);
}
/**
* 料架系统回复记录
* @param joinPoint 请求参数
*/
private void insertReceiveRackSystemInfo(JoinPoint joinPoint){
try {
JSONObject request = (JSONObject) joinPoint.getArgs()[0];
//插入日志
TPlatformDockingTask tPlatformDockingTask = new TPlatformDockingTask();
tPlatformDockingTask.setfTaskId(request.getString("ID"));
tPlatformDockingTask.setfOpType(request.getString("OPTYPE"));
tPlatformDockingTask.setfShelf(request.getString("SHELF"));
tPlatformDockingTask.setfLocation(request.getString("LOCATION"));
tPlatformDockingTask.setfRid(request.getString("RID"));
tPlatformDockingTask.setfType(1);
tPlatformDockingTask.setfUsername(request.getString("USERNAME"));
tPlatformDockingTask.setfOperateDate(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(request.getString("OPERATEDATE")));
platformDockingTaskMapper.insertTPlatformDockingTask(tPlatformDockingTask);
} catch (ParseException e) {
log.error("料架系统回复记录持久化失败:" + e.getMessage());
}
}
}
package com.zehong.system.service.shelf;
import java.util.List;
import com.zehong.system.domain.shelf.TPlatformDockingTask;
/**
* 平台对接任务Service接口
*
* @author zehong
* @date 2025-09-22
*/
public interface ITPlatformDockingTaskService
{
/**
* 查询平台对接任务
*
* @param fId 平台对接任务ID
* @return 平台对接任务
*/
public TPlatformDockingTask selectTPlatformDockingTaskById(Long fId);
/**
* 查询平台对接任务列表
*
* @param tPlatformDockingTask 平台对接任务
* @return 平台对接任务集合
*/
public List<TPlatformDockingTask> selectTPlatformDockingTaskList(TPlatformDockingTask tPlatformDockingTask);
/**
* 新增平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
public int insertTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask);
/**
* 修改平台对接任务
*
* @param tPlatformDockingTask 平台对接任务
* @return 结果
*/
public int updateTPlatformDockingTask(TPlatformDockingTask tPlatformDockingTask);
/**
* 批量删除平台对接任务
*
* @param fIds 需要删除的平台对接任务ID
* @return 结果
*/
public int deleteTPlatformDockingTaskByIds(Long[] fIds);
/**
* 删除平台对接任务信息
*
* @param fId 平台对接任务ID
* @return 结果
*/
public int deleteTPlatformDockingTaskById(Long fId);
}
package com.zehong.system.service.shelf;
import com.alibaba.fastjson.JSONObject;
import java.text.ParseException;
/**
* 货架第三方接口
*/
public interface ITShelfApiService {
/**
* 获取料架状态
* @param param 请求参数
*/
JSONObject getRackStatus(String param);
/**
* 料架出库入库接口
* @param param
* @return
*/
String rackInOutput(String param);
/**
*4 获取料架所有储位信息
* @param param 请求参数
*/
JSONObject lookAllLocation(String param);
/**
* 获取储出储成功后反馈
* @param request
*/
JSONObject receiveFeedBackInfo(JSONObject request) throws ParseException;
}
<?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.zehong.system.mapper.shelf.TPlatformDockingTaskMapper">
<resultMap type="TPlatformDockingTask" id="TPlatformDockingTaskResult">
<result property="fId" column="f_id" />
<result property="fTaskId" column="f_task_id" />
<result property="fOpType" column="f_op_type" />
<result property="fShelf" column="f_shelf" />
<result property="fColor" column="f_color" />
<result property="fType" column="f_type" />
<result property="fLocation" column="f_location" />
<result property="fRid" column="f_rid" />
<result property="fOperateDate" column="f_operate_date" />
<result property="fUsername" column="f_username" />
<result property="fTotalInfo" column="f_total_info" />
<result property="fRequestTime" column="f_request_time" />
<result property="fResponseInfo" column="f_response_info" />
</resultMap>
<sql id="selectTPlatformDockingTaskVo">
select f_id, f_task_id, f_op_type, f_shelf, f_color, f_type, f_location, f_rid, f_operate_date, f_username, f_total_info, f_request_time, f_response_info from t_platform_docking_task
</sql>
<select id="selectTPlatformDockingTaskList" parameterType="TPlatformDockingTask" resultMap="TPlatformDockingTaskResult">
<include refid="selectTPlatformDockingTaskVo"/>
<where>
<if test="fTaskId != null and fTaskId != ''"> and f_task_id = #{fTaskId}</if>
<if test="fOpType != null and fOpType != ''"> and f_op_type = #{fOpType}</if>
<if test="fShelf != null and fShelf != ''"> and f_shelf = #{fShelf}</if>
<if test="fColor != null and fColor != ''"> and f_color = #{fColor}</if>
<if test="fType != null "> and f_type = #{fType}</if>
<if test="fLocation != null and fLocation != ''"> and f_location = #{fLocation}</if>
<if test="fRid != null and fRid != ''"> and f_rid = #{fRid}</if>
<if test="fOperateDate != null "> and f_operate_date = #{fOperateDate}</if>
<if test="fUsername != null and fUsername != ''"> and f_username like concat('%', #{fUsername}, '%')</if>
<if test="fTotalInfo != null and fTotalInfo != ''"> and f_total_info = #{fTotalInfo}</if>
<if test="fRequestTime != null "> and f_request_time = #{fRequestTime}</if>
<if test="fResponseInfo != null and fResponseInfo != ''"> and f_response_info = #{fResponseInfo}</if>
</where>
</select>
<select id="selectTPlatformDockingTaskById" parameterType="Long" resultMap="TPlatformDockingTaskResult">
<include refid="selectTPlatformDockingTaskVo"/>
where f_id = #{fId}
</select>
<insert id="insertTPlatformDockingTask" parameterType="TPlatformDockingTask" useGeneratedKeys="true" keyProperty="fId">
insert into t_platform_docking_task
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="fTaskId != null and fTaskId != ''">f_task_id,</if>
<if test="fOpType != null">f_op_type,</if>
<if test="fShelf != null">f_shelf,</if>
<if test="fColor != null">f_color,</if>
<if test="fType != null">f_type,</if>
<if test="fLocation != null and fLocation != ''">f_location,</if>
<if test="fRid != null">f_rid,</if>
<if test="fOperateDate != null">f_operate_date,</if>
<if test="fUsername != null">f_username,</if>
<if test="fTotalInfo != null">f_total_info,</if>
<if test="fRequestTime != null">f_request_time,</if>
<if test="fResponseInfo != null">f_response_info,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="fTaskId != null and fTaskId != ''">#{fTaskId},</if>
<if test="fOpType != null">#{fOpType},</if>
<if test="fShelf != null">#{fShelf},</if>
<if test="fColor != null">#{fColor},</if>
<if test="fType != null">#{fType},</if>
<if test="fLocation != null and fLocation != ''">#{fLocation},</if>
<if test="fRid != null">#{fRid},</if>
<if test="fOperateDate != null">#{fOperateDate},</if>
<if test="fUsername != null">#{fUsername},</if>
<if test="fTotalInfo != null">#{fTotalInfo},</if>
<if test="fRequestTime != null">#{fRequestTime},</if>
<if test="fResponseInfo != null">#{fResponseInfo},</if>
</trim>
</insert>
<update id="updateTPlatformDockingTask" parameterType="TPlatformDockingTask">
update t_platform_docking_task
<trim prefix="SET" suffixOverrides=",">
<if test="fTaskId != null and fTaskId != ''">f_task_id = #{fTaskId},</if>
<if test="fOpType != null">f_op_type = #{fOpType},</if>
<if test="fShelf != null">f_shelf = #{fShelf},</if>
<if test="fColor != null">f_color = #{fColor},</if>
<if test="fType != null">f_type = #{fType},</if>
<if test="fLocation != null and fLocation != ''">f_location = #{fLocation},</if>
<if test="fRid != null">f_rid = #{fRid},</if>
<if test="fOperateDate != null">f_operate_date = #{fOperateDate},</if>
<if test="fUsername != null">f_username = #{fUsername},</if>
<if test="fTotalInfo != null">f_total_info = #{fTotalInfo},</if>
<if test="fRequestTime != null">f_request_time = #{fRequestTime},</if>
<if test="fResponseInfo != null">f_response_info = #{fResponseInfo},</if>
</trim>
where f_id = #{fId}
</update>
<delete id="deleteTPlatformDockingTaskById" parameterType="Long">
delete from t_platform_docking_task where f_id = #{fId}
</delete>
<delete id="deleteTPlatformDockingTaskByIds" parameterType="String">
delete from t_platform_docking_task where f_id in
<foreach item="fId" collection="array" open="(" separator="," close=")">
#{fId}
</foreach>
</delete>
</mapper>
\ No newline at end of file
......@@ -28,6 +28,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<include refid="selectTShelfInfoVo"/>
where f_shelf_id = #{fShelfId}
</select>
<select id="selectTShelfInfoByShelf" parameterType="String" resultMap="TShelfInfoResult">
<include refid="selectTShelfInfoVo"/>
where f_shelf = #{shelf}
</select>
<insert id="insertTShelfInfo" parameterType="TShelfInfo" useGeneratedKeys="true" keyProperty="fShelfId">
insert into t_shelf_info
......
......@@ -74,6 +74,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
where f_shelf_storage_location_id = #{fShelfStorageLocationId}
</update>
<update id="updateTShelfStorageLocationByLocationAndShelfId" parameterType="TShelfStorageLocation">
update t_shelf_storage_location
<trim prefix="SET" suffixOverrides=",">
<if test="label != null">f_label = #{label},</if>
<if test="index != null">f_index = #{index},</if>
<if test="rid != null and inboundTime != null">f_rid = #{rid},</if>
<if test="rid != null and outboundTime != null">f_rid = null,</if>
<if test="inboundTime != null">f_inbound_time = #{inboundTime},</if>
<if test="outboundTime != null">f_outbound_time = #{outboundTime},</if>
</trim>
where f_location = #{location} AND f_shelf_id = #{shelfId}
</update>
<delete id="deleteTShelfStorageLocationById" parameterType="Long">
delete from t_shelf_storage_location where f_shelf_storage_location_id = #{shelfStorageLocationId}
</delete>
......
......@@ -60,3 +60,12 @@ export function exportLocation(query) {
params: query
})
}
// 出入库
export function rackInOutput(data) {
return request({
url: '/shelf/location/rackInOutput',
method: 'post',
data: data
})
}
......@@ -61,7 +61,7 @@
</template>
<script>
import { locationListInfo,listLocation, getLocation, delLocation, addLocation, updateLocation, exportLocation } from "@/api/shelf/location";
import { locationListInfo, rackInOutput} from "@/api/shelf/location";
export default {
name: "shelf-location",
data(){
......@@ -86,6 +86,7 @@
queryParams: {
shelfId: null,
},
ws: null,
}
},
created(){
......@@ -94,6 +95,7 @@
this.$nextTick(() => {
this.$refs.barCode.focus();
})
this.connect();
},
methods:{
getList(){
......@@ -101,7 +103,7 @@
// 1 正 1-80 反 241-320
// 2 正 81-160 反 321-400
// 3 正 161-240 反 401-480
// 4 正 481-428
// 4 正 481-528
// 5 正 529-576
this.shelfInfo = res.data;
this.shelfLayoutList.push(this.shelfInfo.slice(0,80));
......@@ -118,13 +120,16 @@
checkedLocation(event){
if(event.ctrlKey){
if(!this.lastCtrlSelected){
this.lastCtrlSelected = event.currentTarget.id;
if(this.selectedItems.has(event.currentTarget.id)){
this.selectedItems.delete(event.currentTarget.id);
}else{
this.selectedItems.add(event.currentTarget.id);
const location = this.shelfInfo[event.currentTarget.dataset.index - 1];
if(location.rid){
this.lastCtrlSelected = event.currentTarget.id;
if(this.selectedItems.has(event.currentTarget.id)){
this.selectedItems.delete(event.currentTarget.id);
}else{
this.selectedItems.add(event.currentTarget.id);
}
event.currentTarget.classList.toggle('checked');
}
event.currentTarget.classList.toggle('checked');
return;
}
this.breakSelected(this.lastCtrlSelected,event.currentTarget.id);
......@@ -132,8 +137,7 @@
this.keepSelected(this.lastSelectedItem,event.currentTarget.id);
}else{
const location = this.shelfInfo[event.currentTarget.dataset.index - 1];
console.log(event.currentTarget.dataset,"================",location)
if(!location.rid){
if(location.rid){
this.clearSelection();
this.selectedItems.add(event.currentTarget.id);
event.currentTarget.classList.add('checked');
......@@ -144,7 +148,7 @@
// 连续选中
keepSelected(startId, endId) {
this.clearSelection();
const allItems = Array.from(document.querySelectorAll('.grid-item'));
const allItems = Array.from(document.querySelectorAll('.used'));
const startIndex = allItems.findIndex(item => item.id == startId);
const endIndex = allItems.findIndex(item => item.id == endId);
if (startIndex === -1 || endIndex === -1) return;
......@@ -160,7 +164,7 @@
// 断续选中
breakSelected(startId, endId) {
const allItems = Array.from(document.querySelectorAll('.grid-item'));
const allItems = Array.from(document.querySelectorAll('.used'));
const startIndex = allItems.findIndex(item => item.id == startId);
const endIndex = allItems.findIndex(item => item.id == endId);
if (startIndex === -1 || endIndex === -1) return;
......@@ -193,6 +197,16 @@
this.$message.error("请扫描或输入料盘条形码");
return
}
const param = {
ID: this.generateUUID(),
OPTYPE: "I",
SHELF: this.$route.query.shelf,
COLOR: "1",
USERNAME: "admin",
TOTALINFO: [{RID: this.barCode}]
};
rackInOutput(JSON.stringify(param));
this.clearSelection();
},
// 出库操作需要选择位置可多选不需要扫码
handleOut(){
......@@ -200,7 +214,64 @@
this.$message.error("请选择出库位置");
return;
}
const param = {
ID: this.generateUUID(),
OPTYPE: "O",
SHELF: this.$route.query.shelf,
COLOR: "1",
USERNAME: "admin",
TOTALINFO: []
}
this.selectedItems.forEach(id =>{
const dom = document.getElementById(id);
const locationInfo = this.shelfInfo[dom.dataset.index - 1];
param.TOTALINFO.push({RID: locationInfo.rid,LOCATION: locationInfo.location})
})
rackInOutput(JSON.stringify(param));
this.clearSelection();
},
//生成uuid
generateUUID() {
return ([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
);
},
connect() {
this.ws = new WebSocket('ws://localhost:8080/smartRackBase/ws/notifications');
this.ws.onopen = () => {
console.log('WebSocket Connected');
};
this.ws.onmessage = (event) => {
// Add received message to the list
const message = JSON.parse(event.data);
if(message && message.SHELFID && message.SHELFID == this.$route.query.shelfId){
//入库
if("I" == message.OPTYPE){
const locationInfo = this.shelfLayoutList.flat().find(location => location.location === message.LOCATION);
locationInfo.rid = message.RID;
}
//出库
if("O" == message.OPTYPE){
const locationInfo = this.shelfLayoutList.flat().find(location => location.location === message.LOCATION);
locationInfo.rid = null;
}
}
};
this.ws.onerror = (error) => {
console.error('WebSocket Error:', error);
};
this.ws.onclose = () => {
console.log('WebSocket Closed');
};
},
disconnect() {
if (this.ws) {
this.ws.close();
}
}
},
beforeDestroy() {
this.disconnect();
}
}
</script>
......@@ -324,6 +395,7 @@
position: relative;
aspect-ratio: 1/1;
margin-bottom: 10px;
user-select: none;
}
.checked {
......
<template>
<div class="app-container">
<h1 style="text-align: center">智能货架列表</h1>
<div class="shelves-list">
<div :class="['shelves-info',statusInfo[shelves.fStatus]&&statusInfo[shelves.fStatus].style]" v-for="shelves in shelvesList">
<el-tooltip effect="light" :content="statusInfo[shelves.fStatus]&&statusInfo[shelves.fStatus].name" placement="top">
<div
class="content"
@click="toStorage(shelves)"
>
{{ shelves.fShelf }}
</div>
</el-tooltip>
</div>
</div>
</div>
</template>
<script>
import { shelfListInfo,listInfo, getInfo, delInfo, addInfo, updateInfo, exportInfo } from "@/api/shelf/info";
export default {
name: "produce-manage-index",
data(){
return{
shelvesList: [
{shelf: "001",status: 1},
{shelf: "002",status: 0},
{shelf: "003",status: 1},
{shelf: "004",status: 0},
{shelf: "005",status: 1},
{shelf: "006",status: 0},
{shelf: "007",status: 1},
],
statusInfo:{
0: {
name: "离线",
style: "leave"
},
1: {
name: "就绪",
style: "ready"
}
},
// 查询参数
queryParams: {
fType: 0,
fShelf: null,
fStatus: null
},
}
},
created(){
this.getList();
},
methods:{
getList() {
shelfListInfo(this.queryParams).then(res => {
this.shelvesList = res.data;
});
},
toStorage(shelves){
if(shelves.fStatus == 1){
this.$router.push({ path: "/pcbamanage/pcbashelflocation",query: { shelfId: shelves.fShelfId,shelf: shelves.fShelf } });
}
}
}
}
</script>
<style scoped lang="scss">
.app-container{
padding: 30px;
}
.shelves-list{
display: grid;
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
gap: 25px;
}
.shelves-info {
background: white;
border-radius: 12px;
overflow: hidden;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
transition: transform 0.3s, box-shadow 0.3s;
aspect-ratio: 1/1;
}
.content{
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
text-align: center;
}
.leave{
background-color: #cccccc;
color: white;
}
.ready{
background-color: #13ce66;
color: white;
}
</style>
......@@ -61,7 +61,7 @@
},
toStorage(shelves){
if(shelves.fStatus == 1){
this.$router.push({ path: "/producemange/shelfLocation",query: { shelfId: shelves.fShelfId } });
this.$router.push({ path: "/producemange/shelfLocation",query: { shelfId: shelves.fShelfId,shelf: shelves.fShelf } });
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment