<template> <view class="tally-index"> <view class="fix-box"> <view class="column-box row bothSide verCenter"> <view class="input-box row verCenter"> <input class="uni-input" @input="handleInput($event,1)" :focus="is_focus_1" placeholder="当前箱号" placeholder-style="color:#000;font-weight: bold;" v-model="box_sn" /> </view> <view class="action-bar row verCenter"> <text class="iconfont icon-jinggao2" @click="clearInput(1)" v-if="box_sn"></text> <template v-if="box_sn && wsty_id"> <view class="btn1 row rowCenter verCenter" @click="print()" style="margin-right: 8rpx;">打印箱号</view> <view class="btn row rowCenter verCenter" @click="getBoxSn()">取箱号</view> </template> <template v-else> <view class="btn row rowCenter verCenter" @click="getBoxSn()">取箱号</view> </template> </view> </view> <view class="column-box row bothSide verCenter"> <view class="input-box row verCenter"> <input class="uni-input" :focus="is_focus_2" :disabled="form.length > 0 && step == 1 && erp_order_sn !=''" :class="{ 'disabled': form.length > 0 && step == 1 && erp_order_sn !='' }" placeholder="输入或扫描入仓号" placeholder-style="color:#000;font-weight: bold;" v-model="erp_order_sn" /> </view> <view class="action-bar row verCenter"> <text class="iconfont icon-jinggao2" @click="clearInput(2)" v-if="erp_order_sn"></text> <template v-if="form.length > 0 && step == 1 && erp_order_sn != ''"> <view class="btn1 row rowCenter verCenter" style="margin-right: 8rpx;" @click="cancelRelease()">取消释放</view> <navigator class="btn row rowCenter verCenter" :url="'/pages/tally/closeBox?box_sn='+box_sn+'&wsty_id='+wsty_id" hover-class="none">关单封箱</navigator> </template> <template v-else> <view class="btn row rowCenter verCenter" @click="lockTally()">锁定理货</view> </template> </view> </view> <view class="column-box row verCenter" style="margin-bottom: 0;"> <view class="select-box"> <picker @change="bindPickerChange" :value="index" :range="item"> <view class="wrap row verCenter bothSide"> <view class="uni-input">{{ item[index] }}</view> <text class="iconfont icon-sanjiaoxing1 uni-arrow"></text> </view> </picker> </view> <view class="input-box row verCenter" style="width: calc(100% - 129rpx);"> <!-- 其他 --> <template v-if="index == 0"> <input class="uni-input" maxlength="-1" :focus="is_focus_3" placeholder="输入或扫描" placeholder-style="color:#000;font-weight: bold;" style="width: 100%;" v-model="goods_type" @input="handleInput($event,2)" /> </template> <!-- digikey等供应商--> <template v-else> <input class="uni-input" maxlength="-1" :focus="is_focus_3" :confirm-type="'none'" :hold-keyboard="false" placeholder="输入或扫描" placeholder-style="color:#000;font-weight: bold;" style="width: 100%;" v-model="keyword" @input="handleInput($event,2)" /> </template> <text class="iconfont icon-jinggao2" @click="clearInput(3)" v-if="goods_type || keyword"></text> </view> </view> <!-- 箱子基础信息 --> <view class="info row verCenter" v-if="tallyData && tallyData.detail"> <view class="grid-item row verCenter" style="width: 40%;"> <view class="t1">业务日期:</view> <view class="t2">{{tallyData.create_time_cn}}</view> </view> <view class="grid-item row verCenter" style="width: 30%;"> <view class="t1">总数:</view> <view class="t3">{{tallyData.goods_sn_num}}</view> </view> <view class="grid-item row verCenter" style="width: 30%;"> <view class="t1">未扫描:</view> <view class="t3">{{tallyData.no_scan_num}}</view> </view> <view class="grid-item row verCenter" style="width: 40%;"> <view class="t1">已扫描:</view> <view class="t3">{{tallyData.have_scan_num}}</view> </view> <view class="grid-item row verCenter" style="width: 60%;"> <view class="t1">业务:</view> <view class="t2">{{tallyData.salesname}}</view> </view> </view> </view> <!-- 列表 --> <view class="list" v-if="form.length > 0"> <scroll-view scroll-y="true" class="scroll-Y"> <view class="box" v-for="(item,index) in tallyData.detail" :key="index" :class="{disabled:item.tally_status == 3}"> <view class="title pb16 row verCenter"> <text class="t1">{{item.goods_type}}</text> <text class="t2 row rowCenter verCenter" v-if="item.is_goods_check">检</text> </view> <view class="pb16 row bothSide verCenter"> <view class="row" style="width: 50%;"> <text class="t3 w130">物料名称:</text> <text class="t4">{{item.goods_title}}</text> </view> <!-- 完全理货显示箱号 --> <view class="row" style="width: 50%;justify-content: flex-end;" v-if="item.tally_status == 3"> <text class="t4" style="text-align: right;color: #197adb;">{{item.box_sn}}</text> </view> </view> <view class="pb16 row"> <text class="t3 w130">品牌:</text> <text class="t4">{{item.brand}}</text> </view> <!-- 总数量 --> <template v-if="item.tally_status == 3"> <view class="pb16 row"> <text class="t3 w130">总数量:</text> <text class="t4">{{item.order_numbers}}</text> </view> </template> <!-- 待收数量 && 总数量 --> <template v-else> <view class="pb16 row verCenter"> <view class="row" style="width: 50%;"> <text class="t3 w130">待收数量:</text> <text class="t4">{{item.wait_tally_num}}</text> </view> <view class="row" style="width: 50%;"> <text class="t3 w130">总数量:</text> <text class="t4">{{item.order_numbers}}</text> </view> </view> </template> <view class="pb16 row"> <text class="t3 w130">订单备注:</text> <text class="desc">{{item.order_remark}}</text> </view> <view class="pb16 row verCenter"> <!-- 已入库数量 --> <template v-if="item.tally_status == 3"> <text class="t3 w130">已入库数量:</text> </template> <!-- 入库数量 --> <template v-else> <text class="t3 w130">入库数量:</text> </template> <view class="input-text"> <input class="uni-input" :disabled="item.tally_status == 3" type="number" inputmode="numeric" placeholder="输入" placeholder-style="color:#000;font-weight: bold;" v-model="form[index].tally_num" /> </view> </view> <view class="pb16 row verCenter"> <text class="t3 w130">原产地:</text> <view class="input-text"> <!-- 产地不可编辑 --> <template v-if="item.tally_status == 3"> <input class="uni-input" placeholder="选择产地" placeholder-style="color:#000;font-weight: bold;" disabled="" v-model="form[index].origin" /> </template> <!-- 产地可编辑 --> <template v-else> <input class="uni-input" placeholder="选择产地" placeholder-style="color:#000;font-weight: bold;" disabled="" @click="open(index)" v-model="form[index].origin" /> </template> </view> </view> <view class="pb16 row verCenter"> <text class="t3 w130">净重:</text> <view class="input-text"> <input class="uni-input" :disabled="item.tally_status == 3" type="number" inputmode="decimal" placeholder="输入" placeholder-style="color:#000;font-weight: bold;" v-model="form[index].net_weight" /> </view> </view> <view class="pb16 row verCenter"> <text class="t3 w130">理货备注:</text> <view class="input-text"> <template v-if="item.tally_status == 3"> <input class="uni-input" :disabled="item.tally_status == 3" type="text" placeholder="输入" placeholder-style="color:#000;font-weight: bold;" v-model="form[index].remark" maxlength="100" @click="viewChange(form[index].remark)" /> </template> <template v-else> <input class="uni-input" :disabled="item.tally_status == 3" type="text" placeholder="输入" placeholder-style="color:#000;font-weight: bold;" v-model="form[index].remark" maxlength="100" /> </template> </view> </view> <view class="row bothSide verCenter"> <view class="upload-list row verCenter"> <template v-if="image_list.length > 0"> <view class="pic-box" v-for="(v, i) in image_list[index]" :key="i"> <image :src="v" mode="aspectFill" lazy-load="true" @click="previewChange(image_list[index], i)"></image> <template v-if="item.tally_status != 3"> <view class="delete row rowCenter verCenter" @click="deletePic(index,i)"><text class="iconfont icon-shanchu"></text></view> </template> </view> </template> <template v-if="item.tally_status == 3"> <view class="default row rowCenter verCenter" v-if="image_list[index].length < 4"><text class="iconfont icon-xingzhuangjiehe"></text></view> </template> <template v-else> <view class="default row rowCenter verCenter" @click="chooseImageChange(index)" v-if="image_list[index].length < 4"><text class="iconfont icon-xingzhuangjiehe"></text></view> </template> </view> <!-- 取消理货 --> <template v-if="item.tally_status == 3"> <view class="btn row rowCenter verCenter disabled" @click="cancelTallyDetail(index)">取消理货</view> </template> <!-- 提交 --> <template v-else> <view class="btn row rowCenter verCenter" @click="submitTallyDetail(index)">提 交</view> </template> </view> </view> </scroll-view> </view> <!-- 无数据 --> <view class="no-data column verCenter rowCenter" v-if="form.length == 0 && tallyData.create_time_cn"> <text class="iconfont icon-jinggao2"></text> <text class="text">查找不到相关信息</text> <text class="p">1、请输入正确的入仓号和型号</text> </view> <!-- 操作栏 --> <view class="btn-list row verCenter bothSide" v-if="!tallyData.detail"> <navigator url="/pages/tally/fixBox" class="box row rowCenter verCenter" hover-class="none">合 箱</navigator> <navigator url="/pages/tally/unboxing" class="box row rowCenter verCenter" hover-class="none">重新开箱</navigator> <navigator url="/pages/tally/abnormalTally" class="box row rowCenter verCenter" hover-class="none">理货异常处理</navigator> </view> <!-- 选择国家 --> <uni-popup ref="popup" background-color="#F1F4F6"> <view class="popup-content"> <view class="search-baar row verCenter"> <text class="iconfont icon-a-riqi11"></text> <input type="text" class="uni-input" placeholder="请输入国家或地区名称(支持中英文)" placeholder-style="font-size:26rpx;color:#6E767A;" @input="handleInput($event,3)" v-model="origin" style="width: 100%;" /> </view> <view class="data-list"> <template v-if="origin_list.length > 0"> <view class="box row bothSide verCenter" v-for="(item, index) in origin_list" :key="index" :class="{ curr: filter_status[index] }" @click="filterChange(index)"> <text class="text">{{ item.name }}</text> <view class="check-ico"></view> </view> </template> <template v-else> <view class="box row bothSide verCenter"> <text class="text">暂无数据</text> </view> </template> </view> <view class="pop-btn row rowCenter verCenter" @click="confirmChange">确 认</view> </view> </uni-popup> <!-- 关单封箱弹窗 --> <uni-popup ref="inputDialog" type="dialog" :mask-click="true" @maskClick="maskClick"> <uni-popup-dialog ref="inputClose" mode="input" :title="title" v-model="gross_weight" value="" confirmText="新箱子" cancelText="不需要换箱" placeholder="请输入毛重" @close="dialogInputClose" @confirm="dialogInputConfirm" :before-close="true"></uni-popup-dialog> </uni-popup> <!-- 多个入仓号查询 --> <uni-popup ref="popupTally" background-color="#F1F4F6"> <view class="popup-content-sn"> <view class="tally-title"> <text class="t2">{{erp_order_sn}}</text> <text class="t1">有相似入仓号订单,请选择</text> </view> <view class="tally-list"> <scroll-view scroll-y="true" class="scroll-Y"> <view class="box row verCenter"> <view class="row verCenter" style="width: 90%;"> <text class="t3 row rowCenter verCenter" style="width: 40%;">入仓单号</text> <text class="t3 row rowCenter verCenter" style="width: 25%;">明细数</text> <text class="t3 row rowCenter verCenter" style="width: 35%;">入库状态</text> </view> </view> <view class="box row bothSide verCenter" v-for="(item,index) in tallyList" :key="index"> <view class="row verCenter" style="width: 90%;"> <text class="t1 row rowCenter verCenter" style="width: 45%;">{{item.erp_order_sn}}</text> <text class="t2 row rowCenter verCenter" style="width: 25%;">{{item.order_goods_num}}</text> <text class="t2 row rowCenter verCenter" style="width: 35%;">{{item.stock_in_status_cn}}</text> </view> <text class="select" @click="selecttErpOrderSn(index)">选中</text> </view> </scroll-view> </view> </view> </uni-popup> <!-- 理货提示 --> <uni-popup ref="popupTallyNum" background-color="#F1F4F6"> <view class="popup-content-tally-num"> <view class="input-box row verCenter"> <text class="label">订单待收数量:</text> <text class="tt">{{tally_info.wait_tally_num}}</text> </view> <view class="input-box row verCenter"> <text class="label">本次理货数量:</text> <text class="tt">{{tally_info.tally_num}}</text> </view> <view class="tip">若需再次提交,请确认数量</view> <view class="input-box row verCenter" style="margin-bottom: 40rpx;"> <text style="color: red;">*</text> <text class="label">理货数量:</text> <input class="uni-input" type="number" inputmode="numeric" placeholder="请输入数量" placeholder-style="color:#000;font-weight: bold;" v-model="tally_info.tally_num_temp" /> </view> <view class="btn row bothSide"> <view class="ok row rowCenter verCenter" @click="submitTallyDetailConfirm()">确认提交</view> <view class="canel row rowCenter verCenter" @click="tallyDetailConfirmClose()">返回</view> </view> </view> </uni-popup> <!-- 多个纸箱提示 --> <uni-popup ref="printScanList" background-color="#F1F4F6"> <view class="popup-content-tally-num"> <view class="text">{{box_sn}}有{{checkboxItems.length}}个子箱,选择你需要打印标签</view> <view class="row verCenter" style="font-size: 28rpx;"> <checkbox-group @change="checkboxAllChange"> <label> <checkbox value="cb" style="transform:scale(0.7)" color="#197adb" activeBackgroundColor="#197adb" activeBorderColor="#197adb" :checked="allChecked" />全选 </label> </checkbox-group> </view> <view class="uni-list" style="padding-left: 50rpx;"> <scroll-view scroll-y="true" style="max-height:400rpx"> <checkbox-group @change="checkboxChange"> <label class="row verCenter" v-for="item in checkboxItems" :key="item.value"> <view> <checkbox :value="item.value" :checked="item.checked" style="transform:scale(0.7)" color="#197adb" /> </view> <view>{{item.name}}</view> </label> </checkbox-group> </scroll-view> </view> <view class="btn row bothSide" style="margin-top: 24rpx;"> <view class="ok row rowCenter verCenter" @click="printMultiple()">打印</view> <view class="canel row rowCenter verCenter" @click="close()">返回</view> </view> </view> </uni-popup> </view> </template> <script> import { API } from '@/util/api.js'; import debounce from 'lodash/debounce'; import { createArray } from '@/util/util.js'; export default { data() { return { email: uni.getStorageSync('email') || '', //操作人邮箱 is_focus_1: true, //获取焦点动态化 is_focus_2: false, is_focus_3: false, title: '', step: 0, keyword: '', curr: -1, //当前打开的是哪个产地 fixBoxStyle: '', noexebshowFalg: true, //控制是否会触发生命周期 index: uni.getStorageSync('goodIndex') || 0, item: ['型号', 'DigiKey', 'Rochester', 'TME', 'Chip1stop'], box_sn: '', //箱号信息 wsty_id: '', //箱子id erp_order_sn: '', //入仓号 goods_type: '', //商品型号 tallyData: {}, //理货信息 image_list: [], //图片列表 filter_status: [], //控制状态 origin_list: [], //产地 origin: '', //搜索国家携带的参数 form: [], tallyList: [], isRequestSent: false, isStopRequest: false, gross_weight: '', tally_info: { tally_num_temp: '' }, net_weight_total: 0, //净重合计 allChecked: false, checkboxItems: [] }; }, watch: { image_list: { handler(arr) { arr.forEach((subArr, index) => { if (subArr.length > 0) { // 将数组元素用逗号连接成字符串,并赋值给对应的 form 中的 goods_check_pic 字段 this.form[index].goods_check_pic = subArr.join(','); } else { this.form[index].goods_check_pic = ''; } }); }, deep: true // 深度监听 } }, onNavigationBarButtonTap(e) { if (e.index == 0) { uni.navigateTo({ url: '/pages/tally/record' }); } }, methods: { /** * 点击遮罩层触发 */ maskClick() { this.$refs.inputDialog.close(); }, /** * 找出false对应的下标 * @param {Object} arr * @param {Object} target */ findIndex(arr, target) { const result = []; arr.map((item, index) => { if (item === target) { result.push(index); } }); return result; }, bindPickerChange: function(e) { console.log('picker发送选择改变,携带值为', e.detail.value); this.index = e.detail.value; uni.setStorageSync('goodIndex', this.index); this.clearInput(3); }, /** *筛选过滤出选中的元素 */ filterChange(index) { this.$set(this.filter_status, index, (this.filter_status[index] = !this.filter_status[index])); let filter_arr = this.findIndex(this.filter_status, true); let name = filter_arr.map(i => this.origin_list[i].value); this.form[this.curr].origin = name[0]; this.$forceUpdate(); this.$refs.popup.close(); }, /** * 选择国家确认-关闭弹窗 */ confirmChange() { this.$refs.popup.close(); }, /** * @param {Object} event 输入框监听 * @param {Object} type 1箱号监听 2型号监听 3输入国家监听 */ handleInput: debounce(function(event, type) { var value = event.target.value; if (type == 1) { if (value) { if (value.indexOf('-') !== -1) { // 判断字符串中是否存在 '-' value = value.split('-')[0]; // 存在则截取 '-' 前的部分 } this.getBoxSn(value); } } else if (type == 2) { if (value) { uni.hideKeyboard(); this.identifyQrCodeNumAndSn(); } else { this.goods_type = ''; this.keyword = ''; this.getTallyData(); } } else if (type == 3) { this.origin_list = []; //数组清空 this.getOriginCn(); } }, 500), /** * 打开弹窗 * @param {Object} index */ open(index) { this.curr = index; this.filter_status.fill(false); this.$refs.popup.open('bottom'); }, /** * 选择图片 */ chooseImageChange(key) { this.noexebshowFalg = false; // 使用 chooseImage选择图片 // #ifdef MP-WEIXIN uni.chooseMedia({ count: 4, mediaType: ['image'], sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: chooseImageRes => { console.log('选择图片成功:', chooseImageRes); // 显示loading uni.showLoading({ title: '上传中...' }); // 获取选择的图片路径数组 const imagePaths = chooseImageRes.tempFiles; // 判断选择的图片数量是否超过最大限制数量 let maxNum = Number(imagePaths.length) + Number(this.image_list[key].length); //当前上传的+已经上传的 if (maxNum > 4) { uni.hideLoading(); uni.showToast({ title: '图片不超过4张', icon: 'none' }); return false; } // 遍历图片路径数组,对每张图片进行压缩 imagePaths.forEach((_imagePath, index) => { // 使用compressImage 压缩图片 uni.compressImage({ src: imagePaths[index].tempFilePath, quality: 60, //压缩质量,范围0~100,数值越小,质量越低,压缩率越高 success: compressedRes => { console.log('压缩图片成功:', compressedRes); // 获取压缩后的图片路径 const compressedImagePath = compressedRes.tempFilePath; // 在这里处理压缩后的图片,上传到服务器 uni.uploadFile({ url: API.uploadImageHk + '?sys_type=4', filePath: compressedImagePath, name: 'file', timeout: 10000, header: { 'Content-Type': 'multipart/form-data' }, success: uploadFileRes => { console.log('服务器上传图片成功:', uploadFileRes); uni.hideLoading(); let data = JSON.parse(uploadFileRes.data); if (data.code === 0) { this.image_list[key].push(data.data.oss_image_url); this.$forceUpdate(); } else { uni.showToast({ title: data.msg, icon: 'none' }); } }, fail: () => { uni.hideLoading(); uni.showToast({ title: '上传图片失败', icon: 'none' }); } }); }, fail: err => { console.log('压缩图片失败:', err); } }); }); } }); // #endif // #ifdef APP-PLUS uni.chooseImage({ count: 4, sizeType: ['original', 'compressed'], sourceType: ['album', 'camera'], success: chooseImageRes => { console.log('选择图片成功:', chooseImageRes); // 显示loading uni.showLoading({ title: '上传中...' }); // 获取选择的图片路径数组 const imagePaths = chooseImageRes.tempFilePaths; // 判断选择的图片数量是否超过最大限制数量 let maxNum = Number(imagePaths.length) + Number(this.image_list[key].length); //当前上传的+已经上传的 if (maxNum > 4) { uni.hideLoading(); uni.showToast({ title: '图片不超过4张', icon: 'none' }); return false; } // 遍历图片路径数组,对每张图片进行压缩 imagePaths.forEach((imagePath) => { // 使用compressImage 压缩图片 uni.compressImage({ src: imagePath, quality: 60, //压缩质量,范围0~100,数值越小,质量越低,压缩率越高 success: compressedRes => { console.log('压缩图片成功:', compressedRes); // 获取压缩后的图片路径 const compressedImagePath = compressedRes.tempFilePath; // 在这里处理压缩后的图片,上传到服务器 uni.uploadFile({ url: API.uploadImageHk + '?sys_type=4', filePath: compressedImagePath, name: 'file', timeout: 10000, header: { 'Content-Type': 'multipart/form-data' }, success: uploadFileRes => { console.log('服务器上传图片成功:', uploadFileRes); uni.hideLoading(); let data = JSON.parse(uploadFileRes.data); if (data.code === 0) { this.image_list[key].push(data.data.oss_image_url); this.$forceUpdate(); } else { uni.showToast({ title: data.msg, icon: 'none' }); } }, fail: () => { uni.hideLoading(); uni.showToast({ title: '上传图片失败', icon: 'none' }); } }); }, fail: err => { console.log('压缩图片失败:', err); } }); }); } }); // #endif }, /** * 预览图片 * @param {Object} img * @param {Object} index */ previewChange(img, index) { this.noexebshowFalg = false; uni.previewImage({ current: index, urls: img }); }, /** * 删除图片 * @param {Object} index */ deletePic(index, i) { this.image_list[index].splice(i, 1); this.$forceUpdate(); }, /** * 识别 */ identifyQrCodeNumAndSn() { if (!this.box_sn) { uni.showModal({ title: '', content: '请先取箱号!并将打印的箱号贴于外箱上', showCancel: false }); return false; } if (this.index == 0) { //区分其他 this.keyword = ''; this.getTallyData(); } else { let codeTypeByIndex = { 1: 'DigiKey', 2: 'Rochester', 3: 'TME', 4: 'Chip1stop', 5: 'Mouser' }; let codeType = codeTypeByIndex[this.index] || ''; let device = uni.getDeviceInfo(); //匹配到内容才开始调接口 if (!this.isRequestSent) { this.isRequestSent = true; // 设置标志,防止重复发送请求 console.log(this.keyword) this.request(API.scanQrCode, 'POST', { data: this.keyword, type: codeType, device: device.deviceModel }, true).then(res => { this.isRequestSent = false; // 请求完成后重置标志 if (res.err_code === 0) { //如果后台搜索到型号则替换输入框的值 let model = res.data.model || res.data.model2; if (model) { this.keyword = model; //兼容TME this.goods_type = model; //赋值检索出来的型号 } this.getTallyData((json) => { //解析出一个物料的情况下才执行此操作 if (json.length == 1) { //解析处理的产地 if (res.data.origin) { var originIndex = this.origin_list.findIndex(item => item.name.split('|').includes(res.data.origin)); //通过英文去匹配出对应的中文国家 //排除已理货的数据 if (this.form[0].tally_status != 3) { this.$set(this.form[0], 'origin', this.origin_list[originIndex].value); } } //解析处理的数量 if (res.data.qty) { this.$set(this.form[0], 'tally_num', res.data.qty); //排除已理货的数据 if (this.form[0].tally_status != 3) { this.$set(this.form[0], 'tally_num', res.data.qty); } } } }); } else { uni.showToast({ title: res.msg, icon: 'none' }); } }); } } }, /** * 获取箱号 * @param {Object} box_sn 传值就表示验证入仓号是否正确 */ getBoxSn(box_sn) { this.request(API.getBoxSn, 'POST', { box_sn: box_sn }, true).then(res => { if (res.err_code === 0) { this.box_sn = res.data.box_sn; this.wsty_id = res.data.wsty_id; //取箱号才自动打印,输入箱号不需要自动打印 if (!box_sn) { this.print(); //取箱号成功则自动调用打印箱号 } if (this.form.length > 0) { // 筛选出 tally_status 等于 1 或 2 的数据 var filteredForm = this.form.filter(item => item.tally_status === 1 || item.tally_status === 2); // 替换 wsty_id this.form = filteredForm.map(item => { return { ...item, wsty_id: this.wsty_id, box_sn: this.box_sn }; }); } } else { uni.showModal({ title: '', content: res.err_msg, showCancel: false, success: (res) => { if (res.confirm) { this.box_sn = ''; this.wsty_id = ''; this.clearInput(1); } else if (res.cancel) { console.log('用户点击取消'); } } }); } }); }, /** * 获取产地 */ getOrigin() { this.request(API.getOrigin, 'GET', { origin: this.origin }, true).then(res => { if (res.err_code === 0) { this.origin_list = Object.values(res.data); this.filter_status = createArray(this.origin_list.length, false); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 获取产地升级版 */ getOriginCn() { this.request(API.getOriginCn, 'GET', { coo: this.origin }, true).then(res => { if (res.err_code === 0) { this.origin_list = res.data; this.filter_status = createArray(this.origin_list.length, false); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 锁定理货 */ lockTally() { if (!this.box_sn) { uni.showModal({ title: '', content: '请先取箱号!并将打印的箱号贴于外箱上', showCancel: false }); return false; } if (!this.erp_order_sn) { uni.showToast({ title: '请输入入仓号', icon: 'error' }); return false; } this.step = 1; this.getTallyList(); }, /** * 获取入仓号数量接口 */ getTallyList() { this.request(API.getTallyList, 'POST', { erp_order_sn: this.erp_order_sn }, true).then(res => { if (res.err_code === 0) { this.tallyList = res.data; if (res.data.length > 1) { this.$refs.popupTally.open('center'); } else { this.getTallyData(); } } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 选中入仓号 * @param {Object} index */ selecttErpOrderSn(index) { this.$refs.popupTally.close(); this.erp_order_sn = this.tallyList[index].erp_order_sn; this.getTallyData(); }, /** * 获取锁定理货信息 * */ getTallyData(callback) { this.request(API.getTallyData, 'POST', { erp_order_sn: this.erp_order_sn, goods_type: this.goods_type }, true).then(res => { if (res.err_code === 0) { this.tallyData = res.data; if (res.data.detail.length > 0) { this.getOriginCn(); //获取产地 // 使用 map 方法生成表单数组 this.form = res.data.detail.map((item) => ({ wait_tally_num: item.wait_tally_num, //待理货数量 tally_status: item.tally_status, //理货状态 tally_num: item.tally_num === 0 ? '' : item.tally_num, // 入库数量,0 时显示为空 origin: item.origin, // 原产地 net_weight: item.net_weight, // 净重 goods_check_pic: item.goods_check_pic, // 商检的必须上传图片 wstydl_id: item.wstydl_id, // 理货明细ID erp_order_sn: this.erp_order_sn, // 入仓号 box_sn: item.tally_status == 3 ? item.box_sn : this.box_sn, wsty_id: this.wsty_id, // 箱子id is_goods_check: item.is_goods_check, //是否商检 remark: item.remark //备注 })); this.image_list = res.data.detail.map(() => new Array()); //图片特殊处理 //还原理货的图片 res.data.detail.forEach((item, index) => { if (item.goods_check_pic) { this.image_list[index] = item.goods_check_pic.split(','); } }); typeof callback == 'function' && callback(this.form); } else { this.form = []; } } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 理货数量异常提示 */ tallyDetailConfirmClose() { this.$refs.popupTallyNum.close(); }, /** * 理货明细提交提醒确认 */ submitTallyDetailConfirm() { this.tally_info.tally_num = this.tally_info.tally_num_temp; //更新理货数量 if (!this.tally_info.tally_num) { uni.showToast({ title: '请填写理货数量', icon: 'none' }); return false; } this.request(API.submitTallyDetail, 'POST', this.tally_info, true).then(res => { if (res.err_code === 0) { uni.showToast({ title: '提交成功', icon: 'success', duration: 2000 }); setTimeout(() => { this.$refs.popupTallyNum.close(); //理货提交成功后自动清空型号查询框 this.clearInput(3); // 用户点击确定按钮后的操作 this.getTallyData(); }, 2000); } else if (res.err_code === 10000) { uni.showModal({ title: '', content: res.err_msg, showCancel: false, success: (res) => { if (res.confirm) { this.$refs.popupTallyNum.close(); //理货提交成功后自动清空型号查询框 this.clearInput(3); // 用户点击确定按钮后的操作 this.getTallyData(); } } }); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 理货明细提交 */ submitTallyDetail(index) { var tally_num = parseInt(this.form[index].tally_num); var netWeight = parseFloat(this.form[index].net_weight); if (!this.box_sn) { uni.showModal({ title: '', content: '请先取箱号!并将打印的箱号贴于外箱上', showCancel: false }); return false; } if (!tally_num) { uni.showToast({ title: '请填写入库数量', icon: 'error' }); return false; } if (!this.form[index].origin) { uni.showToast({ title: '请填写原产地', icon: 'error' }); return false; } if (!netWeight) { uni.showToast({ title: '请填写净重', icon: 'error' }); return false; } if (this.form[index].is_goods_check) { if (!this.form[index].goods_check_pic) { uni.showToast({ title: '该物料为商检,必须要上传图片', icon: 'none' }); return false; } } if (this.form[index].wait_tally_num != this.form[index].tally_num) { //当本次理货数量≠待收数量时,则弹出警示弹窗,需用户再次输入理货数量并再次点击【确认提交】时,才执行理货提交 this.tally_info = this.form[index] this.tally_info.tally_num_temp = ''; this.$refs.popupTallyNum.open('center'); return false; } this.request(API.submitTallyDetail, 'POST', this.form[index], true).then(res => { if (res.err_code === 0) { uni.showToast({ title: '提交成功', icon: 'success', duration: 2000 }); setTimeout(() => { //理货提交成功后自动清空型号查询框 this.getTallyData(); this.clearInput(3); }, 2000); } else if (res.err_code === 10000) { uni.showModal({ title: '', content: res.err_msg, showCancel: false, success: (res) => { if (res.confirm) { // 用户点击确定按钮后的操作 this.getTallyData(); this.clearInput(3); } } }); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 理货明细撤销(取消理货) */ cancelTallyDetail(index) { //根据理货明细获取箱数 this.request(API.getBoxNumByDetailId, 'POST', { wstydl_id: this.form[index].wstydl_id }, true).then(json => { if (json.err_code === 0) { if (json.data > 1) { let text = `${this.erp_order_sn}货物分部在${this.box_sn}的${json.data}个子箱,请确认是否全部取消`; uni.showModal({ title: '提示', content: text, success: (res) => { if (res.confirm) { this.request(API.cancelTallyDetail, 'POST', { wstydl_id: this.form[index].wstydl_id, wsty_id: this.form[index].wsty_id }, true).then(res => { if (res.err_code === 0) { this.getTallyData(); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); } else if (res.cancel) { console.log('用户点击取消'); } } }); } else { uni.showModal({ title: '提示', content: '确定取消该商品理货吗?', success: (res) => { if (res.confirm) { this.request(API.cancelTallyDetail, 'POST', { wstydl_id: this.form[index].wstydl_id, wsty_id: this.form[index].wsty_id }, true).then(res => { if (res.err_code === 0) { this.getTallyData(); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); } else if (res.cancel) { console.log('用户点击取消'); } } }); } } else { uni.showToast({ title: json.err_msg, icon: 'none' }); } }); }, /** * 取消释放 */ cancelRelease() { uni.showModal({ title: '提示', content: '确定取消释放该入仓号吗?', success: (res) => { if (res.confirm) { this.request(API.cancelRelease, 'POST', { wsty_id: this.wsty_id, erp_order_sn: this.erp_order_sn }, true).then(res => { if (res.err_code === 0) { this.erp_order_sn = ''; this.goods_type = ''; this.keyword = ''; this.tallyData = []; this.form = []; } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); } else if (res.cancel) { console.log('用户点击取消'); } } }); }, /** * 关单封箱 */ closeBox() { this.net_weight_total = this.form.reduce((total, item) => { // 如果 tally_status 等于 3 并且 box_sn 等于 box_sn 变量,则累加 net_weight 到总和中 if (item.tally_status === 3 && item.box_sn === this.box_sn) { total += parseFloat(item.net_weight); } return total; }, 0).toFixed(2); // 保留两位小数s; this.title = `入仓号${this.erp_order_sn}已经全部验货完毕是否更换新的箱子?\n\n 箱子:${this.box_sn} 总净重:${this.net_weight_total}`; this.$refs.inputDialog.open(); }, /** * 新箱子 */ dialogInputConfirm(val) { if (!val) { uni.showToast({ title: '请输入毛重', icon: 'error' }); return false; } // 判断 val 是否为数字 if (isNaN(val)) { uni.showToast({ title: '请输入合法数字', icon: 'error' }); return false; } if (Number(val) < Number(this.net_weight_total)) { uni.showToast({ title: '毛重不能小于总净重', icon: 'none' }); return false; } this.request(API.closeBox, 'POST', { wsty_id: this.wsty_id, gross_weight: val, box_sn: this.box_sn }, true).then(res => { if (res.err_code === 0) { uni.showToast({ title: '操作成功', icon: 'success', duration: 2000 }); setTimeout(() => { this.box_sn = ''; this.wsty_id = ''; this.$refs.inputDialog.close(); this.clearInput(1); }, 2000); } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 不需要换箱 */ dialogInputClose() { this.$refs.inputDialog.close(); }, /** * 打印箱号 */ print() { if (!this.box_sn) { uni.showModal({ title: '', content: '请先扫描箱号', showCancel: false }); return false; } this.request(API.getPrintScanList, 'POST', { box_sn: this.box_sn }, true).then(res => { if (res.err_code === 0) { //一个标签的时候直接打印 if (res.data.length == 0) { uni.showToast({ title: '数据异常', icon: 'none' }); } else if (res.data.length == 1) { this.printConfirm(res.data); } else { //多个时候 this.allChecked = false; this.checkboxItems = []; res.data.forEach(item => { this.checkboxItems.push({ value: item, name: item, checked: false }); }); this.$refs.printScanList.open(); } } else { uni.showToast({ title: res.err_msg, icon: 'none' }); } }); }, /** * 处理打印标签,单个和多个 */ printConfirm(data) { var box_sn = []; if (data.length > 0) { data.forEach(item => { box_sn.push({ box_sn: item }); }); } var params = { type: 1, email: this.email, print_json: JSON.stringify(box_sn) } this.request(API.addSCTallyData, 'POST', params, true).then(res => { if (res.code === 0) { uni.showToast({ title: '打印箱号成功', icon: 'success' }) setTimeout(() => { this.updateTagPrintTimes(data.join(',')); this.close(); }, 2000) } else { uni.showToast({ title: res.msg, icon: 'none' }); } }); }, /** * 更新统计打印标签次数 */ updateTagPrintTimes(tag_no) { this.request(API.updateTagPrintTimes, 'POST', { tag_no: tag_no }, true).then(res => { }); }, /** * 全选复选框状态变化 * @param {Object} e */ checkboxAllChange(e) { this.allChecked = e.detail.value.length > 0; // 如果全选框被选中,设置为true this.checkboxItems.forEach(item => { item.checked = this.allChecked; }); }, /** * 单个复选框状态变化 * @param {Object} e */ checkboxChange(e) { const values = e.detail.value; this.checkboxItems.forEach(item => { item.checked = values.includes(item.value); }); // 更新全选复选框的状态 this.allChecked = this.checkboxItems.every(item => item.checked); console.log(values); }, /** * 多个打印确认 */ printMultiple() { var checkedItems = this.checkboxItems.filter(item => item.checked); if (checkedItems.length == 0) { uni.showToast({ title: '请勾选要打印的箱号', icon: 'none' }) return false; } var box_sn = checkedItems.map(item => item.value); this.printConfirm(box_sn); }, /** * 关闭打印多个提示 */ close() { this.$refs.printScanList.close(); }, /** * 清空数据 */ clearInput(type) { if (type == 1) { this.box_sn = ''; this.is_focus_1 = false; setTimeout(() => { this.is_focus_1 = true; }, 200); } else if (type == 2) { this.erp_order_sn = ''; this.is_focus_2 = false; setTimeout(() => { this.is_focus_2 = true; }, 200); //X掉入仓号时,自动清空型号查询框 this.goods_type = ''; this.keyword = ''; this.getTallyData(); } else if (type == 3) { this.goods_type = ''; this.keyword = ''; this.is_focus_3 = false; this.getTallyData(); setTimeout(() => { this.is_focus_3 = true; }, 200); } }, /** * 查看备注 */ viewChange(val) { uni.showModal({ title: '', content: val, showCancel: false, confirmText: '关闭' }); }, /** * 再次获取焦点 */ clearInputAndFocus() { this.is_focus = false; setTimeout(() => { this.is_focus = true; }, 200); } } }; </script> <style scoped lang="scss"> @import '@/assets/css/tally/index.scss'; ::v-deep { .uni-dialog-input { font-size: 24rpx !important; } .uni-dialog-title-text { padding: 10px; text-align: center; color: #404547; font-size: 26rpx !important; font-weight: bold !important; } } </style>