初始化仓库
This commit is contained in:
365
pages/wms/stock/addInvQuick.vue
Normal file
365
pages/wms/stock/addInvQuick.vue
Normal file
@@ -0,0 +1,365 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-collapse>
|
||||
<uni-forms ref="form" :modelValue="formData" :rules="rules">
|
||||
<uni-collapse-item title="快速盘点单" :open="true">
|
||||
<uni-forms-item label="物料编码" :labelWidth='90' name="materialCode">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBar" v-model="formData.materialCode"
|
||||
@confirm="scanBarMaterialCode" type="text" v-if="key=='1'" />
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBar" v-model="formData.materialCode"
|
||||
@confirm="scanBarMaterialCodePre" type="text" v-if="key=='2'" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="物料名称" :labelWidth='90' name="materialName">
|
||||
<uni-easyinput v-model="formData.materialName"></uni-easyinput>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="批号" :labelWidth='90' name="batchNo" v-if="key=='1'">
|
||||
<uni-easyinput v-model="formData.batchNo" type="text" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="库位条码" :labelWidth='90' name="storageLocationBarcode" v-if="key=='1'">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBarstorageLocationBarcode"
|
||||
@confirm="splitStlBarcode" type="text" v-model="formData.storageLocationBarcode" />
|
||||
</uni-forms-item>
|
||||
<button @click="key=='1'?queryStockInfo():queryStockTotalInfo()" type="primary"
|
||||
style="text-align: center;font-size: 18px;width: 50%;">查询</button>
|
||||
</uni-collapse-item>
|
||||
|
||||
<uni-collapse-item title="快速盘点单明细" :open="true">
|
||||
|
||||
<uni-swipe-action>
|
||||
<uni-swipe-action-item v-for="(item, index) in quickInvStockList" :key="index"
|
||||
:rightOptions="rightOptions" @click="(data) => clickDetail(index,data)">
|
||||
<uni-badge :text="index+1" type="primary"></uni-badge>
|
||||
<uni-forms-item label="批号" :labelWidth='90' v-if="key=='2'" style="margin-bottom: 0;">
|
||||
{{item.batchNo}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="新批号" :labelWidth='90' style="margin-bottom: 0;">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBarstorageLocationBarcode" type="text"
|
||||
v-model="item.newBatchNo" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="部门编码" :labelWidth='90' style="margin-bottom: 0;">
|
||||
{{item.deptCode}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="物料规格" :labelWidth='90' style="margin-bottom: 0;">
|
||||
{{item.specification}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="物料类型" :labelWidth='90' style="margin-bottom: 0;">
|
||||
<uni-tag :text="item.typeText" type="primary"></uni-tag>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="理论数量" :labelWidth='90' style="margin-bottom: 0;">
|
||||
{{item.theoryNumber}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="锁定数量" :labelWidth='90' style="margin-bottom: 0;">
|
||||
{{item.lockNumber}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="实际数量" :labelWidth='90' style="margin-bottom: 0;">
|
||||
<uni-easyinput type="text" v-model="item.actualNumber" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="四级库位" :labelWidth='90' v-if="key=='2'" style="margin-bottom: 0;">
|
||||
{{item.connectLocation}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="新库位条码" :labelWidth='90' name="newstorageLocationBarcode"
|
||||
style="margin-bottom: 0;">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBarnewstorageLocationBarcode(index)"
|
||||
@change="newsplitStlBarcode(index)" type="text"
|
||||
v-model="item.newstorageLocationBarcode" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="单位" :labelWidth='90' style="margin-bottom: 0;">
|
||||
{{item.unitId}}
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="备注" :labelWidth='90' style="margin-bottom: 0;">
|
||||
<uni-easyinput type="text" v-model="item.remark" />
|
||||
</uni-forms-item>
|
||||
</uni-swipe-action-item>
|
||||
</uni-swipe-action>
|
||||
<button @click="handleAddPreInvStock" size="mini" type="primary" plain="true"
|
||||
style="text-align: center;font-size: 18px;width: 50%;margin-bottom: 10px;display: block;margin-top: 10px;"
|
||||
v-if="key=='2'">添加</button>
|
||||
</uni-collapse-item>
|
||||
</uni-forms>
|
||||
</uni-collapse>
|
||||
<u-button type="primary" @click="submit">提交</u-button>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listInvQuick,
|
||||
advListInvQuick,
|
||||
getInvQuick,
|
||||
delInvQuick,
|
||||
addInvQuick,
|
||||
updateInvQuick,
|
||||
listQuickInvStockInfo,
|
||||
invQuickUpdateStock,
|
||||
preInvUpdateStock,
|
||||
listPreInvStockInfo
|
||||
} from "@/api/wms/invQuick";
|
||||
import {
|
||||
listMaterial
|
||||
} from "@/api/mes/material.js";
|
||||
import {
|
||||
getDicts
|
||||
} from "@/api/system/dict/dictData.js";
|
||||
export default {
|
||||
onLoad: function(option) {
|
||||
getDicts("material_stock_type").then(res => {
|
||||
this.typeOptions = res.data.map(dict => {
|
||||
return {
|
||||
text: dict.dictLabel,
|
||||
value: dict.dictValue,
|
||||
diasble: false
|
||||
}
|
||||
});
|
||||
})
|
||||
//赋值盘点类型
|
||||
this.key = option.key
|
||||
},
|
||||
mounted() {},
|
||||
data() {
|
||||
return {
|
||||
//盘点类型
|
||||
key: null,
|
||||
typeOptions: [],
|
||||
formData: {
|
||||
storageLocationBarcode: null,
|
||||
materialCode: null,
|
||||
materialName: null,
|
||||
batchNo: null,
|
||||
},
|
||||
rightOptions: [{
|
||||
text: '删除',
|
||||
style: {
|
||||
backgroundColor: '#ff2a17'
|
||||
}
|
||||
}, ],
|
||||
quickInvStockList: [],
|
||||
rules: {
|
||||
materialCode: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '请输入物料编码!'
|
||||
}]
|
||||
},
|
||||
materialName: {
|
||||
rules: [{
|
||||
required: true,
|
||||
errorMessage: '请输入物料名称!'
|
||||
}]
|
||||
},
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
deleteDetail(index) {
|
||||
this.quickInvStockList.splice(index, 1);
|
||||
},
|
||||
clickDetail(itemIndex, {
|
||||
position,
|
||||
index
|
||||
}) {
|
||||
if (index == 0) {
|
||||
this.deleteDetail(itemIndex);
|
||||
}
|
||||
},
|
||||
newsplitStlBarcode(i) {
|
||||
this.quickInvStockList[i].whCode = null;
|
||||
this.quickInvStockList[i].areaCode = null;
|
||||
this.quickInvStockList[i].shelvesCode = null;
|
||||
this.quickInvStockList[i].storageLocationCode = null;
|
||||
let array = this.quickInvStockList[i].newstorageLocationBarcode.split('-');
|
||||
console.log(array);
|
||||
this.quickInvStockList[i].newWhCode = array.length > 0 ? array[0] : null;
|
||||
this.quickInvStockList[i].newAreaCode = array.length > 1 ? array[1] : null;
|
||||
this.quickInvStockList[i].newShelvesCode = array.length > 2 ? array[2] : null;
|
||||
this.quickInvStockList[i].newStorageLocationCode = array.length > 3 ? array[3] : null;
|
||||
if (array.length > 4) this.quickInvStockList[i].newStorageLocationCode = array[3] + '-' + array[4];
|
||||
},
|
||||
scanBarnewstorageLocationBarcode(i) {
|
||||
const _this = this;
|
||||
uni.scanCode({
|
||||
scanType: ['barCode', 'qrCode'],
|
||||
success: function(res) {
|
||||
_this.$set(_this.quickInvStockList[i], "newstorageLocationBarcode", res
|
||||
.result);
|
||||
// _this.wmsLotNoList[i].storageLocationBarcode = res.result;
|
||||
_this.newsplitStlBarcode(i);
|
||||
}
|
||||
});
|
||||
},
|
||||
splitStlBarcode(e) {
|
||||
this.formData.whCode = null;
|
||||
this.formData.areaCode = null;
|
||||
this.formData.shelvesCode = null;
|
||||
this.formData.storageLocationCode = null;
|
||||
let array = e.split('-');
|
||||
switch (array.length) {
|
||||
case 1:
|
||||
this.formData.whCode = array[0];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 2:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 3:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 4:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.formData.storageLocationCode = array[3];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 5:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.formData.storageLocationCode = array[3] + '-' + array[4];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
}
|
||||
},
|
||||
scanBarstorageLocationBarcode() {
|
||||
const _this = this;
|
||||
uni.scanCode({
|
||||
scanType: ['barCode', 'qrCode'],
|
||||
success: function(res) {
|
||||
_this.$set(_this.formData, "storageLocationBarcode", res
|
||||
.result);
|
||||
_this.splitStlBarcode(res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
scanBar() {
|
||||
const _this = this;
|
||||
uni.scanCode({
|
||||
scanType: ['barCode', 'qrCode'],
|
||||
success: function(res) {
|
||||
_this.$set(_this.formData, "materialCode", res
|
||||
.result);
|
||||
_this.scanBarMaterialCode(res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
scanBarMaterialCode(code) {
|
||||
listMaterial({
|
||||
materialCode: code
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if (res.total > 0) {
|
||||
console.log(res)
|
||||
this.formData.materialName = res.rows[0].materialName
|
||||
}
|
||||
})
|
||||
},
|
||||
scanBarMaterialCodePre(code) {
|
||||
console.log(1)
|
||||
listMaterial({
|
||||
materialCode: code
|
||||
}).then(res => {
|
||||
console.log(res)
|
||||
if (res.total > 0) {
|
||||
console.log(res)
|
||||
this.formData.materialName = res.rows[0].materialName
|
||||
this.queryStockTotalInfo();
|
||||
} else {
|
||||
this.formData.materialCode = null;
|
||||
this.$modal.msg("未查询到该物料,请重新输入!");
|
||||
}
|
||||
})
|
||||
},
|
||||
queryStockInfo() {
|
||||
listQuickInvStockInfo(this.formData).then(response => {
|
||||
this.quickInvStockList = response.data.map(item => {
|
||||
if (item.type) item.typeText = this.typeOptions.find(tp => tp.value == item.type)
|
||||
.text
|
||||
return item
|
||||
});
|
||||
console.log(response.data, this.quickInvStockList);
|
||||
})
|
||||
},
|
||||
queryStockTotalInfo() {
|
||||
listPreInvStockInfo(this.formData).then(response => {
|
||||
this.quickInvStockList = response.data.map(item => {
|
||||
if (item.type) item.typeText = this.typeOptions.find(tp => tp.value == item.type)
|
||||
.text
|
||||
return item
|
||||
});
|
||||
})
|
||||
},
|
||||
handleAddPreInvStock() {
|
||||
let obj = {}
|
||||
if (this.quickInvStockList.length > 0) {
|
||||
obj = {
|
||||
...this.quickInvStockList[0]
|
||||
};
|
||||
} else {
|
||||
obj = this.formData;
|
||||
}
|
||||
/**新增库存的标志*/
|
||||
obj.newStock = 1;
|
||||
//目前仅支持合格品
|
||||
obj.type = 1;
|
||||
obj.batchNo = null;
|
||||
obj.newBatchNo = null;
|
||||
obj.theoryNumber = 0;
|
||||
obj.lockNumber = 0;
|
||||
obj.actualNumber = 0;
|
||||
obj.whCode = null;
|
||||
obj.areaCode = null;
|
||||
obj.shelvesCode = null;
|
||||
obj.storageLocationCode = null;
|
||||
obj.connectLocation = null;
|
||||
obj.newWhCode = null;
|
||||
obj.newAreaCode = null;
|
||||
obj.newShelvesCode = null;
|
||||
obj.newStorageLocationCode = null;
|
||||
obj.remark = null;
|
||||
this.quickInvStockList.push(obj);
|
||||
},
|
||||
submit() {
|
||||
const _this = this;
|
||||
_this.$refs.form.validate().then(res => {
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您确定盘点该物料吗?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
const quickInvStockList = _this.quickInvStockList;
|
||||
// console.log(quickInvStockList)
|
||||
|
||||
if (_this.key == '1') {
|
||||
invQuickUpdateStock(quickInvStockList).then(() => {
|
||||
_this.$modal.msgSuccess("盘点成功!");
|
||||
setTimeout(() => {
|
||||
_this.$tab.switchTab(
|
||||
"/pages/work/index");
|
||||
}, 500);
|
||||
}).catch(() => {});
|
||||
} else if (_this.key == '2') {
|
||||
preInvUpdateStock(quickInvStockList).then(() => {
|
||||
_this.$modal.msgSuccess("盘点成功!");
|
||||
setTimeout(() => {
|
||||
_this.$tab.switchTab(
|
||||
"/pages/work/index");
|
||||
}, 500);
|
||||
}).catch(() => {});
|
||||
}
|
||||
} else if (res.cancel) {
|
||||
console.log('用户点击取消');
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
</style>
|
||||
553
pages/wms/stock/addTransfer.vue
Normal file
553
pages/wms/stock/addTransfer.vue
Normal file
@@ -0,0 +1,553 @@
|
||||
<template>
|
||||
<view class="container">
|
||||
<uni-forms :modelValue="formData" :label-width="60" label-align="right" class="form">
|
||||
<uni-forms-item label="发起人">
|
||||
<uni-easyinput v-model="formData.transferBy" placeholder="请输入发起人" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="运输员">
|
||||
<uni-easyinput v-model="formData.transportBy" placeholder="请输入运输员" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="原库位">
|
||||
<uni-easyinput v-model="formData.currentLocationCode" placeholder="请输入原库位条码" suffixIcon="scan"
|
||||
@iconClick="scanCurrentLocationCode" @change="fetchLocationDetail" />
|
||||
</uni-forms-item>
|
||||
</uni-forms>
|
||||
<uni-section class="section" title="库位库存明细" type="line">
|
||||
<template #right>
|
||||
<span v-if="materialList.length > 0">
|
||||
库位
|
||||
<strong style="margin: 0 2px">{{ materialList[0].storageLocationCode }}</strong>
|
||||
, 共
|
||||
<strong style="margin: 0 2px">{{ materialList.length }}</strong>
|
||||
条
|
||||
<!-- <checkbox @click="handleSelectAll" /> -->
|
||||
</span>
|
||||
</template>
|
||||
<scroll-view scroll-y>
|
||||
<checkbox-group @change="handleSelectRows">
|
||||
<uni-card v-for="(item, index) in materialList" :key="index">
|
||||
<template #title>
|
||||
<view class="header">
|
||||
<view class="matInfo">
|
||||
<uni-tag :text="String(index + 1)" />
|
||||
<text class="matName">
|
||||
{{ item.materialName }}
|
||||
</text>
|
||||
</view>
|
||||
<checkbox :value="String(index)" :checked="item.checked" @click="handleSelectItem(index)"
|
||||
class="check-dot" />
|
||||
</view>
|
||||
</template>
|
||||
<view class="card-list">
|
||||
<view class="card-item">
|
||||
<span class="card-item__label">物料编码</span>
|
||||
<span class="card-item__value">{{ item.materialCode || '/' }}</span>
|
||||
</view>
|
||||
<view class="card-item">
|
||||
<span class="card-item__label">批号</span>
|
||||
<span class="card-item__value">{{ item.batchNo || '/' }}</span>
|
||||
</view>
|
||||
<view class="card-item">
|
||||
<span class="card-item__label">箱号</span>
|
||||
<span class="card-item__value">{{ item.lotNo || '/' }}</span>
|
||||
</view>
|
||||
<!-- <view class="card-item">
|
||||
<span class="card-item__label">库位编码</span>
|
||||
<span class="card-item__value">{{ item.storageLocationCode }}</span>
|
||||
</view> -->
|
||||
<view class="card-item">
|
||||
<span class="card-item__label">入库时间</span>
|
||||
<span class="card-item__value">{{ item.storageInTime || '/' }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<view class="card-data">
|
||||
<view class="card-data-item">
|
||||
<span class="card-data-item__label">库存总数</span>
|
||||
<span class="card-data-item__value">{{ item.number || '/' }}</span>
|
||||
</view>
|
||||
<view class="card-data-item">
|
||||
<span class="card-data-item__label">锁定数量</span>
|
||||
<span class="card-data-item__value lock">{{ item.lockNumber || '/' }}</span>
|
||||
</view>
|
||||
<view class="card-data-item">
|
||||
<span class="card-data-item__label">可用数量</span>
|
||||
<span class="card-data-item__value avalible">{{ item.availableNumber || '/' }}</span>
|
||||
</view>
|
||||
</view>
|
||||
<template #actions>
|
||||
<u-transition :show="item.checked" mode="fade" duration="200">
|
||||
<view class="card-actions">
|
||||
<uni-forms-item label="目标库位" :labelWidth="80" name="targetLocation">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanTargetLocationCode(index)"
|
||||
@change="validateLocationCode(index)" type="text" v-model="item.targetLocation" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="转移数量" :labelWidth="80" name="actualNumber" style="margin-top: 10px">
|
||||
<u-number-box button-size="36" inputWidth="100%" v-model="item.actualNumber" min="0"
|
||||
:max="item.availableNumber"></u-number-box>
|
||||
</uni-forms-item>
|
||||
</view>
|
||||
</u-transition>
|
||||
</template>
|
||||
</uni-card>
|
||||
</checkbox-group>
|
||||
</scroll-view>
|
||||
</uni-section>
|
||||
<u-modal v-if="showMultiFillModal" :show="showMultiFillModal" title="扫描库位编码" showCancelButton closeOnClickOverlay
|
||||
@cancel="cancelMultiFill" @close="cancelMultiFill" :showConfirmButton="false">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanMultiFill" v-model="multiTargetLocation"
|
||||
@confirm="handleMultiFill" :focus="true" />
|
||||
</u-modal>
|
||||
<view class="btns">
|
||||
<u-button @click="showMultiFill" class="sub-btn">批量移库</u-button>
|
||||
<u-button type="primary" @click="submit" class="pri-btn">提交</u-button>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { listStock, addTransfer } from '@/api/wms/stock.js';
|
||||
import { listLocation } from '@/api/basic/location';
|
||||
import { getConfigKey } from '@/api/system/config.js';
|
||||
export default {
|
||||
mounted() {
|
||||
// 获取参数: 是否使用 货架-库位 查出完整库位
|
||||
getConfigKey('wms.location.queryOption').then((res) => {
|
||||
this.isShortLocation = Boolean(+res.msg);
|
||||
});
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
// 是否为短库位格式(货架-库位)
|
||||
isShortLocation: false,
|
||||
selectedRows: [],
|
||||
showMultiFillModal: false,
|
||||
multiTargetLocation: null,
|
||||
formData: {
|
||||
transferBy: null,
|
||||
transportBy: null,
|
||||
currentLocationCode: null,
|
||||
currentWholeLocationCode: null
|
||||
},
|
||||
materialList: []
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
// 原库位扫描事件
|
||||
async scanCurrentLocationCode() {
|
||||
this.$modal.scanCode(async (res) => {
|
||||
if (!res.result) return;
|
||||
this.$set(this.formData, 'currentLocationCode', res.result);
|
||||
if (this.isShortLocation) {
|
||||
this.formData.currentWholeLocationCode = await this.fetchWholeLocationCode(res.result);
|
||||
} else {
|
||||
this.formData.currentWholeLocationCode = this.formData.currentLocationCode;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 原库位 change 事件,查询库存明细
|
||||
async fetchLocationDetail(code) {
|
||||
if (!code) return;
|
||||
if (this.isShortLocation) {
|
||||
this.formData.currentWholeLocationCode = await this.fetchWholeLocationCode(code);
|
||||
} else {
|
||||
this.formData.currentWholeLocationCode = this.formData.currentLocationCode;
|
||||
}
|
||||
this.fetchMaterialList();
|
||||
},
|
||||
// 目标库位扫描事件
|
||||
async scanTargetLocationCode() {
|
||||
this.$modal.scanCode(async (response) => {
|
||||
if (!response.result) return;
|
||||
let res;
|
||||
if (this.isShortLocation) {
|
||||
res = await this.fetchWholeLocationCode(response.result);
|
||||
} else {
|
||||
res = response.result;
|
||||
}
|
||||
if (res === this.formData.currentWholeLocationCode) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:原库位与目标库位相同`);
|
||||
return;
|
||||
}
|
||||
if (res.split('-')[0] !== this.formData.currentWholeLocationCode.split('-')[0]) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:目标仓库与原仓库不一致`);
|
||||
return;
|
||||
}
|
||||
this.materialList[i].targetLocation = response.result;
|
||||
this.materialList[i].storageLocationBarcode = res;
|
||||
});
|
||||
},
|
||||
// 目标库位 change 事件,校验库位是否合法
|
||||
async validateLocationCode(i) {
|
||||
if (!this.materialList[i].targetLocation) return;
|
||||
let res;
|
||||
if (this.isShortLocation) {
|
||||
res = await this.fetchWholeLocationCode(this.materialList[i].targetLocation);
|
||||
} else {
|
||||
res = this.materialList[i].targetLocation;
|
||||
}
|
||||
if (res === this.formData.currentLocationCode) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:原库位与目标库位相同`);
|
||||
this.materialList[i].targetLocation = null;
|
||||
return;
|
||||
}
|
||||
if (res.split('-')[0] !== this.formData.currentWholeLocationCode.split('-')[0]) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:目标仓库与原仓库不一致`);
|
||||
this.materialList[i].targetLocation = null;
|
||||
return;
|
||||
}
|
||||
this.materialList[i].storageLocationBarcode = res;
|
||||
},
|
||||
// 获取完整库位
|
||||
async fetchWholeLocationCode(shortLocationCode) {
|
||||
if (!shortLocationCode) return null;
|
||||
try {
|
||||
this.$modal.loading('获取完整库位中...');
|
||||
const storageShelvesCode = shortLocationCode.split('-')[0];
|
||||
const storageLocationCode = shortLocationCode.split('-').slice(1).join('-');
|
||||
if (!storageShelvesCode || !storageLocationCode) {
|
||||
throw new Error(`库位编码格式不正确: ${shortLocationCode}`);
|
||||
}
|
||||
const res = await listLocation({
|
||||
storageShelvesCode,
|
||||
storageLocationCode
|
||||
});
|
||||
if (!res.total > 0) {
|
||||
throw new Error(`未查询到 ${shortLocationCode} 的完整库位`);
|
||||
} else if (res.total > 1) {
|
||||
throw new Error(`查询到 ${shortLocationCode} 的完整库位有多个`);
|
||||
}
|
||||
return res.rows[0].storageLocationBarcode;
|
||||
} catch (err) {
|
||||
this.$modal.alert(err.message);
|
||||
return null;
|
||||
} finally {
|
||||
this.$modal.closeLoading();
|
||||
}
|
||||
},
|
||||
// 获取库存明细列表
|
||||
async fetchMaterialList() {
|
||||
this.$modal.loading('获取库存明细中...');
|
||||
await listStock({
|
||||
storageLocationCode: this.formData.currentLocationCode.split('-').slice(1).join('-'),
|
||||
storageLocationBarcode: this.formData.currentWholeLocationCode
|
||||
})
|
||||
.then((res) => {
|
||||
res.rows.forEach((item) => {
|
||||
item.availableNumber = item.number - item.lockNumber;
|
||||
});
|
||||
this.materialList = res.rows;
|
||||
})
|
||||
.catch((err) => {
|
||||
this.$modal.msgError(`查询明细失败\n${err}`);
|
||||
});
|
||||
this.$modal.closeLoading();
|
||||
},
|
||||
// 选中列表中某一项
|
||||
handleSelectItem(i) {
|
||||
this.$set(this.materialList[i], 'checked', !this.materialList[i].checked);
|
||||
},
|
||||
// 选中回调
|
||||
handleSelectRows(e) {
|
||||
this.selectedRows = e.target.value;
|
||||
// for (let i = 0; i < this.materialList.length; i++) {
|
||||
// this.$set(this.materialList[i], 'checked', Boolean(e.target.value.includes(String(i))));
|
||||
// }
|
||||
},
|
||||
// 拆解库位
|
||||
splitLocationCode(code) {
|
||||
const parts = (code || '').split('-');
|
||||
const whCode = parts[0] || null;
|
||||
const areaCode = parts[1] || null;
|
||||
const shelvesCode = parts[2] || null;
|
||||
const storageLocationCode = parts.slice(3).join('-') || null;
|
||||
return {
|
||||
whCode,
|
||||
areaCode,
|
||||
shelvesCode,
|
||||
storageLocationCode
|
||||
};
|
||||
},
|
||||
// 批量填充扫码事件
|
||||
scanMultiFill() {
|
||||
this.$modal.scanCode(async (response) => {
|
||||
let res;
|
||||
if (this.isShortLocation) {
|
||||
res = await this.fetchWholeLocationCode(response.result);
|
||||
} else {
|
||||
res = response.result;
|
||||
}
|
||||
if (res === this.formData.currentLocationCode) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:原库位与目标库位相同`);
|
||||
return;
|
||||
}
|
||||
if (res.split('-')[0] !== this.formData.currentWholeLocationCode.split('-')[0]) {
|
||||
this.$modal.msgError(`第 ${i + 1} 条明细:目标仓库与原仓库不一致`);
|
||||
return;
|
||||
}
|
||||
this.handleMultiFill(res);
|
||||
});
|
||||
},
|
||||
// 批量填充选中项的目标库位
|
||||
async handleMultiFill(code) {
|
||||
console.log(code);
|
||||
this.materialList.forEach(async (item) => {
|
||||
if (item.checked) {
|
||||
item.storageLocationBarcode = await this.fetchWholeLocationCode(code);
|
||||
item.targetLocation = code;
|
||||
}
|
||||
});
|
||||
this.showMultiFillModal = false;
|
||||
},
|
||||
// 打开批量填充
|
||||
showMultiFill() {
|
||||
if (!this.selectedRows.length > 0) {
|
||||
this.$modal.msgError('请先选择明细');
|
||||
return;
|
||||
}
|
||||
this.showMultiFillModal = true;
|
||||
},
|
||||
// 取消标签
|
||||
cancelMultiFill() {
|
||||
this.showMultiFillModal = false;
|
||||
},
|
||||
// 运输员
|
||||
scanBarTransportBy() {
|
||||
this.$modal.scanCode((res) => {
|
||||
this.formData.transportBy = res.result;
|
||||
});
|
||||
},
|
||||
// 发起人
|
||||
scanBarTransferBy() {
|
||||
this.$modal.scanCode((res) => {
|
||||
this.formData.transferBy = res.result;
|
||||
});
|
||||
},
|
||||
// 生成转移单明细
|
||||
renderTransferData() {
|
||||
const transferArr = [];
|
||||
this.materialList.forEach((item) => {
|
||||
if (item.checked) {
|
||||
const { areaCode: targetAreaCode, shelvesCode: targetShelves, storageLocationCode: targetLocation } = this
|
||||
.splitLocationCode(item.storageLocationBarcode);
|
||||
const params = {
|
||||
wmsMaterialStockId: item.id,
|
||||
materialBatchNo: item.batchNo,
|
||||
materialCode: item.materialCode,
|
||||
materialName: item.materialName,
|
||||
materialLotNo: item.lotNo,
|
||||
originAreaCode: item.areaCode,
|
||||
originShelvesCode: item.shelvesCode,
|
||||
originLocationCode: item.storageLocationCode,
|
||||
targetAreaCode,
|
||||
targetShelves,
|
||||
targetLocation,
|
||||
availableNumber: item.availableNumber,
|
||||
actualNumber: item.actualNumber,
|
||||
specification1: item.specification,
|
||||
texture: item.texture,
|
||||
schemeNumber: null,
|
||||
delStatus: null,
|
||||
numUnitId: null,
|
||||
remark: null
|
||||
};
|
||||
transferArr.push(params);
|
||||
}
|
||||
});
|
||||
return transferArr;
|
||||
},
|
||||
submit() {
|
||||
const _this = this;
|
||||
this.materialList
|
||||
.filter((item) => item.checked)
|
||||
.forEach((item) => {
|
||||
if (!item.id) {
|
||||
console.log(item);
|
||||
this.$modal.msg('存在未选择库存的明细!');
|
||||
return;
|
||||
} else if (item.actualNumber == null) {
|
||||
this.$modal.msg('实际数量不能为空!');
|
||||
return;
|
||||
} else if (item.targetLocation == null) {
|
||||
this.$modal.msg('目标库区不能为空!');
|
||||
return;
|
||||
}
|
||||
});
|
||||
uni.showModal({
|
||||
title: '提示',
|
||||
content: '您确定转移这些物料吗?',
|
||||
success: function(res) {
|
||||
if (res.confirm) {
|
||||
const wmsStockTransferDetailList = _this.renderTransferData();
|
||||
_this.$modal.loading('提交中...');
|
||||
addTransfer({
|
||||
warehouse: _this.formData.currentWholeLocationCode.split('-')[0],
|
||||
//跳过审批流
|
||||
transferStatus: '4',
|
||||
transferBy: _this.formData.transferBy,
|
||||
transportBy: _this.formData.transportBy,
|
||||
delStatus: '0',
|
||||
wmsStockTransferDetailList
|
||||
}).then((res) => {
|
||||
_this.$modal.closeLoading();
|
||||
_this.$modal.msgSuccess('转移成功!');
|
||||
setTimeout(() => {
|
||||
_this.$tab.switchTab('/pages/work/index');
|
||||
}, 500);
|
||||
}).catch((err) => {
|
||||
_this.$modal.alert('提交失败', err);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
.container {
|
||||
/* #ifdef H5 */
|
||||
height: calc(100vh - 44px);
|
||||
/* #endif */
|
||||
/* #ifndef H5 */
|
||||
height: 100vh;
|
||||
/* #endif */
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.section {
|
||||
flex: 1;
|
||||
background: transparent;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
::v-deep .uni-section-content {
|
||||
flex: 1;
|
||||
overflow: scroll;
|
||||
}
|
||||
}
|
||||
|
||||
.uni-card {
|
||||
margin: 0 0 10px !important;
|
||||
padding: 0 !important;
|
||||
box-shadow: none !important;
|
||||
border-radius: 11px;
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px;
|
||||
border-bottom: 1px solid #d9d9d9;
|
||||
|
||||
.matInfo {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.matName {
|
||||
font-size: 16px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.uni-tag {
|
||||
box-sizing: border-box;
|
||||
height: 100%;
|
||||
text-align: center;
|
||||
margin-right: 8px;
|
||||
aspect-ratio: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.check-dot {
|
||||
border-radius: 50%;
|
||||
}
|
||||
}
|
||||
|
||||
.card-list {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-gap: 4px;
|
||||
|
||||
.card-item {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
|
||||
.card-item__label {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.card-item__value {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-data {
|
||||
display: flex;
|
||||
margin-top: 10px;
|
||||
background-color: #f1f1f1;
|
||||
border-radius: 4px;
|
||||
padding: 6px 0;
|
||||
|
||||
.card-data-item {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.card-data-item__label {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
.card-data-item__value {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
color: #333;
|
||||
|
||||
&.lock {
|
||||
color: #ef4444;
|
||||
}
|
||||
|
||||
&.avalible {
|
||||
color: #059669;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.card-actions {
|
||||
padding: 8px;
|
||||
border-top: 1px solid #d9d9d9;
|
||||
|
||||
.uni-forms-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.btns {
|
||||
display: flex;
|
||||
justify-content: space-evenly;
|
||||
align-items: center;
|
||||
margin-top: 10px;
|
||||
|
||||
.sub-btn {
|
||||
width: 47%;
|
||||
}
|
||||
|
||||
.pri-btn {
|
||||
width: 47%;
|
||||
}
|
||||
}
|
||||
|
||||
.u-popup {
|
||||
position: absolute;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
205
pages/wms/stock/search.vue
Normal file
205
pages/wms/stock/search.vue
Normal file
@@ -0,0 +1,205 @@
|
||||
<template>
|
||||
<view>
|
||||
<uni-collapse>
|
||||
<uni-forms ref="form" :modelValue="formData" :rules="rules">
|
||||
<!-- <uni-collapse-item title="库存查询" :open="true"> -->
|
||||
<uni-forms-item label="物料编码" :labelWidth='90' name="materialCode">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBar" v-model="formData.materialCode"
|
||||
@confirm="scanBarMaterialCode" type="text" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="物料名称" :labelWidth='90' name="materialName">
|
||||
<uni-easyinput v-model="formData.materialName"></uni-easyinput>
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="批号" :labelWidth='90' name="batchNo">
|
||||
<uni-easyinput v-model="formData.batchNo" type="text" />
|
||||
</uni-forms-item>
|
||||
<uni-forms-item label="库位条码" :labelWidth='90' name="storageLocationBarcode">
|
||||
<uni-easyinput suffixIcon="scan" @iconClick="scanBarstorageLocationBarcode"
|
||||
@confirm="splitStlBarcode" type="text" v-model="formData.storageLocationBarcode" />
|
||||
</uni-forms-item>
|
||||
<button @click="queryStockInfo" form-type="submit" type="primary"
|
||||
style="text-align: center;font-size: 18px;width: 50%;">查询</button>
|
||||
<!-- </uni-collapse-item> -->
|
||||
</uni-forms>
|
||||
<uni-collapse-item title="库位库存明细" :open="true">
|
||||
<view v-for="(item, index) in wmsMaterialDetailList" :key="index" :disabled="item.disabled"
|
||||
class="item">
|
||||
<text>物料编码:{{ item.materialCode }}</text>
|
||||
<text>批号:{{ item.batchNo }}</text>
|
||||
<text>箱号:{{ item.lotNo }}</text>
|
||||
<text>物料名称:{{ item.materialName }}</text>
|
||||
<text>拼接库位:{{ item.connectBin }}</text>
|
||||
<text>入库时间:{{ item.storageInTime }}</text>
|
||||
<text>库存总数:{{ item.number }}</text>
|
||||
<text>锁定数量:{{ item.lockNumber }}</text>
|
||||
<text>可用数量:{{ item.MaterialAvailableNumber }}</text>
|
||||
</view>
|
||||
</uni-collapse-item>
|
||||
</uni-collapse>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {
|
||||
listStock,
|
||||
listStockLike
|
||||
} from "@/api/wms/stock";
|
||||
import {
|
||||
listMaterial
|
||||
} from "@/api/mes/material.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
formData: {
|
||||
storageLocationBarcode: null,
|
||||
materialCode: null,
|
||||
materialName: null,
|
||||
batchNo: null,
|
||||
},
|
||||
wmsMaterialDetailList: [],
|
||||
// rules: {
|
||||
// materialCode: {
|
||||
// rules: [{
|
||||
// required: true,
|
||||
// errorMessage: '请输入物料编码!'
|
||||
// }]
|
||||
// },
|
||||
// materialName: {
|
||||
// rules: [{
|
||||
// required: true,
|
||||
// errorMessage: '请输入物料名称!'
|
||||
// }]
|
||||
// },
|
||||
// }
|
||||
};
|
||||
},
|
||||
|
||||
methods: {
|
||||
// 【物料编码】的扫描按钮点击操作
|
||||
scanBar() {
|
||||
const _this = this;
|
||||
uni.scanCode({
|
||||
scanType: ['barCode', 'qrCode'],
|
||||
success: function(res) {
|
||||
_this.$set(_this.formData, "materialCode", res.result);
|
||||
_this.scanBarMaterialCode(res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 输入物料编码确认后的操作
|
||||
scanBarMaterialCode(code) {
|
||||
// 查出物料编码关联的物料名称
|
||||
listMaterial({
|
||||
materialCode: code
|
||||
}).then(res => {
|
||||
if (res.total > 0) {
|
||||
this.formData.materialName = res.rows[0].materialName;
|
||||
}
|
||||
});
|
||||
},
|
||||
// 【库位条码】的扫描按钮点击操作
|
||||
scanBarstorageLocationBarcode() {
|
||||
const _this = this;
|
||||
uni.scanCode({
|
||||
scanType: ['barCode', 'qrCode'],
|
||||
success: function(res) {
|
||||
_this.$set(_this.formData, "storageLocationBarcode", res.result);
|
||||
_this.splitStlBarcode(res.result);
|
||||
}
|
||||
});
|
||||
},
|
||||
// 分割库位条码
|
||||
splitStlBarcode(e) {
|
||||
this.formData.whCode = null;
|
||||
this.formData.areaCode = null;
|
||||
this.formData.shelvesCode = null;
|
||||
this.formData.storageLocationCode = null;
|
||||
let array = e.split('-');
|
||||
switch (array.length) {
|
||||
case 1:
|
||||
this.formData.whCode = array[0];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 2:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 3:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 4:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.formData.storageLocationCode = array[3];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
case 5:
|
||||
this.formData.whCode = array[0];
|
||||
this.formData.areaCode = array[1];
|
||||
this.formData.shelvesCode = array[2];
|
||||
this.formData.storageLocationCode = array[3] + '-' + array[4];
|
||||
this.queryStockInfo();
|
||||
break;
|
||||
}
|
||||
},
|
||||
queryStockInfo() {
|
||||
// 获取库位库存明细数据
|
||||
listStockLike(this.formData).then(res => {
|
||||
for (let obj of res.rows) {
|
||||
obj.MaterialAvailableNumber = obj.number - obj.lockNumber;
|
||||
}
|
||||
this.wmsMaterialDetailList = res.rows;
|
||||
}).catch(err => {
|
||||
uni.showToast({
|
||||
title: '请输入必填字段',
|
||||
icon: 'none',
|
||||
})
|
||||
console.error('获取库存明细失败:', err);
|
||||
});
|
||||
// // 先验证表单,不知道为什么,uniapp里的验证功能没用,查不出来,自己写吧
|
||||
// this.$refs.form.validate((res) => {
|
||||
// // 自己写个验证逻辑
|
||||
// let required = ['materialCode', 'materialName'];
|
||||
// for (let field of required) {
|
||||
// if (!this.formData[field]) {
|
||||
// uni.showToast({
|
||||
// title: '请输入必填字段',
|
||||
// icon: 'none',
|
||||
// })
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// console.log('表单数据信息:', res);
|
||||
// }).catch((error) => {
|
||||
// console.error('表单验证失败:', error);
|
||||
// });
|
||||
},
|
||||
},
|
||||
onReady() {
|
||||
this.$refs.form.setRules(this.rules);
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.item {
|
||||
margin-bottom: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
background-color: #f7f7f7;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.item text {
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user