opt:发货区管理接口优化
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -90,6 +90,7 @@ public interface StructattrService {
|
||||
* @return
|
||||
*/
|
||||
JSONArray getStructByCodesFs(JSONArray json);
|
||||
Map getStructByCodesFsAnNum(JSONArray json);
|
||||
|
||||
/**
|
||||
* 解锁点位
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -95,6 +95,7 @@
|
||||
import crudStage from '@/api/logicflow/stage'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
import uuidv1 from 'uuid/v1'
|
||||
|
||||
import { LogicFlow } from '@logicflow/core'
|
||||
import { registerCustomElement } from '@/views/system/logicflow/editor/components/node'
|
||||
@@ -112,6 +113,7 @@ export default {
|
||||
tops: '20vh',
|
||||
stage_code: '',
|
||||
stageSelectList: [],
|
||||
resion: {},
|
||||
arr: [], // 显示数组
|
||||
dialogFormVisible: false,
|
||||
dialogFormVisible1: false,
|
||||
@@ -139,6 +141,21 @@ export default {
|
||||
layerNum: '1'
|
||||
}
|
||||
},
|
||||
created() {
|
||||
if (typeof (WebSocket) === 'undefined') {
|
||||
this.$notify({
|
||||
title: '提示',
|
||||
message: '当前浏览器无法接收实时报警信息,请使用谷歌浏览器!',
|
||||
type: 'warning',
|
||||
duration: 0
|
||||
})
|
||||
}
|
||||
// const wsUri = (process.env.VUE_APP_WS_API === '/' ? '/' : (process.env.VUE_APP_WS_API + '/')) + 'messageInfo'
|
||||
const wsUri = window.g.prod.VUE_APP_BASE_API.replace('http', 'ws') + '/webSocket/sendRegion/' + uuidv1()
|
||||
this.websock = new WebSocket(wsUri)
|
||||
this.websock.onerror = this.webSocketOnError
|
||||
this.websock.onmessage = this.webSocketOnMessage
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
this.queryNum()
|
||||
@@ -203,7 +220,6 @@ export default {
|
||||
})
|
||||
// 右键单击事件
|
||||
lf.on('node:contextmenu', (data, e) => {
|
||||
debugger
|
||||
let item = ''
|
||||
item = this.allStructMsg.find((structMsg) => structMsg.id === data.data.id)
|
||||
|
||||
@@ -220,6 +236,24 @@ export default {
|
||||
lf.render(data)
|
||||
this.initStageData()
|
||||
},
|
||||
webSocketOnMessage(e) {
|
||||
const records = JSON.parse(e.data)
|
||||
this.allStructMsg = records.data
|
||||
this.numData.haveMoney = records.haveMoney
|
||||
this.numData.unMoney = records.unMoney
|
||||
for (var item of records.data) { // 循环设置属性
|
||||
if (item.struct_status != undefined) {
|
||||
lf.setProperties(item.id, {
|
||||
struct_status: item.struct_status
|
||||
})
|
||||
}
|
||||
}
|
||||
const { nodes } = lf.getSelectElements() // 获取选中的节点
|
||||
if (nodes.length === 1) { // 因为是定时器,没有选中则不用实时更新显示数据
|
||||
this.moveShow(nodes[0]) // 监控模式下不可能托选,因此就只有一个数据
|
||||
}
|
||||
},
|
||||
|
||||
initStageData() {
|
||||
// 获取舞台编码
|
||||
crudStage.getNewStageDataByCode(this.stageParam).then(res => {
|
||||
@@ -230,15 +264,12 @@ export default {
|
||||
// todo: 定时器
|
||||
this.timer = setInterval(() => { // 定时刷新设备的状态信息
|
||||
console.log('定时器启动')
|
||||
this.initStatus()
|
||||
this.queryNum()
|
||||
}, 10000)
|
||||
this.websock.send(JSON.stringify(this.resion))
|
||||
}, 6000)
|
||||
},
|
||||
initStatus() { // 初始化数据
|
||||
let resion = {}
|
||||
debugger
|
||||
resion = lf.getGraphData().nodes.map(item => ({ id: item.id, struct_id: item.properties.struct_id }))
|
||||
getStructByCodesFs(resion).then(res => {
|
||||
this.resion = lf.getGraphData().nodes.map(item => ({ id: item.id, struct_id: item.properties.struct_id }))
|
||||
getStructByCodesFs(this.resion).then(res => {
|
||||
this.allStructMsg = res
|
||||
// 实时设置状态信息
|
||||
for (var item of res) { // 循环设置属性
|
||||
|
||||
389
lms/nladmin-ui/src/views/wms/sendout/outone/index3.vue
Normal file
389
lms/nladmin-ui/src/views/wms/sendout/outone/index3.vue
Normal file
@@ -0,0 +1,389 @@
|
||||
<template>
|
||||
<div>
|
||||
<el-row style="padding-top: 10px;padding-left: 10px;padding-bottom: 30px">
|
||||
<el-form
|
||||
:inline="true"
|
||||
class="demo-form-inline"
|
||||
label-position="right"
|
||||
label-width="100px"
|
||||
label-suffix=":"
|
||||
>
|
||||
<el-form-item label="发货区层数">
|
||||
<el-select
|
||||
v-model="stageParam"
|
||||
size="mini"
|
||||
placeholder="请选择"
|
||||
class="filter-item"
|
||||
@change="changeStage"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in layerList"
|
||||
:key="item.value"
|
||||
:label="item.label"
|
||||
:value="item.value"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="有货点位">
|
||||
<el-input
|
||||
v-model="numData.haveMoney"
|
||||
disabled
|
||||
style="width: 80px"
|
||||
size="mini"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="无货点位">
|
||||
<el-input
|
||||
v-model="numData.unMoney"
|
||||
disabled
|
||||
style="width: 80px"
|
||||
size="mini"
|
||||
/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<div id="container" className="container" />
|
||||
</el-row>
|
||||
<!--点击设备显示信息-->
|
||||
<el-dialog
|
||||
id="dialogs"
|
||||
title="点位信息"
|
||||
class="newDialog"
|
||||
:visible.sync="dialogDeviceMsgVisible"
|
||||
width="22%"
|
||||
:top="tops"
|
||||
:show-close="false"
|
||||
:modal="false"
|
||||
>
|
||||
<el-table
|
||||
:data="arr"
|
||||
style="width: 100%"
|
||||
max-height="500px"
|
||||
>
|
||||
<el-table-column
|
||||
prop="name"
|
||||
label="监控项"
|
||||
/>
|
||||
<el-table-column
|
||||
prop="value"
|
||||
label="当前值"
|
||||
/>
|
||||
</el-table>
|
||||
</el-dialog>
|
||||
|
||||
<!--弹窗设置设备与图标绑定与角度-->
|
||||
<el-dialog title="点位操作" :visible.sync="dialogFormVisible1" width="35%">
|
||||
<el-form :model="form" size="small">
|
||||
<el-form-item label="点位编码:" prop="device_code" label-width="80px">
|
||||
<el-input v-model="form.point_code" :disabled="true" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="木箱号:" label-width="80px">
|
||||
<el-input v-model="form.vehicle_code" :disabled="true" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="dialogFormVisible1 = false">取 消</el-button>
|
||||
<el-button type="primary" @click="unlock" v-permission="permission.confirm" >解 绑</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import crudStage from '@/api/logicflow/stage'
|
||||
import '@logicflow/core/dist/style/index.css'
|
||||
import '@logicflow/extension/lib/style/index.css'
|
||||
|
||||
import { LogicFlow } from '@logicflow/core'
|
||||
import { registerCustomElement } from '@/views/system/logicflow/editor/components/node'
|
||||
import { getStructByCodesFs, unLockPoint, queryNum } from '@/views/system/monitor/device/structStage'
|
||||
let data = {}
|
||||
let lf = ''
|
||||
export default {
|
||||
// 发货区监控1层
|
||||
name: 'Sendout',
|
||||
data() {
|
||||
return {
|
||||
stageParam: 'FS_1', // 舞台参数
|
||||
dialogDeviceMsgVisible: false,
|
||||
device_code: null,
|
||||
tops: '20vh',
|
||||
stage_code: '',
|
||||
stageSelectList: [],
|
||||
arr: [], // 显示数组
|
||||
dialogFormVisible: false,
|
||||
dialogFormVisible1: false,
|
||||
dialogFormVisible2: false,
|
||||
dialogFormVisible3: false,
|
||||
dialogFormVisible4: false,
|
||||
form: {
|
||||
point_code: '',
|
||||
vehicle_code: ''
|
||||
},
|
||||
permission: {
|
||||
confirm: ['admin', 'sendout:unlock']
|
||||
},
|
||||
allStructMsg: [],
|
||||
msgTop: '200px',
|
||||
msgLeft: '200px',
|
||||
layerList: [
|
||||
{ 'label': '发货1层', 'value': 'FS_1' },
|
||||
{ 'label': '发货2层', 'value': 'FS_2' }
|
||||
],
|
||||
numData: {
|
||||
haveMoney: null,
|
||||
unMoney: null
|
||||
},
|
||||
layerNum: '1'
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.init()
|
||||
this.queryNum()
|
||||
},
|
||||
beforeDestroy() {
|
||||
// js提供的clearInterval方法用来清除定时器
|
||||
console.log('定时器销毁')
|
||||
clearInterval(this.timer)
|
||||
},
|
||||
methods: {
|
||||
// 流程图初始化
|
||||
init() {
|
||||
// 初始化配置
|
||||
lf = new LogicFlow({
|
||||
overlapMode: 1,
|
||||
container: document.querySelector('#container'), // 容器
|
||||
// 画布配置
|
||||
// width: window.innerWidth, // 宽度
|
||||
height: window.innerHeight, // 高度
|
||||
grid: { // 不用格子直接显示,使用背景
|
||||
visible: false,
|
||||
type: 'mesh',
|
||||
size: 5
|
||||
},
|
||||
background: {
|
||||
// backgroundImage: 'url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+PGRlZnM+PHBhdHRlcm4gaWQ9ImdyaWQiIHdpZHRoPSI0MCIgaGVpZ2h0PSI0MCIgcGF0dGVyblVuaXRzPSJ1c2VyU3BhY2VPblVzZSI+PHBhdGggZD0iTSAwIDEwIEwgNDAgMTAgTSAxMCAwIEwgMTAgNDAgTSAwIDIwIEwgNDAgMjAgTSAyMCAwIEwgMjAgNDAgTSAwIDMwIEwgNDAgMzAgTSAzMCAwIEwgMzAgNDAiIGZpbGw9Im5vbmUiIHN0cm9rZT0iI2QwZDBkMCIgb3BhY2l0eT0iMC4yIiBzdHJva2Utd2lkdGg9IjEiLz48cGF0aCBkPSJNIDQwIDAgTCAwIDAgMCA0MCIgZmlsbD0ibm9uZSIgc3Ryb2tlPSIjZDBkMGQwIiBzdHJva2Utd2lkdGg9IjEiLz48L3BhdHRlcm4+PC9kZWZzPjxyZWN0IHdpZHRoPSIxMDAlIiBoZWlnaHQ9IjEwMCUiIGZpbGw9InVybCgjZ3JpZCkiLz48L3N2Zz4=")',
|
||||
backgroundRepeat: 'repeat'
|
||||
},
|
||||
adjustEdge: false,
|
||||
adjustEdgeMiddle: false,
|
||||
adjustEdgeStartAndEnd: false,
|
||||
adjustNodePosition: false,
|
||||
hideAnchors: true,
|
||||
nodeTextEdit: false,
|
||||
edgeTextEdit: false
|
||||
})
|
||||
lf.setTheme(
|
||||
{
|
||||
baseEdge: { strokeWidth: 1 },
|
||||
baseNode: { strokeWidth: 1 },
|
||||
nodeText: { overflowMode: 'autoWrap', lineHeight: 1.5 },
|
||||
edgeText: { overflowMode: 'autoWrap', lineHeight: 1.5 }
|
||||
}
|
||||
)
|
||||
// 注册自定义元素
|
||||
registerCustomElement(lf)
|
||||
// 删除默认的右键菜单
|
||||
lf.extension.menu.setMenuConfig({
|
||||
nodeMenu: false
|
||||
})
|
||||
lf.on('node:click', (data, e) => { // 鼠标点击节点
|
||||
// 展开显示设备信息 todo: 1
|
||||
if (data.data.type !== 'pro-rect' && data.data.type !== 'pro-circle' && data.data.type !== 'triangle' && data.data.type !== 'rect-radius') {
|
||||
if (data.data.properties.struct_id) {
|
||||
this.moveShow(data.data) // 传递节点数据,用来获取id做比对
|
||||
this.dialogDeviceMsgVisible = true
|
||||
this.struct_id = data.data.properties.struct_id // ?暂时没用
|
||||
this.tops = data.e.y + 'px'
|
||||
document.getElementsByClassName('el-dialog')[0].style.marginLeft = data.e.x + 'px'
|
||||
}
|
||||
}
|
||||
})
|
||||
// 右键单击事件
|
||||
lf.on('node:contextmenu', (data, e) => {
|
||||
debugger
|
||||
let item = ''
|
||||
item = this.allStructMsg.find((structMsg) => structMsg.id === data.data.id)
|
||||
|
||||
const data1 = item.data[0]
|
||||
|
||||
this.form.point_code = data1.point_code
|
||||
this.form.vehicle_code = data1.vehicle_code
|
||||
this.dialogFormVisible1 = true
|
||||
})
|
||||
// lf.on('node:mouseleave', (data, e) => {
|
||||
// this.dialogDeviceMsgVisible = false
|
||||
// })
|
||||
// 开始渲染
|
||||
lf.render(data)
|
||||
this.initStageData()
|
||||
},
|
||||
initStageData() {
|
||||
// 获取舞台编码
|
||||
crudStage.getNewStageDataByCode(this.stageParam).then(res => {
|
||||
data = JSON.parse(res.stage_data)
|
||||
lf.render(data)
|
||||
this.initStatus()
|
||||
})
|
||||
// todo: 定时器
|
||||
this.timer = setInterval(() => { // 定时刷新设备的状态信息
|
||||
console.log('定时器启动')
|
||||
this.initStatus()
|
||||
this.queryNum()
|
||||
}, 10000)
|
||||
},
|
||||
initStatus() { // 初始化数据
|
||||
let resion = {}
|
||||
debugger
|
||||
resion = lf.getGraphData().nodes.map(item => ({ id: item.id, struct_id: item.properties.struct_id }))
|
||||
getStructByCodesFs(resion).then(res => {
|
||||
this.allStructMsg = res
|
||||
// 实时设置状态信息
|
||||
for (var item of res) { // 循环设置属性
|
||||
if (item.struct_status != undefined) {
|
||||
lf.setProperties(item.id, {
|
||||
struct_status: item.struct_status
|
||||
})
|
||||
}
|
||||
}
|
||||
// 设置动态实时显示设备信息
|
||||
const { nodes } = lf.getSelectElements() // 获取选中的节点
|
||||
if (nodes.length === 1) { // 因为是定时器,没有选中则不用实时更新显示数据
|
||||
this.moveShow(nodes[0]) // 监控模式下不可能托选,因此就只有一个数据
|
||||
}
|
||||
})
|
||||
},
|
||||
moveShow(nodeData) { // 点击之后显示出来的数据----只需要设备信息
|
||||
let item = ''
|
||||
// 查找点击节点的id
|
||||
item = this.allStructMsg.find((structMsg) => structMsg.id === nodeData.id)
|
||||
this.arr = [] // 清空
|
||||
if (item.struct_id && item.data) { // item.data是数组
|
||||
this.arr = [
|
||||
{ name: '货位编号', value: item.struct_code }
|
||||
]
|
||||
const data1 = item.data[0] // 至少有一条
|
||||
const data = item.data // 总的data数据
|
||||
// 以下是设置参数显示值
|
||||
for (const val in data1) {
|
||||
if (val === 'vehicle_code' && data1.vehicle_code) {
|
||||
const obj = { name: '木箱号', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
if (val === 'quanlity_in_box' && data1.quanlity_in_box) {
|
||||
const obj = { name: '子卷数', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
if (val === 'sale_order_name' && data1.sale_order_name) {
|
||||
const obj = { name: '订单号', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
if (val === 'product_description' && data1.product_description) {
|
||||
const obj = { name: '物料', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
if (val === 'box_weight' && data1.box_weight) {
|
||||
const obj = { name: '木箱总重', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
if (val === 'container_weight' && data1.container_weight) {
|
||||
const obj = { name: '子卷净重', value: data1[val] }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
}
|
||||
if (data.length > 1) { // 显示子卷
|
||||
for (let i = 0; i < data.length; i++) {
|
||||
let container_name
|
||||
let net_weight
|
||||
for (const val in data[i]) {
|
||||
if (val === 'container_name' && data[i].container_name) {
|
||||
container_name = data[i][val]
|
||||
}
|
||||
if (val === 'net_weight' && data[i].net_weight) {
|
||||
net_weight = data[i][val]
|
||||
}
|
||||
}
|
||||
if (container_name && net_weight) {
|
||||
const obj = { name: container_name, value: net_weight }
|
||||
this.arr.push(obj)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
unlock() {
|
||||
// 解锁点位
|
||||
if (this.form.vehicle_code === '') {
|
||||
this.$message({
|
||||
message: '此点位已解绑',
|
||||
type: 'warning'
|
||||
})
|
||||
return
|
||||
}
|
||||
unLockPoint(this.form).then(res => {
|
||||
this.dialogFormVisible1 = false
|
||||
this.initStageData()
|
||||
this.queryNum()
|
||||
this.$message({
|
||||
message: '解绑成功',
|
||||
type: 'success'
|
||||
})
|
||||
})
|
||||
},
|
||||
changeStage(value) {
|
||||
if (value === 'FS_1') {
|
||||
this.layerNum = '1'
|
||||
} else if (value === 'FS_2') {
|
||||
this.layerNum = '2'
|
||||
}
|
||||
this.initStageData()
|
||||
this.queryNum()
|
||||
},
|
||||
queryNum() {
|
||||
queryNum({ 'layer_num': this.layerNum }).then(res => {
|
||||
this.numData.haveMoney = res.haveMoney
|
||||
this.numData.unMoney = res.unMoney
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html, body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
<style scoped>
|
||||
.container {
|
||||
background-color: #f8f9fa;
|
||||
height: 100%;
|
||||
}
|
||||
.newDialog /deep/ .el-dialog__header {
|
||||
padding: 1vh 1vw 0 1vw;
|
||||
}
|
||||
.newDialog /deep/ .el-dialog__body {
|
||||
padding: 1vh 1vw;
|
||||
}
|
||||
.toolbar-sty {
|
||||
position: absolute;
|
||||
margin-top: 5px;
|
||||
top: 0;
|
||||
padding: 5px;
|
||||
left: 30px;
|
||||
height: 45px;
|
||||
/*width: 310px;*/
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-bottom: 1px solid #e5e5e5;
|
||||
z-index: 10;
|
||||
background: #e5e5e5;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user