Files
orico-wms-pda/pages/otherUnderwear/inStockDown.vue
2025-05-09 17:15:16 +08:00

651 lines
27 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- 入库回退下架 -->
<template>
<view class="shpage ckhtsxjpage">
<!-- 标题栏 -->
<view class="mianheade mianheade2" @click="goback()">
<image src="../../static/img/n_baiback.png" class="blacBackico"></image>
<text class="pagetitle">入库回退下架</text>
</view>
<!-- 固定内容-->
<view class="sh_gdInfo">
<view class="item itembg2">
<view class="it">
<text class="t1">仓库:</text>
<text class="t2">{{ warehouseName }}</text>
</view>
</view>
<view class="item" :class="{ itembg2: xlhstrList.length > 0 }" :style="{ 'pointer-events': xlhstrList.length > 0 ? 'none' : '' }">
<view class="it itsp">
<text class="t1">
<text class="redtag">*</text>
箱号:
</text>
<input
v-model.trim="xhNo"
class="inpt1"
type="text"
@focus="inputfocus($event, 'box')"
@blur="inputblur($event, '')"
@confirm="inputConfirm($event, 'box')"
:focus="focusInput == 'box'"
/>
<image src="../../static/img/smico.png" class="searchico" @click="scanImg('box')"></image>
</view>
</view>
<view class="item" :class="{ itembg2: !xhNo }" :style="{ 'pointer-events': !xhNo ? 'none' : '' }">
<view class="it itsp">
<text class="t1">序列号:</text>
<input
v-model.trim="xlhVal"
class="inpt1"
type="text"
@focus="inputfocus($event, 'xlh')"
@blur="inputblur($event, '')"
@confirm="inputConfirm($event, 'xlh')"
:focus="focusInput == 'xlh'"
/>
<image src="../../static/img/smico.png" class="searchico" @click="scanImg('xlh')"></image>
</view>
</view>
<view class="item itembg2">
<view class="it itsp">
<text class="t1">
<text class="redtag">*</text>
下架数量:
</text>
<input v-model.trim="xjNum" class="inpt1" type="number" :disabled="true" />
</view>
</view>
<view class="item item2">
<view class="it2 it50">
<text class="t1">{{ yxjTotalNum }}</text>
<text class="t2">已下架总数量</text>
</view>
<view class="it2 it50" @click="xhmodelOpen">
<text class="t1 rednum">{{ boxstrList.length }}</text>
<text class="t2">已扫描箱数</text>
</view>
</view>
</view>
<!-- 列表内容-->
<view class="shlb cgsjrklb f_cgsjrklb" :style="{ 'margin-top': heights.top + 'px', height: heights.body + 'px' }">
<view class="item" v-for="(item, index) in dataList" :key="item.boxBillNo">
<view class="it" style="border: none">
<text class="txt titstr">{{ item.boxBillNo }}</text>
<view class="cssj_it ckhtit" v-for="(it, indexs) in item.details" :key="it.specifications">
<view class="tlinb">
<text class="txt ntxtcolor">{{ it.specifications }}</text>
<view class="nwemxflex">
<text class="txt">{{ it.materialNumber }}</text>
<view class="fgline"></view>
<text class="txt">数量 {{ it.wuToatal }}</text>
</view>
</view>
<view class="txtNum nslbzflex">
<view class="n-sl-bz">
<view class="tinput">
<text class="ntxtcolor nbtxt">下架数量</text>
<u-input
v-model="it.qty"
border="surround"
clearable
class="inpt"
type="number"
:disabled="it.itxlhlist.length > 0 || dqXH !== item.boxBillNo"
@focus="inputfocus($event, 'xjNum', item.boxBillNo)"
@blur="inputblur($event, '')"
@confirm="inputConfirm($event, 'xjNum')"
@input="xjNumInput($event, 'xjNum', index, item.boxBillNo)"
></u-input>
</view>
<view class="tinput" @click="openRemarTk(it.remark,index,indexs)">
<text class="ntxtcolor nbtxt">备注</text>
<u-input v-model="it.remark" border="surround" clearable class="inpt" type="text" style="pointer-events: none"></u-input>
</view>
</view>
</view>
</view>
</view>
</view>
</view>
<!-- 已上架箱号-->
<u-modal :show="xhlistshow" title="已扫箱信息" @confirm="xhlistshow = false">
<view style="display: flex; flex-direction: column; overflow-y: auto; max-height: 60vh; overflow-y: auto">
<view v-for="(item, index) in boxstrList">{{ item }}</view>
</view>
</u-modal>
<!-- 底部按钮固定-->
<view class="footbts">
<view class="bt bt1" @click="qktkshow = true">清空下架数量</view>
<view class="bt bt2" @click="wcNxetFn">完成/下一单</view>
</view>
<!--清空二次确认弹框-->
<u-modal :show="qktkshow" :title="qktkTitle" :content="qktkContent" @confirm="qktkconfirm" :showCancelButton="true" @cancel="qktkshow = false"></u-modal>
<!--备注弹框-->
<u-modal :show="remarkshow" title="备注" @confirm="remarkconfirm" :showCancelButton="true" @cancel="remarkshow = false">
<textarea v-model="dqremarkVal" auto-height :maxlength="100" class="remaktinpt" placeholder="请输入备注信息" />
</u-modal>
</view>
</template>
<script>
export default {
data() {
return {
heights: {
top: 0,
body: 0
},
xhlistshow: false,
focusInput: 'box', // 自动聚焦
focusTag: '', // 判斷聚焦
warehouseName: '', // 仓库名称
warehouseCode: '', // 仓库编码
cwNum: '', // 仓位的值
cwselectList: [], //仓位下拉集合
cwcode: '', // 仓位code
xhNo: '', // 箱号的值
boxstrList: [], // 缓存的箱号信息(多个)
xlhVal: '', // 序列号的值
xlhstrList: [], // 缓存的序列號信息(多个)
xjNum: '', // 上架数量
yxjTotalNum: 0, // 已上架总数量
filterable: true,
dataList: [], // 明细列表数据
dqBoxInfo: {}, // 扫描当前箱的物料信息
qktkshow: false, //清空二次确认弹框
qktkTitle: '确定清空',
qktkContent: '是否清空当前页面已经扫描的箱号信息/序列号信息和统计数值?',
dqboxNO: '', //用来是否保存当前输入箱号的值
dqboxXlh: '', //用来是否保存当前输入xlh的值
erpOrgCode: '',
dqXH: '', // 点回车确认的当前箱号
APPdevice: uni.getStorageSync('devicePixelRatio'), // 缓存设备的像素比用来区分普通安卓normalAnroid还是pda
requestStatus: false, // 请求状态识别变量
remarkshow: false, // 当前备注弹框
dqremarkVal:'',//当前弹框显示备注内容
remarkidx:[],//记录当前编辑的是那个明细的备注
twoData:[],
scanTracker: {
lastScanTime: 0,
lastScanCode: null
} // 源头处理扫码段时间内重复扫
};
},
watch: {
xhNo(n) {
if (!n) {
this.dqboxNO = '';
}
},
xlhVal(n) {
if (!n) {
this.dqboxXlh = '';
}
}
},
onReady() {
this.heights = this.$util.setlistHeight('.sh_gdInfo', '.footbts');
},
onLoad() {
//获取广播扫码监听
this.$broadcastScan.init(this.getScancode);
this.$broadcastScan.start();
this.stopScanCode();
this.startScanCode();
},
onHide() {
this.$broadcastScan.stop();
this.stopScanCode();
},
onShow() {
this.$broadcastScan.start();
this.startScanCode();
},
onBackPress(e) {
this.$util.appgoBack(e, 'otherUnderwearIndex');
return true;
},
methods: {
// 开启广播
startScanCode() {
uni.$on('xwscan', (res) => {
const now = Date.now();
const timeSinceLastScan = now - this.scanTracker.lastScanTime;
// 如果扫描的箱码和上次相同并且时间间隔小于500ms则不作处理
if (res.code === this.scanTracker.lastScanCode && timeSinceLastScan < 4000) {
return;
} else {
// 更新扫描跟踪信息
this.scanTracker.lastScanTime = now;
this.scanTracker.lastScanCode = res.code;
this.getScancode(res.code);
}
});
},
// 关闭广播
stopScanCode() {
uni.$off('xwscan');
},
// 打开当前明细行备注弹框
openRemarTk(remarkStr,index,indexs){
this.remarkshow=true
this.dqremarkVal = remarkStr
this.remarkidx=[index,indexs]
},
// 确认修改弹框备注
remarkconfirm(){
this.dataList[this.remarkidx[0]].details[this.remarkidx[1]].remark=this.dqremarkVal
this.remarkshow=false
},
// 打开查看箱号
xhmodelOpen() {
if (this.boxstrList.length > 0) {
this.xhlistshow = true;
}
},
//明细上架数量输入实时监听
xjNumInput(val, type, index, dqXH) {
if (val) {
this.yxjTotalNum = this.$util.sumNestedObjectValues(this.dataList, 'details', 'qty');
this.dqXH = dqXH;
this.setxjNUM();
}
},
// 完成
wcNxetFn() {
if (this.boxstrList.length == 0 || !this.yxjTotalNum) {
uni.showToast({
title: '请先输入必填值',
icon: 'none',
duration: 1000
});
return;
}
let formdata = {
method: 2,
orgCode: this.erpOrgCode,
stockCode: this.warehouseCode,
subStockCode: this.cwcode,
details: []
};
console.log(this.dataList, '=this.dataList=');
this.dataList.forEach((it) => {
if (it.details && it.details.length > 0) {
it.details.forEach((k) => {
formdata.details.push({
boxId: k.boxId,
serialNumberBoxId: k.boxId,
materialNumber: k.materialNumber,
qty: k.qty,
subStockCode: k.subStockCode,
serialNumbers: k.itxlhlist,
remark: k.remark
});
});
}
});
console.log('入库回退下架1', this.dataList, formdata);
if (this.requestStatus) {
return false;
}
this.requestStatus = true;
this.$api.post('/BackRecord/OffShelf', formdata).then((res) => {
if (res.status == 200) {
uni.showToast({
title: '成功',
icon: 'none',
duration: 1000
});
setTimeout(() => {
uni.navigateTo({
url: '/pages/otherUnderwear/inStockDown'
});
}, 200);
// this.$router.go(0)
}
});
setTimeout(() => {
this.requestStatus = false;
}, 1500);
},
// 普通安卓设备碘酒扫描图标扫描
scanImg(type) {
if (this.APPdevice == 'normalAnroid') {
this.$util.doScanQrCode().then((res) => {
this.focusInput = type;
this.focusTag = type;
this.getScancode(res.result);
});
}
},
// 获取扫描的值
getScancode(code) {
console.log('获取扫描的值', this.focusTag, code);
if (this.focusTag == 'box') {
// 有些PDA会自带换行符trim函数处理下
this.xhNo = '';
this.xhNo = code.trim();
this.getboxinfo();
}
// 序列号
if (this.focusTag == 'xlh') {
this.xlhVal = '';
this.xlhVal = code.trim();
this.getXlhInfo();
//根据序列号去更新对应的明细规格型号的上架数量的值 扫描一个数量加一,重复扫描要提示
}
},
// 清空二次确认
qktkconfirm() {
this.boxstrList = [];
this.twoData=[]
this.xlhstrList = [];
this.dataList = [];
this.xhNo = '';
this.xlhVal = '';
this.yxjTotalNum = 0;
this.xjNum = null;
this.qktkshow = false;
this.warehouseCode = '';
this.warehouseName = '';
},
// 輸入失去焦點
inputblur(val, type) {},
// 输入聚焦
inputfocus(val, type, dqXH) {
this.focusTag = type;
if (type == 'xjNum') {
this.dqXH = dqXH;
// 统计当前箱子的下架数量总和
this.setxjNUM();
}
},
//当前限制 下架数量重新统计
setxjNUM() {
this.xjNum = 0;
this.dataList.forEach((it) => {
if (it.details && it.details.length > 0 && it.boxBillNo == this.dqXH) {
it.details.forEach((k) => {
this.xjNum = this.xjNum + parseInt(k.qty ? k.qty : 0);
});
}
});
},
// 区分不同的扫描数据、输入数据做处理显示 box
setSMstr(str) {
let lth = str.length - this.dqboxNO.length;
if (lth > 1) {
// 扫描的值
this.xhNo = str.substring(this.dqboxNO.length);
} else {
this.dqboxNO = str;
this.xhNo = str;
}
},
// 区分不同的扫描数据、输入数据做处理显示 xlh
setSMxlhstr(str) {
console.log('扫描的的值', str, this.xlhVal, this.dqboxXlh);
let lth = str.length - this.dqboxXlh.length;
if (lth > 1) {
// 扫描的值
this.xlhVal = str.substring(this.dqboxXlh.length);
console.log('处理扫描的的值', str, this.xlhVal, this.dqboxXlh);
} else {
this.dqboxXlh = str;
this.xlhVal = str;
}
},
// 输入确认
inputConfirm(val, type) {
if (val) {
if (this.focusTag == 'box') {
this.setSMstr(val.target.value);
this.getboxinfo();
}
if (this.focusTag == 'xlh') {
this.setSMxlhstr(val.target.value);
this.getXlhInfo();
}
}
},
// 扫描框数据重置,光标聚焦
setSMinputbox() {
this.focusInput = '';
setTimeout(() => {
this.xhNo = '';
this.dqboxNO = '';
this.focusInput = 'box';
this.xlhVal = '';
this.dqboxXlh = '';
this.xjNum = '';
}, 200);
},
// 根据箱号获取箱信息
getboxinfo() {
if (!this.xhNo) {
this.setSMinputbox();
uni.showToast({
title: '请扫描或输入箱号',
icon: 'none',
duration: 1000
});
return;
}
if (this.boxstrList.includes(this.xhNo)) {
this.setSMinputbox();
uni.showToast({
title: '该箱号已扫描',
icon: 'none',
duration: 1000
});
return;
}
this.focusInput = '';
this.$api
.get('/SysConfig/GetBoxSynthesis', {
boxBillNo: this.xhNo
})
.then((res) => {
if (res.status == 200) {
// 如果查询的箱号正常返回数据,就缓存改箱号信息
if (res.data) {
if (!res.data.stock) {
this.setSMinputbox();
uni.showToast({
title: '该箱号未上架',
icon: 'none',
duration: 1000
});
return;
}
// 缓存当前箱的物料信息
res.data.details.forEach((it) => {
it.boxId = res.data.id;
});
this.dqBoxInfo = JSON.parse(JSON.stringify(res.data));
if (res.data.details) {
res.data.details = res.data.details.filter((detail) => detail.qty > 0);
}
res.data.details.forEach((it) => {
it.wuToatal = JSON.parse(JSON.stringify(it.qty));
it.itxlhlist = [];
it.stockCode = res.data.stockCode;
it.subStockCode = res.data.subStockCode;
it.boxId = it.boxId;
it.remark = '';
});
this.dataList = [res.data].concat(this.dataList);
// 上架数量 当前扫箱的数量
this.xjNum = res.data.totalQty;
// 计算已上架总数量
this.yxjTotalNum = this.$util.sumNestedObjectValues(this.dataList, 'details', 'qty');
// 仓库
this.warehouseCode = res.data.stockCode;
this.warehouseName = res.data.stock;
this.cwcode = res.data.subStockCode;
this.erpOrgCode = res.data.orgCode;
//清空当前框数据 自动聚焦箱号
this.focusInput = 'box';
this.dqboxNO = res.data.boxBillNo;
this.xhNo = res.data.boxBillNo;
// 回车当前箱号
this.dqXH = res.data.boxBillNo;
// 缓存箱号
this.boxstrList.push(this.xhNo);
uni.showToast({
title: '获取成功',
icon: 'none',
duration: 1000
});
}
} else {
this.setSMinputbox();
}
});
},
// 扫描框数据重置,光标聚焦
setSMinputxlh() {
this.focusInput = '';
setTimeout(() => {
this.xlhVal = '';
this.dqboxXlh = '';
this.focusInput = 'xlh';
this.xjNum = null;
}, 200);
},
// 根据序列号获取箱信息
getXlhInfo() {
if (!this.xlhVal) {
this.setSMinputxlh();
uni.showToast({
title: '该扫描或输入序列号',
icon: 'none',
duration: 1000
});
return;
}
if (this.xlhstrList.includes(this.xlhVal) || this.twoData.includes(this.xlhVal)) {
this.setSMinputxlh();
uni.showToast({
title: '该序列号已扫描',
icon: 'none',
duration: 1000
});
return;
}
this.focusInput = '';
//根据序列号或规格型号搜索物料信息
this.$api
.get('/SysConfig/GetMaterial', {
serialNumber: this.xlhVal,
IsOps: true,
serialStatus: 3
})
.then((res) => {
if (res.status == 200) {
if (!res.data.serialNumber) {
this.setSMinputxlh();
uni.showToast({
title: '扫描的不是序列号',
icon: 'none',
duration: 1000
});
return;
}
if (!res.data.isBoxInventory) {
this.setSMinputxlh();
uni.showToast({
title: '序列号未上架入库',
icon: 'none',
duration: 1000
});
return;
}
if (res.data.isOldOps && res.data.boxId !== 0 && res.data.boxId !== this.dqBoxInfo.id) {
this.setSMinputxlh();
uni.showToast({
title: '该序列号不存在所扫箱内',
icon: 'none',
duration: 1000
});
return;
}
// 提取列表的物料id
let materialCodelist = [];
materialCodelist = this.dqBoxInfo.details.flatMap((obj) => obj.serialNumbers);
let czoldxlhtag = this.dqBoxInfo.details.findIndex((it) => it.materialNumber == res.data.materialNumber);
if (czoldxlhtag == -1 && res.data.isOldOps) {
this.setSMinputxlh();
uni.showToast({
title: '该序列号对应物料无箱库存',
icon: 'none',
duration: 1000
});
return;
}
// 判断当前扫描的序列号是否存在当前箱,不存在就提示
if (materialCodelist.includes(res.data.serialNumber) || (czoldxlhtag !== -1 && res.data.isOldOps)) {
this.xjNum = 1;
// 找到这条物料对应的明细的规格物料上架数量加一,切不可在编辑
let indexobj = null;
indexobj = this.$util.findMaterialCodePosition(this.dataList, res.data.materialNumber);
if (indexobj || indexobj == 0) {
// 如果是第一次扫,就清空上架数量,切锁住输入框不能在输入
if (this.dataList[indexobj.objectIndex].details[indexobj.detailIndex].itxlhlist.length == 0) {
this.dataList[indexobj.objectIndex].details[indexobj.detailIndex].qty = 0;
}
++this.dataList[indexobj.objectIndex].details[indexobj.detailIndex].qty;
this.dataList[indexobj.objectIndex].details[indexobj.detailIndex].itxlhlist.push(res.data.serialNumber);
}
// 计算已上架总数量
this.yxjTotalNum = this.$util.sumNestedObjectValues(this.dataList, 'details', 'qty');
// 设置光标和输入框的值
this.focusInput = 'xlh';
this.dqboxXlh = res.data.serialNumber;
this.xlhVal = res.data.serialNumber;
// 缓存序列号
this.xlhstrList.push(res.data.serialNumber);
//缓存2件装序列号
if(res.data.isTwo==2) {
this.twoData.push(res.data.twoSerialNumber)
}
uni.showToast({
title: '获取成功',
icon: 'none',
duration: 1000
});
} else {
this.setSMinputxlh();
uni.showToast({
title: '该序列号不存在所扫箱内',
icon: 'none',
duration: 1000
});
}
} else {
this.setSMinputxlh();
}
});
},
goback() {
uni.navigateTo({
url: '/pages/otherUnderwear/index'
});
}
}
};
</script>
<style lang="scss">
@import '@/static/public.scss';
.mianheade2 {
.pagetitle {
margin-left: 26%;
}
}
</style>