扫码枪展示优化
This commit is contained in:
@@ -3,11 +3,20 @@
|
||||
<el-col :span="4" class="device-panel">
|
||||
<div class="panel-header">
|
||||
<h3>设备列表</h3>
|
||||
<el-button size="mini" type="primary" @click="refreshDevices">刷新</el-button>
|
||||
</div>
|
||||
<div class="device-stats">
|
||||
<span>总设备: {{ deviceStats.totalCount || 0 }}</span>
|
||||
<span>活跃设备: {{ deviceStats.activeCount || 0 }}</span>
|
||||
</div>
|
||||
<ul class="device-list">
|
||||
<li v-for="item in deviceList" :key="item.id" class="device-item">
|
||||
<span class="device-id">{{ item.id }}</span>
|
||||
<span class="device-name">{{ item.name }}</span>
|
||||
<li v-for="item in deviceList" :key="item.id" class="device-item" :class="{ active: item.isActive }">
|
||||
<div class="device-status" :class="{ online: item.isActive }"></div>
|
||||
<div class="device-info">
|
||||
<span class="device-name">{{ item.name }}</span>
|
||||
<span class="device-id">{{ item.id }}</span>
|
||||
<span class="device-ip">{{ item.ip }}</span>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</el-col>
|
||||
@@ -123,6 +132,10 @@ export default {
|
||||
data() {
|
||||
return {
|
||||
deviceList: [],
|
||||
deviceStats: {
|
||||
totalCount: 0,
|
||||
activeCount: 0
|
||||
},
|
||||
messageList: [],
|
||||
socket: null,
|
||||
defaultForm: {
|
||||
@@ -141,42 +154,88 @@ export default {
|
||||
this.initSocket();
|
||||
this.fetchMaster();
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 组件销毁时关闭WebSocket连接
|
||||
if (this.socket) {
|
||||
this.socket.close();
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initSocket() {
|
||||
// 处理WebSocket连接
|
||||
this.socket = new WebSocket("ws://localhost:9000/ws");
|
||||
|
||||
this.socket.onopen = () => {
|
||||
console.log("Socket 连接已建立");
|
||||
};
|
||||
|
||||
this.socket.onmessage = (event) => {
|
||||
const data = JSON.parse(event.data);
|
||||
if (data.type === "deviceList") {
|
||||
console.log(data, '获取设备列表');
|
||||
this.deviceList = data.devices;
|
||||
} else if (data.type === "scanMessage") {
|
||||
console.log(data, '获取消息');
|
||||
this.messageList.push({
|
||||
time: new Date().toLocaleString(),
|
||||
itemId: data.itemId,
|
||||
itemType: data.itemType,
|
||||
stockIoId: this.defaultForm.stockIoId,
|
||||
quantity: this.defaultForm.quantity,
|
||||
ioType: this.defaultForm.ioType,
|
||||
warehouseId: this.defaultForm.warehouseId,
|
||||
batchNo: this.defaultForm.batchNo,
|
||||
unit: '个'
|
||||
});
|
||||
try {
|
||||
const data = JSON.parse(event.data);
|
||||
|
||||
// 处理设备列表数据
|
||||
if (data.type === "allDevices") {
|
||||
console.log("获取设备列表", data);
|
||||
this.deviceList = data.devices || [];
|
||||
this.deviceStats = {
|
||||
totalCount: data.totalCount || 0,
|
||||
activeCount: data.activeCount || 0
|
||||
};
|
||||
}
|
||||
// 处理扫描消息
|
||||
else if (data.type === "scanMessage") {
|
||||
console.log("获取扫描消息", data);
|
||||
this.messageList.push({
|
||||
time: new Date().toLocaleString(),
|
||||
itemId: data.itemId,
|
||||
itemType: data.itemType,
|
||||
stockIoId: this.defaultForm.stockIoId,
|
||||
quantity: this.defaultForm.quantity,
|
||||
ioType: this.defaultForm.ioType,
|
||||
warehouseId: this.defaultForm.warehouseId,
|
||||
batchNo: this.defaultForm.batchNo,
|
||||
unit: '个'
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("解析WebSocket消息失败", error);
|
||||
}
|
||||
};
|
||||
|
||||
this.socket.onclose = () => {
|
||||
console.log("Socket 连接已关闭");
|
||||
// 连接关闭后尝试重连
|
||||
setTimeout(() => {
|
||||
this.initSocket();
|
||||
}, 5000);
|
||||
};
|
||||
|
||||
this.socket.onerror = (error) => {
|
||||
console.error("Socket 错误", error);
|
||||
};
|
||||
},
|
||||
|
||||
// 刷新设备列表
|
||||
refreshDevices() {
|
||||
if (this.socket && this.socket.readyState === WebSocket.OPEN) {
|
||||
this.socket.send(JSON.stringify({ type: "refreshDevices" }));
|
||||
} else {
|
||||
this.$message.warning("WebSocket连接未建立,无法刷新设备列表");
|
||||
// 尝试重新连接
|
||||
this.initSocket();
|
||||
}
|
||||
},
|
||||
|
||||
fetchMaster() {
|
||||
listStockIo({ pageSize: 9999, pageNum: 1 }).then(res => {
|
||||
console.log(res, '获取挂载单据');
|
||||
this.masterList = res.rows;
|
||||
console.log("获取挂载单据", res);
|
||||
this.masterList = res.rows || [];
|
||||
}).catch(error => {
|
||||
console.error("获取挂载单据失败", error);
|
||||
this.$message.error("获取挂载单据失败");
|
||||
});
|
||||
},
|
||||
|
||||
handleDeviceChange(item) {
|
||||
this.socket.send(
|
||||
JSON.stringify({
|
||||
@@ -185,35 +244,67 @@ export default {
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
handleBatchConfirm() {
|
||||
// 汇总会导致的库存变更,需要确认
|
||||
console.log(this.selectedList, '批量确认');
|
||||
this.selectedList.forEach(item => {
|
||||
console.log(item, 'item');
|
||||
});
|
||||
console.log("批量确认", this.selectedList);
|
||||
if (this.selectedList.length === 0) {
|
||||
this.$message.warning("请选择需要确认的记录");
|
||||
return;
|
||||
}
|
||||
|
||||
// 批量处理逻辑
|
||||
Promise.all(this.selectedList.map(item => this.processRecord(item)))
|
||||
.then(() => {
|
||||
this.$message.success("批量确认成功");
|
||||
// 从列表中移除已确认的项
|
||||
this.messageList = this.messageList.filter(
|
||||
item => !this.selectedList.some(selected => selected.time === item.time)
|
||||
);
|
||||
this.selectedList = [];
|
||||
})
|
||||
.catch(error => {
|
||||
console.error("批量确认失败", error);
|
||||
this.$message.error("批量确认失败");
|
||||
});
|
||||
},
|
||||
|
||||
handleSelectionChange(selection) {
|
||||
this.selectedList = selection;
|
||||
},
|
||||
|
||||
handleDelete(row) {
|
||||
this.messageList = this.messageList.filter(item => item.time !== row.time);
|
||||
},
|
||||
|
||||
async handleConfirm(row) {
|
||||
// 同时做两件事,插入记录,修改库存
|
||||
// recordType为1表明记录来源扫码枪
|
||||
await this.insertRecord({...row, recordType: 1})
|
||||
await this.updateStock(row)
|
||||
this.handleDelete(row);
|
||||
this.$message.success('确认成功');
|
||||
try {
|
||||
await this.processRecord(row);
|
||||
this.handleDelete(row);
|
||||
this.$message.success('确认成功');
|
||||
} catch (error) {
|
||||
console.error("确认失败", error);
|
||||
this.$message.error('确认失败');
|
||||
}
|
||||
},
|
||||
|
||||
// 处理单条记录的确认逻辑
|
||||
async processRecord(row) {
|
||||
// 插入记录
|
||||
await this.insertRecord({...row, recordType: 1});
|
||||
// 更新库存
|
||||
await this.updateStock(row);
|
||||
},
|
||||
|
||||
insertRecord(row) {
|
||||
return addStockIoDetail(row)
|
||||
return addStockIoDetail(row);
|
||||
},
|
||||
|
||||
updateStock(row) {
|
||||
if (row.ioType === 'in') {
|
||||
return scanInStock(row)
|
||||
return scanInStock(row);
|
||||
} else {
|
||||
return scanOutStock(row)
|
||||
return scanOutStock(row);
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -249,6 +340,9 @@ export default {
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
background-color: #f8fafc;
|
||||
border-radius: 8px 8px 0 0;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.panel-header h3 {
|
||||
@@ -258,6 +352,16 @@ export default {
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 设备统计信息 */
|
||||
.device-stats {
|
||||
padding: 10px 20px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
font-size: 13px;
|
||||
color: #606266;
|
||||
}
|
||||
|
||||
.device-list {
|
||||
flex: 1;
|
||||
overflow-y: auto;
|
||||
@@ -267,25 +371,57 @@ export default {
|
||||
|
||||
.device-item {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 12px 20px;
|
||||
border-bottom: 1px solid #ebeef5;
|
||||
transition: background-color 0.3s;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.device-item:hover {
|
||||
background-color: #f5f7fa;
|
||||
}
|
||||
|
||||
.device-id {
|
||||
font-weight: 500;
|
||||
color: #606266;
|
||||
/* 设备状态指示器 */
|
||||
.device-status {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
border-radius: 50%;
|
||||
background-color: #ccc;
|
||||
margin-right: 12px;
|
||||
}
|
||||
|
||||
.device-status.online {
|
||||
background-color: #42b983; /* 绿色表示在线 */
|
||||
}
|
||||
|
||||
.device-info {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.device-name {
|
||||
display: block;
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.device-id {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #606266;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.device-ip {
|
||||
display: block;
|
||||
font-size: 12px;
|
||||
color: #909399;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
/* 活跃设备高亮 */
|
||||
.device-item.active {
|
||||
background-color: #f0f9eb;
|
||||
}
|
||||
|
||||
.form-panel {
|
||||
|
||||
@@ -35,9 +35,14 @@
|
||||
<el-option
|
||||
v-for="task in availableTasks"
|
||||
:key="task.taskId"
|
||||
:label="`[产品: ${task.productName || task.productId}] [工艺: ${task.processName || task.processId}] 数量: ${task.taskQuantity}`"
|
||||
:value="task.taskId"
|
||||
></el-option>
|
||||
>
|
||||
<div class="task-info">
|
||||
<ProductInfo :productId="task.productId" />
|
||||
<CraftInfo :craftId="task.processId" />
|
||||
<span class="task-quantity">数量: {{ task.taskQuantity }}</span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user