Compare commits

..

No commits in common. "2cec12510e06f3db4fd1859f82dfa342ecf904b4" and "8567c728cab2ebb89901185fa5fd04a842da190a" have entirely different histories.

27 changed files with 0 additions and 11801 deletions

8
.idea/.gitignore vendored
View File

@ -1,8 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

23
board/CODE/.gitignore vendored
View File

@ -1,23 +0,0 @@
.DS_Store
node_modules
/dist
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,19 +0,0 @@
# wms_stand
## Project setup
```
npm install
```
### Compiles and hot-reloads for development
```
npm run serve
```
### Compiles and minifies for production
```
npm run build
```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -1,5 +0,0 @@
module.exports = {
presets: [
'@vue/cli-plugin-babel/preset'
]
}

View File

@ -1,19 +0,0 @@
{
"compilerOptions": {
"target": "es5",
"module": "esnext",
"baseUrl": "./",
"moduleResolution": "node",
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
{
"name": "wms_stand",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build"
},
"dependencies": {
"axios": "^1.7.9",
"core-js": "^3.8.3",
"element-plus": "^2.9.4",
"fullscreen": "^1.1.1",
"vue": "^3.2.13",
"vue-router": "^4.0.3",
"vuex": "^4.0.0"
},
"devDependencies": {
"@vue/cli-plugin-babel": "~5.0.0",
"@vue/cli-plugin-router": "~5.0.0",
"@vue/cli-plugin-vuex": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"sass": "^1.32.7",
"sass-loader": "^12.0.0"
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -1,17 +0,0 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>丰尚立库状态一览表</title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -1,169 +0,0 @@
<template>
<div class="layout">
<header class="navbar">
<div class="brand">{{ dynamicTitle }}</div>
<div class="control-buttons">
<button
v-show="!isFullscreenState"
@click="enterFullscreen"
class="hidBtn fullscreen-btn"
>
全屏
</button>
<button
v-show="isFullscreenState"
@click="exitFullscreen"
class="hidBtn exit-btn"
>
退出
</button>
</div>
</header>
<main class="content">
<component :is="currentComponent" />
</main>
</div>
</template>
<script>
import { ref, onMounted, onUnmounted, computed } from 'vue';
import { useRoute } from 'vue-router';
import Inbound from './views/Inbound.vue';
import Outbound from './views/Outbound.vue';
import Pick from './views/Pick.vue';
const debounce = (fn, delay) => {
let timer = null;
return function () {
let context = this;
let args = arguments;
clearTimeout(timer);
timer = setTimeout(function () {
fn.apply(context, args);
}, delay);
};
};
const _ResizeObserver = window.ResizeObserver;
window.ResizeObserver = class ResizeObserver extends _ResizeObserver {
constructor(callback) {
callback = debounce(callback, 16);
super(callback);
}
};
export default {
name: 'App',
components: {
Inbound,
Outbound,
Pick
},
setup() {
const route = useRoute();
const isFullscreenState = ref(false);
// standId
const currentStandId = computed(() => {
const params = new URLSearchParams(window.location.search);
return params.get('standId');
});
//
const titleMapping = {
'1': '入库',
'2': '出库',
'3': '拣选'
};
//
const dynamicTitle = computed(() => {
const standId = currentStandId.value;
if (!standId) {
// standId
return '丰尚立库  状态一览表';
}
const operation = titleMapping[standId];
if (operation) {
return `丰尚立库 ${operation} 状态一览表`;
}
// standId
return '丰尚立库 状态一览表';
});
// standId
const currentComponent = computed(() => {
const standId = currentStandId.value;
if (standId === '2') return 'Outbound';
if (standId === '3') return 'Pick';
return 'Inbound'; //
});
function isFullscreen() {
return !!(document.fullscreenElement || document.webkitFullscreenElement || document.mozFullScreenElement || document.msFullscreenElement);
}
async function requestFS(el) {
if (el.requestFullscreen) return el.requestFullscreen();
if (el.webkitRequestFullscreen) return el.webkitRequestFullscreen();
if (el.mozRequestFullScreen) return el.mozRequestFullScreen();
if (el.msRequestFullscreen) return el.msRequestFullscreen();
}
async function exitFS() {
if (document.exitFullscreen) return document.exitFullscreen();
if (document.webkitExitFullscreen) return document.webkitExitFullscreen();
if (document.mozCancelFullScreen) return document.mozCancelFullScreen();
if (document.msExitFullscreen) return document.msExitFullscreen();
}
async function enterFullscreen() {
try {
await requestFS(document.documentElement);
isFullscreenState.value = true;
} catch (err) {
console.error('Error attempting to enable full-screen mode:', err);
}
}
async function exitFullscreen() {
try {
await exitFS();
isFullscreenState.value = false;
} catch (err) {
console.error('Error attempting to exit full-screen mode:', err);
}
}
function handleFullscreenChange() {
isFullscreenState.value = isFullscreen();
}
onMounted(() => {
isFullscreenState.value = isFullscreen();
document.addEventListener('fullscreenchange', handleFullscreenChange);
document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
document.addEventListener('mozfullscreenchange', handleFullscreenChange);
document.addEventListener('MSFullscreenChange', handleFullscreenChange);
});
onUnmounted(() => {
document.removeEventListener('fullscreenchange', handleFullscreenChange);
document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
document.removeEventListener('mozfullscreenchange', handleFullscreenChange);
document.removeEventListener('MSFullscreenChange', handleFullscreenChange);
});
return {
dynamicTitle,
currentComponent,
isFullscreenState,
enterFullscreen,
exitFullscreen
};
}
};
</script>
<style>
@import './assets/board-styles.css';
</style>

View File

@ -1,161 +0,0 @@
:root {
--bg: #ffffff;
--text: #141a29;
--muted: #5b6b8a;
--brand: #3756b5;
--header: #142357;
--border: #20315e;
}
* {
box-sizing: border-box;
}
html, body, #app {
height: 100%;
margin: 0;
}
body {
background: var(--bg);
color: var(--text);
}
.board-title {
font-size: 22px;
margin: 0 0 12px 4px;
color: var(--brand);
}
.table-wrapper {
border-radius: 8px;
overflow: hidden;
border: 1px solid var(--border);
box-shadow: 0 4px 16px rgba(0,0,0,.35);
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
thead th {
background: var(--header);
color: #fff;
padding: 12px 10px;
font-weight: 700;
font-size: 18px;
text-align: center;
border-right: 2px solid rgba(255,255,255,0.3);
}
thead th:last-child {
border-right: none;
}
tbody td {
padding: 12px 10px;
text-align: center;
border-top: 1px solid #e0e6f3;
border-right: 2px solid #d2d9eb;
color: var(--text);
}
tbody td:last-child {
border-right: none;
}
.empty-row td {
color: #8fa3d6;
padding: 24px 0;
}
.muted {
color: var(--muted);
}
.legend {
margin: 10px 4px 0;
font-size: 13px;
}
.layout {
background: var(--bg);
min-height: 100vh;
color: var(--text);
}
.navbar {
position: relative;
display: flex;
justify-content: center;
align-items: center;
padding: 12px 20px 22px;
background: #ffffff;
}
.navbar::after {
content: "";
position: absolute;
left: 0;
right: 0;
bottom: -14px;
border-bottom: 1px dashed #e0e6f3;
}
.brand {
position: absolute;
left: 50%;
top: 10px;
transform: translateX(-50%);
font-weight: 700;
color: var(--brand);
font-size: 28px;
}
.control-buttons {
position: absolute;
right: 20px;
top: 8px;
}
.hidBtn {
width: 60px;
height: 30px;
border: transparent;
background: white;
color: transparent;
cursor: pointer;
font-size: 14px;
border-radius: 4px;
}
.hidBtn:hover {
background: #30f1e6;
border: #2c3e50 solid 2px;
color: #2c3e50;
}
.fullscreen-btn {
margin-right: 10px;
}
.exit-btn {
margin-left: 10px;
}
.links a {
color: #3552a8;
margin-left: 16px;
text-decoration: none;
}
.links a.router-link-active {
color: #0f1f57;
font-weight: 700;
}
.content {
padding: 24px 24px 40px;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -1,83 +0,0 @@
<template>
<div class="table-wrapper">
<table>
<thead>
<tr>
<th v-for="col in columns" :key="col.key">{{ col.title }}</th>
</tr>
</thead>
<tbody>
<tr v-if="!data?.length" class="empty-row"><td :colspan="columns.length">暂无数据</td></tr>
<tr v-for="(row, idx) in data" :key="idx">
<td v-for="col in columns" :key="col.key">{{ formatCell(row, col) }}</td>
</tr>
</tbody>
</table>
</div>
</template>
<script setup>
import {compileToFunction} from "vue";
const props = defineProps({
data: {
type: Array,
default: () => []
},
columns: {
type: Array,
default: () => []
}
});
function formatCell(row, col){
const v = row?.[col.key];
return col.formatter ? col.formatter(v, row) : (v ?? '');
}
</script>
<style scoped>
.table-wrapper {
border-radius: 8px;
overflow: hidden;
border: 1px solid #20315e;
box-shadow: 0 4px 16px rgba(0,0,0,.35);
}
table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
thead th {
background: #142357;
color: #fff;
padding: 12px 10px;
font-weight: 700;
font-size: 18px;
text-align: center;
border-right: 2px solid rgba(255,255,255,0.3);
}
thead th:last-child {
border-right: none;
}
tbody td {
padding: 12px 10px;
text-align: center;
border-top: 1px solid #e0e6f3;
border-right: 2px solid #d2d9eb;
color: #141a29;
}
tbody td:last-child {
border-right: none;
}
.empty-row td {
color: #8fa3d6;
padding: 24px 0;
}
</style>

View File

@ -1,20 +0,0 @@
import axios from "axios";
if(process.env.NODE_ENV === 'development') {
axios.defaults.baseURL = 'http://localhost:9980';
}else {
axios.defaults.baseURL = 'http://172.18.222.253:12315';
}
//axios.defaults.headers.post['Content-Type'] = 'application/json';
//axios.defaults.responseType = 'application/json'
axios.defaults.timeout = 10000
axios.interceptors.request.use(function (config) {
// 在发送请求之前做些什么
config.headers.set('Content-Type', 'application/json');
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
export default axios;

View File

@ -1,8 +0,0 @@
import axios from "@/http/base";
export default {
getData(data) {
return axios.post("/api/wms/GetCkTaskList", data);
}
};

View File

@ -1,9 +0,0 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import installElementPlus from './plugins/element'
const app = createApp(App)
installElementPlus(app);
app.use(store).use(router).mount('#app')

View File

@ -1,7 +0,0 @@
import ElementPlus from 'element-plus'
import 'element-plus/theme-chalk/index.css'
import locale from 'element-plus/es/locale/lang/zh-cn'
export default (app) => {
app.use(ElementPlus, { locale })
}

View File

@ -1,21 +0,0 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
const routes = [
{
path: '/',
redirect: '/home',
},
{
path: '/home',
name: 'home',
component: HomeView
},
]
const router = createRouter({
history: createWebHashHistory(),
routes
})
export default router

View File

@ -1,52 +0,0 @@
import axios from 'axios';
// 生产环境默认同源,开发可由 .env 覆盖
const baseURL = process.env.VUE_APP_API_BASE_URL || (typeof window !== 'undefined' ? `${window.location.protocol}//${window.location.hostname}:12315` : '');
export const http = axios.create({ baseURL, timeout: 15000 });
export async function queryTasksByPage(params) {
const { data } = await http.post('/wms/taskQuery/queryTasksByPage', params);
return data?.data;
}
export async function queryPickTasksByPage(params) {
const { data } = await http.post('/wms/taskQuery/queryPickTasksByPage', params);
return data?.data;
}
export async function queryPickPlansByPage(params) {
const { data } = await http.post('/wms/pickPlan/queryPickPlansByPage', params);
return data?.data;
}
export async function getGoodsInfoByGoodsId(goodsId) {
const { data } = await http.get('/wms/goods/getGoodsInfoByGoodsId', { params: { goodsId } });
return data?.data;
}
export async function queryOutsByPage(params) {
const { data } = await http.post('/wms/taskQuery/queryOutsByPage', params);
return data?.data;
}
export async function queryStocks(params) {
const { data } = await http.post('/wms/stock/queryStocks', params);
return data?.data;
}
// 新增的看板数据接口
export async function getTaskTypInData(params = {}) {
const { data } = await http.get('/wms/board/getTaskTypInData', { params });
return data;
}
export async function getOutsData(params = {}) {
const { data } = await http.get('/wms/board/getOutsData', { params });
return data;
}
export async function getPickTaskData(params = {}) {
const { data } = await http.get('/wms/board/getPickTaskData', { params });
return data;
}

View File

@ -1,14 +0,0 @@
import { createStore } from 'vuex'
export default createStore({
state: {
},
getters: {
},
mutations: {
},
actions: {
},
modules: {
}
})

View File

@ -1,100 +0,0 @@
<template>
<div class="home">
<el-row style="width: 100%">
<h1 style="margin-left: auto; margin-right: auto">成品仓智能仓 {{route.query.standId}}&nbsp;号线出库状态一览表</h1>
</el-row>
<el-divider style="margin-top: 0" />
<el-row style="margin-right: 20px;margin-left: 20px;">
<el-table :data="tableData" :border="true" :header-cell-style="headerStyle" :row-style="dataStyle">
<el-table-column prop="plcid" label="任务号" width="150" align="center"></el-table-column>
<el-table-column prop="customer_id" label="客户代码" align="center"></el-table-column>
<el-table-column prop="good_id" label="产品编号" align="center"></el-table-column>
<el-table-column prop="loc_id" label="库位" align="center"></el-table-column>
<el-table-column prop="docctnumber" label="周期" align="center"></el-table-column>
<el-table-column prop="mistock_num" label="数量" align="center"></el-table-column>
<el-table-column prop="status" label="出库状态位置" align="center"></el-table-column>
</el-table>
</el-row>
<div style="font-size: 1.5rem; color: #ab0a07;position: fixed;left: 10px; bottom:10px">精心·精品</div>
<img src="@/assets/img.png" alt="logo" style="position: fixed;bottom: 10px; right: 10px"/>
<img src="@/assets/img.png" alt="logo" style="position: fixed;top: 20px; left: 10px"/>
<button class="hidBtn" style="position: fixed;top: 10px; right: 10px;" @click="fullScreenFuc">全屏</button>
<button class="hidBtn" style="position: fixed;top: 10px; right: 70px;" @click="outScreenFuc">退出</button>
</div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import {useRoute} from 'vue-router';
import getData from "@/http/get-data";
//
const route = useRoute();
const standId = ref("50");
let tableData = ref([]);
const headerStyle = ref((row, index) => {
return {
fontSize: "1.5rem",
color: "#fff",
backgroundColor: "#1f2964",
marginTop: "10px",
paddingTop: "10px",
paddingBottom: "10px",
textAlign: "center",
}
});
const dataStyle = ref((row, index) => {
return {
fontSize: "1.5rem",
color: "#454444",
}
});
const fullScreenFuc = () => {
document.documentElement.requestFullscreen();
}
const outScreenFuc = () => {
document.exitFullscreen();
}
// url
const resolveStand = () => {
standId.value = route.query.standId.toString();
}
onMounted(() => {
tableData.value = [];
//resolveStand();
setInterval(() => {
getData.getData({ PORT: route.query.standId }).then(res => {
const response = res.data;
if(response.code === 0) {
tableData.value = response.data;
return;
}
console.log(response);
}).catch(err => {
console.log(err);
})
}, 5000)
});
</script>
<style scoped>
.hidBtn {
width: 60px;height: 30px;
border: transparent;
background: white;
color: transparent;
}
.hidBtn:hover {
background: #30f1e6;
border: #2c3e50 solid 2px;
color: #2c3e50;
}
</style>

View File

@ -1,79 +0,0 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getTaskTypInData } from '../services/api';
//
const columns = [
{ key: 'vehicleId', title: '料箱号' },
{ key: 'origin', title: '起点' },
{ key: 'destination', title: '终点' },
{ key: 'taskPriority', title: '优先级' },
{ key: 'taskStatus', title: '状态' },
];
const rows = ref([]);
let timer = null;
function mapStatus(status) {
const code = Number(status);
// WmsStackerTaskStatusEnums
switch (code) {
case -2: return '定时器用';
case -1: return '暂存';
case 0: return '初始化';
case 1: return '已解析';
case 2: return '已下发';
case 3: return '正在执行';
case 4: return '执行完成';
case 98: return '已取消';
case 99: return '执行异常';
default: return String(status ?? '');
}
}
async function load() {
try {
const data = await getTaskTypInData({ pageNum: 1, pageSize: 200 });
const list = data || [];
rows.value = list.map((t) => ({
vehicleId: t?.vehicleId ?? '',
origin: t?.origin ?? t?.startPoint ?? '',
destination: t?.destination ?? t?.endPoint ?? '',
taskPriority: (
t?.task_priority ??
t?.taskPriority ??
t?.priority ??
t?.priorityLevel ??
''
),
taskStatus: mapStatus(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;
}
</style>

View File

@ -1,56 +0,0 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getOutsData } from '../services/api';
//
const columns = [
{ key: 'goodsId', title: '物料号' },
{ key: 'needNum', title: '需求数量' },
{ key: 'distributeNum', title: '分配数量' },
{ key: 'pickNum', title: '拣选数量' },
{ key: 'reason', title: '原因' },
];
const rows = ref([]);
let timer = null;
async function load() {
try {
const outsData = await getOutsData({ pageNum: 1, pageSize: 500 });
const outs = outsData || [];
rows.value = outs.map((o) => ({
goodsId: o?.goodsId ?? '',
needNum: Number(o?.needNum ?? 0),
distributeNum: Number(o?.distribute_num ?? o?.distributeNum ?? o?.allocNum ?? o?.allocateNum ?? 0),
pickNum: Number(o?.pick_num ?? o?.pickNum ?? 0),
reason: o?.reason ?? o?.reasonDesc ?? '',
}));
} catch (error) {
console.error('加载出库数据失败:', error);
}
}
onMounted(() => {
load();
timer = setInterval(load, 5000);
});
onUnmounted(() => {
if (timer) {
clearInterval(timer);
}
});
</script>
<style scoped>
.title-center {
text-align: center;
}
</style>

View File

@ -1,72 +0,0 @@
<template>
<div>
<DataTable :columns="columns" :data="rows" />
</div>
</template>
<script setup>
import { ref, onMounted, onUnmounted } from 'vue';
import DataTable from '../components/DataTable.vue';
import { getPickTaskData } from '../services/api';
//
const columns = [
{ key: 'vehicleId', title: '料箱号' },
{ 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 getPickTaskData({ 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;
}
</style>

View File

@ -1,14 +0,0 @@
const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
transpileDependencies: true,
chainWebpack: (config) => {
config.plugin('define').tap((defineConfig) => {
Object.assign(defineConfig[0], {
__VUE_OPTIONS_API__: 'true',
__VUE_PROD_DEVTOOLS__: false,
__VUE_PROD_HYDRATION_MISMATCH_DETAILS__: false
})
return defineConfig
})
}
})

Binary file not shown.