opt:发货区管理接口优化

This commit is contained in:
zhangzq
2024-01-08 17:39:11 +08:00
parent f6f19e73a1
commit eeeffbb708
7 changed files with 711 additions and 23 deletions

View File

@@ -0,0 +1,44 @@
package org.nl.common.utils;
import lombok.SneakyThrows;
import org.nl.modules.wql.util.SpringContextHolder;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.function.Supplier;
/*
* @author ZZQ
* @Date 2023/3/27 10:30
*/
public class RedissonUtils {
/**
*
* @param process 业务代码
* @param key
* @param seconds 尝试获取锁的等待时间,允许为空
*/
@SneakyThrows
public static void lock(Function process, String key, Object param){
RedissonClient redissonClient = SpringContextHolder.getBean(RedissonClient.class);
RLock lock = redissonClient.getLock(key);
boolean isLock;
isLock = lock.tryLock();
try {
if (isLock){
process.apply(param);
} else {
return;
}
}catch (Exception ex){
ex.printStackTrace();
throw ex;
}finally {
if (isLock && lock.isHeldByCurrentThread()){
lock.unlock();
}
}
}
}

View File

@@ -0,0 +1,110 @@
/*
* Copyright 2019-2020 Zheng Jie
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.nl.modules.mnt.websocket;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.nl.common.utils.RedissonUtils;
import org.nl.modules.mnt.service.AutoRiKuService;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.wms.basedata.st.service.StructattrService;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArraySet;
/*
* @author ZZQ
* @Date 2024/1/8 17:03
*/
@ServerEndpoint("/webSocket/sendRegion/{sid}")
@Slf4j
@Component
public class SendRegionWebSocketServer {
/**
* concurrent包的线程安全Set用来存放每个客户端对应的MyWebSocket对象。
*/
private static CopyOnWriteArraySet<SendRegionWebSocketServer> webSocketSet = new CopyOnWriteArraySet<SendRegionWebSocketServer>();
/**
* 与某个客户端的连接会话,需要通过它来给客户端发送数据
*/
private Session session;
/**
* 接收sid
*/
private String sid = "";
/**
* 连接建立成功调用的方法
*/
@OnOpen
public void onOpen(Session session, @PathParam("sid") String sid) {
this.session = session;
//如果存在就先删除一个,防止重复推送消息
for (SendRegionWebSocketServer webSocket : webSocketSet) {
if (webSocket.sid.equals(sid)) {
webSocketSet.remove(webSocket);
}
}
webSocketSet.add(this);
this.sid = sid;
}
/**
* 连接关闭调用的方法
*/
@OnClose
public void onClose() {
webSocketSet.remove(this);
}
/**
* 收到客户端消息后调用的方法
*
* @param message 客户端发送过来的消息
*/
@OnMessage
public void onMessage(String message, Session session) {
System.out.println(webSocketSet.size()+"_接收到消息_"+session.getId());
if (StringUtils.isNotEmpty(message)){
RedissonUtils.lock(key -> {
StructattrService service = SpringContextHolder.getBean(StructattrService.class);
Map record = service.getStructByCodesFsAnNum(JSONArray.parseArray(message));
try {
Thread.sleep(2000);
for (SendRegionWebSocketServer consumer : webSocketSet) {
consumer.session.getBasicRemote().sendText(JSON.toJSONString(record));
}
}catch (Exception ex){
ex.printStackTrace();
}
return "";
}, message, message);
}
}
@OnError
public void onError(Session session, Throwable error) {
log.error("发生错误");
webSocketSet.remove(session);
error.printStackTrace();
}
}

View File

@@ -90,6 +90,7 @@ public interface StructattrService {
* @return
*/
JSONArray getStructByCodesFs(JSONArray json);
Map getStructByCodesFsAnNum(JSONArray json);
/**
* 解锁点位

View File

@@ -28,9 +28,12 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;
/**
* @author zhouz
@@ -319,6 +322,33 @@ public class StructattrServiceImpl implements StructattrService {
public JSONArray getStructByCodesFs(JSONArray jsonArray) {
WQLObject attrTab = WQLObject.getWQLObject("sch_base_point");
JSONArray arr = new JSONArray();
List<String> list = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject js = jsonArray.getJSONObject(i);
String struct_id = js.getString("struct_id");
if (ObjectUtil.isEmpty(struct_id)) {
continue;
}
list.add(struct_id);
}
String sql = "('" + list.stream().collect(Collectors.joining("','")) + "')";
JSONArray array = WQL
.getWO("QST_STRUCTATTR")
.addParamMap(MapOf.of("struct_ids", sql, "flag", "3"))
.process()
.getResultJSONArray(0);
Map<String, JSONObject> pointMap = array.stream().collect(HashMap::new, (BiConsumer<HashMap<String, JSONObject>, Object>) (m, o) -> {
JSONObject item = (JSONObject) o;
m.put(item.getString("point_id"), item);
}, HashMap::putAll);
JSONArray attrs = attrTab.query("point_id in " + sql).getResultJSONArray(0);
Map<String, JSONObject> attrMap = attrs.stream().collect(HashMap::new, (BiConsumer<HashMap<String, JSONObject>, Object>) (m, o) -> {
JSONObject item = (JSONObject) o;
m.put(item.getString("point_id"), item);
}, HashMap::putAll);
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject obj = new JSONObject();
JSONObject js = jsonArray.getJSONObject(i);
@@ -327,18 +357,10 @@ public class StructattrServiceImpl implements StructattrService {
if (ObjectUtil.isEmpty(struct_id)) {
continue;
}
int struct_status = 2;
// 获取信息 1蓝色空载具 2黄色木箱 3绿色空位 4灰色禁用
// 查找详细信息, 这里可能是有多条数据
JSONArray array = WQL
.getWO("QST_STRUCTATTR")
.addParamMap(MapOf.of("struct_id", struct_id, "flag", "2"))
.process()
.getResultJSONArray(0);
// 计算子卷净重
JSONObject json = array.getJSONObject(0);
JSONObject json = pointMap.get(struct_id);
if (ObjectUtil.isNotEmpty(json.getString("net_weight"))) {
BigDecimal container_weight = array.stream().map(row -> ((JSONObject) row).getBigDecimal("net_weight")).reduce(BigDecimal.ZERO, BigDecimal::add);
@@ -348,11 +370,8 @@ public class StructattrServiceImpl implements StructattrService {
}
}
// 获取仓位表中的信息
JSONObject strInfo = attrTab
.query("point_id = '" + struct_id + "'")
.uniqueResult(0);
if (ObjectUtil.isEmpty(strInfo.getString("vehicle_code"))) {
JSONObject strInfo = attrMap.get(struct_id);
if (strInfo !=null && ObjectUtil.isEmpty(strInfo.getString("vehicle_code"))) {
// 空位
struct_status = 3;
}
@@ -368,6 +387,76 @@ public class StructattrServiceImpl implements StructattrService {
return arr;
}
@Override
public Map getStructByCodesFsAnNum(JSONArray jsonArray) {
WQLObject attrTab = WQLObject.getWQLObject("sch_base_point");
JSONArray arr = new JSONArray();
List<String> list = new ArrayList<>();
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject js = jsonArray.getJSONObject(i);
String struct_id = js.getString("struct_id");
if (ObjectUtil.isEmpty(struct_id)) {
continue;
}
list.add(struct_id);
}
String sql = "('" + list.stream().collect(Collectors.joining("','")) + "')";
JSONArray array = WQL
.getWO("QST_STRUCTATTR")
.addParamMap(MapOf.of("struct_ids", sql, "flag", "3"))
.process()
.getResultJSONArray(0);
Map<String, JSONObject> pointMap = array.stream().collect(HashMap::new, (BiConsumer<HashMap<String, JSONObject>, Object>) (m, o) -> {
JSONObject item = (JSONObject) o;
m.put(item.getString("point_id"), item);
}, HashMap::putAll);
JSONArray attrs = attrTab.query("point_id in " + sql).getResultJSONArray(0);
Map<String, JSONObject> attrMap = attrs.stream().collect(HashMap::new, (BiConsumer<HashMap<String, JSONObject>, Object>) (m, o) -> {
JSONObject item = (JSONObject) o;
m.put(item.getString("point_id"), item);
}, HashMap::putAll);
int unMoney = 0;
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject obj = new JSONObject();
JSONObject js = jsonArray.getJSONObject(i);
String struct_id = js.getString("struct_id");
if (ObjectUtil.isEmpty(struct_id)) {
continue;
}
int struct_status = 2;
// 获取信息 1蓝色空载具 2黄色木箱 3绿色空位 4灰色禁用
// 计算子卷净重
JSONObject json = pointMap.get(struct_id);
if (ObjectUtil.isNotEmpty(json.getString("net_weight"))) {
BigDecimal container_weight = array.stream().map(row -> ((JSONObject) row).getBigDecimal("net_weight")).reduce(BigDecimal.ZERO, BigDecimal::add);
for (int j = 0; j < array.size(); j++) {
JSONObject jsonObject = array.getJSONObject(j);
jsonObject.put("container_weight", container_weight);
}
}
JSONObject strInfo = attrMap.get(struct_id);
if (strInfo !=null && ObjectUtil.isEmpty(strInfo.getString("vehicle_code"))) {
// 空位
unMoney++;
struct_status = 3;
}
// 剩余层数货位信息没统计统计可以用obj.put(key, value)返给前端前端在initStatus()就可以遍历去获取,给节点赋值
obj.put("data", array);
obj.put("struct_status", struct_status);
obj.put("struct_id", strInfo.getString("point_id"));
obj.put("struct_code", strInfo.getString("point_code"));
obj.put("id", js.getString("id")); // 设备不存在就只保留id方便前端查看
arr.add(obj);
}
return MapOf.of("data",arr,"haveMoney",arr.size()-unMoney,"unMoney",unMoney);
}
@Override
@Transactional(rollbackFor = Exception.class)
public JSONObject unLockPoint(JSONObject whereJson) {

View File

@@ -14,7 +14,8 @@
## 表字段对应输入参数
#################################################
输入.flag TYPEAS s_string
输入.struct_id TYPEAS s_string
输入.struct_id TYPEAS s_string
输入.struct_ids TYPEAS f_string
[临时表]
--这边列出来的临时表就会在运行期动态创建
@@ -83,3 +84,26 @@
ENDSELECT
ENDQUERY
ENDIF
IF 输入.flag = "3"
QUERY
SELECT
attr.*,
sub.package_box_sn,
sub.quanlity_in_box,
sub.box_weight,
sub.sale_order_name,
sub.container_name,
sub.product_description,
sub.net_weight
FROM
sch_base_point attr
LEFT JOIN pdm_bi_subpackagerelation sub ON sub.package_box_sn = attr.vehicle_code
WHERE
1 = 1
OPTION 输入.struct_ids <> ""
attr.point_id in 输入.struct_ids
ENDOPTION
ENDSELECT
ENDQUERY
ENDIF