项目初始化

This commit is contained in:
陆一凡 2025-02-20 13:42:25 +08:00
commit 4443f48bc2
65 changed files with 31359 additions and 0 deletions

23
.gitignore vendored Normal file
View File

@ -0,0 +1,23 @@
.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?

24
README.md Normal file
View File

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

5
babel.config.js Normal file
View File

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

BIN
dist.zip Normal file

Binary file not shown.

19
jsconfig.json Normal file
View File

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

23809
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

59
package.json Normal file
View File

@ -0,0 +1,59 @@
{
"name": "WMS",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build",
"lint": "vue-cli-service lint"
},
"dependencies": {
"@element-plus/icons-vue": "^2.3.1",
"axios": "^1.3.3",
"core-js": "^3.8.3",
"element-plus": "^2.4.0",
"file-saver": "^2.0.5",
"moment": "^2.29.4",
"node-polyfill-webpack-plugin": "^2.0.1",
"qrcode": "^1.5.3",
"qrcode.vue": "^3.4.1",
"stream-http": "^3.2.0",
"vue": "^3.2.13",
"vue-print-nb": "^1.7.5",
"vue-router": "^4.0.3",
"vue3-print-nb": "^0.1.4",
"vuex": "^4.0.0",
"xlsx": "^0.18.5"
},
"devDependencies": {
"@babel/core": "^7.12.16",
"@babel/eslint-parser": "^7.12.16",
"@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",
"node-sass": "^8.0.0",
"sass-loader": "^13.2.0"
},
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential"
],
"parserOptions": {
"parser": "@babel/eslint-parser"
},
"rules": {
"no-unused-vars": "off"
}
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

BIN
public/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

37
public/index.html Normal file
View File

@ -0,0 +1,37 @@
<!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><%= htmlWebpackPlugin.options.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 -->
<script>
let timeout; // 定义一个变量存储定时器
function resetTimer() {
clearTimeout(timeout); // 清除之前的定时器
// 设置一个新的定时器,用户空闲时刷新
timeout = setTimeout(() => {
location.reload(); // 刷新当前页面
}, 300000); // 10 分钟
}
// 监听用户活动事件
window.onload = function() {
resetTimer(); // 页面加载时重置定时器
window.addEventListener('mousemove', resetTimer);
window.addEventListener('keypress', resetTimer);
window.addEventListener('scroll', resetTimer);
window.addEventListener('click', resetTimer);
};
</script>
</body>
</html>

55
src/App.vue Normal file
View File

@ -0,0 +1,55 @@
<template>
<router-view></router-view>
</template>
<script>
export default {
created() {
//sessionStorage
if (sessionStorage.getItem('storeState')) {
//replaceStatestore
this.$store.replaceState(Object.assign({}, this.$store.state, JSON.parse(sessionStorage.getItem('storeState'))))
}
//vuexsessionStorage
window.addEventListener('beforeunload', () => {
sessionStorage.setItem('storeState', JSON.stringify(this.$store.state))
})
}
}
</script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
height: 100%;
width: 100%;
}
nav {
padding: 30px;
}
nav a {
font-weight: bold;
color: #2c3e50;
}
nav a.router-link-exact-active {
color: #42b983;
}
html {
height: 100%;
width: 100%;
}
body {
margin: 0px;
height: 100%;
width: 100%;
}
</style>

39
src/api/config.js Normal file
View File

@ -0,0 +1,39 @@
import request from "@/http/request";
const getConfigs = () => {
return request.get('/config/getConfigs')
}
const updateConfig = (params) => {
return request.post('/config/updateConfig', params)
}
const queryBoxConfig = (params) => {
return request.post('/config/queryBoxConfig', params)
}
const queryBoxConfigByPage = (params) => {
return request.post('/config/queryBoxConfigByPage', params)
}
const updateBoxConfig = (params) => {
return request.post('/config/updateBoxConfig', params)
}
const addBoxConfig = (params) => {
return request.post('/config/addBoxConfig', params)
}
const deleteBoxConfig = (params) => {
return request.post('/config/deleteBoxConfig', params)
}
export {
getConfigs,
updateConfig,
queryBoxConfig,
queryBoxConfigByPage,
updateBoxConfig,
addBoxConfig,
deleteBoxConfig
}

183
src/api/excel.js Normal file
View File

@ -0,0 +1,183 @@
import request from "@/http/request";
const downlocadExcel = () => {
return request.get('/test/testExcelExport', {
responseType: 'blob'
})
}
const uploadExcel = (formData) => {
return request({
url: '/test/testExcelImport',
method: 'post',
data: formData,
timeout: 100000
})
}
const uploadExcelPeijian = (data) => {
return request({
url: '/excel/uploadExcelPeijian',
method: 'post',
data: data,
timeout: 100000
})
}
const uploadExcelHejian = (data) => {
return request({
url: '/excel/uploadExcelHejian',
method: 'post',
data: data,
timeout: 100000
})
}
const uploadExcelJinji = (data) => {
return request({
url: '/excel/uploadExcelJinji',
method: 'post',
data: data,
timeout: 100000
})
}
const uploadExcelKatePackage = (data) => {
return request({
url: '/excel/uploadExcelKatePackage',
method: 'post',
data: data,
timeout: 100000
})
}
const uploadExcelParts = (data) => {
return request({
url: '/excel/uploadPartInfos',
method: 'post',
data: data,
timeout: 100000
})
}
const uploadBoxConfig = (data) => {
return request({
url: '/excel/uploadBoxConfig',
method: 'post',
data: data,
timeout: 100000
})
}
const distributePeijianTasks = (data) => {
return request({
url: '/excel/distributePeijianTasks',
method: 'post',
data: data,
timeout: 100000
})
}
const distributeHejianTasks = (data) => {
return request({
url: '/excel/distributeHejianTasks',
method: 'post',
data: data,
timeout: 100000
})
}
const distributeJinjiTasks = (data) => {
return request({
url: '/excel/distributeJinjiTasks',
method: 'post',
data: data,
timeout: 100000
})
}
const downloadStockExcel = () => {
return request({
url: '/excel/downloadStockExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadKateTaskExcel = () => {
return request({
url: '/excel/downloadKateTaskExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadPeijianExcel = () => {
return request({
url: '/excel/downloadPeijianExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadRukuExcel = () => {
return request({
url: '/excel/downloadRukuExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadHejianExcel = () => {
return request({
url: '/excel/downloadHejianExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadJinjiExcel = () => {
return request({
url: '/excel/downloadJinjiExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadPackageExcel = () => {
return request({
url: '/excel/downloadPackageExcel',
method: 'get',
responseType: 'blob'
})
}
const downloadMaterialExcel = () => {
return request({
url: '/excel/downloadMaterialExcel',
method: 'get',
responseType: 'blob'
})
}
export {
downlocadExcel,
uploadExcel,
uploadExcelPeijian,
uploadExcelHejian,
uploadExcelParts,
distributePeijianTasks,
distributeHejianTasks,
downloadStockExcel,
downloadKateTaskExcel,
uploadExcelJinji,
distributeJinjiTasks,
downloadPeijianExcel,
downloadRukuExcel,
downloadHejianExcel,
downloadJinjiExcel,
downloadPackageExcel,
uploadBoxConfig,
uploadExcelKatePackage,
downloadMaterialExcel
}

66
src/api/goods.js Normal file
View File

@ -0,0 +1,66 @@
import request from "@/http/request";
const getAllGoods = () => {
return request({
url: '/goods/getAllGoods',
method: 'get'
})
}
const getPartInfo = (params) => {
return request({
url: '/goods/getPartInfo',
method: 'post',
data: params
})
}
const updateGoodsInfo = (params) => {
return request({
url: '/goods/updateGoodsInfo',
method: 'post',
data: params
})
}
const queryPartInfoByPartNo = (params) => {
return request({
url: '/goods/queryPartInfoByPartNo',
method: 'post',
data: params
})
}
const updatePartInfo = (params) => {
return request({
url: '/goods/updatePartInfo',
method: 'post',
data: params
})
}
const queryPartNo = (params) => {
return request({
url: '/goods/queryPartNo',
method: 'post',
data: params
})
}
const deleteCurrentPartInfo = (params) => {
return request({
url: '/goods/deletePartInfo',
method: 'post',
data: params
})
}
export {
getAllGoods,
updateGoodsInfo,
queryPartInfoByPartNo,
getPartInfo,
updatePartInfo,
queryPartNo,
deleteCurrentPartInfo
}

31
src/api/location.js Normal file
View File

@ -0,0 +1,31 @@
import request from "@/http/request";
const getLocations = (params) => {
return request({
url: '/location/getLocations',
method: 'post',
data: params
})
}
const updateLocation = (params) => {
return request({
url: '/location/updateLocation',
method: 'post',
data: params
})
}
const getAvailableLocations = (params) => {
return request({
url: '/location/getAvailableLocations',
method: 'post',
data: params
})
}
export {
getLocations,
updateLocation,
getAvailableLocations
}

31
src/api/login.js Normal file
View File

@ -0,0 +1,31 @@
import request from "@/http/request";
const loginWithoutAuth = (params) => {
return request({
url: '/user/loginWithoutAuth',
method: 'post',
data: params
})
}
const loginWithAuth = (params) => {
return request({
url: '/user/loginWithAuth',
method: 'post',
data: params
})
}
const getUser = (params) => {
return request({
url: '/login/getUser',
method: 'post',
data: params
})
}
export {
loginWithoutAuth,
loginWithAuth,
getUser
}

61
src/api/order.in.js Normal file
View File

@ -0,0 +1,61 @@
import request from "@/http/request";
export default {
// 根据条件获取全部订单
getOrderInList(params) {
return request.post('/api/orderIn/queryOrderIn', params)
},
// 根据载具号查询
getOrderInWithVehicleNo(vehicleNo) {
return request.get('/api/orderIn/getOrderInWithVehicleNo', {
params: {
vehicleNo: vehicleNo
}
})
},
//下发任务
addOrderIn(params){
return request.post('/api/orderIn/addOrderIn', params)
},
// 绑定物料
bindingVehicle(params) {
return request.post('/api/orderIn/bindingVehicle', params)
},
//提交更新入库信息
updateForNum(params){
return request.post('/api/orderIn/updateForNum', params)
},
// 解绑物料
unbindingVehicle(rowId) {
return request.put('/api/orderIn/unBindingVehicle/' + rowId)
},
//删除订单
deleteOrderIn(rowId) {
return request.delete('/api/orderIn/deleteOrderIn/' + rowId)
},
// 根据条件获取全部订单
getOrderCheckList(params) {
return request.post('/api/orderCheck/queryOrderCheck',params)
},
downInventoryTask(){
return request.post('/api/orderCheck/downInventoryTask')
},
// 删除订单
deleteGoodsOrderInCheck(remarkReturn) {
return request.delete('/api/orderCheck/deleteCheckAll/' + remarkReturn)
},
//执行订单
executeCheck(recordId){
return request.put('/api/orderCheck/executeOrderCheck/' + recordId)
},
// 删除订单
deleteCheckList(recordId) {
return request.delete('/api/orderCheck/deleteCheck/' + recordId)
},
}

30
src/api/order.out.js Normal file
View File

@ -0,0 +1,30 @@
import request from "@/http/request";
export default {
// 根据条件获取全部订单
getOrderOutList(params) {
return request.post('/api/orderOut/queryOrderOut', params)
},
// 执行出库
executeOut(rowId) {
return request.put('/api/orderOut/executeOrderOut/' + rowId)
},
// 刪除按钮
deleteOrder(rowId){
return request.delete('/api/orderOut/deleteOrderOut/' + rowId)
},
// 添加按钮
addOrder(params){
return request.post('/api/orderOut/addOrderOut', params)
},
emptyAddOrder(params){
return request.post('/api/orderOut/emptyAddOrderOut', params)
},
addOrderByInsertEmpty(params){
return request.post('/api/orderOut/addOrderByInsertEmpty', params)
},
// // 库存页面执行出库
// outRowStock(rowId){
// return request.put('/api/orderOut/outRowStock/' + rowId)
// }
}

13
src/api/record.js Normal file
View File

@ -0,0 +1,13 @@
import request from "@/http/request";
const getTaskRecords = (params) => {
return request({
url: '/record/getTaskRecords',
method: 'post',
data: params
})
}
export {
getTaskRecords
}

22
src/api/stand.js Normal file
View File

@ -0,0 +1,22 @@
import request from "@/http/request";
const getAllStands = (params) => {
return request({
url: '/stand/getAllStands',
method: 'post',
data: params
})
}
const updateStandInfo = (params) => {
return request({
url: '/stand/updateStandInfo',
method: 'post',
data: params
})
}
export {
getAllStands,
updateStandInfo
}

31
src/api/stock.js Normal file
View File

@ -0,0 +1,31 @@
import request from "@/http/request";
const getAllStocks = (params) => {
return request({
url: '/stock/getAllStocks',
method: 'post',
data: params
})
}
const getAllStocksByGoodsId = (params) => {
return request({
url: '/stock/getAllStocksByGoodsId',
method: 'post',
data: params
})
}
const updateStockInfo = (params) => {
return request({
url: '/stock/updateStockInfo',
method: 'post',
data: params
})
}
export {
getAllStocks,
updateStockInfo,
getAllStocksByGoodsId
}

255
src/api/task.js Normal file
View File

@ -0,0 +1,255 @@
import request from "@/http/request";
const sendVehicleNo = (params) => {
return request({
url: '/task/sendVehicleNo',
method: 'post',
data: params
})
}
const sendGoodsInTask = (params) => {
return request({
url: '/task/sendGoodsInTask',
method: 'post',
data: params
})
}
const submitPackageTask = (params) => {
return request({
url: '/taskOut/submitPackageTask',
method: 'post',
data: params
})
}
const sendGoodsOutTask = (params) => {
return request({
url: '/task/sendGoodsOutTask',
method: 'post',
data: params
})
}
const getAllTasks = () => {
return request({
url: '/task/getAllTasks',
method: 'get'
})
}
const sendInventoryTask = (params) => {
return request({
url: '/task/sendInventoryTask',
method: 'post',
data: params
})
}
const finishInventoryTask = (params) => {
return request({
url: '/task/finishInventoryTask',
method: 'post',
data: params
})
}
const getTasks = (params) => {
return request({
url: '/task/getTasks',
method: 'post',
data: params
})
}
const getAllKateTasks = (params) => {
return request({
url: '/task/getKateTasks',
method: 'post',
data: params
})
}
const getKateTasksByTask = (params) => {
return request({
url: '/task/getKateTasksByTask',
method: 'post',
data: params
})
}
const finishPicking = (params) => {
return request({
url: '/task/finishPicking',
method: 'post',
data: params
})
}
const finishCurrentKateTask = (params) => {
return request({
url: '/task/finishCurrentKateTask',
method: 'post',
data: params
})
}
const getTaskByTask = (params) => {
return request({
url: '/task/getTaskByTask',
method: 'post',
data: params
})
}
const getAllPeijians = (params) => {
return request({
url: '/task/getAllPeijians',
method: 'post',
data: params
})
}
const getPeijians = (params) => {
return request({
url: '/task/getPeijians',
method: 'post',
data: params
})
}
const getAllHejians = (params) => {
return request({
url: '/task/getAllHejians',
method: 'post',
data: params
})
}
const getHejians = (params) => {
return request({
url: '/task/getHejians',
method: 'post',
data: params
})
}
const getAllJinjis = (params) => {
return request({
url: '/task/getAllJinjis',
method: 'post',
data: params
})
}
const getJinjis = (params) => {
return request({
url: '/task/getJinjis',
method: 'post',
data: params
})
}
const getAllPackages = (params) => {
return request({
url: '/task/getAllPackages',
method: 'post',
data: params
})
}
const getPackages = (params) => {
return request({
url: '/task/getPackages',
method: 'post',
data: params
})
}
const getPrintData = (params) => {
return request({
url: '/task/getPrintData',
method: 'post',
data: params
})
}
const redistributeLackKateTask = (params) =>{
return request({
url: '/task/redistributeLackKateTask',
method: 'post',
data: params
})
}
const callEmptyVehicle = (params) => {
return request({
url: '/taskOut/callEmptyVehicle',
method: 'post',
data: params
})
}
const changeTaskStatus = (params) => {
return request({
url: '/taskDeal/changeTaskStatus',
method: 'post',
data: params
})
}
const deleteAllKateTasks = (params) => {
return request({
url: '/taskDeal/deleteAllKateTasks',
method: 'post',
data: params
})
}
const sendBoxArrive = (params) => {
return request({
url: '/task/boxArrive',
method: 'post',
data: params
})
}
const selectVehicleOut = (params) => {
return request({
url: '/task/vehicleOut',
method: 'post',
data: params
})
}
export {
sendVehicleNo,
sendGoodsInTask,
sendGoodsOutTask,
getAllTasks,
sendInventoryTask,
finishInventoryTask,
getTasks,
getAllKateTasks,
getKateTasksByTask,
finishPicking,
finishCurrentKateTask,
getTaskByTask,
getAllPeijians,
getAllHejians,
getPrintData,
redistributeLackKateTask,
getPeijians,
getHejians,
getJinjis,
getAllJinjis,
getAllPackages,
getPackages,
callEmptyVehicle,
changeTaskStatus,
deleteAllKateTasks,
submitPackageTask,
sendBoxArrive,
selectVehicleOut
}

59
src/api/user.js Normal file
View File

@ -0,0 +1,59 @@
import request from "@/http/request";
// 登录方法
export function login(username, password, code, uuid) {
const data = {
username,
password,
code,
uuid
}
return request({
url: '/login',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 注册方法
export function register(data) {
return request({
url: '/register',
headers: {
isToken: false
},
method: 'post',
data: data
})
}
// 获取用户详细信息
export function getInfo() {
return request({
url: '/getInfo',
method: 'get'
})
}
// 退出方法
export function logout() {
return request({
url: '/logout',
method: 'post'
})
}
// 获取验证码
export function getCodeImg() {
return request({
url: '/captchaImage',
headers: {
isToken: false
},
method: 'get',
timeout: 20000
})
}

31
src/api/vehicle.js Normal file
View File

@ -0,0 +1,31 @@
import request from "@/http/request";
const getAllVehicles = (params) => {
return request({
url: '/location/getVehicles',
method: 'post',
data: params
})
}
const updateVehicleInfo = (params) => {
return request({
url: '/location/updateVehicleInfo',
method: 'post',
data: params
})
}
const deleteCurrentVehicle = (params) => {
return request({
url: '/location/deleteVehicle',
method: 'post',
data: params
})
}
export {
getAllVehicles,
updateVehicleInfo,
deleteCurrentVehicle
}

BIN
src/assets/fdbk_log.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
src/assets/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

View File

@ -0,0 +1,258 @@
<!-- -->
<template>
<div style="margin-left: 10px">
<el-dialog :model-value="modelValue" :show-close="false" title="下发入库任务"
@close="() => $emit('update:modelValue', false)">
<div>
<el-form
label-width="100px"
:model="bindingData"
require-asterisk-position="right"
inline
>
<el-form-item label="载具号:" required>
<el-input class="form-input" v-model="bindingData.vehicleNo" clearable/>
</el-form-item>
<el-form-item label="零件号:">
<el-input class="form-input" v-model="bindingData.goodsId" clearable/>
</el-form-item>
<el-form-item label="数量:" >
<el-input class="form-input" v-model="bindingData.goodsNum" clearable/>
</el-form-item>
<el-form-item label="库区选择:" prop="abcSelect" required>
<el-select v-model="bindingData.abcSelect" placeholder="请选择" style="width: 100%;">
<el-option label="A" value="A"></el-option>
<el-option label="B" value="B"></el-option>
<el-option label="C" value="C"></el-option>
</el-select>
</el-form-item>
<el-form-item label="物料种类:" prop="efSelect" required>
<el-select v-model="bindingData.efSelect" placeholder="请选择" style="width: 120%;">
<el-option label="单种" value="E"></el-option>
<el-option label="多种" value="F"></el-option>
<el-option label="空托" value="G"></el-option>
</el-select>
</el-form-item>
<div style="margin-top: 50px">
<el-button type="warning" @click="resetInput">
<el-icon class="el-icon--left"><RefreshRight/></el-icon>
重置输入
</el-button>
<el-button type="primary" @click="addOrderIn()">
<el-icon class="el-icon--left"><Search /></el-icon>
下发任务
</el-button>
<el-button type="danger" @click="$emit('update:modelValue', false)">
<el-icon class="el-icon--left"><CircleCloseFilled/></el-icon>
关闭窗口
</el-button>
</div>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
// import from ' ';
import {CircleCloseFilled, Close, RefreshRight} from "@element-plus/icons-vue";
import {formatterOrderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import {ElMessage, ElMessageBox} from "element-plus";
import apiOrderIn from '@/api/order.in';
export default {
// import 使
components: {Close, CircleCloseFilled, RefreshRight},
props: ['modelValue'],
emits: ['update:modelValue'],
data() {
//
return {
//
bindingData: {
vehicleNo: '',
goodsId: '',
goodsNum: '',
abcSelect: '',
efSelect: ''
},
bindOrderInList: []
}
},
// data
computed: {},
// data
watch: {},
//
methods: {
formatCellValueTime,
formatterOrderInEnum,
test() {
console.log(this.bindingData);
},
//
addOrderIn() {
if(this.bindingData.efSelect === 'G') {
if(this.bindingData.goodsId !== '' || this.bindingData.goodsNum !== '' ){
ElMessage({
message: '空托盘入库不能填写物料号和数量',
type: 'error',
});
return;
}
}else {
if(this.bindingData.goodsId === '' || this.bindingData.goodsNum === '' ){
ElMessage({
message: '物料号和数量不能为空',
type: 'error',
});
return;
}
}
if(this.bindingData.vehicleNo === '' || this.bindingData.abcSelect === '' || this.bindingData.efSelect === '') {
ElMessage({
message: '载具号,库区和物料种类不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = []
ElMessageBox.confirm(`是否下发入库任务?`, '提示')
.then(() => {
apiOrderIn.addOrderIn(this.bindingData).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
//
resetInput() {
this.bindingData.vehicleNo = '';
this.bindingData.goodsId = '';
this.bindingData.goodsNum = '';
},
//
bindingGoods() {
if(this.bindingData.vehicleNo === '' || this.bindingData.code === '') {
ElMessage({
message: '载具号和物料号不能为空',
type: 'error',
});
return;
}
apiOrderIn.bindingVehicle({vehicleNo: this.bindingData.vehicleNo, code: this.bindingData.code}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '绑定成功',
type: 'success',
});
this.queryBinding();
this.bindingData.code = '';
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '绑定失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
unBindingOrder(row) {
apiOrderIn.unbindingVehicle(row.rowId).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '解绑成功',
type: 'success',
});
this.queryBinding();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '解绑失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
}
},
// API
setup() {
},
//
beforeCreate() {
},
// (访 this )
created() {
},
// -
beforeMount() {
},
// - 访 DOM
mounted() {
},
//
beforeUpdate() {
},
//
updated() {
},
//
beforeUnmount() {
},
//
unmounted() {
}
}
</script>
<style lang="scss" scoped>
$input-width: 500px;
.form-input {
width: $input-width;
}
</style>

71
src/components/appTag.vue Normal file
View File

@ -0,0 +1,71 @@
// AppTag
<template>
<div class="app-tag">
<el-tag closable size="default" v-for="(tag, index) in tags" :key="tag.labelName" :disable-transitions="true"
:effect="$route.path === tag.path ? 'dark' : 'plain'" @close="handleClose(tag, index)"
@click="handleClick(tag)">
{{ tag.labelName }}
</el-tag>
</div>
</template>
<script>
import { mapState, mapMutations } from 'vuex';
export default {
name: 'app-tag',
data() {
return {
tags: []
}
},
created() {
//stateTagsListstate.jstagskeystateTagsList
this.tags = this.stateTagsList;
},
computed: {
...mapState(['stateTagsList'])
},
methods: {
...mapMutations({
close: 'mutationCloseTag'
}),
handleClose(tag, index) {
if (this.tags.length === 1) { //
return
}
this.close(tag) // tag
if (this.$router.path === tag.path) { //
return
} else {
if (index === (this.tags.length - 1)) { // ,
this.$router.push(this.tags[index].path)
} else { //
if (index === 0) {
this.$router.push(this.tags[0].path)
} else {
this.$router.push(this.tags[index - 1].path)
}
}
}
},
// tags
handleClick(tag) {
this.$router.push(tag.path)
}
}
}
</script>
<style scoped>
.app-tag .el-tag {
cursor: pointer;
height: 30px;
margin-right: 2px;
}
.app-tag .el-tag:hover {
color: #000;
background-color: #5A9CF8;
}
</style>

View File

@ -0,0 +1,222 @@
<!-- -->
<template>
<div style="margin-left: 10px">
<el-dialog :model-value="modelValue" :show-close="false" title="下发盘点任务"
@close="() => $emit('update:modelValue', false)">
<div>
<el-form
label-width="100px"
:model="bindingData"
require-asterisk-position="right"
inline
>
<el-form-item label="载具号:" required>
<el-input class="form-input" v-model="bindingData.vehicleNo" clearable/>
</el-form-item>
<el-form-item label="零件号:" required>
<el-input class="form-input" v-model="bindingData.goodsId" clearable/>
</el-form-item>
<el-form-item label="数量:" required>
<el-input class="form-input" v-model="bindingData.goodsNum" clearable/>
</el-form-item>
<div style="margin-top: 50px">
<el-button type="warning" @click="resetInput">
<el-icon class="el-icon--left"><RefreshRight/></el-icon>
重置输入
</el-button>
<el-button type="primary" @click="addOrderIn()">
<el-icon class="el-icon--left"><Search /></el-icon>
下发任务
</el-button>
<el-button type="danger" @click="$emit('update:modelValue', false)">
<el-icon class="el-icon--left"><CircleCloseFilled/></el-icon>
关闭窗口
</el-button>
</div>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
// import from ' ';
import {CircleCloseFilled, Close, RefreshRight} from "@element-plus/icons-vue";
import {formatterOrderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import {ElMessage, ElMessageBox} from "element-plus";
import apiOrderIn from '@/api/order.in';
export default {
// import 使
components: {Close, CircleCloseFilled, RefreshRight},
props: ['modelValue'],
emits: ['update:modelValue'],
data() {
//
return {
//
bindingData: {
vehicleNo: '',
goodsId: '',
goodsNum: ''
},
bindOrderInList: []
}
},
// data
computed: {},
// data
watch: {},
//
methods: {
formatCellValueTime,
formatterOrderInEnum,
//
addOrderIn() {
if(this.bindingData.vehicleNo === '' || this.bindingData.goodsId === '' || this.bindingData.goodsNum === '') {
ElMessage({
message: '载具号、零件号和数量不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = []
ElMessageBox.confirm(`是否下发入库任务?`, '提示')
.then(() => {
apiOrderIn.addOrderIn(this.bindingData).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
//
resetInput() {
this.bindingData.vehicleNo = '';
this.bindingData.goodsId = '';
this.bindingData.goodsNum = '';
},
//
bindingGoods() {
if(this.bindingData.vehicleNo === '' || this.bindingData.code === '') {
ElMessage({
message: '载具号和物料号不能为空',
type: 'error',
});
return;
}
apiOrderIn.bindingVehicle({vehicleNo: this.bindingData.vehicleNo, code: this.bindingData.code}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '绑定成功',
type: 'success',
});
this.queryBinding();
this.bindingData.code = '';
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '绑定失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
unBindingOrder(row) {
apiOrderIn.unbindingVehicle(row.rowId).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '解绑成功',
type: 'success',
});
this.queryBinding();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '解绑失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
}
},
// API
setup() {
},
//
beforeCreate() {
},
// (访 this )
created() {
},
// -
beforeMount() {
},
// - 访 DOM
mounted() {
},
//
beforeUpdate() {
},
//
updated() {
},
//
beforeUnmount() {
},
//
unmounted() {
}
}
</script>
<style lang="scss" scoped>
$input-width: 500px;
.form-input {
width: $input-width;
}
</style>

View File

@ -0,0 +1,225 @@
<!-- -->
<template>
<div style="margin-left: 10px">
<el-dialog :model-value="modelValue" :show-close="false" title="下发空托盘出库任务"
@close="() => $emit('update:modelValue', false)">
<div>
<el-form
label-width="150px"
:model="bindingData"
require-asterisk-position="right"
inline
>
<el-form-item label="托盘号:" required>
<el-input class="form-input" v-model="bindingData.vehicleNo" clearable/>
</el-form-item>
<div style="margin-top: 50px">
<el-button type="warning" @click="resetInput">
<el-icon class="el-icon--left"><RefreshRight/></el-icon>
重置输入
</el-button>
<el-button type="primary" @click="addOrder()">
<el-icon class="el-icon--left"><Search /></el-icon>
下发任务
</el-button>
<el-button type="danger" @click="$emit('update:modelValue', false)">
<el-icon class="el-icon--left"><CircleCloseFilled/></el-icon>
关闭窗口
</el-button>
</div>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
// import from ' ';
import {CircleCloseFilled, Close, RefreshRight} from "@element-plus/icons-vue";
import {formatterOrderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import {ElMessage, ElMessageBox} from "element-plus";
//import apiOrderIn from '@/api/order.in';
import apiOrderOut from '@/api/order.out'
export default {
// import 使
components: {Close, CircleCloseFilled, RefreshRight},
props: ['modelValue'],
emits: ['update:modelValue'],
data() {
//
return {
//
bindingData: {
vehicleNo: '',
},
bindOrderInList: []
}
},
// data
computed: {},
// data
watch: {},
//
methods: {
formatCellValueTime,
formatterOrderInEnum,
addOrder() {
if(this.bindingData.vehicleNo === '') {
ElMessage({
message: '托盘号不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = []
ElMessageBox.confirm(`是否执行空托出库?`, '提示')
.then(() => {
apiOrderOut.addOrder(this.bindingData).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
test() {
console.log(this.bindingData);
},
//
queryBinding() {
if(this.bindingData.vehicleNo === '') {
ElMessage({
message: '载具号不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = [];
apiOrderIn.getOrderInWithVehicleNo(this.bindingData.vehicleNo).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
resetInput() {
this.bindingData.vehicleNo = '';
},
//
bindingGoods() {
if(this.bindingData.vehicleNo === '' || this.bindingData.code === '') {
ElMessage({
message: '载具号和物料号不能为空',
type: 'error',
});
return;
}
apiOrderIn.bindingVehicle({vehicleNo: this.bindingData.vehicleNo, code: this.bindingData.code}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '绑定成功',
type: 'success',
});
this.queryBinding();
this.bindingData.code = '';
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '绑定失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
},
// API
setup() {
},
//
beforeCreate() {
},
// (访 this )
created() {
},
// -
beforeMount() {
},
// - 访 DOM
mounted() {
},
//
beforeUpdate() {
},
//
updated() {
},
//
beforeUnmount() {
},
//
unmounted() {
}
}
</script>
<style lang="scss" scoped>
$input-width: 500px;
.form-input {
width: $input-width;
}
</style>

230
src/components/handOut.vue Normal file
View File

@ -0,0 +1,230 @@
<!-- -->
<template>
<div style="margin-left: 10px">
<el-dialog :model-value="modelValue" :show-close="false" title="下发出库任务"
@close="() => $emit('update:modelValue', false)">
<div>
<el-form
label-width="150px"
:model="bindingData"
require-asterisk-position="right"
inline
>
<el-form-item label="零件号:" required>
<el-input class="form-input" v-model="bindingData.goodsId" clearable/>
</el-form-item>
<el-form-item label="数量:" required>
<el-input class="form-input" v-model="bindingData.goodsNum" clearable/>
</el-form-item>
<div style="margin-top: 50px">
<el-button type="warning" @click="resetInput">
<el-icon class="el-icon--left"><RefreshRight/></el-icon>
重置输入
</el-button>
<el-button type="primary" @click="addOrder()">
<el-icon class="el-icon--left"><Search /></el-icon>
下发任务
</el-button>
<el-button type="danger" @click="$emit('update:modelValue', false)">
<el-icon class="el-icon--left"><CircleCloseFilled/></el-icon>
关闭窗口
</el-button>
</div>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
// import from ' ';
import {CircleCloseFilled, Close, RefreshRight} from "@element-plus/icons-vue";
import {formatterOrderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import {ElMessage, ElMessageBox} from "element-plus";
//import apiOrderIn from '@/api/order.in';
import apiOrderOut from '@/api/order.out'
export default {
// import 使
components: {Close, CircleCloseFilled, RefreshRight},
props: ['modelValue'],
emits: ['update:modelValue'],
data() {
//
return {
//
bindingData: {
goodsId: '',
goodsNum: '',
},
bindOrderInList: []
}
},
// data
computed: {},
// data
watch: {},
//
methods: {
formatCellValueTime,
formatterOrderInEnum,
addOrder() {
if(this.bindingData.goodsId === '' || this.bindingData.goodsNum === '') {
ElMessage({
message: '数量和物料号不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = []
ElMessageBox.confirm(`是否执行手动出库?`, '提示')
.then(() => {
apiOrderOut.addOrder(this.bindingData).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
test() {
console.log(this.bindingData);
},
//
queryBinding() {
if(this.bindingData.vehicleNo === '') {
ElMessage({
message: '载具号不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = [];
apiOrderIn.getOrderInWithVehicleNo(this.bindingData.vehicleNo).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
resetInput() {
this.bindingData.goodsId = '';
this.bindingData.goodsNum = '';
},
//
bindingGoods() {
if(this.bindingData.vehicleNo === '' || this.bindingData.code === '') {
ElMessage({
message: '载具号和物料号不能为空',
type: 'error',
});
return;
}
apiOrderIn.bindingVehicle({vehicleNo: this.bindingData.vehicleNo, code: this.bindingData.code}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '绑定成功',
type: 'success',
});
this.queryBinding();
this.bindingData.code = '';
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '绑定失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
},
// API
setup() {
},
//
beforeCreate() {
},
// (访 this )
created() {
},
// -
beforeMount() {
},
// - 访 DOM
mounted() {
},
//
beforeUpdate() {
},
//
updated() {
},
//
beforeUnmount() {
},
//
unmounted() {
}
}
</script>
<style lang="scss" scoped>
$input-width: 500px;
.form-input {
width: $input-width;
}
</style>

View File

@ -0,0 +1,229 @@
<!-- -->
<template>
<div style="margin-left: 10px">
<el-dialog :model-value="modelValue" :show-close="false" title="添加一个空托盘"
@close="() => $emit('update:modelValue', false)">
<div>
<el-form
label-width="150px"
:model="bindingData"
require-asterisk-position="right"
inline
>
<el-form-item label="托盘号:" required>
<el-input class="form-input" v-model="bindingData.vehicleNo" clearable/>
</el-form-item>
<el-form-item label="位置:" required>
<el-input class="form-input" v-model="bindingData.location" clearable/>
</el-form-item>
<div style="margin-top: 50px">
<el-button type="warning" @click="resetInput">
<el-icon class="el-icon--left"><RefreshRight/></el-icon>
重置输入
</el-button>
<el-button type="primary" @click="addOrder()">
<el-icon class="el-icon--left"><Search /></el-icon>
添加空框
</el-button>
<el-button type="danger" @click="$emit('update:modelValue', false)">
<el-icon class="el-icon--left"><CircleCloseFilled/></el-icon>
关闭窗口
</el-button>
</div>
</el-form>
</div>
</el-dialog>
</div>
</template>
<script>
// import from ' ';
import {CircleCloseFilled, Close, RefreshRight} from "@element-plus/icons-vue";
import {formatterOrderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import {ElMessage, ElMessageBox} from "element-plus";
//import apiOrderIn from '@/api/order.in';
import apiOrderOut from '@/api/order.out'
export default {
// import 使
components: {Close, CircleCloseFilled, RefreshRight},
props: ['modelValue'],
emits: ['update:modelValue'],
data() {
//
return {
//
bindingData: {
vehicleNo: '',
location: '',
},
bindOrderInList: []
}
},
// data
computed: {},
// data
watch: {},
//
methods: {
formatCellValueTime,
formatterOrderInEnum,
addOrder() {
if(this.bindingData.vehicleNo === '' || this.bindingData.location === '') {
ElMessage({
message: '托盘号和位置不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = []
ElMessageBox.confirm(`是否添加一个空托盘?`, '提示')
.then(() => {
apiOrderOut.addOrderByInsertEmpty(this.bindingData).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
test() {
console.log(this.bindingData);
},
//
queryBinding() {
if(this.bindingData.vehicleNo === '') {
ElMessage({
message: '载具号不能为空',
type: 'error',
});
return;
}
this.bindOrderInList = [];
apiOrderIn.getOrderInWithVehicleNo(this.bindingData.vehicleNo).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.bindOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
resetInput() {
this.bindingData.vehicleNo = '';
},
//
bindingGoods() {
if(this.bindingData.vehicleNo === '' || this.bindingData.code === '') {
ElMessage({
message: '载具号和物料号不能为空',
type: 'error',
});
return;
}
apiOrderIn.bindingVehicle({vehicleNo: this.bindingData.vehicleNo, code: this.bindingData.code}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '绑定成功',
type: 'success',
});
this.queryBinding();
this.bindingData.code = '';
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '绑定失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
},
// API
setup() {
},
//
beforeCreate() {
},
// (访 this )
created() {
},
// -
beforeMount() {
},
// - 访 DOM
mounted() {
},
//
beforeUpdate() {
},
//
updated() {
},
//
beforeUnmount() {
},
//
unmounted() {
}
}
</script>
<style lang="scss" scoped>
$input-width: 500px;
.form-input {
width: $input-width;
}
</style>

View File

@ -0,0 +1,58 @@
<template>
<div class="menu-title">主菜单</div>
<!-- 侧边栏菜单区域 -->
<el-menu active-text-color="#409Eff" background-color="#fff" text-color="#000" :router="true" unique-opened>
<!-- 一级菜单 -->
<el-sub-menu :index="item.id" v-for="item in menuList" :key="item.id">
<!-- 一级菜单模板区域 -->
<template #title>
<el-icon>
<component :is="item.iconValue"></component>
</el-icon>
<span>{{ item.labelName }}</span>
</template>
<!-- 二级菜单 -->
<el-menu-item :index="subItem.path" v-for="subItem in item.children" :key="subItem.id"
@click="clickMenu(subItem)">
<template #title>
<span>{{ subItem.labelName }}</span>
</template>
</el-menu-item>
</el-sub-menu>
</el-menu>
</template>
<script setup>
import store from '@/store'
// import { mapState, mapMutations } from 'vuex';
</script>
<script>
export default {
name: 'side-menu',
data() {
return {
menuList: []
}
},
mounted() {
this.getMenuList()
},
methods: {
getMenuList() {
// this.menuList = this.$store.state.menuList
this.menuList = store.getters.getMenuList
},
//
clickMenu(value) {
//vuexstore
store.commit('mutationSelectTags', value)
}
}
}
</script>
<style scoped>
.menu-title {
margin-top: 5px;
}
</style>

55
src/demo/excelDemo.vue Normal file
View File

@ -0,0 +1,55 @@
<template>
<el-upload :on-preview="previewFile" :limit="1" :on-change="changeFile" :auto-upload="false" :data="uploadForm.data">
<template #trigger>
<el-button size="small" type="primary">选取文件</el-button>
</template>
<el-button style="margin-left: 10px;" size="small" type="success" @click="submitUpload">确认导入</el-button>
</el-upload>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { uploadExcel } from '@/api/excel.js'
import { ElMessage } from 'element-plus'
const file = ref()
const uploadForm = reactive({
data: {
fileId: '',
name: '',
type: ''
}
})
const changeFile = (uploadFile) => {
file.value = uploadFile
}
const submitUpload = () => {
if (uploadForm == undefined || file.value == undefined) {
ElMessage.error('请选择文件之后再导入')
}
const jsonStr = JSON.stringify(uploadForm.data);
const blob = new Blob([jsonStr], {
type: 'application/json'
});
let formData = new FormData();
// file.value.rawfilefile.valueProxy
formData.append("file", file.value.raw);
uploadExcel(formData).then(res => {
console.log(res.data)
if (res.data.code == 0) {
ElMessage({
message: '导入成功',
type: 'success',
})
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('导入错误')
})
}
const previewFile = () => {
}
</script>
<style scoped></style>

39
src/enum/order.in.enum.js Normal file
View File

@ -0,0 +1,39 @@
// 入库单状态
export const orderInEnum = {
creat: {
value: 0,
label: '待入库',
color: 'info'
},
running: {
value: 1,
label: '正在入库',
color: 'primary'
},
finish: {
value: 2,
label: '绑定成功',
color: 'success'
},
error: {
value: 9,
label: '执行异常',
color: 'danger'
}
}
export function formatterOrderInEnum(value) {
switch (parseInt(value)){
case orderInEnum.creat.value:
return {label: orderInEnum.creat.label, type: orderInEnum.creat.color};
case orderInEnum.running.value:
return {label: orderInEnum.running.label, type: orderInEnum.running.color};
case orderInEnum.finish.value:
return {label: orderInEnum.finish.label, type: orderInEnum.finish.color};
case orderInEnum.error.value:
return {label: orderInEnum.error.label, type: orderInEnum.error.color};
default:
return {label: `未知类型:${value}`, type: 'danger'};
}
}

View File

@ -0,0 +1,32 @@
// 出库单状态
export const orderOutEnum = {
creat: {
value: 0,
label: '待出库',
color: 'info'
},
running: {
value: 1,
label: '出库中',
color: 'primary'
},
error: {
value: 9,
label: '执行异常',
color: 'danger'
}
}
export function formatterOrderOutEnum(value) {
switch (parseInt(value)){
case orderOutEnum.creat.value:
return {label: orderOutEnum.creat.label, type: orderOutEnum.creat.color};
case orderOutEnum.running.value:
return {label: orderOutEnum.running.label, type: orderOutEnum.running.color};
case orderOutEnum.error.value:
return {label: orderOutEnum.error.label, type: orderOutEnum.error.color};
default:
return {label: `未知类型:${value}`, type: 'danger'};
}
}

View File

@ -0,0 +1,58 @@
<template>
<el-upload ref="uploadRef" :on-preview="previewFile" :limit="1" :on-change="changeFile" :auto-upload="false" :data="uploadForm.data">
<template #trigger>
<el-button type="primary">选取文件</el-button>
</template>
<el-button style="margin-left: 5px;" type="success" @click="uploadParts">确认导入零件数据</el-button>
</el-upload>
</template>
<script setup>
import { ref, reactive } from 'vue';
import { uploadExcelParts } from '@/api/excel.js'
import { ElMessage } from 'element-plus'
const file = ref()
const uploadForm = reactive({
data: {
fileId: '',
name: '',
type: ''
}
})
const changeFile = (uploadFile) => {
file.value = uploadFile
}
const uploadRef = ref()
const uploadParts = () => {
if (uploadForm == undefined || file.value == undefined) {
ElMessage.error('请选择文件之后再导入')
}
const jsonStr = JSON.stringify(uploadForm.data);
const blob = new Blob([jsonStr], {
type: 'application/json'
});
let formData = new FormData();
// file.value.rawfilefile.valueProxy
formData.append("file", file.value.raw);
uploadExcelParts(formData).then(res => {
if (res.data.code == 0) {
ElMessage({
message: '导入成功',
type: 'success',
})
//
uploadRef.value.clearFiles()
file.value = undefined
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('导入错误')
})
}
const previewFile = () => {
}
</script>
<style scoped></style>

46
src/http/request.js Normal file
View File

@ -0,0 +1,46 @@
import axios from 'axios'
//192.168.16.116
const request = axios.create({
baseURL: 'http://localhost:19990/wms',
timeout: 5000
})
// axios.defaults.baseURL = 'http://192.168.103.202:12315/wms'
// axios.defaults.baseURL = 'http://localhost:12315/wms'
// axios.defaults.baseURL = 'http://192.168.8.21:12315/wms'
// // request 请求器
// // 可以自请求发送前对请求做一些处理
// // 比如统一加token对请求参数统一加密
// request.interceptors.request.use(config => {
// if (config && config.headers) {
// config.headers['Content-Type'] = 'application/json;charset=utf-8';
// }
// // config.headers['token'] = user.token; // 设置请求头
// return config
// }, error => {
// return Promise.reject(error)
// });
// // response 拦截器
// // 可以在接口响应后统一处理结果
// request.interceptors.response.use(
// response => {
// let res = response.data;
// // 如果是返回的文件
// if (response.config.responseType === 'blob') {
// return res
// }
// // 兼容服务端返回的字符串数据
// if (typeof res === 'string') {
// res = res ? JSON.parse(res) : res
// }
// return res;
// },
// error => {
// console.log('err' + error) // for debug
// return Promise.reject(error)
// }
// )
export default request

311
src/layout/boxConfig.vue Normal file
View File

@ -0,0 +1,311 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row>
<UploadExcelBoxConfig></UploadExcelBoxConfig>
</el-row>
<el-row style="margin-top: 10px;">
<el-input v-model="boxNoQuery" style="width: 256px; margin-right: 10px;" placeholder="料盒号" />
<el-input v-model="stationQuery" style="width: 256px; margin-right: 10px;" placeholder="站台号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="addBoxConfigFunc()">新增配置</el-button>
</el-row>
<br />
<el-table :data="boxConfigs" stripe border v-loading="loading" class="table-class" max-height="650px"
highlight-current-row @row-click="getCurrentRow" :header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.boxNo" v-model="boxNo">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="boxNo" label="料盒号" fixed="left" sortable min-width="120px" />
<el-table-column prop="station" label="站台号" fixed="left" min-width="120px" />
<el-table-column fixed="right" label="操作" width="240px">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentBoxConfig(scope.row)">编辑</el-button>
<el-button plain type="danger" @click="deleteCurrentBoxConfig(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
<el-dialog v-model="dialogVisible" title="更新料盒配置" width="40%" draggable :show-close="false">
<el-form ref="configFormRef" :model="configFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料盒号" prop="boxNo">
<el-input v-model="configFormEntity.boxNo" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="站台号" prop="station">
<el-select-v2 v-model="configFormEntity.station" placeholder="请选择分配站台"
:options="stationOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitUpdateBoxConfig(configFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
<el-dialog v-model="dialogVisibleAdd" title="添加料盒配置" width="40%" draggable :show-close="false">
<el-form ref="configAddFormRef" :model="configAddFormEntity" :label-position="labelPosition"
label-width="100px" style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料盒号" prop="boxNo">
<el-input v-model="configAddFormEntity.boxNo" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="站台号" prop="station">
<el-select-v2 v-model="configAddFormEntity.station" placeholder="请选择分配站台"
:options="stationOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisibleAdd = false">取消</el-button>
<el-button type="primary" @click="submitAddBoxConfig(configAddFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import { queryBoxConfigByPage, updateBoxConfig, addBoxConfig, deleteBoxConfig } from '@/api/config.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import { ref, reactive } from 'vue'
import UploadExcelBoxConfig from '@/excel/UploadExcelBoxConfig.vue'
</script>
<script>
export default {
name: 'boxConfig',
component: {
UploadExcelBoxConfig
},
data() {
return {
boxConfigs: [],
pageInfo: {},
currentPage: 1,
pageSize: 10,
total: 0,
boxNoQuery: '',
stationQuery: '',
loading: true,
dialogVisible: false,
dialogVisibleAdd: false,
boxNo: '',
labelPosition: 'top',
configFormEntity: reactive({}),
configFormRef: ref(),
configAddFormEntity: reactive({}),
configAddFormRef: ref(),
rules: reactive({}),
stationOptions: [
{
label: '2001',
value: '2001'
},
{
label: '2002',
value: '2002'
},
{
label: '2003',
value: '2003'
},
{
label: '2004',
value: '2004'
},
{
label: '2005',
value: '2005'
},
{
label: '2006',
value: '2006'
},
{
label: '2007',
value: '2007'
},
{
label: '2008',
value: '2008'
}
]
}
},
mounted() {
this.search()
},
methods: {
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
boxNo: this.boxNoQuery.trim(),
station: this.stationQuery.trim()
},
}
queryBoxConfigByPage(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.boxConfigs = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
ElMessage.error('查询料盒配置错误' + err.message)
})
this.loading = false
},
reset() {
this.queryKey = ''
this.search
},
editCurrentBoxConfig(row) {
this.configFormEntity = row
this.dialogVisible = true
},
addBoxConfigFunc() {
this.configAddFormEntity = reactive({})
this.dialogVisibleAdd = true
},
deleteCurrentBoxConfig(row) {
this.boxNo = row.boxNo
const boxConfig = {
boxNo: row.boxNo
}
deleteBoxConfig(boxConfig).then(res => {
if (res.data.code == 0) {
ElMessage({
message: '删除料盒配置成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('删除料盒配置失败:' + err)
})
},
submitUpdateBoxConfig(formData) {
if (formData.boxNo == null | undefined || formData.station == null | undefined) {
ElMessage({
message: '料盒号和站台号必须输入',
type: 'error',
})
return;
}
updateBoxConfig(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新料盒配置信息成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('更新料盒配置信息失败')
})
},
submitAddBoxConfig(formData) {
if (formData.boxNo == null | undefined || formData.station == null | undefined) {
ElMessage({
message: '料盒号和站台号必须输入',
type: 'error',
})
return;
}
addBoxConfig(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisibleAdd = false
ElMessage({
message: '添加料盒配置成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('添加料盒配置失败')
})
},
getCurrentRow(row) {
this.boxNo = row.boxNo
},
},
// watch: {
// currentPage() {
// this.getCurrentPageGoods()
// },
// pageSize() {
// this.getCurrentPageGoods()
// }
// }
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
.el-row .el-form-item {
width: 10% inherit;
justify-content: center;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

145
src/layout/config.vue Normal file
View File

@ -0,0 +1,145 @@
<template>
<el-config-provider :locale="zhCn">
<el-container class="content">
<fieldset class="input-area">
<legend>系统配置</legend>
<div v-for="config in configs">
<el-form :model="config" :label-position="'top'" label-width="100px" style="max-width: 544px"
:rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="1" v-if="config.configKey == 'MAIL_ADDRESS'">
<el-form-item label="邮箱账户(账户之间用;隔开)">
<div>
<el-input v-model="config.configValue" @change="updateCurrentConfig(config)" />
</div>
</el-form-item>
</el-col>
<el-col :span="12" :offset="1"
v-if="config.configType == '1' && config.configKey != 'MAIL_ADDRESS'">
<el-form-item :label="config.configName">
<div>
<el-input v-model="config.configValue" @change="updateCurrentConfig(config)" />
</div>
</el-form-item>
</el-col>
<el-col :span="12" :offset="1"
v-if="config.configType == '2' && config.configKey != 'MAIL_ADDRESS'">
<el-form-item :label="config.configName">
<div v-if="config.configType == '2'">
<el-select v-model="config.configValue" multiple collapse-tags collapse-tags-tooltip
:placeholder="'请选择' + config.configName" @change="updateCurrentConfig(config)">
<el-option v-for="(value, index) in mails" :key="index" :label="value"
:value="value" />
</el-select>
</div>
</el-form-item>
</el-col>
</el-row>
</el-form>
</div>
</fieldset>
</el-container>
</el-config-provider>
</template>
<script setup>
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { getConfigs, updateConfig } from '@/api/config.js'
import { ElMessage, ElLoading } from 'element-plus'
</script>
<script>
export default {
name: 'config',
data() {
return {
configs: [],
mails: [],
rules: {}
}
},
mounted() {
this.getAllConfigs()
},
methods: {
getAllConfigs() {//
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
getConfigs().then(res => {
loading.close()
this.configs = res.data
this.configs.forEach((config) => {
if (config.configType == '2') {
const tempArray = config.configValue.split(';')
config.configValue = tempArray
}
if (config.configKey == 'MAIL_ADDRESS') {
const tempArray = config.configValue.split(';')
this.mails = tempArray
}
})
}).catch(err => {
console.log(err)
loading.close()
ElMessage.error('查询系统配置失败!')
})
},
updateCurrentConfig(config) {//
// config
const param = Object.assign({}, config)
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
if (param.configType == '2') {
param.configValue = param.configValue.join(';')
}
updateConfig(param).then(res => {
loading.close()
if (res.data.code == 0) {
ElMessage({
message: '更新系统配置成功!',
type: 'success',
})
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
loading.close()
ElMessage.error('更新系统配置失败!')
})
}
}
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.input-area {
margin: 10px;
width: 100%;
height: 85%;
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
}
.el-row .el-form-item .el-select {
width: 512px;
}
.el-row .el-form-item .el-input {
width: 512px;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

363
src/layout/goods.vue Normal file
View File

@ -0,0 +1,363 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row>
<UploadExcelPart></UploadExcelPart>
</el-row>
<el-row style="margin-top: 10px;">
<el-input v-model="queryKey" style="width: 256px; margin-right: 10px;" placeholder="零件号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="search()">刷新</el-button>
<el-button type="success" @click="exportExcel()">导出信息</el-button>
</el-row>
<br />
<el-table :data="partInfos" stripe border v-loading="loading" class="table-class" max-height="650px"
highlight-current-row @row-click="getCurrentRow" :header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.material" v-model="material">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="material" label="零件号" fixed="left" sortable min-width="120px" />
<el-table-column prop="itemDesc" label="描述" fixed="left" min-width="120px" />
<el-table-column prop="category" label="零件类型" fixed="left" sortable min-width="120px" />
<el-table-column prop="categoryRemark" label="策略" min-width="120px" />
<el-table-column prop="unloadPlace" label="卸货点" min-width="120px" />
<el-table-column prop="kittingPoint" label="配料点" min-width="120px" />
<el-table-column prop="property" label="可用性" min-width="120px" />
<el-table-column prop="vendorId" label="供应商代码" min-width="120px" />
<el-table-column prop="dataOwner" label="数据负责人" min-width="120px" />
<el-table-column prop="partWeight" label="重量" min-width="120px" />
<el-table-column prop="storageLocation" label="库位" min-width="120px" />
<el-table-column prop="storageType" label="存储类型" min-width="120px" />
<el-table-column prop="storageBin" label="BIN位" min-width="120px" />
<el-table-column prop="vendorNameEN" label="供应商名称(英文)" min-width="120px" />
<el-table-column prop="vendorNameCN" label="供应商名称(中文)" min-width="120px" />
<el-table-column prop="vendorCountry" label="供应商国家/地区" min-width="120px" />
<el-table-column prop="SLED" label="SLED" min-width="120px" />
<el-table-column prop="updateDate" label="更新日期" min-width="120px" />
<el-table-column fixed="right" label="操作" width="240px">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentRowGoods(scope.row)">编辑</el-button>
<el-button plain type="danger" @click="deleteCurrentRowGoods(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
<el-dialog v-model="dialogVisible" title="物料信息" width="40%" draggable :show-close="false">
<el-form ref="goodsFormRef" :model="goodsFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="零件号" prop="material">
<el-input v-model="goodsFormEntity.material" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="描述" prop="itemDesc">
<el-input v-model="goodsFormEntity.itemDesc" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="零件类型" prop="category">
<el-input v-model="goodsFormEntity.category" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="策略" prop="categoryRemark">
<el-input v-model="goodsFormEntity.categoryRemark" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="卸货点" prop="unloadPlace">
<el-input v-model="goodsFormEntity.unloadPlace" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="配料点" prop="kittingPoint">
<el-input v-model="goodsFormEntity.kittingPoint" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="可用性" prop="property">
<el-input v-model="goodsFormEntity.property" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="供应商代码" prop="vendorId">
<el-input v-model="goodsFormEntity.vendorId" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="数据负责人" prop="dataOwner">
<el-input v-model="goodsFormEntity.dataOwner" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="重量" prop="partWeight">
<el-input v-model="goodsFormEntity.partWeight" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="库位" prop="storageLocation">
<el-input v-model="goodsFormEntity.storageLocation" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="存储类型" prop="storageType">
<el-input v-model="goodsFormEntity.storageType" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="BIN位" prop="storageBin">
<el-input v-model="goodsFormEntity.storageBin" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="供应商名称(英文)" prop="vendorNameEN">
<el-input v-model="goodsFormEntity.vendorNameEN" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="供应商名称(中文)" prop="vendorNameCN">
<el-input v-model="goodsFormEntity.vendorNameCN" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="供应商国家/地区" prop="vendorCountry">
<el-input v-model="goodsFormEntity.vendorCountry" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="SLED" prop="SLED">
<el-input-number v-model.number="goodsFormEntity.SLED" clearable controls-position="right"
:min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="更新日期" prop="updateDate">
<el-input v-model="goodsFormEntity.updateDate" clearable />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitGoodsInfo(goodsFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import { getPartInfo, updatePartInfo, deleteCurrentPartInfo } from '@/api/goods.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import { ref, reactive } from 'vue'
import { dateFormatter } from '@/utils/formatter.js'
import UploadExcelPart from '@/excel/UploadExcelPart.vue'
import { downloadMaterialExcel } from '@/api/excel.js'
</script>
<script>
export default {
name: 'goods',
data() {
return {
partInfos: [],
pageInfo: {},
currentPage: 1,
pageSize: 10,
total: 0,
queryKey: '',
loading: true,
dialogVisible: false,
material: '',
goodsFormEntity: reactive({}),
labelPosition: 'top',
goodsFormRef: ref(),
rules: reactive({})
}
},
mounted() {
this.search()
},
methods: {
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
material: this.queryKey.trim()
},
}
getPartInfo(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
console.log(tableResponse.code + ':' + tableResponse.message)
ElMessage.error(tableResponse.message)
}
this.partInfos = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
ElMessage.error('查询物料错误' + err.message)
})
this.loading = false
},
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
reset() {
this.queryKey = ''
this.search
},
// getCurrentPageGoods() {
// this.currentGoods = this.displayGoods.slice((this.currentPage - 1) * this.pageSize, this.currentPage * this.pageSize)
// },
editCurrentRowGoods(row) {
this.goodsFormEntity = row
this.dialogVisible = true
},
deleteCurrentRowGoods(row) {
this.material = row.material
const goods = {
material: row.material
}
deleteCurrentPartInfo(goods).then(res => {
if (res.data.code == 0) {
ElMessage({
message: '删除零件信息成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('删除零件信息失败:' + err)
})
},
submitGoodsInfo(formData) {
updatePartInfo(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新零件信息成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('更新零件信息失败')
})
},
getCurrentRow(row) {
this.goodsId = row.goodsId
},
exportExcel() {
downloadMaterialExcel().then(res => {
const link = document.createElement('a');//a
try {
// let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //blobblobtypexls
let blob = res.data //blob
// let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //
let _fileName = "导出物料信息" + dateFormatter(new Date) + ".xlsx"
link.style.display = 'none'//
// URL
const url = window.URL || window.webkitURL || window.moxURL
link.href = url.createObjectURL(blob)
link.setAttribute('download', _fileName.substring(_fileName.lastIndexOf('_') + 1))
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
url.revokeObjectURL(link.href)//url
} catch (e) {
ElMessage({
message: '下载文件失败:: ' + e,
type: 'error',
showClose: true
})
}
}).catch(err => {
ElMessage({
message: '导出失败:: ' + err,
type: 'error',
showClose: true
})
})
},
},
// watch: {
// currentPage() {
// this.getCurrentPageGoods()
// },
// pageSize() {
// this.getCurrentPageGoods()
// }
// }
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
.el-row .el-form-item {
width: 10% inherit;
justify-content: center;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

293
src/layout/goodsIn.vue Normal file
View File

@ -0,0 +1,293 @@
<template>
<el-config-provider :locale="localLanguage">
<div style="width: calc(100vw - 300px)">
<div style="border-radius: 5px; border: #2c3e5033 solid 1px; padding: 10px; calc(100vw - 300px)"><!-- 搜索-->
<el-row style="width: 100%">
<el-form :model="searchParams" label-width="120" label-position="left" >
<el-form-item style="width: 600px" label="查询关键字:">
<el-input placeholder="输入 料箱号/库位/任务号 查询..." v-model="searchParams.searchStr" clearable></el-input>
</el-form-item>
<el-form-item style="width: 600px" label="任务状态:">
<el-select style="width: 600px" v-model="searchParams.orderStatus" multiple placeholder="请选择需要查询的任务状态">
<el-option v-for="item in orderInEnum" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-form>
</el-row>
<el-row>
<el-button type="primary" @click="queryGoodsOrderIn">查询入库单</el-button>
<el-button type="success" @click="showBindingGoods = true">下发入库任务</el-button>
</el-row>
</div>
<div> <!-- 表格-->
<el-row style="width: calc(100vw - 300px)">
<h5>入库单</h5>
<el-table :data="goodsOrderInList" border stripe max-height="calc(100vh - 550px)">
<el-table-column fixed prop="rowId" label="识别号" width="130px" align="center" show-overflow-tooltip/>
<el-table-column fixed prop="guid" label="GUID" width="200px" align="center" show-overflow-tooltip/>
<el-table-column prop="inType" label="入库类型" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="batchNo" label="批次" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="vehicleNo" label="载具号" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="goodsId" label="物料号" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="goodsNum" label="物料数量" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="wareHouse" label="库别" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="orderStatus" label="入库单状态" width="95px" align="center">
<template #default="scope">
<el-tag class="ml-2" :type=formatterOrderInEnum(scope.row.orderStatus).type>
{{formatterOrderInEnum(scope.row.orderStatus).label }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createPerson" label="创建人" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="createTime" label="创建时间" :formatter="formatCellValueTime" width="180px"
align="center" show-overflow-tooltip/>
<el-table-column prop="updateTime" label="更新时间" :formatter="formatCellValueTime" width="180px" align="center" show-overflow-tooltip/>
<el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="120px"/>
<el-table-column fixed="right" label="操作" align="center" width="190">
<template #default="scope">
<el-button-group class="ml-4">
<!-- <el-tooltip content="解绑" placement="top" effect="light">
<el-button type="warning" size="small" @click="unBindingOrder(scope.row)">
<el-icon><Close /></el-icon>
</el-button>
</el-tooltip> -->
<el-tooltip content="更新数量" placement="top" effect="light">
<el-button type="success" size="small" @click="updateGoodsNum(scope.row)">
<el-icon><Edit/></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top" effect="light">
<el-button type="danger" size="small" @click="deleteOrder(scope.row)">
<el-icon><Delete/></el-icon>
</el-button>
</el-tooltip>
</el-button-group>
</template>
</el-table-column>
</el-table>
<!-- 对话框部分 -->
<el-dialog v-model="dialogVisible" title="更新数量" width="40%" @close="resetForm">
<el-form ref="updateFormRef" :model="updateFormEntity" :rules="rules" status-icon>
<el-form-item label="识别号" prop="rowId">
<el-input v-model="updateFormEntity.rowId" readonly />
</el-form-item>
<el-form-item label="实际数量" prop="realNum">
<el-input-number v-model.number="updateFormEntity.realNum" controls-position="right" :min="0" clearable />
</el-form-item>
<!-- 其他表单项 -->
</el-form>
<span slot="footer" class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitUpdate">确认</el-button>
</span>
</el-dialog>
</el-row>
</div>
</div>
<!-- 绑定物料框-->
<BindingGoods v-model="showBindingGoods"></BindingGoods>
</el-config-provider>
</template>
<script>
import { Delete, Close, Edit } from "@element-plus/icons-vue";
import apiOrderIn from '@/api/order.in';
import {ElMessage, ElMessageBox} from 'element-plus'
import stock from '@/layout/stock.vue'
import {formatterOrderInEnum, orderInEnum} from "@/enum/order.in.enum";
import {formatCellValueTime} from "@/utils/formatter";
import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
import en from 'element-plus/dist/locale/en.mjs';
import {ref} from "vue";
import BindingGoods from "@/components/BindingGoods.vue";
const language = ref('zh-cn');
export default {
name: 'goodsIn',
computed: {
orderInEnum() {
return orderInEnum
},
localLanguage: () => (language.value === 'zh-cn' ? zhCn : en)
},
components: {BindingGoods, Delete, Close, Edit },
data() {
return {
//
searchParams: {
searchStr: '',
orderStatus: [0,1,2]
},
//
showBindingGoods: false,
//
dialogVisible: false,
updateFormEntity: {
rowId: '',
realNum: 0
//
},
rules: {
//
},
tableData: [], //
//
goodsOrderInList: []
}
},
mounted() {},
methods: {
formatCellValueTime,
formatterOrderInEnum,
//
queryGoodsOrderIn() {
this.goodsOrderInList = [];
apiOrderIn.getOrderInList(this.searchParams).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.goodsOrderInList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.msg}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
deleteOrder(row) {
ElMessageBox.confirm('确定执行删除吗?','提示')
.then(() => {
apiOrderIn.deleteOrderIn(row.rowId).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '删除成功',
type: 'success',
});
this.queryGoodsOrderIn();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '删除失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
//
updateGoodsNum(row) {
this.dialogVisible = true;
this.updateFormEntity = row;
},
test() {
console.log({rowId:this.updateFormEntity.rowId,realNum:this.updateFormEntity.realNum,orderStatus:this.updateFormEntity.orderStatus});
},
//
submitUpdate(){
if(this.updateFormEntity.realNum === 0){
ElMessage({
message: '数量不能为0',
type: 'error',
});
return;
}
if(this.updateFormEntity.orderStatus === 1){
ElMessage({
message: '正在入库的订单不能更新数量',
type: 'error',
});
return;
}
apiOrderIn.updateForNum({rowId:this.updateFormEntity.rowId,realNum:this.updateFormEntity.realNum}).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '更新成功',
type: 'success',
});
this.queryGoodsOrderIn();
}else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '更新失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
unBindingOrder(row) {
ElMessageBox.confirm('你确定要解绑该吗','提示')
.then(() => {
apiOrderIn.unbindingVehicle(row.rowId).then(res => {
const responseData = res.data
if (responseData.code === 0) {
//
ElMessage({
message: '解绑成功',
type: 'success',
});
this.queryGoodsOrderIn();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '解绑失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
}
}
}
</script>
<style scoped>
</style>

View File

@ -0,0 +1,407 @@
<template>
<el-config-provider :locale="zhCn">
<el-container class="content">
<fieldset class="input-area">
<legend style="font-size: xxx-large;">入库界面</legend>
<el-form ref="taskInRequestRef" :model="taskInRequestEntity" :label-position="labelPosition"
label-width="100px" style="max-width: 100%" :rules="rules" status-icon size="large">
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="是否入空托" prop="isEmpty">
<el-select-v2 v-model="taskInRequestEntity.isEmpty" placeholder="请选择入库类型"
:options="stockTypeOptions"
@change="autoCompleteEmptyInfo(taskInRequestEntity)"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="箱号" prop="vehicleNo">
<el-input v-model="taskInRequestEntity.vehicleNo" ref="vehicleNo" clearable
style="height: 50px;" v-on:keyup.tab="detectEndInputVehicleNo(taskInRequestEntity)" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="零件号" prop="goodsId">
<el-input v-model="taskInRequestEntity.goodsId" ref="goodsId" clearable
:disabled="disabledEmpty" @blur="queryAndAutoComplete(taskInRequestEntity)"
style="height: 50px;" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="零件名称" prop="goodsName">
<el-input v-model="taskInRequestEntity.goodsName" clearable readonly
style="height: 50px;" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="零件数量" prop="goodsNum">
<el-input-number v-model.number="taskInRequestEntity.goodsNum" ref="goodsNum" clearable
:disabled="disabledEmpty" controls-position="right" :min="1"
@blur="detectEndInputNum(taskInRequestEntity)" style="height: 50px;"></el-input-number>
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1">
<el-form-item label="零件重量(千克)" prop="weight">
<el-input v-model="taskInRequestEntity.weight" clearable readonly style="height: 50px;" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1" v-show="disPlayDateFlag">
<el-form-item label="有效期(年)" prop="shelfLife">
<!-- // TODO -->
<el-input v-model="taskInRequestEntity.shelfLife" clearable readonly
style="height: 50px;" />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="22" :offset="1" v-show="disPlayDateFlag">
<el-form-item label="生产日期" prop="productionDate">
<el-date-picker v-model="taskInRequestEntity.productionDate" ref="productionDate"
:disabled="disabledEmpty" style="width: 100%;height: 75px;" type="date"
placeholder="请选择生产日期" :editable="false" size="large" clearable />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="4" class="btn-area">
<el-col :span="8" :offset="0">
<el-form-item>
<el-button type="primary" round
@click="addTempTasks(taskInRequestRef, taskInRequestEntity)">绑定信息</el-button>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="success" round
@click="submitGoodsInTask(taskInRequestRef)">下发任务</el-button>
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item>
<el-button type="warning" round @click="callEmptyVehicles(taskInRequestEntity)">请求空箱</el-button>
</el-form-item>
</el-col>
</el-row>
</el-form>
</fieldset>
<div ref="btnArea"></div>
</el-container>
</el-config-provider>
</template>
<script setup>
import store from '@/store'
import { sendGoodsInTask, callEmptyVehicle } from '@/api/task'
import { queryPartInfoByPartNo } from '@/api/goods'
import { reactive, ref } from 'vue'
import { ElMessage } from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import UploadExcelPart from '@/excel/UploadExcelPart.vue'
const taskInRequestRef = ref()
const taskInRequestEntity = reactive({
vehicleNo: '',//
goodsId: '',//
goodsName: '',//
goodsNum: 1,//
weight: 0,//
shelfLife: 0,//
productionDate: '',//
isEmpty: '1',
userName: store.getters.getUserName//
})
const rules = reactive({
vehicleNo: [
{ required: true, message: '请输入载具编号' }
],
goodsId: [
{ required: true, message: '请输入物料编号' }
],
goodsNum: [
{ required: true, message: '请输入数量' },
{ type: 'number', message: '请输入数字' }
]
})
const labelPosition = "top"
</script>
<script>
export default {
name: 'goodsInPda',
components: {
UploadExcelPart
},
data() {
return {
tempTasks: [],
tempVehicleNo: '',
disPlayDateFlag: false,
currentPartInfo: {},
stockTypeOptions: [
{
value: '0',
label: '空箱入库'
},
{
value: '1',
label: '带料入库'
}
],
disabledEmpty: false,
totalWeight: 0,
isOverWeight: false
}
},
mounted() {
this.$refs.vehicleNo.focus()
},
methods: {
//
queryAndAutoComplete(taskInRequestEntity) {
this.loading = true
const param = { material: taskInRequestEntity.goodsId }
queryPartInfoByPartNo(param).then(res => {
console.log(res)
if (res.data.code == 0) {
this.currentPartInfo = res.data.returnData
taskInRequestEntity.goodsName = this.currentPartInfo.itemDesc
this.calWeight(taskInRequestEntity)
if (this.currentPartInfo.SLED > 0) {//
this.disPlayDateFlag = true
taskInRequestEntity.shelfLife = this.currentPartInfo.SLED
} else {
this.disPlayDateFlag = false
taskInRequestEntity.shelfLife = 0
taskInRequestEntity.productionDate = ''
}
taskInRequestEntity.goodsNum = ''
this.$refs.goodsNum.focus()
} else {
taskInRequestEntity.goodsName = ''
taskInRequestEntity.goodsNum = ''
taskInRequestEntity.weight = 0
this.disPlayDateFlag = false
taskInRequestEntity.shelfLife = 0
taskInRequestEntity.productionDate = ''
ElMessage.error(res.data.message)
}
}).catch(err => {
taskInRequestEntity.goodsName = ''
taskInRequestEntity.goodsNum = ''
taskInRequestEntity.weight = 0
this.disPlayDateFlag = false
taskInRequestEntity.shelfLife = 0
taskInRequestEntity.productionDate = ''
ElMessage.error('查询物料信息错误' + err.message)
})
this.loading = false
},
calWeight(taskInRequestEntity) {
taskInRequestEntity.weight = this.currentPartInfo.partWeight * taskInRequestEntity.goodsNum
this.totalWeight = this.totalWeight + taskInRequestEntity.weight
if (this.totalWeight > 30) {
this.isOverWeight = true
ElMessage({
message: '箱子重量超过30kg',
type: 'warning',
})
}
},
autoCompleteEmptyInfo(taskInRequestEntity) {//
if (taskInRequestEntity.isEmpty == '0') {//
taskInRequestEntity.goodsId = '000000000'
taskInRequestEntity.batchNo = '000000000'
taskInRequestEntity.goodsNum = 1
taskInRequestEntity.weight = 0
taskInRequestEntity.shelfLife = 0
taskInRequestEntity.productionDate = ''
this.currentPartInfo = {}
this.disabledEmpty = true
this.disPlayDateFlag = false
} else {
taskInRequestEntity.goodsId = ''
taskInRequestEntity.batchNo = ''
taskInRequestEntity.goodsNum = 1
this.disabledEmpty = false
}
this.$refs.vehicleNo.focus()
},
addTempTasks(formEl, formData) {//
if (!formEl) return
formEl.validate((valid) => {
if (!valid) {
ElMessage({
message: '请输入必须的入库信息!',
type: 'warning',
})
return
}
if (this.tempVehicleNo !== '' && this.tempVehicleNo !== formData.vehicleNo) {
ElMessage({
message: '载具编号不一致,请确认后重新输入!',
type: 'warning',
})
return
}
if (this.tempVehicleNo != '' && formData.isEmpty == '0') {
ElMessage({
message: '此箱子已经绑定过,请下发。',
type: 'warning',
})
return
}
if (this.isOverWeight) {
ElMessage({
message: '已超重,不可继续绑定,请移除此物料,并下发任务',
type: 'error',
showClose: true
})
return
}
this.tempVehicleNo = formData.vehicleNo
formData.userName = store.getters.getUserName
this.tempTasks.push(Object.assign({}, formData))
formEl.resetFields()
this.disabledEmpty = false
formData.vehicleNo = this.tempVehicleNo
this.currentPartInfo = {}
ElMessage({
message: '绑定成功!',
type: 'success',
})
})
},
submitGoodsInTask(formEl) {//
if (this.tempTasks.length == 0) {
ElMessage.error("未绑定任何信息")
}
sendGoodsInTask(this.tempTasks).then(res => {
console.log(res)
if (res.data.code == 0) {
this.tempTasks = []
this.tempVehicleNo = ''
formEl.resetFields()
this.disPlayDateFlag = false
this.disabledEmpty = false
this.currentPartInfo = {}
this.totalWeight = 0
this.isOverWeight = false
ElMessage({
message: '下发任务成功',
type: 'success'
})
this.$refs.vehicleNo.focus()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('创建入库任务错误!' + err.message)
})
},
resetForm(formEl) {//
if (!formEl) return
formEl.resetFields()
this.tempTasks = []
this.tempVehicleNo = ''
this.currentPartInfo = {}
this.disPlayDateFlag = false
},
callEmptyVehicles(taskInRequestEntity) {
callEmptyVehicle(taskInRequestEntity).then(res => {
if (res.data.code == 0) {
ElMessage({
message: res.data.message,
type: 'success'
})
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
ElMessage.error('呼叫空箱错误' + err.message)
})
},
deleteRowTask(row) {//
this.tempTasks.splice(this.tempTasks.indexOf(row), 1)
if (this.tempTasks.length == 0) {
this.tempVehicleNo = ''
}
},
detectEndInputVehicleNo(taskInRequestEntity) {
if (taskInRequestEntity.isEmpty == '0') {//
this.$refs.btnArea.scrollIntoView();
// this.$refs.vehicleNo.blur()
} else {
this.$refs.goodsId.focus()
}
},
detectEndInputNum(taskInRequestEntity) {
this.calWeight(taskInRequestEntity)
}
}
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.el-row {
margin: 20px 0;
}
:deep(.el-form-item__label) {
font-size: x-large;
/* margin: 10px; */
padding: 10px 0;
}
:deep(.el-select-v2--large .el-select-v2__placeholder) {
font-size: 25px;
}
.el-row .el-form-item {
justify-content: center;
}
.el-row .el-form-item .el-select {
width: 100% !important;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
width: 80px;
height: 50px;
margin: auto;
font-size: small;
}
.input-area {
margin: 10px;
width: 1080px;
/* height: 730px; */
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
}
</style>

216
src/layout/goodsOut.vue Normal file
View File

@ -0,0 +1,216 @@
<template>
<el-config-provider :locale="localLanguage">
<div style="width: calc(100vw - 300px)">
<div style="border-radius: 5px; border: #2c3e5033 solid 1px; padding: 10px; calc(100vw - 300px)"><!-- 搜索-->
<el-row style="width: 100%">
<el-form :model="searchParams" label-width="120" label-position="left" >
<el-form-item style="width: 600px" label="查询关键字:">
<el-input placeholder="输入 料箱号/库位/任务号 查询..." v-model="searchParams.searchStr" clearable></el-input>
</el-form-item>
<el-form-item style="width: 600px" label="任务状态:">
<el-select style="width: 600px" v-model="searchParams.orderStatus" multiple placeholder="请选择需要查询的任务状态">
<el-option v-for="item in orderOutEnum" :key="item.value" :label="item.label" :value="item.value"/>
</el-select>
</el-form-item>
</el-form>
</el-row>
<el-row>
<el-button type="primary" @click="queryGoodsOrderOut">查询出库单</el-button>
<el-button type="success" @click="showhandOut = true">下发出库任务</el-button>
<el-button type="success" @click="emptyhandOut = true">空托盘出库</el-button>
</el-row>
</div>
<div> <!-- 表格-->
<el-row style="width: calc(100vw - 300px)">
<h5>出库单</h5>
<el-table :data="goodsOrderOutList" border stripe max-height="calc(100vh - 550px)">
<el-table-column fixed prop="rowId" label="行号" width="130px" align="center" show-overflow-tooltip/>
<el-table-column fixed prop="recordId" label="识别号" width="130px" align="center" show-overflow-tooltip/>
<el-table-column fixed prop="orderId" label="订单号" width="200px" align="center" show-overflow-tooltip/>
<el-table-column prop="warehouseOrigin" label="源库别" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="warehouseDestination" label="托盘号" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="orderType" label="订单类型" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="goodsId" label="物料号" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="deliveryTime" label="需求时间" width="120px" align="center" show-overflow-tooltip/>
<el-table-column prop="rowNo" label="行号" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="goodsId" label="物料编号" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="goodsNum" label="物料数量" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="unit" label="单位" width="100px" align="center" show-overflow-tooltip/>
<el-table-column prop="status" label="出库单状态" width="95px" align="center">
<template #default="scope">
<el-tag class="ml-2" :type=formatterOrderOutEnum(scope.row.status).type>
{{formatterOrderOutEnum(scope.row.status).label }}</el-tag>
</template>
</el-table-column>
<el-table-column prop="createTime" label="创建时间" :formatter="formatCellValueTime" width="180px"
align="center" show-overflow-tooltip/>
<el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="120px" fixed="right"/>
<el-table-column fixed="right" label="操作" align="center" width="140">
<template #default="scope">
<el-button-group class="ml-4">
<el-tooltip content="执行出库" placement="top" effect="light">
<el-button type="success" size="small" @click="executeOut(scope.row)">
<el-icon><Check /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top" effect="light">
<el-button type="danger" size="small" @click="deleteOrder(scope.row)">
<el-icon><Delete/></el-icon>
</el-button>
</el-tooltip>
</el-button-group>
</template>
</el-table-column>
</el-table>
</el-row>
</div>
</div>
<HandOut v-model="showhandOut"/>
<emptyHandOut v-model="emptyhandOut"/>
</el-config-provider>
</template>
<script>
import {taskStatusFormatter, dueFormatter, formatCellValueTime} from '@/utils/formatter.js'
import HandOut from '@/components/handOut.vue'
import emptyHandOut from '@/components/emptyHandOut.vue'
import { reactive, ref } from 'vue'
import {ElMessage, ElMessageBox} from 'element-plus'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs';
import en from 'element-plus/dist/locale/en.mjs';
import {Check, Delete} from "@element-plus/icons-vue";
import {formatterOrderOutEnum, orderOutEnum} from "@/enum/order.out.enum";
const language = ref('zh-cn');
import apiOrderOut from '@/api/order.out'
export default {
name: 'goodsOut',
components: {Check, Delete, HandOut,emptyHandOut},
data() {
return {
//
searchParams: {
searchStr: '',
orderStatus: [0,1]
},
//
showhandOut: false,
//
emptyhandOut: false,
//
goodsOrderOutList: []
}
},
mounted() {
},
beforeUnmount() {
},
methods: {
formatCellValueTime,
formatterOrderOutEnum,
//
queryGoodsOrderOut() {
this.goodsOrderOutList = [];
apiOrderOut.getOrderOutList(this.searchParams).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.goodsOrderOutList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
},
//
deleteOrder(row) {
ElMessageBox.confirm('是否删除该出库单?','提示')
.then(() => {
apiOrderOut.deleteOrder(row.rowId).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '删除成功',
type: 'success',
});
this.queryGoodsOrderOut();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '删除失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务删除失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
//
executeOut(row) {
ElMessageBox.confirm(`是否执行 ${row.rowId} 的出库?`, '提示')
.then(() => {
apiOrderOut.executeOut(row.rowId).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.queryGoodsOrderOut();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
}
},
computed: {
orderOutEnum() {
return orderOutEnum
},
localLanguage: () => (language.value === 'zh-cn' ? zhCn : en)
}
}
</script>
<style scoped>
</style>

178
src/layout/inTaskRecord.vue Normal file
View File

@ -0,0 +1,178 @@
<template>
<div style="margin-bottom: 15px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="goodsIdQuery" style="width: 256px; margin-right: 10px;" placeholder="零件号" />
<el-input v-model="vehicleNoQuery" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="search()">刷新</el-button>
<el-button type="success" @click="exportExcel()">导出记录</el-button>
</el-row>
<br />
<el-table :data="tasks" stripe border v-loading="loading" style="width: 100%" max-height="684px"
class="table-class" :header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }">
<el-table-column prop="goodsId" label="零件号" fixed="left" min-width="120px" />
<el-table-column prop="vehicleNo" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="goodsName" label="零件名称" min-width="120px" />
<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormat" min-width="120px" />
<el-table-column prop="taskGroup" label="任务组" min-width="120px" />
<el-table-column prop="origin" label="起点" min-width="120px" />
<el-table-column prop="destination" label="终点" min-width="120px" />
<el-table-column prop="pickStand" label="拣选站台" min-width="120px" />
<el-table-column prop="weight" label="重量" min-width="120px" />
<el-table-column prop="productionDate" label="生产日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="expirationDate" label="有效日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="operateNum" label="操作数量" min-width="120px" />
<el-table-column prop="totalNum" label="库存数量" min-width="120px" />
<el-table-column prop="taskPriority" label="任务优先级" min-width="120px" />
<el-table-column prop="kateTaskId" label="配件任务号" min-width="140px" />
<el-table-column prop="userName" label="操作人员姓名" min-width="120px" />
<el-table-column prop="createTime" label="创建时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="finishTime" label="任务完成时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="taskStatus" label="任务状态" fixed="right" :formatter="taskStatusFormat"
min-width="120px" />
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
</el-config-provider>
</div>
</template>
<script setup>
import { getTaskRecords } from '@/api/record.js'
import { dateFormatter, taskStatusFormatter, timeFormatter } from '@/utils/formatter.js'
import { downloadRukuExcel } from '@/api/excel.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import store from '@/store'
</script>
<script>
export default {
name: 'inTaskRecord',
data() {
return {
pageInfo: {},
tasks: [],
currentPage: 1,
pageSize: 10,
total: 0,
goodsIdQuery: '',
vehicleNoQuery: '',
loading: true
}
},
mounted() {
this.search()
},
methods: {
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
timeFormat: (row, column, cellValue, index) => {
return timeFormatter(cellValue)
},
taskStatusFormat: (row, column, cellValue, index) => {
return taskStatusFormatter(cellValue)
},
taskTypeFormat: (row, column, cellValue, index) => {
switch (cellValue) {
case 1:
if (row.taskId.substr(0, 2) == 'HK') {
return '回库'
} else {
return '入库'
}
case 2: return '出库'
case 3: return '盘点'
default: return '未知'
}
},
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
taskType: 1,
goodsId: this.goodsIdQuery.trim(),
vehicleNo: this.vehicleNoQuery.trim(),
userName: store.getters.getUserName
}
}
getTaskRecords(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.tasks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询任务记录错误')
})
this.loading = false
},
reset() {
this.goodsIdQuery = ''
this.vehicleNoQuery = ''
this.search()
},
exportExcel() {
downloadRukuExcel().then(res => {
const link = document.createElement('a');//a
try {
// let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //blobblobtypexls
let blob = res.data //blob
// let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //
let _fileName = "导出入库记录" + dateFormatter(new Date) + ".xlsx"
link.style.display = 'none'//
// URL
const url = window.URL || window.webkitURL || window.moxURL
link.href = url.createObjectURL(blob)
link.setAttribute('download', _fileName.substring(_fileName.lastIndexOf('_') + 1))
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
url.revokeObjectURL(link.href)//url
} catch (e) {
ElMessage({
message: '下载文件失败:: ' + e,
type: 'error',
showClose: true
})
}
}).catch(err => {
ElMessage({
message: '导出失败:: ' + err,
type: 'error',
showClose: true
})
})
},
},
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
</style>

259
src/layout/inventory.vue Normal file
View File

@ -0,0 +1,259 @@
<template>
<el-config-provider :locale="localLanguage">
<div style="width: calc(100vw - 300px)">
<div style="border-radius: 5px; border: #2c3e5033 solid 1px; padding: 10px; calc(100vw - 300px)">
<el-row>
<el-button type="primary" @click="queryGoodsOrderCheck">查询盘点单</el-button>
<el-button type="success" @click="downInventoryTask">下发盘点任务</el-button>
</el-row>
</div>
<div>
<el-row style="width: calc(100vw - 300px)">
<h5>盘点单</h5>
<el-table :data="goodsInventoryList" border stripe max-height="calc(100vh - 550px)">
<el-table-column fixed prop="recordId" label="记录号" width="210px" align="center" show-overflow-tooltip/>
<el-table-column fixed prop="checkId" label="盘点单号" width="210px" align="center" show-overflow-tooltip/>
<el-table-column fixed prop="warehouse" label="盘点库别" width="210px" align="center" show-overflow-tooltip/>
<el-table-column prop="status" label="盘点单状态" width="210px" align="center" show-overflow-tooltip/>
<el-table-column prop="createTime" label="创建时间" width="210px" align="center" show-overflow-tooltip/>
<el-table-column prop="completeTime" label="完成时间" width="210px" align="center" show-overflow-tooltip/>
<el-table-column prop="remark" label="备注" show-overflow-tooltip min-width="120px" fixed="right"/>
<el-table-column fixed="right" label="操作" align="center" width="180">
<template #default="scope">
<el-button-group class="ml-4">
<el-tooltip content="执行盘点" placement="top" effect="light">
<el-button type="success" size="small" @click="executeCheck(scope.row)">
<el-icon><Check /></el-icon>
</el-button>
</el-tooltip>
<el-tooltip content="删除" placement="top" effect="light">
<el-button type="danger" size="small" @click="deleteCheck(scope.row)">
<el-icon><Delete/></el-icon>
</el-button>
</el-tooltip>
</el-button-group>
</template>
</el-table-column>
</el-table>
</el-row>
</div>
</div>
</el-config-provider>
</template>
<script setup>
import store from '@/store'
import { sendInventoryTask, finishPicking, getTasks, getTaskByTask, sendBoxArrive } from '@/api/task'
import { queryPartNo } from '@/api/goods'
import { taskStatusFormatter, dueFormatter } from '@/utils/formatter.js'
import { reactive, ref } from 'vue'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import OrderCheck from '@/api/order.in'
import {ElMessage, ElMessageBox} from 'element-plus'
</script>
<script>
export default {
name: 'inventory',
data() {
return {
searchParams: {
searchStr: '',
orderStatus: [0]
},
//
remarkR:{
remarkReturn: "盘点回库"
},
goodsInventoryList: []
}
},
methods: {
queryGoodsOrderCheck(){
OrderCheck.getOrderCheckList(this.searchParams).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '查询成功',
type: 'success',
});
this.goodsInventoryList = responseData['returnData'];
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '查询失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
}).catch(err => {
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
}
})
},
downInventoryTask(){
ElMessageBox.confirm(`是否下发一个盘点任务?`, '提示')
.then(() => {
OrderCheck.downInventoryTask().then(res => {
const responseData = res.data;
if (responseData.code === 1) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.queryGoodsOrderCheck();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
executeCheck(row){
ElMessageBox.confirm(`是否执行 ${row.recordId} 的盘点?`, '提示')
.then(() => {
OrderCheck.executeCheck(row.recordId).then(res => {
const responseData = res.data;
if (responseData.code === 1) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.queryGoodsOrderCheck();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
deleteCheck(row) {
ElMessageBox.confirm('是否删除该出库单?','提示')
.then(() => {
OrderCheck.deleteCheckList(row.recordId).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '删除成功',
type: 'success',
});
this.queryGoodsOrderCheck();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '删除失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务删除失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
}
}
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.el-row .el-form-item {
width: 30% inherit;
justify-content: center;
}
.btn-area .el-form-item {
width: 30% inherit;
padding-left: 15px;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-select {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
.right {
width: 40%;
padding: 5px;
}
.left {
width: 60%;
padding: 5px;
}
.input-area {
margin: auto;
max-width: inherit;
height: 300px;
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
}
.display-area {
margin: auto;
min-width: inherit;
height: 632px;
border: solid 1px;
border-radius: 10px;
box-shadow: 0px 15px 10px -15px #000;
}
.table-class {
width: 100%;
}
</style>

View File

@ -0,0 +1,150 @@
<template>
<div style="margin-bottom: 15px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="goodsIdQuery" style="width: 256px; margin-right: 10px;" placeholder="零件号" />
<el-input v-model="vehicleNoQuery" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="refresh()">刷新</el-button>
</el-row>
<br />
<el-table :data="tasks" stripe border v-loading="loading" style="width: 100%" max-height="684px"
class="table-class" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
<el-table-column prop="goodsId" label="零件号" fixed="left" min-width="120px" />
<el-table-column prop="vehicleNo" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="goodsName" label="零件名称" min-width="120px" />
<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormat" sortable min-width="120px" />
<el-table-column prop="taskGroup" label="任务组" min-width="120px" />
<el-table-column prop="origin" label="起点" min-width="120px" />
<el-table-column prop="destination" label="终点" min-width="120px" />
<el-table-column prop="pickStand" label="拣选站台" min-width="120px" />
<el-table-column prop="weight" label="重量" min-width="120px" />
<el-table-column prop="productionDate" label="生产日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="expirationDate" label="有效日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="operateNum" label="操作数量" min-width="120px" />
<el-table-column prop="totalNum" label="库存数量" min-width="120px" />
<el-table-column prop="taskPriority" label="任务优先级" sortable min-width="120px" />
<el-table-column prop="kateTaskId" label="配件任务号" sortable min-width="140px" />
<el-table-column prop="userName" label="操作人员姓名" min-width="120px" />
<el-table-column prop="createTime" label="创建时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="finishTime" label="任务完成时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="taskStatus" label="任务状态" fixed="right" :formatter="taskStatusFormat" min-width="120px" />
<!-- <el-table-column fixed="right" label="操作" width="180px">
<template v-slot="scope">
<el-popconfirm confirm-button-text="" cancel-button-text="" title="请确认是否取消任务?" :hide-after="10" @confirm="">
<template #reference>
<el-button plain type="warning">取消</el-button>
</template>
</el-popconfirm>
<el-popconfirm confirm-button-text="" cancel-button-text="" title="请确认是否完成任务?" :hide-after="10" @confirm="">
<template #reference>
<el-button plain type="primary">完成</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column> -->
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
</el-config-provider>
</div>
</template>
<script setup>
import { getTaskRecords } from '@/api/record.js'
import { dateFormatter, taskStatusFormatter, timeFormatter } from '@/utils/formatter.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import store from '@/store'
</script>
<script>
export default {
name: 'inventoryRecord',
data() {
return {
pageInfo: {},
tasks: [],
currentPage: 1,
pageSize: 10,
total: 0,
goodsIdQuery: '',
vehicleNoQuery: '',
loading: true
}
},
mounted() {
this.search()
},
methods: {
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
timeFormat: (row, column, cellValue, index) => {
return timeFormatter(cellValue)
},
taskStatusFormat: (row, column, cellValue, index) => {
return taskStatusFormatter(cellValue)
},
taskTypeFormat: (row, column, cellValue, index) => {
switch (cellValue) {
case 1: return '入库'
case 2: return '出库'
case 3: return '盘点'
default: return '未知'
}
},
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
taskType: 3,
goodsId: this.goodsIdQuery.trim(),
vehicleNo: this.vehicleNoQuery.trim(),
userName: store.getters.getUserName
}
}
getTaskRecords(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.tasks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询盘点记录错误')
})
this.loading = false
},
reset() {
this.goodsIdQuery = ''
this.vehicleNoQuery = ''
this.search()
},
},
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
</style>

205
src/layout/location.vue Normal file
View File

@ -0,0 +1,205 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row style="align-items: center;">
<!-- <span>选择库区</span>
<el-select v-model="areaId" placeholder="请选择库区" style="width: 120px;" @change="getAllLocations">
<el-option label="3楼库区" :value='1' />
<el-option label="2楼库区" :value='2' />
</el-select> -->
<span style="margin-left: 5px;">状态说明</span>
<el-button color="green">空闲</el-button>
<el-button color="red">占用</el-button>
<el-button color="yellow">锁定</el-button>
<el-button color="#00BFFF" style="margin: 0 0 0 auto;" @click="getAllLocations">刷新</el-button>
</el-row>
<hr style="border: 1px solid #ff0000" />
<div>
<el-scrollbar max-height="760px">
<div v-for="currentRowLocation in allLocations">
<span>{{ currentRowLocation.row }}</span>
<div class="row" v-for="currentLayerLocation in currentRowLocation.currentLayerLocations">
<div class="col" v-for="currentColLocation in currentLayerLocation.currentColLocations">
<el-button :color="getLocationStatus(currentColLocation)"
@click="showDialog(currentColLocation)">
<span style="font-size: 13px;">{{ currentColLocation.queue}}{{ currentColLocation.line}}{{ currentColLocation.layer}} -{{ currentColLocation.wareArea}}</span>
</el-button>
</div>
</div>
<hr style="border: 1px solid #000000" />
</div>
</el-scrollbar>
<el-dialog v-model="dialogVisible" :title="currentLocationTitle" width="30%" draggable :show-close="false">
<el-form :model="location">
<el-form-item label="库位号" :label-width="140">
<el-input v-model="this.currentSelectedLocation.locationId" style="width: 70%;" readonly />
</el-form-item>
<el-form-item label="占用/解除占用库位" :label-width="140">
<el-select v-model="location.locationStatus" placeholder="库位是否占用" style="width: 70%;">
<el-option label="空闲" :value='0' />
<el-option label="占用" :value='1' />
</el-select>
</el-form-item>
<el-form-item label="锁定/解锁库位" :label-width="140">
<el-select v-model="location.isLock" placeholder="库位是否锁定" style="width: 70%;">
<el-option label="解锁" :value='0' />
<el-option label="锁定" :value='1' />
</el-select>
</el-form-item>
<el-form-item label="载具" :label-width="140">
<el-input v-model="location.vehicleId" style="width: 70%;" />
</el-form-item>
<el-form-item label="库区选择" :label-width="140">
<el-select v-model="location.wareArea" placeholder="选择库区" style="width: 70%;">
<el-option label="A" value="A" />
<el-option label="B" value="B" />
<el-option label="C" value="C" />
</el-select>
</el-form-item>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitLocationStatus()">
确定
</el-button>
</span>
</template>
</el-dialog>
</div>
</el-config-provider>
</div>
</template>
<script setup>
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { getLocations, updateLocation } from '@/api/location.js'
import { ElMessage, ElLoading } from 'element-plus'
import { reactive } from 'vue'
</script>
<script>
export default {
name: 'location',
data() {
return {
dialogVisible: false,
currentSelectedLocation: {},
allLocations: [],
location: reactive({
locationId:'this.currentSelectedLocation.locationId',
locationStatus: '',
isLock: '',
vehicleId: '',
wareArea: ''
}),
currentLocationTitle: '',
areaId: 1
}
},
mounted() {
this.getAllLocations()
},
methods: {
getLocationStatus: (currentColLocation) => {
if (currentColLocation.isLock === 1) {
return 'yellow'
}
if (currentColLocation.locationStatus === 1) {
return 'red'
}
return 'green'
},
getAllLocations() {
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
const data = { areaId: this.areaId }
getLocations(data).then(res => {
loading.close()
if (res.data.code == 0) {
console.log(res.data.returnData)
this.allLocations = res.data.returnData
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
loading.close()
ElMessage.error('查询库位失败!')
})
},
test() {
console.log(this.location);
},
showDialog(currentColLocation) {
this.dialogVisible = true
this.currentSelectedLocation = currentColLocation
this.setCurrentLocationTitle()
this.location.locationId = this.currentSelectedLocation.locationId
this.location.locationStatus = this.currentSelectedLocation.locationStatus
this.location.isLock = this.currentSelectedLocation.isLock
this.location.vehicleId = this.currentSelectedLocation.vehicleId
this.location.wareArea = this.currentSelectedLocation.wareArea
},
submitLocationStatus() {
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
this.currentSelectedLocation.locationId = this.location.locationId
this.currentSelectedLocation.locationStatus = this.location.locationStatus
this.currentSelectedLocation.isLock = this.location.isLock
this.currentSelectedLocation.vehicleId = this.location.vehicleId
this.currentSelectedLocation.wareArea = this.location.wareArea
updateLocation(this.currentSelectedLocation).then(res => {
if (res.data.code == 0) {
loading.close()
this.dialogVisible = false
ElMessage({
message: '更新库位信息成功!',
type: 'success',
})
this.getAllLocations()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
loading.close()
ElMessage.error('更新库位信息失败')
})
},
setCurrentLocationTitle() {
const parts = this.currentSelectedLocation.locationId.split('-');
this.currentLocationTitle = '当前选择库位:' + parts[0] + '排' + parts[1] + '列' + parts[2] + '层';
//this.currentLocationTitle = '' + this.currentSelectedLocation.queue + '' + this.currentSelectedLocation.line + '' + this.currentSelectedLocation.layer + '' + '(' + this.currentSelectedLocation.warearea + ')'
}
}
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.row {
display: flex;
justify-content: space-between;
margin: 5px;
}
.col {
/* width: 100px; */
/* height: 40px; */
padding: 1px;
margin: 1px;
}
.col .el-button {
width: 100px;
height: 50px;
}
</style>

View File

@ -0,0 +1,150 @@
<template>
<div style="margin-bottom: 15px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="goodsIdQuery" style="width: 256px; margin-right: 10px;" placeholder="零件号" />
<el-input v-model="vehicleNoQuery" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="search()">刷新</el-button>
</el-row>
<br />
<el-table :data="tasks" stripe border v-loading="loading" style="width: 100%" max-height="684px"
class="table-class" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
<el-table-column prop="goodsId" label="零件号" fixed="left" min-width="120px" />
<el-table-column prop="vehicleNo" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="goodsName" label="零件名称" min-width="120px" />
<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormat" sortable min-width="120px" />
<el-table-column prop="taskGroup" label="任务组" min-width="120px" />
<el-table-column prop="origin" label="起点" min-width="120px" />
<el-table-column prop="destination" label="终点" min-width="120px" />
<el-table-column prop="pickStand" label="拣选站台" min-width="120px" />
<el-table-column prop="weight" label="重量" min-width="120px" />
<el-table-column prop="productionDate" label="生产日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="expirationDate" label="有效日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="operateNum" label="操作数量" min-width="120px" />
<el-table-column prop="totalNum" label="库存数量" min-width="120px" />
<el-table-column prop="taskPriority" label="任务优先级" sortable min-width="120px" />
<el-table-column prop="kateTaskId" label="配件任务号" sortable min-width="140px" />
<el-table-column prop="userName" label="操作人员姓名" min-width="120px" />
<el-table-column prop="createTime" label="创建时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="finishTime" label="任务完成时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="taskStatus" label="任务状态" fixed="right" :formatter="taskStatusFormat" min-width="120px" />
<!-- <el-table-column fixed="right" label="操作" width="180px">
<template v-slot="scope">
<el-popconfirm confirm-button-text="" cancel-button-text="" title="请确认是否取消任务?" :hide-after="10" @confirm="">
<template #reference>
<el-button plain type="warning">取消</el-button>
</template>
</el-popconfirm>
<el-popconfirm confirm-button-text="" cancel-button-text="" title="请确认是否完成任务?" :hide-after="10" @confirm="">
<template #reference>
<el-button plain type="primary">完成</el-button>
</template>
</el-popconfirm>
</template>
</el-table-column> -->
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
</el-config-provider>
</div>
</template>
<script setup>
import { getTaskRecords } from '@/api/record.js'
import { dateFormatter, taskStatusFormatter, timeFormatter } from '@/utils/formatter.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import store from '@/store'
</script>
<script>
export default {
name: 'outTaskRecord',
data() {
return {
pageInfo: {},
tasks: [],
currentPage: 1,
pageSize: 10,
total: 0,
goodsIdQuery: '',
vehicleNoQuery: '',
loading: true
}
},
mounted() {
this.search()
},
methods: {
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
timeFormat: (row, column, cellValue, index) => {
return timeFormatter(cellValue)
},
taskStatusFormat: (row, column, cellValue, index) => {
return taskStatusFormatter(cellValue)
},
taskTypeFormat: (row, column, cellValue, index) => {
switch (cellValue) {
case 1: return '入库'
case 2: return '出库'
case 3: return '盘点'
default: return '未知'
}
},
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
taskType: 2,
goodsId: this.goodsIdQuery.trim(),
vehicleNo: this.vehicleNoQuery.trim(),
userName: store.getters.getUserName
}
}
getTaskRecords(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.tasks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询任务记录错误')
})
this.loading = false
},
reset() {
this.goodsIdQuery = ''
this.vehicleNoQuery = ''
this.search()
},
},
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
</style>

View File

@ -0,0 +1,260 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="queryKey" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<!-- <el-button type="success" @click="refresh()">刷新</el-button> -->
</el-row>
<br />
<el-table :data="vehicles" stripe border v-loading="loading" class="table-class" max-height="650px"
highlight-current-row @row-click="getCurrentRow" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.vehicleId" v-model="vehicleId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="vehicleId" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="currentLocation" label="当前位置" fixed="left" min-width="120px" />
<el-table-column prop="vehicleStatus" label="料箱状态" :formatter="vehicleStatusFormat" min-width="120px" />
<el-table-column prop="isEmpty" label="是否空箱" :formatter="isEmptyFormat" min-width="120px" />
<el-table-column fixed="right" label="操作" width="200px" v-if="selVehicle == null">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentRowVehicle(scope.row)">编辑</el-button>
<el-button plain type="danger" @click="deleteCurrentRowVehicle(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
<el-dialog v-model="dialogVisible" title="托盘信息" width="40%" draggable :show-close="false">
<el-form ref="vehicleFormRef" :model="vehicleFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料箱号" prop="vehicleId">
<el-input v-model="vehicleFormEntity.vehicleId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="当前位置" prop="currentLocation">
<el-input v-model="vehicleFormEntity.currentLocation" placeholder="请输入当前位置" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="是否空箱" prop="isEmpty">
<el-select-v2 v-model="vehicleFormEntity.isEmpty" placeholder="请选择托盘状态"
:options="isEmptyOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="托盘状态" prop="vehicleStatus">
<el-select-v2 v-model="vehicleFormEntity.vehicleStatus" placeholder="请选择托盘状态"
:options="vehicleStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitVehicleInfo(vehicleFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import { getAllVehicles, updateVehicleInfo, deleteCurrentVehicle } from '@/api/vehicle'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import { ref, reactive } from 'vue'
import { vehicleStatusFormatter, locationFormatter } from '@/utils/formatter.js'
</script>
<script>
export default {
name: 'stand',
props: ['selVehicle'],
emits: ['update:selVehicle'],
data() {
return {
pageInfo: {},
vehicles: [],
currentPage: 1,
pageSize: 10,
total: 0,
queryKey: '',
loading: true,
dialogVisible: false,
vehicleId: '',
vehicleFormEntity: reactive({}),
labelPosition: 'top',
vehicleFormRef: ref(),
rules: reactive({
locationId: [
{ required: true, message: '请输入库位' }
]
}),
//
isEmptyOptions: [
{
value: 0,
label: '带料'
},
{
value: 1,
label: '空箱'
}
],
//
vehicleStatusOptions: [
{
value: 0,
label: '入库中'
},
{
value: 1,
label: '在库中'
},
{
value: 2,
label: '出库中'
}
]
}
},
mounted() {
this.search()
},
methods: {
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
vehicleId: this.queryKey.trim()
},
}
getAllVehicles(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
console.log(tableResponse.code + ':' + tableResponse.message)
ElMessage.error(tableResponse.message)
}
this.vehicles = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
ElMessage.error('查询托盘信息错误' + err.message)
})
this.loading = false
},
vehicleStatusFormat: (row, column, cellValue, index) => {
return vehicleStatusFormatter(cellValue)
},
locationFormat: (row, column, cellValue, index) => {
return locationFormatter(cellValue)
},
isEmptyFormat: (row, column, cellValue, index) => {
if (cellValue == 0) {
return '带料'
}
if (cellValue == 1) {
return '空箱'
}
},
reset() {
this.queryKey = ''
this.search()
},
editCurrentRowVehicle(row) {
this.vehicleFormEntity = row
this.dialogVisible = true
},
deleteCurrentRowVehicle(row) {
this.vehicleId = row.vehicleId
const vehicle = {
vehicleId: row.vehicleId
}
deleteCurrentVehicle(vehicle).then(res => {
if (res.data.code == 0) {
ElMessage({
message: '删除料箱成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('删除料箱信息失败:' + err)
})
},
submitVehicleInfo(formData) {
updateVehicleInfo(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新料箱信息成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('更新料箱信息失败:' + err)
})
},
getCurrentRow(row) {
this.vehicleId = row.vehicleId
this.$emit('update:selVehicle', row)
}
}
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
/* font-size: 5px; */
}
.el-row .el-form-item {
width: 10% inherit;
justify-content: center;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

457
src/layout/stock.vue Normal file
View File

@ -0,0 +1,457 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="queryKey" v-if="dataType == 1" style="width: 256px; margin-right: 10px;"
placeholder="零件号/箱号/零件名称" :suffix-icon="Search" />
<el-input v-if="dataType == 2" v-model="goodsIdQuery" style="width: 256px; margin-right: 10px;"
placeholder="零件号" :suffix-icon="Search" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="exportExcel()">导出表格</el-button>
<el-select-v2 v-if="selStock == null" v-model="dataType" style="width: 156px; margin-right: 10px;"
placeholder="请选择库存显示类型" :options="dataTypeOptions" @change="search()"></el-select-v2>
</el-row>
<br />
<el-table id="stock-table" :data="displayStocks" stripe border v-loading="loading" class="table-class"
max-height="650px" highlight-current-row @row-click="getCurrentRow" :row-style="rowStyle"
:header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.stockId" v-model="stockId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="stockId" label="库存ID" min-width="120px" show-overflow-tooltip/>
<el-table-column prop="goodsId" label="物料号" min-width="120px" />
<el-table-column prop="batchNo" v-if="dataType == 1" label="批次号" min-width="120px" />
<el-table-column prop="goodsName" label="零件描述" min-width="120px" />
<el-table-column prop="availableNum" v-if="dataType == 1" label="可用数量" min-width="120px" />
<el-table-column prop="remainNum" v-if="dataType == 1" label="剩余数量" min-width="120px" />
<el-table-column prop="realNum" label="实际数量" min-width="120px" />
<el-table-column prop="vehicleId" v-if="dataType == 1" label="料箱号" fixed="left" min-width="120px" />
<el-table-column prop="providerId" v-if="dataType == 1" label="供应商编号" min-width="130px" />
<el-table-column prop="providerName" v-if="dataType == 1" label="供应商名称" min-width="130px" />
<el-table-column prop="shelfLife" v-if="dataType == 1" label="保质期" min-width="120px" />
<el-table-column prop="expirationDate" v-if="dataType == 1" label="有效日期" :formatter="dateFormat" min-width="140px" />
<el-table-column prop="locationId" v-if="dataType == 1" label="库位" :formatter="locationFormat" min-width="160px" />
<el-table-column prop="currentLocation" v-if="dataType == 1" label="当前位置" min-width="120px" />
<el-table-column prop="isInventory" v-if="dataType == 1" label="是否盘点" min-width="120px" />
<el-table-column prop="createTime" v-if="dataType == 1" label="上架时间" :formatter="timeFormat" min-width="140px" />
<el-table-column prop="goodsStatus" v-if="dataType == 1" label="物料状态" :formatter="goodsStatusFormat" min-width="120px" />
<el-table-column prop="stockStatus" v-if="dataType == 1" label="库存状态" :formatter="stockStatusFormat" fixed="right"
min-width="120px" />
<el-table-column fixed="right" label="操作" width="135px" v-if="selStock == null">
<template v-slot="scope">
<el-button size="small" plain type="primary" @click="editCurrentRowStock(scope.row)">编辑</el-button>
<!--<el-button size="small" plain type="warning" @click="outRowStock(scope.row)">出库</el-button>-->
</template>
</el-table-column>
<!-- <el-table-column prop="areaCode" label="库区代码" fixed="right" sortable min-width="120px" /> -->
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10" @size-change="search"
@current-change="search" layout="total, sizes, prev, pager, next, jumper" :total="total" />
<el-dialog v-model="dialogVisible" title="物料信息" width="40%" draggable :show-close="false">
<el-form ref="stockFormRef" :model="stockFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="零件号" prop="goodsId">
<el-input v-model="stockFormEntity.goodsId" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="零件描述" prop="goodsName">
<el-input v-model="stockFormEntity.goodsName" readonly />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="可用数量" prop="availableNum">
<el-input-number v-model.number="stockFormEntity.availableNum" clearable
controls-position="right" :min="0" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="剩余数量" prop="remainNum">
<el-input-number v-model.number="stockFormEntity.remainNum" clearable
controls-position="right" :min="0" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="实际数量为0时删除库存" prop="realNum">
<el-input-number v-model.number="stockFormEntity.realNum" controls-position="right"
:min="0" clearable />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="货箱号" prop="vehicleId">
<el-input v-model="stockFormEntity.vehicleId" clearable readonly />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="库存状态" prop="stockStatus">
<el-select-v2 v-model="stockFormEntity.stockStatus" placeholder="请选择库存状态"
:options="stockStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料状态" prop="goodsStatus">
<el-select-v2 v-model="stockFormEntity.goodsStatus" placeholder="请选择物料状态"
:options="goodsStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitStockInfo(stockFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import { getAllStocks, updateStockInfo, getAllStocksByGoodsId } from '@/api/stock.js'
import { downloadStockExcel } from '@/api/excel.js'
import { dateFormatter, locationFormatter, timeFormatter } from '@/utils/formatter.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { Search } from '@element-plus/icons-vue'
import { ref, reactive } from 'vue'
//import { ElMessage } from 'element-plus'
import {ElMessage, ElMessageBox} from 'element-plus'
import apiOrderOut from '@/api/order.out'
// import FileSaver from 'file-saver';
// import * as XLSX from 'xlsx';
</script>
<script>
export default {
name: 'stock',
props: ['selStock'],
emits: ['update:selStock'],
data() {
return {
pageInfo: {},
displayStocks: [],
currentPage: 1,
pageSize: 10,
total: 0,
queryKey: '',
loading: true,
stockId: '',
stockFormRef: ref(),
stockFormEntity: reactive({}),
rules: reactive({}),
labelPosition: 'top',
dialogVisible: false,
goodsStatusOptions: [
{
value: 0,
label: '合格'
},
{
value: 1,
label: '不合格'
},
{
value: 2,
label: '延期'
},
{
value: 3,
label: '过期'
},
{
value: 5,
label: '长时间未使用'
}
],
stockStatusOptions: [
{
value: 0,
label: '库存正常'
},
{
value: 1,
label: '准备出库'
},
{
value: 2,
label: '正在出库'
},
{
value: 3,
label: '出库完成,环线运输中'
},
{
value: 4,
label: '站台拣货中'
},
{
value: 5,
label: '站台盘点中'
},
{
value: 6,
label: '正在回库'
},
{
value: 9,
label: '库存锁定'
}
],
dataType: 1,
dataTypeOptions: [
{
value: 1,
label: '按料箱分类'
},
{
value: 2,
label: '按零件分类'
}
],
goodsIdQuery: ''
}
},
mounted() {
this.refresh()
},
methods: {
locationFormat: (row, column, cellValue, index) => {
return locationFormatter(cellValue)
},
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
timeFormat: (row, column, cellValue, index) => {
return timeFormatter(cellValue)
},
goodsStatusFormat: (row, column, cellValue, index) => {
if (cellValue === 0) {
return '合格'
} else if (cellValue === 1) {
return '不合格'
} else if (cellValue === 2) {
return '延期'
} else if (cellValue === 3) {
return '过期'
} else if (cellValue === 5) {
return '长时间未使用'
}
},
stockStatusFormat: (row, column, cellValue, index) => {
switch (cellValue) {
case 0:
return '库存正常'
case 1:
return '准备出库'
case 2:
return '正在出库'
case 3:
return '出库完成,环线运输中'
case 4:
return '站台拣货中'
case 5:
return '站台盘点中'
case 6:
return '正在回库'
case 7:
return '到达拣选站台'
case 9:
return '库存锁定'
default:
return '异常'
}
},
rowStyle: ({ row, rowIndex }) => {
if (row.goodsStatus == 3) {
return { "color": "red" }
}
if (row.goodsStatus == 5) {
return { "color": "yellow" }
}
},
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
if (this.dataType == 1) {
const tableRequest = {
page: this.pageInfo,
param: this.queryKey.trim(),
}
getAllStocks(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.displayStocks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询库存错误')
})
} else if (this.dataType == 2) {
const tableRequest = {
page: this.pageInfo,
param: this.goodsIdQuery.trim(),
}
getAllStocksByGoodsId(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
ElMessage.error(tableResponse.message)
}
this.displayStocks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询库存错误')
})
}
this.loading = false
},
reset() {
this.queryKey = ''
this.goodsIdQuery = ''
this.search()
},
refresh() {
this.search()
},
getCurrentRow(row) {
this.stockId = row.stockId
this.$emit('update:selStock', row)
},
exportExcel() {
downloadStockExcel().then(res => {
const link = document.createElement('a');//a
try {
// let blob = new Blob([res.data],{type: 'application/vnd.ms-excel'}); //blobblobtypexls
let blob = res.data //blob
// let _fileName = res.headers['content-disposition'].split(';')[1].split('=')[1]; //
let _fileName = "库存报表" + dateFormatter(new Date) + ".xlsx"
link.style.display = 'none'//
// URL
const url = window.URL || window.webkitURL || window.moxURL
link.href = url.createObjectURL(blob)
link.setAttribute('download', _fileName.substring(_fileName.lastIndexOf('_') + 1))
document.body.appendChild(link)
link.click()
document.body.removeChild(link)
url.revokeObjectURL(link.href)//url
} catch (e) {
ElMessage({
message: '下载文件失败:: ' + e,
type: 'error',
showClose: true
})
}
}).catch(err => {
ElMessage({
message: '导出失败:: ' + err,
type: 'error',
showClose: true
})
})
},
editCurrentRowStock(row) {
this.stockFormEntity = row
this.dialogVisible = true
},
outRowStock(row) {
const stockId = row.stockId;
ElMessageBox.confirm(`是否执行 ${stockId} 的出库?`, '提示')
.then(() => {
apiOrderOut.outRowStock(stockId).then(res => {
const responseData = res.data;
if (responseData.code === 0) {
//
ElMessage({
message: '执行成功',
type: 'success',
});
this.queryGoodsOrderOut();
} else {
//
ElMessageBox.alert(`服务器返回失败:${responseData.message}`, '执行失败', {
type: 'warning',
confirmButtonText: '确定',
showClose: false
})
}
}).catch(err => {
//
ElMessageBox.alert(`请求服务器失败::${err}`, '任务添加失败', {
type: 'warning',
confirmButtonText: '确定'
})
})
})
.catch(() => {
})
},
submitStockInfo(stockFormEntity) {
console.log(stockFormEntity)
updateStockInfo(stockFormEntity).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新库存成功',
type: 'success'
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage({
message: '更新料箱信息失败: ' + err,
type: 'error',
showClose: true
})
})
}
},
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
</style>

326
src/layout/taskMonitor.vue Normal file
View File

@ -0,0 +1,326 @@
<template>
<div style="margin-bottom: 15px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="goodsIdQuery" style="width: 256px; margin-right: 10px;" placeholder="零件号" />
<el-input v-model="vehicleNoQuery" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">重置</el-button>
<el-button type="success" @click="search()">刷新</el-button>
</el-row>
<br />
<el-table :data="tasks" stripe border v-loading="loading" style="width: 100%" max-height="684px"
class="table-class" :header-cell-style="{ 'text-align': 'center' }" :cell-style="{ 'text-align': 'center' }"
@row-click="getCurrentRow">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.taskId" v-model="taskId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="goodsId" label="零件号" fixed="left" min-width="120px" />
<el-table-column prop="vehicleNo" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="goodsName" label="零件名称" min-width="120px" />
<el-table-column prop="taskType" label="任务类型" :formatter="taskTypeFormat" min-width="120px" />
<el-table-column prop="taskGroup" label="任务组" min-width="120px" />
<el-table-column prop="origin" label="起点" min-width="120px" />
<el-table-column prop="destination" label="终点" min-width="120px" />
<el-table-column prop="pickStand" label="拣选站台" min-width="120px" />
<el-table-column prop="weight" label="重量" min-width="120px" />
<el-table-column prop="productionDate" label="生产日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="expirationDate" label="有效日期" :formatter="dateFormat" min-width="120px" />
<el-table-column prop="operateNum" label="操作数量" min-width="120px" />
<el-table-column prop="totalNum" label="库存数量" min-width="120px" />
<el-table-column prop="taskPriority" label="任务优先级" min-width="120px" />
<el-table-column prop="kateTaskId" label="配件任务号" min-width="140px" />
<el-table-column prop="createTime" label="创建时间" :formatter="timeFormat" min-width="120px" />
<el-table-column prop="createTime" label="运行时长" :formatter="dueFormat" min-width="120px" />
<el-table-column prop="userName" label="操作人员姓名" min-width="120px" />
<el-table-column prop="taskStatus" label="任务状态" fixed="right" :formatter="taskStatusFormat"
min-width="120px" />
<el-table-column fixed="right" label="操作" width="120px">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentRowTask(scope.row)">编辑</el-button>
</template>
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
<el-dialog v-model="dialogVisible" title="任务信息" width="40%" draggable :show-close="false">
<el-form ref="taskFormRef" :model="taskFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料箱号" prop="vehicleNo">
<el-input v-model="taskFormEntity.vehicleNo" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="零件号" prop="goodsId">
<el-input v-model="taskFormEntity.goodsId" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="起点" prop="origin">
<el-input v-model="taskFormEntity.origin" disabled />
</el-form-item>
</el-col>
<el-col :span="12" v-if="taskFormEntity.taskType == 1">
<el-form-item label="终点" prop="destination">
<el-select-v2 v-model="taskFormEntity.destination"
:options="availableLocationOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12" v-if="taskFormEntity.taskType == 2">
<el-form-item label="终点" prop="destination">
<el-input v-model="taskFormEntity.destination" disabled />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="任务类型" prop="taskType">
<el-select-v2 v-model="taskFormEntity.taskType" placeholder="请选择任务类型" disabled
:options="taskTypeOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="任务状态" prop="taskStatus">
<el-select-v2 v-model="taskFormEntity.taskStatus" placeholder="请选择任务状态"
:options="taskStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitTaskInfo(taskFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
</div>
</template>
<script setup>
import { getTasks, changeTaskStatus } from '@/api/task.js'
import { getAvailableLocations } from '@/api/location.js'
import { dateFormatter, locationFormatter, taskStatusFormatter, timeFormatter, dueFormatter } from '@/utils/formatter.js'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import store from '@/store'
import { ref, reactive } from 'vue'
</script>
<script>
export default {
name: 'taskMonitor',
data() {
return {
pageInfo: {},
tasks: [],
currentPage: 1,
pageSize: 10,
total: 0,
goodsIdQuery: '',
vehicleNoQuery: '',
loading: true,
dialogVisible: false,
taskFormEntity: reactive({}),
labelPosition: 'top',
taskFormRef: ref(),
rules: reactive({}),
taskId: '',
taskTypeOptions: [
{
value: 1,
label: '入库'
},
{
value: 2,
label: '出库'
},
{
value: 3,
label: '盘点'
},
],
taskStatusOptions: [
{
value: 0,
label: '任务重置'
},
{
value: 1,
label: '任务取消'
},
{
value: 2,
label: '任务完成'
}
],
availableLocationOptions: []
}
},
mounted() {
this.search()
},
methods: {
dateFormat: (row, column, cellValue, index) => {
return dateFormatter(cellValue)
},
timeFormat: (row, column, cellValue, index) => {
return timeFormatter(cellValue)
},
taskStatusFormat: (row, column, cellValue, index) => {
return taskStatusFormatter(cellValue)
},
taskTypeFormat: (row, column, cellValue, index) => {
switch (cellValue) {
case 1:
if (row.taskId.substr(0, 2) == 'HK') {
return '回库'
} else {
return '入库'
}
case 2: return '出库'
case 3: return '盘点'
default: return '未知'
}
},
dueFormat: (row, column, cellValue, index) => {
return dueFormatter(cellValue)
},
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
goodsId: this.goodsIdQuery.trim(),
vehicleNo: this.vehicleNoQuery.trim(),
userName: store.getters.getUserName
}
}
getTasks(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
console.log(tableResponse.code + ':' + tableResponse.message)
ElMessage.error(tableResponse.message)
}
this.tasks = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
console.log(err)
ElMessage.error('查询任务错误')
})
this.loading = false
},
reset() {
this.goodsIdQuery = ''
this.vehicleNoQuery = ''
},
editCurrentRowTask(row) {
if (row.taskType == 1) {
this.availableLocationOptions = []
var currentOption = {
value: row.destination,
label: locationFormatter(row.destination)
}
this.availableLocationOptions.push(currentOption)
//
const requestParam = {
areaId: 1
}
getAvailableLocations(requestParam).then(res => {
if (res.data.code == 0) {
for (const location of res.data.returnData) {
var newOption = {}
newOption.value = location.locationId
newOption.label = locationFormatter(location.locationId)
this.availableLocationOptions.push(newOption)
}
}
}).catch(err => {
ElMessage.error('查找可用库位失败:' + err)
})
}
this.taskFormEntity.taskId = row.taskId
this.taskFormEntity.vehicleNo = row.vehicleNo
this.taskFormEntity.goodsId = row.goodsId
this.taskFormEntity.origin = row.origin
this.taskFormEntity.destination = row.destination
this.taskFormEntity.taskType = row.taskType
this.taskFormEntity.taskStatus = null
this.dialogVisible = true
},
submitTaskInfo(formData) {
if (formData.taskStatus == null || formData.taskStatus == undefined) {
ElMessage.error('请选择任务状态')
return
}
formData.userName = store.getters.getUserName
changeTaskStatus(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新任务状态成功',
type: 'success',
})
this.taskFormEntity.taskId = ''
this.taskFormEntity.vehicleNo = ''
this.taskFormEntity.goodsId = ''
this.taskFormEntity.origin = ''
this.taskFormEntity.destination = ''
this.taskFormEntity.taskType = null
this.taskFormEntity.taskStatus = null
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('更新任务状态失败:' + err)
})
},
getCurrentRow(row) {
this.taskId = row.taskId
}
},
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

265
src/layout/vehicle.vue Normal file
View File

@ -0,0 +1,265 @@
<template>
<div style="margin-bottom: 10px">
<el-config-provider :locale="zhCn">
<el-row>
<el-input v-model="queryKey" style="width: 256px; margin-right: 10px;" placeholder="箱号" />
<el-button type="primary" @click="search()">搜索</el-button>
<el-button type="warning" @click="reset()">刷新</el-button>
<el-button type="success" @click="inserthandOut = true">添加</el-button>
<!-- <el-button type="success" @click="refresh()">刷新</el-button> -->
</el-row>
<br />
<el-table :data="vehicles" stripe border v-loading="loading" class="table-class" max-height="650px"
highlight-current-row @row-click="getCurrentRow" :header-cell-style="{ 'text-align': 'center' }"
:cell-style="{ 'text-align': 'center' }">
<el-table-column width="65px" fixed="left">
<template v-slot="scope">
<el-radio :label="scope.row.vehicleId" v-model="vehicleId">&nbsp;</el-radio>
</template>
</el-table-column>
<el-table-column prop="vehicleId" label="箱号" fixed="left" min-width="120px" />
<el-table-column prop="currentLocation" label="当前位置" fixed="left" min-width="120px" />
<el-table-column prop="vehicleStatus" label="料箱状态" :formatter="vehicleStatusFormat" min-width="120px" />
<el-table-column prop="isEmpty" label="是否空箱" :formatter="isEmptyFormat" min-width="120px" />
<el-table-column fixed="right" label="操作" width="200px" v-if="selVehicle == null">
<template v-slot="scope">
<el-button plain type="primary" @click="editCurrentRowVehicle(scope.row)">编辑</el-button>
<el-button plain type="danger" @click="deleteCurrentRowVehicle(scope.row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<br />
<el-pagination v-model:current-page="currentPage" v-model:page-size="pageSize" :page-sizes="[10, 25, 50]"
:small="false" :disabled="false" :background="false" :default-page-size="10"
layout="total, sizes, prev, pager, next, jumper" :total="total" @size-change="search"
@current-change="search" />
<el-dialog v-model="dialogVisible" title="托盘信息" width="40%" draggable :show-close="false">
<el-form ref="vehicleFormRef" :model="vehicleFormEntity" :label-position="labelPosition" label-width="100px"
style="max-width: 100%" :rules="rules" status-icon>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="料箱号" prop="vehicleId">
<el-input v-model="vehicleFormEntity.vehicleId" disabled />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="当前位置" prop="currentLocation">
<el-input v-model="vehicleFormEntity.currentLocation" placeholder="请输入当前位置" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="16">
<el-col :span="12" :offset="0">
<el-form-item label="是否空箱" prop="isEmpty">
<el-select-v2 v-model="vehicleFormEntity.isEmpty" placeholder="请选择托盘状态"
:options="isEmptyOptions"></el-select-v2>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="托盘状态" prop="vehicleStatus">
<el-select-v2 v-model="vehicleFormEntity.vehicleStatus" placeholder="请选择托盘状态"
:options="vehicleStatusOptions"></el-select-v2>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<span class="dialog-footer">
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitVehicleInfo(vehicleFormEntity)">
确定
</el-button>
</span>
</template>
</el-dialog>
</el-config-provider>
<insertHandOut v-model="inserthandOut"/>
</div>
</template>
<script setup>
import insertHandOut from '@/components/inserthandOut.vue'
import { getAllVehicles, updateVehicleInfo, deleteCurrentVehicle } from '@/api/vehicle'
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ElMessage } from 'element-plus'
import { ref, reactive } from 'vue'
import { vehicleStatusFormatter, locationFormatter } from '@/utils/formatter.js'
</script>
<script>
export default {
name: 'vehicle',
props: ['selVehicle'],
emits: ['update:selVehicle'],
data() {
return {
pageInfo: {},
vehicles: [],
currentPage: 1,
pageSize: 10,
total: 0,
queryKey: '',
loading: true,
dialogVisible: false,
vehicleId: '',
vehicleFormEntity: reactive({}),
labelPosition: 'top',
vehicleFormRef: ref(),
rules: reactive({
locationId: [
{ required: true, message: '请输入库位' }
]
}),
//
isEmptyOptions: [
{
value: 0,
label: '带料'
},
{
value: 1,
label: '空箱'
}
],
//
vehicleStatusOptions: [
{
value: 1,
label: '入库中'
},
{
value: 2,
label: '在库中'
},
{
value: 3,
label: '出库中'
}
],
inserthandOut: false,
}
},
mounted() {
this.search()
},
methods: {
search() {
this.loading = true
this.pageInfo.pageNum = this.currentPage
this.pageInfo.pageSize = this.pageSize
const tableRequest = {
page: this.pageInfo,
param: {
vehicleId: this.queryKey.trim()
},
}
getAllVehicles(tableRequest).then(res => {
const tableResponse = res.data
if (tableResponse.code != 0) {
console.log(tableResponse.code + ':' + tableResponse.message)
ElMessage.error(tableResponse.message)
}
this.vehicles = tableResponse.rows
this.total = tableResponse.total
}).catch(err => {
ElMessage.error('查询托盘信息错误' + err.message)
})
this.loading = false
},
vehicleStatusFormat: (row, column, cellValue, index) => {
return vehicleStatusFormatter(cellValue)
},
locationFormat: (row, column, cellValue, index) => {
return locationFormatter(cellValue)
},
isEmptyFormat: (row, column, cellValue, index) => {
if (cellValue == 0) {
return '带料'
}
if (cellValue == 1) {
return '空箱'
}
},
reset() {
this.queryKey = ''
this.search()
},
editCurrentRowVehicle(row) {
this.vehicleFormEntity = row
this.dialogVisible = true
},
deleteCurrentRowVehicle(row) {
this.vehicleId = row.vehicleId
const vehicle = {
vehicleId: row.vehicleId
}
deleteCurrentVehicle(vehicle).then(res => {
if (res.data.code == 0) {
ElMessage({
message: '删除料箱成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('删除料箱信息失败:' + err)
})
},
submitVehicleInfo(formData) {
updateVehicleInfo(formData).then(res => {
if (res.data.code == 0) {
this.dialogVisible = false
ElMessage({
message: '更新料箱信息成功',
type: 'success',
})
this.search()
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
ElMessage.error('更新料箱信息失败:' + err)
})
},
getCurrentRow(row) {
this.vehicleId = row.vehicleId
this.$emit('update:selVehicle', row)
}
}
}
</script>
<style scoped>
.el-pagination {
padding-left: 5px;
}
.el-row .el-button {
width: 72px;
margin-left: 0px;
margin-right: 5px;
}
.table-class {
width: 100%;
/* font-size: 5px; */
}
.el-row .el-form-item {
width: 10% inherit;
justify-content: center;
}
.el-row .el-form-item .el-select-v2 {
width: 100% !important;
}
.el-row .el-form-item .el-input-number {
width: 100% !important;
}
.el-row .el-form-item .el-button {
margin: auto;
}
</style>

19
src/main.js Normal file
View File

@ -0,0 +1,19 @@
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import './styles/index.scss'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import * as ElementPlusIconsVue from '@element-plus/icons-vue'
import print from 'vue3-print-nb'
const app = createApp(App)
app.use(store)
app.use(router)
app.use(ElementPlus)
app.use(print)
for (const [key, component] of Object.entries(ElementPlusIconsVue)) {
app.component(key, component)
}
app.mount('#app')

85
src/print/printDemo.vue Normal file
View File

@ -0,0 +1,85 @@
<template>
<el-config-provider :locale="zhCn">
<el-row>
<el-button style="margin-left: 25px;" color="#626aef" v-print="'#printArea'"><el-icon>
<Printer />
</el-icon></el-button>
</el-row>
<el-container class="content">
<!-- <div style="width: 0;height: 0;overflow: hidden"> -->
<div>
<div id="printArea" class="objectDialogFlowPrint">
<div class="myPrint">
<div class="pageWarp" v-for="item in printTabs">
<el-card :body-style="{ padding: '0px', display: 'flex' }">
<qrcode-vue :value="item.name + '&' + item.quantity" :size="size" :foreground="color"
level="H" style="margin: 15px" />
<div style="padding: 14px; text-align: left;">
<span style="font-size: 27pt;font-weight: bold; margin-left: 0;">零件号{{ item.name
}}</span>
<br />
<span style="font-size: 27pt;font-weight: bold; margin-left: 0;">&#8195;{{
item.quantity }}</span>
</div>
</el-card>
</div>
</div>
</div>
</div>
</el-container>
</el-config-provider>
</template>
<script setup>
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import { ref } from 'vue'
import QrcodeVue from 'qrcode.vue'
</script>
<script>
export default {
name: 'printDemo',
components: {
},
data() {
return {
printTabs: [
{
name: '测试物料1',
quantity: 1
},
{
name: '测试物料2',
quantity: 2
}
],
size: ref(200),
color: ref('#000000')
}
},
methods: {
}
}
</script>
<style scoped>
.content {
display: flex;
width: 100%;
}
.objectDialogFlowPrint .pageWarp {
/*这句话很重要,控制时候强制分页 https://www.w3school.com.cn/cssref/pr_page-break-after.asp*/
page-break-after: always;
height: 100%;
width: 100%;
text-align: center;
margin: 5px auto;
padding: auto;
}
.objectDialogFlowPrint .myPrint {
/* 打印的时候是否显示底色 */
print-color-adjust: exact;
}</style>

62
src/router/index.js Normal file
View File

@ -0,0 +1,62 @@
import { createRouter, createWebHashHistory } from 'vue-router'
import HomeView from '@/views/HomeView.vue'
import stock from '@/layout/stock.vue'
import login from '@/views/login.vue'
import systemCenter from'@/views/SystemCenter.vue'
import goodsInPda from '@/layout/goodsInForPDA.vue'
const routes = [
{
path: '/home',
name: 'home',
component: HomeView,
redirect: '/stock',
children: [
{ path: '/stock', component: stock },// 库存
{ path: '/goodsIn', component: () => import('@/layout/goodsIn.vue') },// 入库
{ path: '/goodsOut', component: () => import('@/layout/goodsOut.vue') },// 出库
{ path: '/inTaskRecord', component: () => import('@/layout/inTaskRecord.vue') },// 入库记录
{ path: '/outTaskRecord', component: () => import('@/layout/outTaskRecord.vue') },// 出库记录
{ path: '/location', component: () => import('@/layout/location.vue') },// 库位
{ path: '/goods', component: () => import('@/layout/goods.vue') },// 物料
{ path: '/standSettings', component: () => import('@/layout/standSettings.vue') },// 站台(库口)设置
{ path: '/config', component: () => import('@/layout/config.vue') },// 系统配置
{ path: '/taskMonitor', component: () => import('@/layout/taskMonitor.vue') },// 任务监控
{ path: '/inventory', component: () => import('@/layout/inventory.vue') },// 盘点
{ path: '/inventoryRecord', component: () => import('@/layout/inventoryRecord.vue') },// 盘点
{ path: '/vehicle', component: () => import('@/layout/vehicle.vue') },// 料箱
]
},
{
path: '/',
name: 'login',
component: login
},
{
path: '/systemCenter',
name: 'systemCenter',
component: systemCenter
},
{
path: '/goodsInPda',
name: 'goodsInPda',
component: goodsInPda
},
]
const router = createRouter({
base: '/',
history: createWebHashHistory(),
routes
})
// 挂载路由导航守卫
router.beforeEach((to, from, next) => {
if (to.path === '/') return next()
// 获取token
const user = sessionStorage.getItem('user')
if (!user) return next('/')
next()
})
export default router

82
src/store/index.js Normal file
View File

@ -0,0 +1,82 @@
import { createStore } from 'vuex'
export default createStore({
state: {
stateTagsList: [{
id: '21',
labelName: '库存',
path: '/stock'
}],
user: {},
menuList: [],
token: '',
verifier: ''
},
getters: {
getUserName(state) {
return state.user.userName
},
getMenuList(state) {
return state.menuList
},
getToken(state) {
return state.token
},
getVerify(state) {
return state.verifier
},
},
mutations: {
/**
* 选择tag标签
*/
mutationSelectTags(state, data) {
let result = false
for (let i = 0; i < state.stateTagsList.length; i++) {
if (state.stateTagsList[i].path == data.path) {
return result = true
}
}
result === false ? state.stateTagsList.push(data) : ''
},
/**
* 关闭tag标签
*/
mutationCloseTag(state, data) {
let result = state.stateTagsList.findIndex(item => item.path === data.path)
state.stateTagsList.splice(result, 1)
},
/**
* 存储用户信息
*/
mutationUser(state, data) {
state.user = data
sessionStorage.setItem("user", state.user)
},
/**
* 存储菜单信息
*/
mutationMenu(state, data) {
state.menuList = data
sessionStorage.setItem("menuList", state.menuList)
},
/**
* 存储认证
*/
mutationAddVerify(state, data) {
state.verifier = data
},
mutationClearVerify(state) {
state.verifier = ''
},
},
actions: {
},
modules: {
}
})

9
src/styles/index.scss Normal file
View File

@ -0,0 +1,9 @@
/* 只需要重写你需要的即可 */
@forward 'element-plus/theme-chalk/src/common/var.scss' with ($colors: ('primary': ('base': green,
),
),
);
// 如果只是按需导入则可以忽略以下内容
// 如果你想导入所有样式:
// @use "element-plus/theme-chalk/src/index.scss" as *;

23
src/utils/dateUtils.js Normal file
View File

@ -0,0 +1,23 @@
function revertSeconds(originSeconds) {
const dayRule = 60*60*24
const hourRule = 60*60
const days = Math.floor(originSeconds/dayRule)
const hours = Math.floor((originSeconds%dayRule)/hourRule)
const minutes = Math.floor((originSeconds%hourRule)/60)
const seconds = originSeconds%60
var dueTime = ''
if (days > 0) {
dueTime = dueTime.concat(days).concat('天')
}
if (hours > 0) {
dueTime = dueTime.concat(hours).concat('小时')
}
if (minutes > 0) {
dueTime = dueTime.concat(minutes).concat('分')
}
return dueTime.concat(seconds).concat('秒')
}
export {
revertSeconds
}

153
src/utils/formatter.js Normal file
View File

@ -0,0 +1,153 @@
import moment from "moment";
import { revertSeconds } from '@/utils/dateUtils'
function timeFormatter(date) {
if (date === null || date === undefined) {
return ''
}
return moment(date).format('yyyy-MM-DD HH:mm:ss');
}
function formatCellValueTime(row, column, cellValue) {
if (cellValue === null || cellValue === '') {
return ''
}
try {
return moment(cellValue).format('yyyy-MM-DD HH:mm:ss')
}catch {
return cellValue
}
}
function dateFormatter(date) {
if (date === null || date === undefined) {
return ''
}
return moment(date).format('yyyy-MM-DD');
}
function dueFormatter(date) {
if (date === null || date === undefined) {
return ''
}
return revertSeconds(moment(new Date().getTime()).diff(moment(date), 'seconds'));
}
function taskStatusFormatter(value) {
switch (value) {
case 0:
return '任务新建,待下发'
case 1:
return '任务已下发'
case 2:
return '任务开始执行'
case 3:
return '出库完成'
case 4:
return '输送线转运中'
case 5:
return '到达拣选站台'
case 6:
return '正在拣货'
case 7:
return '正在回库'
case 8:
return '盘点中'
case 100:
return '任务完成'
case 998:
return '任务取消'
case 999:
return '任务异常'
default:
return '未完成'
}
}
function locationFormatter(locationId) {
if (locationId === null || locationId == undefined) {
return ''
}
const parts = locationId.split('-');
if (parts.length === 4) {
return parts[0] + '排' + parts[1] + '列' + parts[2] + '层' + parts[3] + '深';
} else if (parts.length === 3) {
return parts[0] + '排' + parts[1] + '列' + parts[2] + '层';
} else {
return '格式错误';
}
// const parts = locationId.split('-');
// return parts[0] + '排' + parts[1] + '列' + parts[2] + '层' + parts[3] + '深度';
//return locationId.substr(0, 2) + '排' + locationId.substr(2, 2) + '列' + locationId.substr(4, 2) + '层'
}
function kateTaskStatusFormatter(value) {
switch (value) {
case 0:
return '待下发'
case 1:
return '已下发'
case 2:
return '执行中'
case 3:
return '正在拣货'
case 5:
return '任务完成'
default:
return '异常状态'
}
}
function pickingStatusFormatter(value) {
switch (value) {
case 0:
return '待拣货'
case 1:
return '正在拣货'
case 2:
return '拣货完成'
default:
return '未拣货'
}
}
function vehicleStatusFormatter(value) {
switch (value) {
case 1:
return '入库中'
case 2:
return '在库中'
case 3:
return '出库中'
default:
return '异常状态'
}
}
function kateTaskTypeFormatter(value) {
switch (value) {
case 1:
return '配件'
case 2:
return '合件'
case 3:
return '紧急'
case 4:
return '原包装'
default:
return '任务类型异常'
}
}
export {
timeFormatter,
dateFormatter,
taskStatusFormatter,
locationFormatter,
kateTaskStatusFormatter,
pickingStatusFormatter,
vehicleStatusFormatter,
kateTaskTypeFormatter,
dueFormatter,
formatCellValueTime
}

9
src/utils/loading.js Normal file
View File

@ -0,0 +1,9 @@
import { ElLoading } from 'element-plus'
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
export default loading

146
src/utils/request.js Normal file
View File

@ -0,0 +1,146 @@
import axios from 'axios'
import { ElNotification, ElMessageBox, ElMessage, ElLoading } from 'element-plus'
import { getToken } from '@/utils/auth'
import errorCode from '@/utils/errorCode'
import { tansParams, blobValidate } from '@/utils/ruoyi'
import cache from '@/plugins/cache'
import { saveAs } from 'file-saver'
import useUserStore from '@/store/modules/user'
let downloadLoadingInstance;
// 是否显示重新登录
export let isRelogin = { show: false };
axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8'
// 创建axios实例
const service = axios.create({
// axios中请求配置有baseURL选项表示请求URL公共部分
baseURL: import.meta.env.VITE_APP_BASE_API,
// 超时
timeout: 10000
})
// request拦截器
service.interceptors.request.use(config => {
// 是否需要设置 token
const isToken = (config.headers || {}).isToken === false
// 是否需要防止数据重复提交
const isRepeatSubmit = (config.headers || {}).repeatSubmit === false
if (getToken() && !isToken) {
config.headers['Authorization'] = 'Bearer ' + getToken() // 让每个请求携带自定义token 请根据实际情况自行修改
}
// get请求映射params参数
if (config.method === 'get' && config.params) {
let url = config.url + '?' + tansParams(config.params);
url = url.slice(0, -1);
config.params = {};
config.url = url;
}
if (!isRepeatSubmit && (config.method === 'post' || config.method === 'put')) {
const requestObj = {
url: config.url,
data: typeof config.data === 'object' ? JSON.stringify(config.data) : config.data,
time: new Date().getTime()
}
const sessionObj = cache.session.getJSON('sessionObj')
if (sessionObj === undefined || sessionObj === null || sessionObj === '') {
cache.session.setJSON('sessionObj', requestObj)
} else {
const s_url = sessionObj.url; // 请求地址
const s_data = sessionObj.data; // 请求数据
const s_time = sessionObj.time; // 请求时间
const interval = 1000; // 间隔时间(ms),小于此时间视为重复提交
if (s_data === requestObj.data && requestObj.time - s_time < interval && s_url === requestObj.url) {
const message = '数据正在处理,请勿重复提交';
console.warn(`[${s_url}]: ` + message)
return Promise.reject(new Error(message))
} else {
cache.session.setJSON('sessionObj', requestObj)
}
}
}
return config
}, error => {
console.log(error)
Promise.reject(error)
})
// 响应拦截器
service.interceptors.response.use(res => {
// 未设置状态码则默认成功状态
const code = res.data.code || 200;
// 获取错误信息
const msg = errorCode[code] || res.data.msg || errorCode['default']
// 二进制数据则直接返回
if (res.request.responseType === 'blob' || res.request.responseType === 'arraybuffer') {
return res.data
}
if (code === 401) {
if (!isRelogin.show) {
isRelogin.show = true;
ElMessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' }).then(() => {
isRelogin.show = false;
useUserStore().logOut().then(() => {
location.href = '/index';
})
}).catch(() => {
isRelogin.show = false;
});
}
return Promise.reject('无效的会话,或者会话已过期,请重新登录。')
} else if (code === 500) {
ElMessage({ message: msg, type: 'error' })
return Promise.reject(new Error(msg))
} else if (code === 601) {
ElMessage({ message: msg, type: 'warning' })
return Promise.reject(new Error(msg))
} else if (code !== 200) {
ElNotification.error({ title: msg })
return Promise.reject('error')
} else {
return Promise.resolve(res.data)
}
},
error => {
console.log('err' + error)
let { message } = error;
if (message == "Network Error") {
message = "后端接口连接异常";
} else if (message.includes("timeout")) {
message = "系统接口请求超时";
} else if (message.includes("Request failed with status code")) {
message = "系统接口" + message.substr(message.length - 3) + "异常";
}
ElMessage({ message: message, type: 'error', duration: 5 * 1000 })
return Promise.reject(error)
}
)
// 通用下载方法
export function download(url, params, filename, config) {
downloadLoadingInstance = ElLoading.service({ text: "正在下载数据,请稍候", background: "rgba(0, 0, 0, 0.7)", })
return service.post(url, params, {
transformRequest: [(params) => { return tansParams(params) }],
headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
responseType: 'blob',
...config
}).then(async (data) => {
const isLogin = await blobValidate(data);
if (isLogin) {
const blob = new Blob([data])
saveAs(blob, filename)
} else {
const resText = await data.text();
const rspObj = JSON.parse(resText);
const errMsg = errorCode[rspObj.code] || rspObj.msg || errorCode['default']
ElMessage.error(errMsg);
}
downloadLoadingInstance.close();
}).catch((r) => {
console.error(r)
ElMessage.error('下载文件出现错误,请联系管理员!')
downloadLoadingInstance.close();
})
}
export default service

165
src/views/HomeView.vue Normal file
View File

@ -0,0 +1,165 @@
<template>
<el-container class="wms-home">
<el-header class="header">
<div class="icon-img">
<el-image :src="icon_img_url" :fit="'fill'" />
</div>
<div class="title">
<span>WMS仓库管理系统</span>
</div>
<div class="user">{{ userName }}</div>
</el-header>
<el-container class="content">
<el-aside class="aside">
<el-scrollbar style="max-height: 95%;">
<sideMenu></sideMenu>
</el-scrollbar>
<div :class="$route.path === '/location' ? 'locationsSel' : 'locations'" @click="openLocations">
<el-icon>
<View />
</el-icon>
<span>库位监控</span>
</div>
</el-aside>
<el-container>
<el-header class="tag">
<appTag></appTag>
</el-header>
<el-main>
<!-- 路由占位符 -->
<el-scrollbar>
<router-view v-slot="{ Component }">
<!-- // TODO keepAlive -->
<keep-alive>
<component :is="Component" />
</keep-alive>
</router-view>
</el-scrollbar>
</el-main>
<el-footer class="footer">© 1970-2023 江苏菲达宝开电气股份有限公司</el-footer>
</el-container>
</el-container>
</el-container>
</template>
<script setup>
// @ is an alias to /src
import sideMenu from '@/components/sideMenu.vue'
import appTag from '@/components/appTag.vue'
const icon_img_url = require('@/assets/fdbk_log.png')
</script>
<script>
export default {
name: 'HomeView',
components: {
sideMenu,
appTag
},
computed: {
userName() {
return this.$store.state.user.userName
}
},
methods: {
openLocations() {
this.$store.commit('mutationSelectTags', {
id: '25',
labelName: '库位监控',
path: '/location'
})
this.$router.push('/location')
}
}
}
</script>
<style scoped>
.wms-home {
height: 100%;
background-color: #CCCCCC;
}
.content {
height: 95%;
background-color: #FFFFFF;
}
.header {
/* background-color: #66CCFF; */
background-color: #D9E3EE;
display: flex;
align-items: center;
height: 5%;
/* font-size: 15px; */
}
.aside {
background-color: #fff;
height: 100%;
width: 10%;
border-right: 1px solid #66CCFF;
}
.footer {
background-color: #F0FFFF;
display: flex;
justify-content: center;
flex-direction: column;
height: 3%;
}
.tag {
padding-left: 1px;
display: flex;
align-items: center;
height: 30px;
border-bottom: solid 1px;
}
.icon-img {
height: 100%;
width: 3%;
}
.icon-img .el-image {
height: 100%;
width: 100%;
}
.title {
margin-left: 2px;
}
.user {
margin-left: auto;
}
.locations {
padding: 5px;
display: flex;
justify-content: center;
align-items: center;
height: 3.8%;
border-top: solid 1px;
cursor: pointer;
color: #5A9CF8;
}
.locationsSel {
padding: 5px;
display: flex;
justify-content: center;
align-items: center;
height: 3.8%;
border-top: solid 1px;
cursor: pointer;
background-color: #5A9CF8;
color: #000;
}
.locations:hover {
background-color: #5A9CF8;
color: #000;
}
</style>

112
src/views/SystemCenter.vue Normal file
View File

@ -0,0 +1,112 @@
<template>
<body id="login-page">
<el-form class="login-container" label-position="left" label-width="0px">
<h3 class="login_title">请选择系统</h3>
<el-form-item style="width: 100%">
<el-button color="#87CEFA" style="width: 100%; border: none" @click="loginToWms">WMS系统</el-button>
</el-form-item>
<!-- <el-form-item style="width: 100%">
<el-button color="#87CEEB" style="width: 100%; border: none" @click="loginToPda">手持入库系统</el-button>
</el-form-item>
<el-form-item style="width: 100%">
<el-button color="#AFEEEE" style="width: 100%; border: none" @click="loginToSideScan">线边扫码系统</el-button>
</el-form-item>
<el-form-item style="width: 100%">
<el-button color="#ADD8E6" style="width: 100%; border: none" @click="loginToWcs">WCS系统</el-button>
</el-form-item>
<el-form-item style="width: 100%">
<el-button color="#B0E0E6" style="width: 100%; border: none" @click="loginToMonitor">监控系统</el-button>
</el-form-item> -->
</el-form>
</body>
</template>
<script setup>
import { getUser } from '@/api/login.js'
import { ElMessage, ElLoading } from 'element-plus'
import { onMounted } from 'vue';
import store from '@/store'
import router from '@/router'
const user = store.getters.getUserNam//
const token = store.getters.getToken//
// WMS
const loginToWms = () => {
router.replace({ path: '/home' })
}
const loginToPda = () => {
router.replace({ path: '/goodsInPda' })
}
const loginToSideScan = () => {
router.replace({ path: '/sideScan' })
}
// WCS
const loginToWcs = () => {
const wcsUrl = `https://cxlasrs.ecorp.cat.com/wcs/#/login?user=user&pwd=user`
window.location.href = wcsUrl//
}
const loginToMonitor = () => {
const mpnitorUrl = `https://cxlasrs.ecorp.cat.com?user=${user}&token=${token}`
window.location.href = mpnitorUrl//
}
onMounted(() => {
if (router.currentRoute.value.query.code != undefined) {
console.log(router.currentRoute.value.query.code)
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
const codeInfo = {
code: router.currentRoute.value.query.code,
state: router.currentRoute.value.query.state
}
getUser(codeInfo).then(res => {
loading.close()
if (res.data.code == 0) {
store.commit('mutationUser', res.data.returnData.user)//
store.commit('mutationMenu', res.data.returnData.menuList)//
router.replace({ path: '/' })
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
loading.close()
ElMessage.error('登录失败!')
})
}
})
</script>
<style scoped>
#login-page {
/* background: url("../assets/img/bg.jpg") no-repeat; */
background-position: center;
height: 100%;
width: 100%;
background-size: cover;
position: fixed;
}
body {
margin: 0px;
}
.login-container {
border-radius: 15px;
background-clip: padding-box;
margin: 90px auto;
width: 350px;
padding: 35px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
.login_title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
</style>

83
src/views/login.vue Normal file
View File

@ -0,0 +1,83 @@
<template>
<body id="login-page">
<el-form class="login-container" :model="loginForm" label-position="left" label-width="0px">
<h3 class="login_title">系统登录</h3>
<el-form-item>
<el-input type="text" v-model="loginForm.loginAccount" auto-complete="off" placeholder="账号"></el-input>
</el-form-item>
<el-form-item>
<el-input type="password" v-model="loginForm.loginPassword" auto-complete="off" placeholder="密码"></el-input>
</el-form-item>
<el-form-item style="width: 100%">
<el-button type="primary" style="width: 100%; border: none" @click="login">登录</el-button>
</el-form-item>
</el-form>
</body>
</template>
<script setup>
import { loginWithAuth } from '@/api/login.js'
import { ElMessage, ElLoading } from 'element-plus'
import { reactive } from 'vue';
import store from '@/store'
import router from '@/router'
const loginForm = reactive({
loginAccount: "",
loginPassword: "",
})
//
const login = () => {
const loading = ElLoading.service({
lock: true,
text: 'Loading',
background: 'rgba(0, 0, 0, 0.7)',
})
loginWithAuth(loginForm).then(res => {
loading.close()
if (res.data.code == 0) {
store.commit('mutationUser', res.data.returnData.user)//
store.commit('mutationMenu', res.data.returnData.menuList)//
// router.replace({ path: '/' })//
router.replace({ path: '/systemCenter' })//
} else {
ElMessage.error(res.data.message)
}
}).catch(err => {
console.log(err)
loading.close()
ElMessage.error('登录失败!')
})
}
</script>
<style scoped>
#login-page {
/* background: url("../assets/img/bg.jpg") no-repeat; */
background-position: center;
height: 100%;
width: 100%;
background-size: cover;
position: fixed;
}
body {
margin: 0px;
}
.login-container {
border-radius: 15px;
background-clip: padding-box;
margin: 90px auto;
width: 350px;
padding: 35px 35px 15px 35px;
background: #fff;
border: 1px solid #eaeaea;
box-shadow: 0 0 25px #cac6c6;
}
.login_title {
margin: 0px auto 40px auto;
text-align: center;
color: #505458;
}
</style>

20
vue.config.js Normal file
View File

@ -0,0 +1,20 @@
const { defineConfig } = require('@vue/cli-service')
const NodePolyfillPlugin = require('node-polyfill-webpack-plugin')
module.exports = defineConfig({
transpileDependencies: true,
configureWebpack: {
plugins: [new NodePolyfillPlugin()]
},
devServer: {
port: 12306, // 端口
proxy: {
'/authorize': { // 若请求的前缀不是这个'/wms',那请求就不会走代理服务器
target: "https://login.microsoftonline.com/caterpillar.onmicrosoft.com/", //这里写路径
pathRewrite: { '^/authorize': '' }, //将所有含/wms路径的去掉/wms转发给服务器
ws: true, //用于支持websocket
changeOrigin: true //用于控制请求头中的host值
},
}
},
})