admin/addon/cashier/source/os/pages/stock/add_check.vue

451 lines
11 KiB
Vue

<template>
<base-page>
<view class="content-wrap" @click="goodsShow = false">
<view class="title">添加盘点单</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: 1;">单位</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: 1;"></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 }}</view>
<view class="table-td" style="flex: 1;">{{ item.stock }}</view>
<view class="table-td" style="flex: 1;">{{ item.unit }}</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.stock || 0 }}</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.upNum }}种,盘亏:{{ totalData.downNum }}种,持平:{{ totalData.sameNum }}种
</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,
upNum: 0,
downNum: 0,
sameNum: 0
},
isSubmit: false,
scanCode: {
code: '',
lastTime: 0
}
};
},
onLoad(option) {
uni.hideTabBar();
},
onHide() {
// #ifdef APP-PLUS
plus.key.removeEventListener('keyup', this.listenerScancode, true);
// #endif
// #ifdef H5
window.removeEventListener('keypress', this.listenerScancode, true);
// #endif
},
onShow() {
this.getGoodsData();
// #ifdef APP-PLUS
plus.key.addEventListener('keyup', this.listenerScancode, true);
// #endif
// #ifdef H5
window.addEventListener('keypress', this.listenerScancode, true);
// #endif
},
watch: {
goodsIdArr(data){
this.calcTotalData();
}
},
methods: {
getGoodsData() {
this.$api.sendRequest({
url: '/stock/storeapi/manage/getskulist',
data:{search: this.name},
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();
},
stockOutFn(){
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
});
throw new Error('end');
}
var obj = {};
obj.goods_num = item.goods_num;
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/check/add',
data:{stock_json: 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/check');
},
calcTotalData(){
this.totalData.kindsNum = 0;
this.totalData.upNum = 0;
this.totalData.downNum = 0;
this.totalData.sameNum = 0;
this.goodsList.forEach((item,index)=>{
if(this.goodsIdArr.includes(item.sku_id) && item.goods_num){
if((item.goods_num - item.stock) == 0){
this.totalData.sameNum++;
}else if((item.goods_num - item.stock) > 0){
this.totalData.upNum++;
}else if((item.goods_num - item.stock) < 0){
this.totalData.downNum++;
}
}
})
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">
.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;
}
.table-wrap {
position: relative;
margin-top: 40rpx;
border: 2rpx 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 0.15rem 0.2rem;
align-items: center;
.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>