615 lines
15 KiB
Vue
615 lines
15 KiB
Vue
<template>
|
|
<base-page>
|
|
<view class="content-wrap" @click="goodsShow = false">
|
|
<view class="title">添加调拨单</view>
|
|
<view class="screen-warp form-content">
|
|
<view class="form-item store-info" v-if="storeInfo">
|
|
<view class="form-label">当前门店:</view>
|
|
<view class="form-inline">{{ storeInfo.store_name }}</view>
|
|
</view>
|
|
<view class="form-item">
|
|
<label class="form-label">
|
|
<text class="required">*</text>
|
|
调拨方式
|
|
</label>
|
|
<view class="form-inline">
|
|
<select-lay
|
|
:zindex="10"
|
|
:value="type"
|
|
name="names"
|
|
placeholder="请选择调拨方式"
|
|
:options="screen.allocateTypeList"
|
|
@selectitem="selectAllocateType"
|
|
></select-lay>
|
|
</view>
|
|
</view>
|
|
<view class="form-item">
|
|
<label class="form-label">
|
|
<text class="required">*</text>
|
|
{{ storeName }}
|
|
</label>
|
|
<view class="form-inline">
|
|
<select-lay
|
|
:zindex="10"
|
|
:value="screen.store_id"
|
|
name="names"
|
|
:placeholder="'请选择' + storeName"
|
|
:options="screen.storeList"
|
|
@selectitem="selectStore"
|
|
></select-lay>
|
|
</view>
|
|
</view>
|
|
<view class="form-item">
|
|
<label class="form-label">
|
|
<text class="required">*</text>
|
|
调拨时间
|
|
</label>
|
|
<view class="form-inline">
|
|
<uni-datetime-picker :start="screen.startDate" v-model="screen.birthday" type="timestamp" :clearIcon="false" @change="changeTime" />
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<view class="table-wrap">
|
|
<view class="table-head">
|
|
<view class="table-tr">
|
|
<view class="table-th" style="flex: 3;">产品名称/规格/编码</view>
|
|
<view class="table-th" style="flex: 1;">当前库存</view>
|
|
<view class="table-th" style="flex: 1;">单位</view>
|
|
<view class="table-th" style="flex: 2;">成本价</view>
|
|
<view class="table-th" style="flex: 2;">数量</view>
|
|
<view class="table-th" style="flex: 1;">总金额</view>
|
|
<view class="table-th" style="flex: 1;">操作</view>
|
|
</view>
|
|
</view>
|
|
<view class="table-body">
|
|
<view class="table-tr">
|
|
<view class="table-td select-goods-input" style="flex: 3;" @click.stop="goodsShow = true">
|
|
<input type="text" v-model="name" @confirm="getGoodsData" placeholder="请输入产品名称/规格/编码" />
|
|
<scroll-view class="select-goods-frame" :scroll-y="true" v-show="goodsShow">
|
|
<view :class="['goods-item', { select: selectGoodsId == item.sku_id }]" v-for="(item, index) in goodsList" @click.stop="selectGoods(item)">
|
|
{{ item.sku_name }}
|
|
</view>
|
|
<view class="goods-item-empty" v-if="!goodsList.length">暂无商品</view>
|
|
</scroll-view>
|
|
</view>
|
|
<view class="table-td" style="flex: 1;"></view>
|
|
<view class="table-td" style="flex: 1;"></view>
|
|
<view class="table-td" style="flex: 2;"></view>
|
|
<view class="table-td" style="flex: 2;"></view>
|
|
<view class="table-td" style="flex: 1;"></view>
|
|
<view class="table-td" style="flex: 1;"></view>
|
|
</view>
|
|
<block v-for="(item, index) in goodsList" :key="index">
|
|
<view class="table-tr" v-if="goodsIdArr.includes(item.sku_id)">
|
|
<view class="table-td goods-name" style="flex: 3;">
|
|
<image :src="$util.img(item.sku_image, { size: 'small' })" mode="aspectFill"></image>
|
|
<text class="name multi-hidden">{{ item.sku_name }}</text>
|
|
</view>
|
|
<view class="table-td" style="flex: 1;">{{ item.real_stock || 0 }}</view>
|
|
<view class="table-td" style="flex: 1;">{{ item.unit }}</view>
|
|
<view class="table-td" style="flex: 2;">{{ item.cost_price || 0 }}</view>
|
|
<view class="table-td" style="flex: 2;">
|
|
<input type="number" class="goods-num" v-model="item.goods_num" placeholder="请输入数量" @input="calcTotalData" />
|
|
</view>
|
|
<view class="table-td" style="flex: 1;">{{ (item.goods_num * item.cost_price || 0).toFixed(2) }}</view>
|
|
<view class="table-td" style="flex: 1;"><button type="default" class="delete" @click="delGoods(item.sku_id)">删除</button></view>
|
|
</view>
|
|
</block>
|
|
<view class="table-tr table-empty" v-if="!goodsIdArr.length">暂无数据,请选择商品数据</view>
|
|
</view>
|
|
</view>
|
|
<view class="action-wrap">
|
|
<view class="table-total">合计:共{{ totalData.kindsNum }}种{{ totalData.countNum }}件产品,合计金额{{ totalData.price.toFixed(2) }}</view>
|
|
<view class="btn-wrap">
|
|
<button type="default" class="stockout-btn" @click="stockOutFn">确认调拨</button>
|
|
<button type="default" @click="backFn">返回</button>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</base-page>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
name: '', //产品名称
|
|
goodsList:[],
|
|
goodsIdArr:[],
|
|
selectGoodsId: 0,
|
|
goodsShow: false,
|
|
totalData:{
|
|
kindsNum:0,
|
|
countNum:0,
|
|
price: 0
|
|
},
|
|
isSubmit: false,
|
|
|
|
// 筛选面板的时间
|
|
type: 'out',
|
|
storeName: '出库门店',
|
|
screen:{
|
|
store_id: "",
|
|
storeList:[],
|
|
startDate:'1998-01-30 00:00:00',
|
|
birthday:'',
|
|
allocateTypeList: [
|
|
{
|
|
label: '调拨入库',
|
|
value: 'out'
|
|
},
|
|
{
|
|
label: '调拨出库',
|
|
value: 'in'
|
|
}
|
|
]
|
|
},
|
|
scanCode: {
|
|
code: '',
|
|
lastTime: 0
|
|
}
|
|
};
|
|
},
|
|
onLoad(option) {
|
|
uni.hideTabBar();
|
|
},
|
|
onShow() {
|
|
this.screen.birthday = this.$util.timeFormat(Date.parse(new Date())/1000);
|
|
this.getStoreLists();
|
|
this.getGoodsData();
|
|
|
|
// #ifdef APP-PLUS
|
|
plus.key.addEventListener('keyup', this.listenerScancode, true);
|
|
// #endif
|
|
// #ifdef H5
|
|
window.addEventListener('keypress', this.listenerScancode, true);
|
|
// #endif
|
|
},
|
|
onHide() {
|
|
// #ifdef APP-PLUS
|
|
plus.key.removeEventListener('keyup', this.listenerScancode, true);
|
|
// #endif
|
|
// #ifdef H5
|
|
window.removeEventListener('keypress', this.listenerScancode, true);
|
|
// #endif
|
|
},
|
|
watch: {
|
|
goodsIdArr(data){
|
|
this.calcTotalData();
|
|
}
|
|
},
|
|
methods: {
|
|
selectAllocateType(id){
|
|
this.type = id == -1 ? '' : this.screen.allocateTypeList[id].value;
|
|
this.storeName = id == -1 ? '出库门店' : this.screen.allocateTypeList[id].label;
|
|
if(this.type == 'in') this.getGoodsData(); //当是入库的时候,需要查出库门店的商品
|
|
},
|
|
selectStore(id){
|
|
this.screen.store_id = id == -1 ? '' : this.screen.storeList[id].value;
|
|
},
|
|
changeTime(data){
|
|
this.screen.birthday = data;
|
|
},
|
|
getGoodsData() {
|
|
let data = {search: this.name};
|
|
if(this.type == 'in')
|
|
data.temp_store_id = this.screen.store_id;
|
|
this.$api.sendRequest({
|
|
url: '/stock/storeapi/manage/getskulist',
|
|
data:data,
|
|
success: res => {
|
|
this.goodsList = [];
|
|
if (res.code >= 0 && res.data.length != 0) {
|
|
this.goodsList = res.data;
|
|
this.selectGoodsId = this.goodsList[0].sku_id;
|
|
}else{
|
|
this.$util.showToast({
|
|
title:res.message
|
|
});
|
|
}
|
|
}
|
|
});
|
|
},
|
|
selectGoods(data){
|
|
this.selectGoodsId = data.sku_id;
|
|
if(!this.goodsIdArr.includes(data.sku_id))
|
|
this.goodsIdArr.push(data.sku_id);
|
|
this.goodsShow = false;
|
|
},
|
|
delGoods(id){
|
|
this.goodsIdArr.splice(this.goodsIdArr.indexOf(id),1);
|
|
this.$forceUpdate();
|
|
},
|
|
getStoreLists(){
|
|
this.screen.storeList = [];
|
|
this.$api.sendRequest({
|
|
url: '/stock/storeapi/store/lists',
|
|
success: res => {
|
|
if(res.code >= 0){
|
|
let data = res.data;
|
|
let storeId = uni.getStorageSync('store_id');
|
|
for(let i = 0; i < data.length; i++){
|
|
if(storeId != data[i]['store_id']){
|
|
this.screen.storeList.push({
|
|
'label': data[i]['store_name'],
|
|
'value': data[i]['store_id'].toString()
|
|
});
|
|
}
|
|
}
|
|
this.screen.store_id = this.screen.storeList[0].value;
|
|
}
|
|
}
|
|
});
|
|
},
|
|
stockOutFn(){
|
|
if(!this.type){
|
|
this.$util.showToast({
|
|
title: "请选择调拨方式"
|
|
});
|
|
return false;
|
|
}
|
|
if(!this.screen.store_id){
|
|
this.$util.showToast({
|
|
title: "请选择出库门店"
|
|
});
|
|
return false;
|
|
}
|
|
if(!this.screen.birthday){
|
|
this.$util.showToast({
|
|
title: "请选择调拨时间"
|
|
});
|
|
return false;
|
|
}
|
|
if(!this.goodsIdArr.length){
|
|
this.$util.showToast({
|
|
title: "请选择调拨数据"
|
|
});
|
|
return false;
|
|
}
|
|
|
|
// 检测库存是否填写,且提取数据
|
|
let isStock = false;
|
|
let saveData = [];
|
|
try{
|
|
this.goodsList.forEach((item,index)=>{
|
|
if(this.goodsIdArr.includes(item.sku_id)){
|
|
if(!parseInt(item.goods_num || 0)){
|
|
isStock = true;
|
|
let toast = "请输入" + item.sku_name + "的调拨数量";
|
|
this.$util.showToast({
|
|
title: toast
|
|
});
|
|
return false;
|
|
throw new Error('end');
|
|
}
|
|
var obj = {};
|
|
obj.goods_num = item.goods_num;
|
|
obj.goods_price = item.cost_price;
|
|
obj.goods_sku_id = item.sku_id;
|
|
saveData.push(obj);
|
|
}
|
|
})
|
|
}catch(e){
|
|
if(e.message != "end") throw e;
|
|
}
|
|
|
|
if(isStock) return false;
|
|
if(this.isSubmit) return false;
|
|
this.isSubmit = true;
|
|
|
|
this.$api.sendRequest({
|
|
url: '/stock/storeapi/allocate/addallocate',
|
|
data:{
|
|
allot_type: this.type,
|
|
temp_store_id: this.screen.store_id,
|
|
allot_time: this.screen.birthday,
|
|
goods_sku_list: JSON.stringify(saveData)
|
|
},
|
|
success: res => {
|
|
this.isSubmit = false;
|
|
this.$util.showToast({
|
|
title:res.message
|
|
});
|
|
if (res.code >= 0) {
|
|
setTimeout(()=>{
|
|
this.backFn();
|
|
},500);
|
|
this.resetFn();
|
|
}
|
|
}
|
|
});
|
|
},
|
|
backFn(){
|
|
this.$util.redirectTo('/pages/stock/allocate');
|
|
},
|
|
calcTotalData(){
|
|
this.totalData.countNum = 0;
|
|
this.totalData.kindsNum = 0;
|
|
this.totalData.price = 0;
|
|
|
|
this.goodsList.forEach((item,index)=>{
|
|
if(this.goodsIdArr.includes(item.sku_id)){
|
|
this.totalData.price += parseFloat(item.cost_price || 0) * parseInt(item.goods_num || 1);
|
|
this.totalData.countNum += parseInt(item.goods_num || 0);
|
|
}
|
|
})
|
|
this.totalData.kindsNum = this.goodsIdArr.length;
|
|
},
|
|
resetFn(){
|
|
this.goodsIdArr = [];
|
|
this.selectGoodsId = this.goodsList[0].sku_id;
|
|
this.goodsShow = false;
|
|
this.totalData.kindsNum = 0;
|
|
this.totalData.countNum = 0;
|
|
this.totalData.price = 0;
|
|
},
|
|
/**
|
|
* 监听扫码事件
|
|
* @param {Object} e
|
|
*/
|
|
listenerScancode(e){
|
|
const clearBarCode = ()=> {
|
|
this.scanCode = { lastTime: 0, code: '' }
|
|
}
|
|
|
|
// #ifdef H5
|
|
var currCode = e.keyCode || e.which || e.charCode;
|
|
// #endif
|
|
|
|
// #ifdef APP-PLUS
|
|
const keycode = ['keycode_7': 0, 'keycode_8': 1, 'keycode_9': 2, 'keycode_10': 3, 'keycode_11': 4, 'keycode_12':
|
|
5, 'keycode_13': 6, 'keycode_14': 7, 'keycode_15': 8, 'keycode_16': 9
|
|
];
|
|
var currCode = keyArr['keycode_' + e.keyCode] || '';
|
|
// #endif
|
|
|
|
var currTime = new Date().getTime();
|
|
if (this.scanCode.lastTime > 0) {
|
|
if (currTime - this.scanCode.lastTime <= 100) {
|
|
this.scanCode.code += String.fromCharCode(currCode);
|
|
} else if (currTime - this.scanCode.lastTime > 500) {
|
|
// 输入间隔500毫秒清空
|
|
clearBarCode();
|
|
}
|
|
} else {
|
|
this.scanCode.code = String.fromCharCode(currCode);
|
|
}
|
|
this.scanCode.lastTime = currTime;
|
|
|
|
// #ifdef H5
|
|
if (currCode == 13) {
|
|
// #endif
|
|
// #ifdef APP-PLUS
|
|
if (e.keyCode == 66) {
|
|
// #endif
|
|
if (this.scanCode.code && this.scanCode.code.length >= 8) this.getSkuBycode(this.scanCode.code)
|
|
// 回车输入后清空
|
|
clearBarCode();
|
|
}
|
|
},
|
|
/**
|
|
* 获取商品信息通过条形码
|
|
*/
|
|
getSkuBycode(code){
|
|
this.$api.sendRequest({
|
|
url: '/cashier/storeapi/goods/skuinfo',
|
|
data: {
|
|
sku_no: code.trim()
|
|
},
|
|
success: res => {
|
|
if (res.code == 0) {
|
|
if (res.data) {
|
|
res.data.goods_num = 0;
|
|
this.selectGoods(res.data)
|
|
} else {
|
|
this.$util.showToast({
|
|
title: '未找到该商品!'
|
|
})
|
|
}
|
|
} else {
|
|
this.$util.showToast({
|
|
title: res.message,
|
|
})
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss">
|
|
.form-content {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
margin-top: 0.2rem;
|
|
.store-info {
|
|
.form-inline {
|
|
padding-left: 0.05rem;
|
|
}
|
|
}
|
|
.form-item {
|
|
margin-bottom: 0.1rem;
|
|
display: flex;
|
|
.form-label {
|
|
width: 1.3rem;
|
|
text-align: right;
|
|
padding-right: 0.1rem;
|
|
box-sizing: border-box;
|
|
height: 0.32rem;
|
|
line-height: 0.32rem;
|
|
.required {
|
|
color: red;
|
|
margin-right: 0.03rem;
|
|
}
|
|
}
|
|
.form-inline {
|
|
width: 2.4rem;
|
|
line-height: 0.32rem;
|
|
margin-right: 0.1rem;
|
|
box-sizing: border-box;
|
|
.form-input {
|
|
border-width: 0.01rem;
|
|
border-style: solid;
|
|
background-color: #fff;
|
|
color: rgba(0, 0, 0, 0.85);
|
|
border-radius: 0.02rem;
|
|
padding-left: 0.1rem;
|
|
height: 0.32rem;
|
|
line-height: 0.32rem;
|
|
font-size: 0.14rem;
|
|
border-color: #e6e6e6;
|
|
border-radius: 0.02rem;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.content-wrap {
|
|
position: relative;
|
|
padding: 0.15rem;
|
|
background-color: #fff;
|
|
min-height: 100vh;
|
|
box-sizing: border-box;
|
|
.title {
|
|
font-size: 0.18rem;
|
|
margin-bottom: 0.2rem;
|
|
text-align: center;
|
|
}
|
|
.table-wrap {
|
|
position: relative;
|
|
margin-top: 40rpx;
|
|
border: 1rpx solid #ccc;
|
|
.table-head {
|
|
background-color: #f7f7f7;
|
|
}
|
|
.table-body {
|
|
overflow: auto;
|
|
max-height: 6rem;
|
|
.table-tr {
|
|
&:nth-child(1) {
|
|
position: absolute;
|
|
left: 0;
|
|
right: 0;
|
|
background: #fff;
|
|
z-index: 2;
|
|
}
|
|
&:nth-child(2) {
|
|
margin-top: 0.51rem;
|
|
}
|
|
&:last-of-type .table-td {
|
|
border-bottom: 0;
|
|
}
|
|
}
|
|
}
|
|
.table-tr {
|
|
display: flex;
|
|
}
|
|
.table-th,
|
|
.table-td {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
padding: 0.15rem 0.3rem;
|
|
border-bottom: 0.01rem solid #ccc;
|
|
border-right: 0.01rem solid #ccc;
|
|
text-align: center;
|
|
&:last-of-type {
|
|
border-right: 0;
|
|
justify-content: flex-end;
|
|
}
|
|
&.goods-name {
|
|
justify-content: flex-start;
|
|
image {
|
|
width: 0.45rem;
|
|
height: 0.45rem;
|
|
flex-shrink: 0;
|
|
}
|
|
.name {
|
|
margin-left: 0.1rem;
|
|
}
|
|
}
|
|
}
|
|
.goods-num {
|
|
border: 0.01rem solid #eee;
|
|
height: 0.35rem;
|
|
line-height: 0.35rem;
|
|
border-radius: 0.05rem;
|
|
}
|
|
input {
|
|
font-size: $uni-font-size-base;
|
|
}
|
|
.delete {
|
|
margin: 0;
|
|
font-size: $uni-font-size-base;
|
|
background-color: $uni-color-primary;
|
|
color: #fff;
|
|
}
|
|
.table-empty {
|
|
justify-content: center;
|
|
padding: 0.3rem;
|
|
color: #999;
|
|
}
|
|
}
|
|
.action-wrap {
|
|
position: absolute;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
display: flex;
|
|
justify-content: space-between;
|
|
padding: 0.1rem 0.15rem 0.2rem;
|
|
align-items: center;
|
|
border-top: 0.01rem solid #ccc;
|
|
.btn-wrap {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
button {
|
|
margin: 0;
|
|
min-width: 2.75rem;
|
|
height: 0.4rem;
|
|
line-height: 0.4rem;
|
|
font-size: $uni-font-size-base;
|
|
&.stockout-btn {
|
|
margin-right: 0.15rem;
|
|
background-color: $uni-color-primary;
|
|
color: #fff;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.select-goods-input {
|
|
position: relative;
|
|
input {
|
|
flex: 1;
|
|
font-size: $uni-font-size-base;
|
|
}
|
|
}
|
|
.select-goods-frame {
|
|
position: absolute;
|
|
z-index: 2;
|
|
padding: 0.05rem 0;
|
|
top: 0.45rem;
|
|
left: 0;
|
|
width: 5rem;
|
|
height: 5rem;
|
|
background-color: #fff;
|
|
box-shadow: 0 0 36rpx rgba(0, 0, 0, 0.4);
|
|
.goods-item {
|
|
padding: 10rpx 30rpx;
|
|
line-height: 1.5;
|
|
text-align: left;
|
|
&.select {
|
|
background-color: $uni-color-primary;
|
|
color: #fff;
|
|
}
|
|
}
|
|
.goods-item-empty {
|
|
padding: 10rpx 30rpx;
|
|
line-height: 1.5;
|
|
text-align: center;
|
|
}
|
|
}
|
|
}
|
|
</style>
|