Compare commits

..

5 Commits

Author SHA1 Message Date
Yxq
497ea3cceb Ewm接口切换正式生产环境 2025-10-11 16:46:42 +08:00
Yxq
e49d4bafff 看板数据接口修改 2025-10-11 16:46:03 +08:00
Yxq
2c56587cae 前端出库页面调整 2025-10-11 16:45:19 +08:00
Yxq
e74af4da82 看板代码更新 2025-10-11 16:44:40 +08:00
Yxq
ea8dfb6fb6 目标箱号添加ewm检验接口 2025-10-11 14:08:33 +08:00
24 changed files with 757 additions and 108 deletions

View File

@ -30,7 +30,10 @@ import { ref, onMounted, onUnmounted, computed } from 'vue';
import { useRoute } from 'vue-router'; import { useRoute } from 'vue-router';
import Inbound from './views/Inbound.vue'; import Inbound from './views/Inbound.vue';
import Outbound from './views/Outbound.vue'; import Outbound from './views/Outbound.vue';
import Pick from './views/Pick.vue'; import PickP1 from './views/PickP1.vue';
import Stacker from "@/views/Stacker.vue";
import PickP2 from "@/views/PickP2.vue";
import PickP3 from "@/views/PickP3.vue";
const debounce = (fn, delay) => { const debounce = (fn, delay) => {
let timer = null; let timer = null;
@ -56,7 +59,10 @@ export default {
components: { components: {
Inbound, Inbound,
Outbound, Outbound,
Pick Stacker,
PickP1,
PickP2,
PickP3
}, },
setup() { setup() {
const route = useRoute(); const route = useRoute();
@ -72,7 +78,10 @@ export default {
const titleMapping = { const titleMapping = {
'1': '入库', '1': '入库',
'2': '出库', '2': '出库',
'3': '拣选' '3': '堆垛机',
'4': 'P1 站台拣选',
'5': 'P2 站台拣选',
'6': 'P3 站台拣选',
}; };
// //
@ -93,8 +102,12 @@ export default {
// standId // standId
const currentComponent = computed(() => { const currentComponent = computed(() => {
const standId = currentStandId.value; const standId = currentStandId.value;
if (standId === '1') return 'Inbound';
if (standId === '2') return 'Outbound'; if (standId === '2') return 'Outbound';
if (standId === '3') return 'Pick'; if (standId === '3') return 'Stacker';
if (standId === '4') return 'PickP1';
if (standId === '5') return 'PickP2';
if (standId === '6') return 'PickP3';
return 'Inbound'; // return 'Inbound'; //
}); });
@ -166,4 +179,28 @@ export default {
<style> <style>
@import './assets/board-styles.css'; @import './assets/board-styles.css';
/* 增大标题字体大小 */
.navbar .brand {
font-size: 50px !important;
font-weight: 700;
}
/* 增加标题与内容区域的间距 */
.navbar {
margin-bottom: 30px;
}
.navbar::after {
display: none !important;
}
/* 或者增加品牌标题的上下边距 */
.navbar .brand {
font-size: 50px !important;
font-weight: 700;
margin: 0 35px;
}
</style> </style>

View File

@ -22,7 +22,7 @@ body {
} }
.board-title { .board-title {
font-size: 22px; font-size: 40px;
margin: 0 0 12px 4px; margin: 0 0 12px 4px;
color: var(--brand); color: var(--brand);
} }

View File

@ -2,23 +2,31 @@
<div class="table-wrapper"> <div class="table-wrapper">
<table> <table>
<thead> <thead>
<tr> <tr>
<th v-for="col in columns" :key="col.key">{{ col.title }}</th> <th v-for="col in columns" :key="col.key">{{ col.title }}</th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr v-if="!data?.length" class="empty-row"><td :colspan="columns.length">暂无数据</td></tr> <tr v-if="!data?.length" class="empty-row"><td :colspan="columns.length">暂无数据</td></tr>
<tr v-for="(row, idx) in data" :key="idx"> <tr v-for="(row, idx) in data" :key="idx">
<td v-for="col in columns" :key="col.key">{{ formatCell(row, col) }}</td> <td v-for="col in columns" :key="col.key" :class="getCellClass(col, row)">
</tr> <span
v-if="col.key === 'stackerStatus'"
class="stacker-status"
>
{{ formatCell(row, col) }}
</span>
<template v-else>
{{ formatCell(row, col) }}
</template>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>
</template> </template>
<script setup> <script setup>
import {compileToFunction} from "vue";
const props = defineProps({ const props = defineProps({
data: { data: {
type: Array, type: Array,
@ -34,6 +42,14 @@ function formatCell(row, col){
const v = row?.[col.key]; const v = row?.[col.key];
return col.formatter ? col.formatter(v, row) : (v ?? ''); return col.formatter ? col.formatter(v, row) : (v ?? '');
} }
function getCellClass(col, row) {
//
if (col.key === 'stackerStatus') {
return 'status-cell';
}
return '';
}
</script> </script>
<style scoped> <style scoped>
@ -80,4 +96,20 @@ tbody td:last-child {
color: #8fa3d6; color: #8fa3d6;
padding: 24px 0; padding: 24px 0;
} }
/* 为设备状态添加淡色框包围样式 */
.stacker-status {
display: inline-block;
padding: 4px 8px;
border: 1px solid #d0d7de;
border-radius: 4px;
background-color: #f6f8fa;
color: #24292f;
font-size: 14px;
line-height: 1.4;
}
.status-cell {
/* 可以为状态单元格添加额外样式 */
}
</style> </style>

View File

@ -5,6 +5,12 @@ const baseURL = process.env.VUE_APP_API_BASE_URL || (typeof window !== 'undefine
export const http = axios.create({ baseURL, timeout: 15000 }); export const http = axios.create({ baseURL, timeout: 15000 });
// 创建专门用于堆垛机数据的axios实例
const stackerHttp = axios.create({
baseURL: 'http://172.18.222.253:9980',
timeout: 15000
});
export async function queryTasksByPage(params) { export async function queryTasksByPage(params) {
const { data } = await http.post('/wms/taskQuery/queryTasksByPage', params); const { data } = await http.post('/wms/taskQuery/queryTasksByPage', params);
return data?.data; return data?.data;
@ -46,7 +52,22 @@ export async function getOutsData(params = {}) {
return data; return data;
} }
export async function getPickTaskData(params = {}) { export async function getPickTaskDataP1(params = {}) {
const { data } = await http.get('/wms/board/getPickTaskData', { params }); const { data } = await http.get('/wms/board/getPickTaskDataP1', { params });
return data;
}
export async function getPickTaskDataP2(params = {}) {
const { data } = await http.get('/wms/board/getPickTaskDataP2', { params });
return data;
}
export async function getPickTaskDataP3(params = {}) {
const { data } = await http.get('/wms/board/getPickTaskDataP3', { params });
return data;
}
export async function getStackerData(params = {}) {
const { data } = await stackerHttp.get('/api/upper/pub/queryStackerInfo', params);
return data; return data;
} }

View File

@ -76,4 +76,18 @@ onUnmounted(() => {
.title-center { .title-center {
text-align: center; text-align: center;
} }
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
</style> </style>

View File

@ -7,7 +7,7 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from 'vue'; import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue'; import DataTable from '../components/DataTable.vue';
import { getOutsData } from '../services/api'; import { getOutsData } from '@/services/api';
// //
const columns = [ const columns = [
@ -53,4 +53,17 @@ onUnmounted(() => {
.title-center { .title-center {
text-align: center; text-align: center;
} }
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
</style> </style>

View File

@ -0,0 +1,91 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getPickTaskDataP1 } from '@/services/api';
//
const columns = [
{ key: 'vehicleId', title: '料箱号', width: 200 },
{ key: 'pickStand', title: '拣选站台' },
{ key: 'createTime', title: '创建时间' },
{ key: 'arriveTime', title: '到达时间' },
{ key: 'pickStatus', title: '状态' },
];
const rows = ref([]);
let timer = null;
function mapStatus(status) {
const code = Number(status);
// WmsPickTaskStatusEnum
switch (code) {
case -2: return '入库用';
case -1: return '暂存中';
case 0: return '待下发';
case 1: return '已下发';
case 2: return '执行中';
case 3: return '已到达';
case 4: return '已离开';
case 5: return '已取消';
default: return String(status ?? '');
}
}
async function load() {
try {
const tasksData = await getPickTaskDataP1({ pageNum: 1, pageSize: 1000 });
const tasks = tasksData || [];
rows.value = tasks.map((t) => ({
vehicleId: t?.vehicleId ?? '',
pickStand: t?.pickStand ?? t?.pick_stand ?? t?.pickStation ?? t?.station ?? '',
createTime: t?.createTime ?? t?.gmtCreate ?? '',
arriveTime: t?.arriveTime ?? t?.reachTime ?? '',
pickStatus: mapStatus(t?.pickStatus ?? t?.pick_status ?? t?.taskStatus ?? t?.status),
}));
} catch (error) {
console.error('加载拣选数据失败:', error);
}
}
onMounted(() => {
load();
timer = setInterval(load, 5000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style scoped>
.title-center {
text-align: center;
}
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
/* 设置料箱号列更宽 */
:deep(th:first-child),
:deep(td:first-child) {
width: 25%;
}
</style>

View File

@ -0,0 +1,91 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getPickTaskDataP2 } from '@/services/api';
//
const columns = [
{ key: 'vehicleId', title: '料箱号', width: 200 },
{ key: 'pickStand', title: '拣选站台' },
{ key: 'createTime', title: '创建时间' },
{ key: 'arriveTime', title: '到达时间' },
{ key: 'pickStatus', title: '状态' },
];
const rows = ref([]);
let timer = null;
function mapStatus(status) {
const code = Number(status);
// WmsPickTaskStatusEnum
switch (code) {
case -2: return '入库用';
case -1: return '暂存中';
case 0: return '待下发';
case 1: return '已下发';
case 2: return '执行中';
case 3: return '已到达';
case 4: return '已离开';
case 5: return '已取消';
default: return String(status ?? '');
}
}
async function load() {
try {
const tasksData = await getPickTaskDataP2({ pageNum: 1, pageSize: 1000 });
const tasks = tasksData || [];
rows.value = tasks.map((t) => ({
vehicleId: t?.vehicleId ?? '',
pickStand: t?.pickStand ?? t?.pick_stand ?? t?.pickStation ?? t?.station ?? '',
createTime: t?.createTime ?? t?.gmtCreate ?? '',
arriveTime: t?.arriveTime ?? t?.reachTime ?? '',
pickStatus: mapStatus(t?.pickStatus ?? t?.pick_status ?? t?.taskStatus ?? t?.status),
}));
} catch (error) {
console.error('加载拣选数据失败:', error);
}
}
onMounted(() => {
load();
timer = setInterval(load, 5000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style scoped>
.title-center {
text-align: center;
}
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
/* 设置料箱号列更宽 */
:deep(th:first-child),
:deep(td:first-child) {
width: 25%;
}
</style>

View File

@ -7,7 +7,7 @@
<script setup> <script setup>
import { ref, onMounted, onUnmounted } from 'vue'; import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue'; import DataTable from '../components/DataTable.vue';
import { getPickTaskData } from '../services/api'; import { getPickTaskDataP3 } from '@/services/api';
// //
const columns = [ const columns = [
@ -39,7 +39,7 @@ function mapStatus(status) {
async function load() { async function load() {
try { try {
const tasksData = await getPickTaskData({ pageNum: 1, pageSize: 1000 }); const tasksData = await getPickTaskDataP3({ pageNum: 1, pageSize: 1000 });
const tasks = tasksData || []; const tasks = tasksData || [];
rows.value = tasks.map((t) => ({ rows.value = tasks.map((t) => ({
vehicleId: t?.vehicleId ?? '', vehicleId: t?.vehicleId ?? '',
@ -69,4 +69,23 @@ onUnmounted(() => {
.title-center { .title-center {
text-align: center; text-align: center;
} }
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
/* 设置料箱号列更宽 */
:deep(th:first-child),
:deep(td:first-child) {
width: 25%;
}
</style> </style>

View File

@ -0,0 +1,122 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getStackerData } from '@/services/api';
//
const columns = [
{ key: 'tunnelId', title: '堆垛机编号' },
{ key: 'plcId', title: '任务号' },
{
key: 'stackerStatus',
title: '设备状态',
formatter: (value) => value //
},
{ key: 'controlModel', title: '堆垛机控制方式' },
];
const rows = ref([]);
let timer = null;
//
const statusMap = {
'-1': '未知',
0: '脱机',
1: '空闲',
2: '任务接收',
3: '取货移动',
4: '取货中',
5: '取货完成',
6: '卸货移动',
7: '卸货中',
8: '卸货完成',
9: '任务完成',
10: '删除任务',
11: '盘点中',
21: '二次预约申请'
};
//
const controlModeMap = {
'-1': '未知',
0: '离线',
1: '自学习',
2: '调试',
3: '手动',
4: '单机',
5: '联机'
};
async function load() {
try {
const response = await getStackerData({ pageNum: 1, pageSize: 100 });
//
const stackerData = response?.returnData || response?.data || [];
if (Array.isArray(stackerData)) {
rows.value = stackerData.map(item => ({
tunnelId: item?.tunnelId ?? '',
plcId: item?.plcId ?? '',
stackerStatus: statusMap[item?.stackerStatus] || item?.stackerStatus || '',
controlModel: controlModeMap[item?.controlModel] || item?.controlModel || ''
}));
} else {
rows.value = [];
}
} catch (error) {
console.error('加载堆垛机状态数据失败:', error);
rows.value = [];
}
}
onMounted(() => {
load();
timer = setInterval(load, 5000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style scoped>
.title-center {
text-align: center;
}
/* 为设备状态添加淡色框包围样式,增大字体 */
:deep(.stacker-status) {
display: inline-block;
padding: 6px 12px;
border: 1px solid #d0d7de;
border-radius: 4px;
background-color: #f6f8fa;
color: #24292f;
font-size: 40px; /* 增大字体 */
line-height: 1.4;
}
/* 增大表格整体字体 */
:deep(.table-wrapper) {
font-size: 40px;
}
:deep(thead th) {
font-size: 40px; /* 表头字体稍大 */
}
:deep(tbody td) {
font-size: 40px; /* 表格内容字体 */
padding: 16px 12px; /* 同时增加内边距使布局更舒适 */
}
</style>

Binary file not shown.

View File

@ -1,8 +1,8 @@
import axios from 'axios' import axios from 'axios'
const request = axios.create({ const request = axios.create({
baseURL: 'http://172.18.222.253:12315/wms', //baseURL: 'http://172.18.222.253:12315/wms',
//baseURL: 'http://localhost:12315/wms', baseURL: 'http://localhost:12315/wms',
timeout: 5000 timeout: 5000
}) })
// 172.18.222.253 // 172.18.222.253

View File

@ -2,46 +2,46 @@
<el-config-provider :locale="zhCn"> <el-config-provider :locale="zhCn">
<el-container class="content"> <el-container class="content">
<div class="work-area"> <div class="work-area">
<fieldset class="search-area"> <!-- <fieldset class="search-area">-->
<el-form ref="outTaskRef" :model="outTaskEntity" :label-position="labelPosition" label-width="158px" <!-- <el-form ref="outTaskRef" :model="outTaskEntity" :label-position="labelPosition" label-width="158px"-->
style="max-width: 100%" :rules="requestRules" status-icon> <!-- style="max-width: 100%" :rules="requestRules" status-icon>-->
<div style="display: flex; justify-content: space-between;"> <!-- <div style="display: flex; justify-content: space-between;">-->
<el-row> <!-- <el-row>-->
<!-- <el-form-item label="出库类型" prop="outType"> <!-- &lt;!&ndash; <el-form-item label="出库类型" prop="outType">-->
<el-select-v2 style="width: 196px" v-model="outTaskEntity.outType" placeholder="请选择入库类型" <!-- <el-select-v2 style="width: 196px" v-model="outTaskEntity.outType" placeholder="请选择入库类型"-->
:options="outTypeOptions"></el-select-v2> <!-- :options="outTypeOptions"></el-select-v2>-->
</el-form-item> --> <!-- </el-form-item> &ndash;&gt;-->
<el-form-item label="料号" prop="goodsId"> <!-- <el-form-item label="料号" prop="goodsId">-->
<el-input v-model="outTaskEntity.goodsId" @blur="getLackQty()" clearable/> <!-- <el-input v-model="outTaskEntity.goodsId" @blur="getLackQty()" clearable/>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="箱号" prop="vehicleId" v-if="outTaskEntity.outType !== 9"> <!-- <el-form-item label="箱号" prop="vehicleId" v-if="outTaskEntity.outType !== 9">-->
<el-input v-model="outTaskEntity.vehicleId" clearable/> <!-- <el-input v-model="outTaskEntity.vehicleId" clearable/>-->
</el-form-item> <!-- </el-form-item>-->
<el-form-item label="数量" prop="needNum"> <!-- <el-form-item label="数量" prop="needNum">-->
<el-input-number style="width: 196px" v-model.number="outTaskEntity.needNum" <!-- <el-input-number style="width: 196px" v-model.number="outTaskEntity.needNum"-->
controls-position="right" :min="1" clearable/> <!-- controls-position="right" :min="1" clearable/>-->
</el-form-item> <!-- </el-form-item>-->
<!-- <el-form-item label="原因" prop="reason" v-if="outTaskEntity.outType === 9"> <!-- &lt;!&ndash; <el-form-item label="原因" prop="reason" v-if="outTaskEntity.outType === 9">-->
<el-select-v2 style="width: 196px" v-model="outTaskEntity.reason" placeholder="请选择紧急出库原因" <!-- <el-select-v2 style="width: 196px" v-model="outTaskEntity.reason" placeholder="请选择紧急出库原因"-->
:options="reasonOptions"></el-select-v2> <!-- :options="reasonOptions"></el-select-v2>-->
</el-form-item> --> <!-- </el-form-item> &ndash;&gt;-->
<el-form-item label="工单" prop="workOrder" v-if="outTaskEntity.reason === '缺料'"> <!-- <el-form-item label="工单" prop="workOrder" v-if="outTaskEntity.reason === '缺料'">-->
<el-input v-model="outTaskEntity.workOrder" @blur="getLackQty()" clearable/> <!-- <el-input v-model="outTaskEntity.workOrder" @blur="getLackQty()" clearable/>-->
</el-form-item> <!-- </el-form-item>-->
</el-row> <!-- </el-row>-->
<el-row> <!-- <el-row>-->
<el-button type="primary" <!-- <el-button type="primary"-->
style="height: 50px; width: 100px; margin: auto 5px auto 5px; font-size: large; color: black;" <!-- style="height: 50px; width: 100px; margin: auto 5px auto 5px; font-size: large; color: black;"-->
@click="confirmOut()">确认出库 <!-- @click="confirmOut()">确认出库-->
</el-button> <!-- </el-button>-->
<el-button type="warning" <!-- <el-button type="warning"-->
style="height: 50px; width: 100px; margin: auto 5px auto 5px; font-size: large; color: black;" <!-- style="height: 50px; width: 100px; margin: auto 5px auto 5px; font-size: large; color: black;"-->
@click="clearInput()">清除输入 <!-- @click="clearInput()">清除输入-->
</el-button> <!-- </el-button>-->
</el-row> <!-- </el-row>-->
</div> <!-- </div>-->
</el-form> <!-- </el-form>-->
</fieldset> <!-- </fieldset>-->
<!-- 修改confirm-area为竖直布局表单项两两一排 --> <!-- 修改confirm-area为竖直布局表单项两两一排 -->
<!-- 修改confirm-area为竖直布局表单项两两一排 --> <!-- 修改confirm-area为竖直布局表单项两两一排 -->
<div style="display: flex; margin-top: 10px;"> <div style="display: flex; margin-top: 10px;">
@ -230,25 +230,30 @@ let confirmEntities = reactive([
} }
]) ])
const confirmRules = reactive({}) const confirmRules = reactive({})
let pauseGetPickFlag = ref(false) //let pauseGetPickFlag = ref(false)
let hasDataTaskResult = ref(false) //
const route = useRoute()// const route = useRoute()//
// //
onMounted(() => { onMounted(() => {
nextTick(() => { nextTick(() => {
timer.value = setInterval(() => { startTimer() //
timerTask_1()
}, 1000)
}) })
}) })
onBeforeUnmount(() => { onBeforeUnmount(() => {
clearInterval(timer.value) clearInterval(timer.value)
}) })
//
const startTimer = () => {
clearInterval(timer.value) //
timer.value = setInterval(() => {
timerTask_1()
}, 2000) // 2
}
// //
// watch
watch(() => route.path, (newVal, oldVal) => { watch(() => route.path, (newVal, oldVal) => {
if (newVal === '/goodsOut') { if (newVal === '/goodsOut') {
timer.value = setInterval(() => { startTimer() //
timerTask_1()
}, 1000)
} else { } else {
clearInterval(timer.value) clearInterval(timer.value)
} }
@ -259,9 +264,9 @@ const timerTask_1 = () => {
} }
// //
const getTask = () => { const getTask = () => {
if (pauseGetPickFlag.value) { // if (pauseGetPickFlag.value) {
return // return
} // }
const request = { const request = {
standId: STAND_ID, standId: STAND_ID,
userName: USER_NAME userName: USER_NAME
@ -271,6 +276,16 @@ const getTask = () => {
const response = res.data const response = res.data
console.log(response) console.log(response)
if (response.code === 0) { if (response.code === 0) {
//
if (!hasDataTaskResult.value) {
//
hasDataTaskResult.value = true
clearInterval(timer.value)
timer.value = setInterval(() => {
timerTask_1()
}, 10000) // 10
}
const confirmVos = response.data const confirmVos = response.data
// ID // ID
let childStandOrder = [] let childStandOrder = []
@ -326,18 +341,28 @@ const getTask = () => {
warningBox(`请注意!${found.childStandId}站台,剩余数量小于预警值,请检查并核对数量。`) warningBox(`请注意!${found.childStandId}站台,剩余数量小于预警值,请检查并核对数量。`)
} }
}) })
} else if (response.code === 400) {
//
if (hasDataTaskResult.value) {
pauseGetPickFlag.value = true //
} else if (response.code === 400) { hasDataTaskResult.value = false
// clearInterval(timer.value)
pauseGetPickFlag.value = true timer.value = setInterval(() => {
timerTask_1()
}, 2000) // 2
}
warningBox(response.message) warningBox(response.message)
} }
}).catch(err => { }).catch(err => {
console.log(err) console.log(err)
pauseGetPickFlag.value = true //
if (hasDataTaskResult.value) {
hasDataTaskResult.value = false
clearInterval(timer.value)
timer.value = setInterval(() => {
timerTask_1()
}, 2000) // 2
}
errorBox('请求错误,请检查完原因后刷新界面。') errorBox('请求错误,请检查完原因后刷新界面。')
}) })
} }
@ -444,12 +469,14 @@ const confirmOrRelease = (index) => {
confirmCurrentTask(request, { timeout: 5000 }).then(res => { confirmCurrentTask(request, { timeout: 5000 }).then(res => {
const response = res.data const response = res.data
if (response.code === 0) { if (response.code === 0) {
clearConfirmEntity(index) // clearConfirmEntity(index)
//
pauseGetPickFlag.value = false
ElMessage.success(response.message) ElMessage.success(response.message)
// 2
setTimeout(() => {
//
getTask()
}, 100)
} else if (response.code === 400) { } else if (response.code === 400) {
pauseGetPickFlag.value = false
warningBox(response.message) warningBox(response.message)
} else { } else {
// //

View File

@ -24,6 +24,7 @@ public enum AppConfigKeyEnums {
EWM_SEND_WAREHOUSE_IN_COMPLETED_URL("EwmSendTaskCompleteUrl", "发送入库完成地址"), EWM_SEND_WAREHOUSE_IN_COMPLETED_URL("EwmSendTaskCompleteUrl", "发送入库完成地址"),
EWM_SEND_CONTAINER_EMPTY_URL("VehicleEmpty", "发送箱体清空地址"), EWM_SEND_CONTAINER_EMPTY_URL("VehicleEmpty", "发送箱体清空地址"),
EWM_GET_STOCK_LIST_URL("EwmStockBackUrl", "发送出库任务地址"), EWM_GET_STOCK_LIST_URL("EwmStockBackUrl", "发送出库任务地址"),
EWM_CHECK_CONTAINER_NO_URL("EwmCheckContainerNo", "检验目标箱号是否可用"),
EWM_SEND_WAREHOUSE_OUT_COMPLETED_URL("EwmSendOutTaskCompleteUrl", "发送出库完成地址"); EWM_SEND_WAREHOUSE_OUT_COMPLETED_URL("EwmSendOutTaskCompleteUrl", "发送出库完成地址");
private final String key; private final String key;
private final String desc; private final String desc;

View File

@ -50,15 +50,33 @@ public class DataController {
/** /**
* 获取拣选任务 * 获取拣选任务
*/ */
@GetMapping("/getPickTaskData") @GetMapping("/getPickTaskDataP1")
public Object getPickTaskData(@RequestParam(defaultValue = "1") int pageNum, public Object getPickTaskDataP1(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) { @RequestParam(defaultValue = "10") int pageSize) {
try { try {
return dataControllerService.getPickTaskData(pageNum, pageSize); return dataControllerService.getPickTaskDataP1(pageNum, pageSize);
} catch (Exception e) { } catch (Exception e) {
return "获取拣选任务失败: " + e.getMessage(); return "获取拣选任务失败: " + e.getMessage();
} }
} }
@GetMapping("/getPickTaskDataP2")
public Object getPickTaskDataP2(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
try {
return dataControllerService.getPickTaskDataP2(pageNum, pageSize);
} catch (Exception e) {
return "获取拣选任务失败: " + e.getMessage();
}
}
@GetMapping("/getPickTaskDataP3")
public Object getPickTaskDataP3(@RequestParam(defaultValue = "1") int pageNum,
@RequestParam(defaultValue = "10") int pageSize) {
try {
return dataControllerService.getPickTaskDataP3(pageNum, pageSize);
} catch (Exception e) {
return "获取拣选任务失败: " + e.getMessage();
}
}
} }

View File

@ -141,6 +141,13 @@ public class EwmOutTaskRequest {
@JsonProperty("batchNo") @JsonProperty("batchNo")
private String batchNo; private String batchNo;
/**
* 颗粒度
*/
@JsonProperty("secondPickingKey")
private String secondPickingKey;
// Getters and Setters // Getters and Setters
} }

View File

@ -0,0 +1,32 @@
package com.wms_main.model.dto.request.ewm;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class SendEwmCheckContainerNo {
/**
* 载具号
*/
@JsonProperty("containerNo")
private String containerNo;
/**
* 类型
*/
@JsonProperty("type")
private String type;
/**
* 是否二次
*/
@JsonProperty("firstOrSecond")
private boolean firstOrSecond;
/**
* 颗粒度
*/
@JsonProperty("checkKey")
private String checkKey;
}

View File

@ -127,4 +127,11 @@ public class TAppOuts {
*/ */
@TableField(value = "unit") @TableField(value = "unit")
private String unit; private String unit;
/**
* 二次拣货码/颗粒度
*/
@TableField(value = "second_picking_code")
private String secondPickingCode;
} }

View File

@ -63,4 +63,18 @@ public class TAppOutsCheck {
*/ */
@TableField(value = "container_no") @TableField(value = "container_no")
private String containerNo; private String containerNo;
/**
* 二次拣货码/颗粒度
*/
@TableField(value = "second_picking_code")
private String secondPickingCode;
/**
* 客户工单号
*/
@TableField(value = "order_no")
private String orderNo;
} }

View File

@ -1,9 +1,6 @@
package com.wms_main.service.api; package com.wms_main.service.api;
import com.wms_main.model.dto.request.ewm.SendEwmGetStockInformationRequest; import com.wms_main.model.dto.request.ewm.*;
import com.wms_main.model.dto.request.ewm.SendEwmVehicleForInRequest;
import com.wms_main.model.dto.request.ewm.SendWarehouseInCompletedRequest;
import com.wms_main.model.dto.request.ewm.SendWarehouseOutCompletedRequest;
import com.wms_main.model.dto.response.ewm.EwmApiBackResponse; import com.wms_main.model.dto.response.ewm.EwmApiBackResponse;
import com.wms_main.model.dto.response.ewm.EwmApiLocalResponse; import com.wms_main.model.dto.response.ewm.EwmApiLocalResponse;
import com.wms_main.model.dto.response.ewm.EwmApiStockResponse; import com.wms_main.model.dto.response.ewm.EwmApiStockResponse;
@ -45,4 +42,10 @@ public interface IEwmApiService {
*/ */
EwmApiStockResponse getEwmStock(SendEwmGetStockInformationRequest request); EwmApiStockResponse getEwmStock(SendEwmGetStockInformationRequest request);
/**
* 目标箱号向EWM系统验证
* @return 获取到的库存
*/
EwmApiBackResponse sendEwmCheckContainerNo(SendEwmCheckContainerNo request);
} }

View File

@ -2,10 +2,7 @@ package com.wms_main.service.api.serviceImpl;
import com.wms_main.app.AppCommon; import com.wms_main.app.AppCommon;
import com.wms_main.constant.enums.wms.AppConfigKeyEnums; import com.wms_main.constant.enums.wms.AppConfigKeyEnums;
import com.wms_main.model.dto.request.ewm.SendEwmGetStockInformationRequest; import com.wms_main.model.dto.request.ewm.*;
import com.wms_main.model.dto.request.ewm.SendEwmVehicleForInRequest;
import com.wms_main.model.dto.request.ewm.SendWarehouseInCompletedRequest;
import com.wms_main.model.dto.request.ewm.SendWarehouseOutCompletedRequest;
import com.wms_main.model.dto.response.ewm.EwmApiBackResponse; import com.wms_main.model.dto.response.ewm.EwmApiBackResponse;
import com.wms_main.model.dto.response.ewm.EwmApiLocalResponse; import com.wms_main.model.dto.response.ewm.EwmApiLocalResponse;
import com.wms_main.model.dto.response.ewm.EwmApiStockResponse; import com.wms_main.model.dto.response.ewm.EwmApiStockResponse;
@ -25,7 +22,7 @@ import org.springframework.stereotype.Service;
@Slf4j @Slf4j
public class EwmApiServiceImpl implements IEwmApiService { public class EwmApiServiceImpl implements IEwmApiService {
private final HttpClient httpClient;// http客户端 private final HttpClient httpClient;// http客户端
private final AppCommon appCommon;// 应用共通 private final AppCommon appCommon;// 应用共通asrs/mom@123456
/** /**
* 发送载具入库请求到EWM系统 * 发送载具入库请求到EWM系统
@ -36,7 +33,7 @@ public class EwmApiServiceImpl implements IEwmApiService {
public EwmApiLocalResponse sendVehicleForIn(SendEwmVehicleForInRequest request) { public EwmApiLocalResponse sendVehicleForIn(SendEwmVehicleForInRequest request) {
try { try {
// 构建Basic Auth认证信息 // 构建Basic Auth认证信息
String auth = "mom:test@123"; String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes()); String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求 // 设置http请求
@ -73,7 +70,7 @@ public class EwmApiServiceImpl implements IEwmApiService {
public EwmApiBackResponse sendWarehouseInCompleted(SendWarehouseInCompletedRequest request) { public EwmApiBackResponse sendWarehouseInCompleted(SendWarehouseInCompletedRequest request) {
try { try {
// 构建Basic Auth认证信息 // 构建Basic Auth认证信息
String auth = "mom:test@123"; String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes()); String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求 // 设置http请求
@ -101,7 +98,7 @@ public class EwmApiServiceImpl implements IEwmApiService {
public EwmApiBackResponse sendWarehouseOutCompleted(SendWarehouseOutCompletedRequest request) { public EwmApiBackResponse sendWarehouseOutCompleted(SendWarehouseOutCompletedRequest request) {
try { try {
// 构建Basic Auth认证信息 // 构建Basic Auth认证信息
String auth = "mom:test@123"; String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes()); String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求 // 设置http请求
@ -137,7 +134,7 @@ public class EwmApiServiceImpl implements IEwmApiService {
String finalUrl = baseUrl.replace("{palletNo}", request.getContainerNo()); // 示例具体字段名需根据实际类确定 String finalUrl = baseUrl.replace("{palletNo}", request.getContainerNo()); // 示例具体字段名需根据实际类确定
// 构建Basic Auth认证信息 // 构建Basic Auth认证信息
String auth = "mom:test@123"; String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes()); String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求将认证信息放在token字段中 // 设置http请求将认证信息放在token字段中
@ -165,7 +162,7 @@ public class EwmApiServiceImpl implements IEwmApiService {
public EwmApiStockResponse getEwmStock(SendEwmGetStockInformationRequest request) { public EwmApiStockResponse getEwmStock(SendEwmGetStockInformationRequest request) {
try { try {
// 构建Basic Auth认证信息 // 构建Basic Auth认证信息
String auth = "mom:test@123"; String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes()); String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求 // 设置http请求
@ -187,4 +184,32 @@ public class EwmApiServiceImpl implements IEwmApiService {
return EwmApiStockResponse.error("调用EWM系统接口异常: " + e.getMessage()); return EwmApiStockResponse.error("调用EWM系统接口异常: " + e.getMessage());
} }
} }
@Override
public EwmApiBackResponse sendEwmCheckContainerNo(SendEwmCheckContainerNo request) {
try {
// 构建Basic Auth认证信息
String auth = "asrs:mom@123456";
String encodedAuth = java.util.Base64.getEncoder().encodeToString(auth.getBytes());
// 设置http请求
HttpRequest httpRequest = HttpRequest.postInstanceOf(
appCommon.getConfigByKey(AppConfigKeyEnums.EWM_CHECK_CONTAINER_NO_URL.getKey()),
request,
5000,
"application/json",
"Basic " + encodedAuth);
HttpResponse httpResponse = httpClient.httpPost(httpRequest);
if (httpResponse != null && httpResponse.isSuccess()) {
return httpResponse.getData(EwmApiBackResponse.class);
}
log.warn("请求验证EWM系统返回空响应或请求失败请求参数: {}", request);
return EwmApiBackResponse.error("EWM系统返回空响应或请求失败");
} catch (Exception e) {
log.error("调用EWM系统接口异常请求参数: {}", request, e);
return EwmApiBackResponse.error("调用EWM系统接口异常: " + e.getMessage());
}
}
} }

View File

@ -26,5 +26,18 @@ public interface IDataControllerService {
* 获取拣选任务信息 * 获取拣选任务信息
* @return 拣选任务信息 * @return 拣选任务信息
*/ */
List<TAppPickTask> getPickTaskData(int pageNum, int pageSize); List<TAppPickTask> getPickTaskDataP1(int pageNum, int pageSize);
/**
* 获取拣选任务信息
* @return 拣选任务信息
*/
List<TAppPickTask> getPickTaskDataP2(int pageNum, int pageSize);
/**
* 获取拣选任务信息
* @return 拣选任务信息
*/
List<TAppPickTask> getPickTaskDataP3(int pageNum, int pageSize);
} }

View File

@ -52,8 +52,23 @@ public class DataControllerServiceImpl implements IDataControllerService {
* @return 拣选任务数据列表 * @return 拣选任务数据列表
*/ */
@Override @Override
public List<TAppPickTask> getPickTaskData(int pageNum, int pageSize) { public List<TAppPickTask> getPickTaskDataP1(int pageNum, int pageSize) {
LambdaQueryWrapper<TAppPickTask> queryWrapper = new LambdaQueryWrapper<>(); LambdaQueryWrapper<TAppPickTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(TAppPickTask::getPickStand, "P11", "P12", "P13");
return tAppPickTaskService.page(new Page<>(pageNum, pageSize), queryWrapper).getRecords();
}
@Override
public List<TAppPickTask> getPickTaskDataP2(int pageNum, int pageSize) {
LambdaQueryWrapper<TAppPickTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(TAppPickTask::getPickStand, "P14", "P15", "P16");
return tAppPickTaskService.page(new Page<>(pageNum, pageSize), queryWrapper).getRecords();
}
@Override
public List<TAppPickTask> getPickTaskDataP3(int pageNum, int pageSize) {
LambdaQueryWrapper<TAppPickTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.in(TAppPickTask::getPickStand, "P17", "P18", "P19");
return tAppPickTaskService.page(new Page<>(pageNum, pageSize), queryWrapper).getRecords(); return tAppPickTaskService.page(new Page<>(pageNum, pageSize), queryWrapper).getRecords();
} }
} }

View File

@ -355,7 +355,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
null, null,
null, null,
null, null,
null,null null,null, null
); );
appOutsService.save(task); appOutsService.save(task);
return BaseWmsApiResponse.success("添加出库请求成功。"); return BaseWmsApiResponse.success("添加出库请求成功。");
@ -501,7 +501,8 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
task.getBatchNo(), task.getBatchNo(),
ewmOutTaskRequest.getPickingType(), ewmOutTaskRequest.getPickingType(),
ewmOutTaskRequest.getWaveNo(), ewmOutTaskRequest.getWaveNo(),
task.getSkuUnit() task.getSkuUnit(),
task.getSecondPickingKey()
); );
//appOuts.add(outs); //appOuts.add(outs);
appOutsService.save(outs); appOutsService.save(outs);
@ -809,7 +810,8 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
null, null,
null, null,
null, null,
null,null null,null,
null
)); ));
} }
@ -1426,9 +1428,52 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
if (pickTaskList.size() > 1) { if (pickTaskList.size() > 1) {
return BaseWmsApiResponse.error("当前站台有多个箱子到达,请检查。"); return BaseWmsApiResponse.error("当前站台有多个箱子到达,请检查。");
} }
TAppOuts thisOut = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>() TAppOuts thisOut = appOutsService.getOne(new LambdaQueryWrapper<TAppOuts>()
.eq(TAppOuts::getTaskId, confirmTaskRequest.getTaskConfirm().getTaskId())); .eq(TAppOuts::getTaskId, confirmTaskRequest.getTaskConfirm().getTaskId()));
// 调用EWM系统检验箱子
SendEwmCheckContainerNo request = new SendEwmCheckContainerNo();
request.setContainerNo(confirmTaskRequest.getTaskConfirm().getContainerNo());
request.setType(thisOut.getPickingType());
request.setFirstOrSecond(false);
request.setCheckKey(thisOut.getSecondPickingCode());
EwmApiBackResponse ewmResponse = ewmApiService.sendEwmCheckContainerNo(request);
// 判断EWM系统返回结果
if (ewmResponse == null || !"successfully".equals(ewmResponse.getState())) {
if (ewmResponse != null) {
return BaseWmsApiResponse.error(ewmResponse.getContent().toString());
}
return BaseWmsApiResponse.error("EWM系统异常请检查。");
}
// 检测目标箱号是否存在别的物料以颗粒度为第一优先级如果颗粒度为空则使用工单号
List<TAppOutsCheck> thisOutsChecks = appOutsCheckService.list(new LambdaQueryWrapper<TAppOutsCheck>()
.eq(TAppOutsCheck::getContainerNo, confirmTaskRequest.getTaskConfirm().getContainerNo()));
if (thisOutsChecks != null && !thisOutsChecks.isEmpty()) {
TAppOutsCheck existingCheck = thisOutsChecks.getFirst();
// 1. 检测是否是颗粒度相同考虑 null empty
String existingSecondPickingCode = existingCheck.getSecondPickingCode();
String newSecondPickingCode = thisOut.getSecondPickingCode();
boolean isSecondPickingCodeMatch = (StringUtils.isEmpty(existingSecondPickingCode) && StringUtils.isEmpty(newSecondPickingCode))
|| Objects.equals(existingSecondPickingCode, newSecondPickingCode);
if (!isSecondPickingCodeMatch) {
return BaseWmsApiResponse.error("当前目标箱号已存在其他颗粒度物料,请检查。");
}
// 2. 如果颗粒度一致包括都为空再检测工单号是否相同
String existingOrderNo = existingCheck.getOrderNo();
String newOrderNo = thisOut.getOrderNo();
boolean isOrderNoMatch = Objects.equals(existingOrderNo, newOrderNo);
if (!isOrderNoMatch) {
return BaseWmsApiResponse.error("当前目标箱号已存在其他工单号物料,请检查。");
}
}
// 将出库完成需要反馈的信息插入outsCheck表中 // 将出库完成需要反馈的信息插入outsCheck表中
List<TAppOutsCheck> outsChecks = new ArrayList<>(); List<TAppOutsCheck> outsChecks = new ArrayList<>();
outsChecks.add(new TAppOutsCheck( outsChecks.add(new TAppOutsCheck(
@ -1439,7 +1484,9 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
confirmTaskRequest.getTaskConfirm().getTotalNeed(), confirmTaskRequest.getTaskConfirm().getTotalNeed(),
confirmTaskRequest.getTaskConfirm().getRealPickQty(), confirmTaskRequest.getTaskConfirm().getRealPickQty(),
thisOut.getUnit(), thisOut.getUnit(),
confirmTaskRequest.getTaskConfirm().getContainerNo() confirmTaskRequest.getTaskConfirm().getContainerNo(),
thisOut.getSecondPickingCode(),
thisOut.getOrderNo()
)); ));
appOutsCheckService.saveBatch(outsChecks); appOutsCheckService.saveBatch(outsChecks);
// 当前站台到达的拣选任务 // 当前站台到达的拣选任务
@ -1966,7 +2013,7 @@ public class TaskControllerServiceImpl implements ITaskControllerService {
// 触发事务回滚 // 触发事务回滚
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly(); TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
// 返回错误信息 // 返回错误信息
return "调用EWM系统接口异常"; return ewmApiBackResponse.toString();
} }