<template> <BasicContainer ref="basicContainer" :option="option"> <template #head> <!-- 主体内容 --> <view class="main"> <!-- 顶部 --> <view class="main_top"> <input type="text" v-model="details.searchText" placeholder="请输入库位码" class="main_top_search" /> <view class="button" @click="submitSearch">搜索</view> </view> <!-- 库位信息 --> <view class="main_info"> <view class="main_info_row"> <view class="main_info_item"> <text>托盘号:</text> <text>{{info.trayCode}}</text> </view> <view class="main_info_item"> <text>货物类型:</text> <text>{{info.goodsType}}</text> </view> <view @click="upData" class="button"> 上架 </view> </view> <view class="main_info_row"> <view class="main_info_item"> <text>总数:</text> <text>{{info.total}}</text> </view> <view class="main_info_item"> <text>已盘数:</text> <text>{{info.unTotal}}</text> </view> <view class="main_info_item"> <text>未盘数:</text> <text>{{info.total - info.unTotal}}</text> </view> </view> </view> <!-- tabBar选项卡 --> <!-- <view class="tabBar"> <view class="tabBar-item active"> {{info.goodsType}}({{info.total}}) </view> </view> --> <!-- 控件 --> <view class="control"> <view class="button" @click="showControl = true" v-show="!showControl">批量操作</view> <view class="button" @click="grounding" v-show="!showControl">添加物料</view> <template v-if="showControl"> <view class="button" @click="handleInvertSelection">反选</view> <view class="controlList"> <view class="button" @click="handleBatchDel"> 批量删除 </view> <view class="button" @click="handleBatchState"> 状态修改 </view> </view> </template> </view> </view> </template> <template #body> <!-- 列表 --> <scroll-view class="scvmabx" @scrolltolower="reachBottomInitPage" scroll-y="true" @touchmove.stop> <!-- 按库位盘点 --> <template v-if="renderList && renderList.length !== 0"> <view v-for="(item, index) in renderList" :class="`list ${details.activeColor[item.questStatus]}`" :key="item"> <!-- 复选框 --> <template v-if="item.questStatus !== 3"> <view class="leftIcon"> <image class="checkImage" @click="details.checkList[index] = !details.checkList[index]" :src="details.checkList[index]?'/pagesHome/static/check.png':'/pagesHome/static/nocheck.png'"> </image> </view> </template> <!-- 定制品 --> <template v-if="info.goodsType === '定制品'"> <view class="rightMsg"> <template v-if="item.questStatus !== 3"> <view class="tpbx"> <view style="flex: none;"> 操作: </view> <view style="display: flex; justify-content: space-between;"> <text class="button" @click="handleState(item)">处理</text> </view> </view> </template> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>包条码:{{item.ordePackageCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>合同号:{{item.orderCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>库位:{{item.positionCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>状态:在库</view> </view> </view> </template> <!-- 零担 --> <template v-else-if="info.goodsType === '零担'"> <view class="rightMsg"> <view class="tpbx"> <view style="flex: none;"> 操作: </view> <view style="display: flex; justify-content: space-between;"> <text class="button" @click="handleState(item)">处理</text> </view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>物料编码:{{item.materialCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>物料名称:{{item.marketName}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>数量:{{item.stockNum}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>库位:{{item.positionCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>状态:在库</view> </view> </view> </template> <!-- 库存品 --> <template v-else-if="info.goodsType === '库存品'"> <view class="rightMsg"> <view class="tpbx"> <view style="flex: none;"> 操作: </view> <view style="display: flex; justify-content: space-between;"> <text class="button" @click="handleState(item)">处理</text> </view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>订单号:{{item.orderCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>运单号:{{''}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>数量:{{item.stockNum}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>库位:{{item.positionCode}}</view> </view> <view class="tpbx"> <image src="/pagesHome/static/kuweiicon.png"></image> <view>状态:在库</view> </view> </view> </template> </view> </template> </scroll-view> </template> </BasicContainer> <!-- 提交 --> <button @click="submitCheck" class="submitButton" type="primary">提交盘点</button> <view class="popUp" @click="details.showUpData = false" v-if="details.showUpData"> <view class="container" @click.stop> <view style="text-align: center;" class=""> 上架 </view> <view class="up" style="height: 100px;"> <input style="padding: 10px; border: 1px solid #000;" type="text" v-model="details.scancode" placeholder="扫描或输入库位码" id=""> </view> <view style="display: flex; align-items: center;" class=""> <button style="flex: 1;" @click.stop="details.showUpData = false" class="button">取消</button> <button style="flex: 1;" @click.stop="upDataForm" class="button">上架</button> </view> </view> </view> <!-- #ifdef APP --> <saomiao2 :ishidestop="scanState !== 0"></saomiao2> <!-- #endif --> <tiplist ref="tiplists"></tiplist> </template> <script setup lang="ts"> import { onShow, onLoad, onHide, } from '@dcloudio/uni-app' import { ref, reactive, toRefs, onMounted } from "vue"; import { getWarehousetrayListInfo, getWarehouseUpdateQuestDetail, getWarehouseDeleteQuestDetail, getWarehouseSaveNewQuestDetail, postqueryupdateQuestDetailAllocation, postWarehouseTaskSelectPackageInfo } from '@/api/user.js'; import utils from '@/utils/utils'; import useSystemSettingsStore from '@/store/useSystemSettingsStore'; import { storeToRefs } from 'pinia'; const { scanState } = storeToRefs(useSystemSettingsStore()) const option = reactive({ title: '按托盘盘点', isEnd: false, haveData: true, async pullDownRefreshInitPage() { console.log('下拉刷新') // if (details.holdBackFirstPost) return details.holdBackFirstPost = false // 页面信息清空 details.renderList = [] // 页码清零 details.pages.current = 1 option.isEnd = false // console.log('首次') return await initPage() }, reachBottomInitPage() { console.log('触底加载') } }) const details = reactive({ // 页面标题 title: '', // 选项卡页码 tabBarCode: 1, // 是否显示控件 showControl: false, // 搜索框的值 searchText: '', // 扫描后的值 scancode: '', // 是否为扫描 isScan: false, // 渲染的列表 renderList: [], // 复选框 checkList: [], // 页面传递时的数据 pageInfo: {}, activeColor: [ 'normal', 'green', '', 'red' ], showUpData: false, pages: { size: 10, current: 1, } }) // 本页数据 const info = reactive({ // 托盘码 trayCode: '', // 已盘数 unTotal: 0, // 未盘数 total: 0, // 物料类型 goodsType: '' }) const { showControl, renderList, } = toRefs(details) const tiplists = ref(null) const basicContainer = ref(null) // 页面初始化执行回调 onLoad((data) => { console.log('data :>> ', data); details.pageInfo = JSON.parse(data.info) info.trayCode = details.pageInfo.trayCode info.goodsType = details.pageInfo.type }) // 开启监听扫描 onShow(() => { // #ifdef APP uni.$off('scancodedate') uni.$on('scancodedate', function (code) { if (code) { // console.log(code); console.log('code :>> ', code); details.scancode = code scandata() } }) // #endif // if (details.holdBackFirstPost) return const timer = setTimeout(() => { console.log('123 :>> ', 123); basicContainer.value.startPullDownRefresh() clearTimeout(timer) }, 200) }) // 关闭扫描监听 // onHide(() => { // uni.$off('scancodedate') // }) // // 添加防抖函数 let antiShake : any = null // 触底加载 function reachBottomInitPage() { // 数据请求完毕, 不再请求 if (option.isEnd) { return uni.showToast({ icon: 'success', title: '数据已加载完毕' }) } console.log('antiShake :>> ', antiShake); if (antiShake) { uni.hideLoading() // 清空定时器 clearTimeout(antiShake) return antiShake = null } // 显示Loading, 并阻止点击屏幕 uni.showLoading({ title: '正在加载', mask: true }) antiShake = setTimeout(async () => { // 触底请求 console.log('触底') details.pages.current += 1 await initPage() // 关闭Loading效果 uni.hideLoading() // 清空定时器 clearTimeout(antiShake) antiShake = null }, 1000) } // 请求页面数据 async function initPage() { try { const submitForm = { ...details.pages, taskId: details.pageInfo.taskId, trayId: details.pageInfo.trayId, questNum: details.pageInfo.questNum } const res = await getWarehousetrayListInfo(submitForm) console.log('res :>> ', res); const { code, data } = res if (code === 200) { console.log('data :>> ', data); // const dataInfo = res.data[0] details.renderList = [...details.renderList, ...data.list] info.total = data.total info.unTotal = data.unTotal if (details.renderList.length >= info.total) option.isEnd = true if (data.list) details.checkList = data.list.map(() => false) } } catch (err) { console.log('err :>> ', err); //TODO handle the exception } finally { return true } } // 扫描后执行的回调 async function scandata() { if (info.goodsType !== '定制品') return details.scancode const flag = details.renderList.find(val => val.ordePackageCode === details.scancode) console.log('flag :>> ', flag); // 当包件存在 if (flag) { const questDetailList = [{ id: flag.id, // 在库数 stockNum: flag.stockNum, // 丢失 lossNum: 0, // 配送 deliveNum: 0, // 破损 wornNum: 0, // 不可修复 noRepairNum: 0, // 未入库 noReceivedNum: 0, }] const res = await getWarehouseUpdateQuestDetail({ questDetailList, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum }) const { code, msg } = res console.log('res :>> ', res); if (code === 200) { basicContainer.value.startPullDownRefresh() utils.ttsspke(msg) } } else { const res = await postWarehouseTaskSelectPackageInfo({ orderPackageCode: details.scancode, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum }) console.log('res :>> ', res); // grounding() } } /** * 提交搜索请求 */ function submitSearch() { uni.showToast({ title: '功能还在开发中' }) } /** * 上架 */ function upData() { details.showUpData = true } /** * 提交上架 */ async function upDataForm() { if (!details.scancode) return uni.showToast({ title: '请输入或扫描库位码', icon: 'none' }) const arr = details.renderList.filter(v => v.questStatus !== 3) console.log('arr :>> ', arr); const questDetailList = arr.map(val => { return { id: val.id } }) const res = await postqueryupdateQuestDetailAllocation({ allocationId: details.scancode, questId: details.pageInfo.taskId, questDetailList, questNum: details.pageInfo.questNum }) if (res.code === 200) { details.showUpData = false } utils.ttsspke(res.msg) } /** * 提交盘点 */ function submitCheck() { // 返回上一级页面 uni.navigateBack() } /** * 复选框反选 */ function handleInvertSelection() { details.checkList = details.checkList.map(val => !val) } /** * 批量删除 */ function handleBatchDel() { console.log('details :>> ', details.checkList); if (!details.checkList.some(val => val)) { return uni.showToast({ icon: 'none', title: '最少选择一条数据' }) } const questDetailList = [] details.renderList.forEach((val, index) => { if (details.checkList[index]) questDetailList.push({ id: val.id }) }) tiplists.value.setdetails({ title: '确认批量删除', isshow: true, tipstate: 2, list: [], confirmTxt: '确认删除', isonecheck: true, success: (deta) => { // const res = getWarehouseUpdateQuestDetail({ ids }) // console.log('res :>> ', res); console.log('111 :>> ', 111); try { getWarehouseDeleteQuestDetail({ questDetailList, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum }).then(res => { basicContainer.value.startPullDownRefresh() }) } catch (e) { //TODO handle the exception } finally { tiplists.value.setdetails({ isshow: false }) } }, cancel: () => { tiplists.value.setdetails({ isshow: false }) }, close: () => { tiplists.value.setdetails({ isshow: false }) } }) } /** * 批量修改状态 */ function handleBatchState() { if (!details.checkList.some(val => val)) { return uni.showToast({ icon: 'none', title: '最少选择一条数据' }) } const questDetailList = [] details.renderList.forEach((val, index) => { if (details.checkList[index]) { questDetailList.push({ id: val.id, // 在库数 stockNum: val.stockNum, // 丢失 lossNum: 0, // 配送 deliveNum: 0, // 破损 wornNum: 0, // 不可修复 noRepairNum: 0, // 未入库 noReceivedNum: 0, }) } }) tiplists.value.setdetails({ title: '确定批量修改', isshow: true, tipstate: 2, list: [], confirmTxt: '确认修改', isonecheck: true, success: (deta) => { // const res = getWarehouseUpdateQuestDetail({ ids }) // console.log('res :>> ', res); try { getWarehouseUpdateQuestDetail({ questDetailList, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum }).then(res => { basicContainer.value.startPullDownRefresh() }) } catch (e) { //TODO handle the exception } finally { tiplists.value.setdetails({ isshow: false }) } }, cancel: () => { tiplists.value.setdetails({ isshow: false }) }, close: () => { tiplists.value.setdetails({ isshow: false }) } }) } /** * 修改状态 */ function handleState(item) { try { const checkSectionList = [ { title: '丢失', isCheck: false, value: 0, disabled: true }, { title: '配送', isCheck: false, value: 0, disabled: true }, { title: '破损', isCheck: false, value: 0, disabled: true }, { title: '不可修复', isCheck: false, value: 0, disabled: true }, { title: '未入库', isCheck: false, value: 0, disabled: true } ] tiplists.value.setdetails({ title: '修改状态', isshow: true, tipstate: 6, list: [{ title: '在库', value: item.stockNum }], checkSectionList, checklist: [], inputtext: '', confirmTxt: '确认选择', isonecheck: true, success: async (deta) => { const { checklist, checkSectionList } = deta if (checklist.length == 0) { uni.showToast({ title: '请选择修改的状态', icon: 'none' }) return } if (checkSectionList[checklist[0]].value === 0) { return uni.showToast({ title: '请输入修改的数量', icon: 'none' }) } const questDetailList = [{ id: item.id, // 在库数 stockNum: item.stockNum, // 丢失 lossNum: checkSectionList[0].value, // 配送 deliveNum: checkSectionList[1].value, // 破损 wornNum: checkSectionList[2].value, // 不可修复 noRepairNum: checkSectionList[3].value, // 未入库 noReceivedNum: checkSectionList[4].value, }] const res = await getWarehouseUpdateQuestDetail({ questDetailList, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum }) const { code } = res if (code === 200) basicContainer.value.startPullDownRefresh() tiplists.value.setdetails({ isshow: false }) }, cancel: () => { tiplists.value.setdetails({ isshow: false }) }, close: () => { tiplists.value.setdetails({ isshow: false }) } }) } catch (e) { //TODO handle the exception } finally { } } /** * 新增物料 */ function grounding() { const marketName = Array.from(details.pageInfo.marketName) console.log('marketName :>> ', marketName); tiplists.value.setdetails({ title: '新增', isshow: true, tipstate: 5, upform: { article: { // 合同号 contractNumber: '', // 包条码 orderPackageCode: details.scancode }, stock: {} }, marketName, goodsType: '库存品', // goodsType: info.goodsType, confirmTxt: '确认新增', isonecheck: true, success: async (deta) => { let submitData : any = {} if (info.goodsType === '定制品') submitData = articleAdd(deta) if (info.goodsType === '零担') { uni.showToast({ title: '功能还在开发中' }) tiplists.value.setdetails({ isshow: false }) return submitData = zeroAdd(deta) } if (info.goodsType === '库存品') submitData = stockAdd(deta) const res = await getWarehouseSaveNewQuestDetail(submitData) console.log('res :>> ', res); const { code } = res if (code === 200) { basicContainer.value.startPullDownRefresh() uni.showToast({ title: '操作成功', icon: 'success' }) } tiplists.value.setdetails({ isshow: false }) }, cancel: () => { tiplists.value.setdetails({ isshow: false }) }, close: () => { tiplists.value.setdetails({ isshow: false }) } }) } // 定制品添加 function articleAdd(deta) { const { upform: { article: { contractNumber, orderPackageCode } } } = deta if (!contractNumber) return uni.showToast({ title: '请输入合同号', icon: 'none' }) if (!orderPackageCode) return uni.showToast({ title: '请输入或扫描包条码', icon: 'none' }) const submitData = { questDetail: { ordePackageCode: orderPackageCode, orderCode: contractNumber, stockNum: 1, }, trayCode: info.trayCode, questTarget: 1, questType: 4, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum } return submitData } // 零担添加 function zeroAdd(deta) { } // 库存品添加 function stockAdd(deta) { console.log('deta :>> ', deta); const { upform: { stock: { orderCode, stockNum, marketName, incomingBatch } } } = deta console.log('data :>> ', deta); const submitData = { questDetail: { orderCode: orderCode, stockNum: stockNum, marketName, incomingBatch }, trayCode: info.trayCode, questTarget: 3, questType: 4, questId: details.pageInfo.taskId, questNum: details.pageInfo.questNum } return submitData } </script> <style lang="scss" scoped> $buttonColor: #d3832a; // 本页按钮样式 .button { font-size: 28upx; padding: 10upx 20upx; border: 1upx solid $buttonColor; background-color: #fff; color: #d3832a; border-radius: 5upx; } .main { padding: 10upx; font-size: 28upx; // 本页字体大小 } .main_top { display: flex; // align-items: center; justify-content: space-between; margin-bottom: 10upx; // 顶部搜索框 &_search { flex: 1; padding-left: 20upx; margin-right: 20upx; box-sizing: border-box; height: 28upx * 2; border-radius: 28upx; border: 1upx solid #000; } .button { background-color: $buttonColor; color: #fff; padding: 0 60upx; display: inline-flex; align-items: center; } } // 顶部信息区 .main_info { margin-bottom: 10upx; padding: 10upx; background-color: #fff; &_row { padding: 10upx 0; display: flex; align-items: center; justify-content: space-between; border-bottom: 2upx solid #000; &:last-child { border-bottom: none; } } &_item { flex: 1; flex-basis: 0; display: inline-flex; text:first-child { margin-right: 10upx; } } } // tabBar选项卡 .tabBar { display: flex; justify-content: space-evenly; background-color: #fff; margin-bottom: 10upx; &-item { position: relative; flex: 1; flex-basis: 0; padding: 20upx 0; text-align: center; &::after { content: ''; position: absolute; bottom: 0; left: 50%; display: block; width: 0; box-sizing: border-box; border: 1upx solid $buttonColor; transition: all 0.5s; } &.active { color: $buttonColor; &::after { left: 0; width: 100%; } } } } // 控件区 .control { display: flex; justify-content: space-between; .controlList { display: flex; .button { margin: 0 5upx; &:last-child { margin-right: 0; } } } } // 滚动区 .scvmabx { width: 100%; height: 60vh; } .list { display: flex; margin: 20upx 0; padding: 0 10upx; border-radius: 10upx; box-shadow: 0 0 20upx #d3832a; &.normal { background-color: none; } &.green { background: #eaffc9; } &.red { background: #ffc9c9; } .leftIcon { flex: none; margin-right: 30upx; // padding-top: 18upx; .checkImage { width: 48upx; height: 48upx; } } .rightMsg { flex: 1; } } // 列表 .tpbx { display: flex; align-items: center; // padding: 18upx 24upx; box-sizing: border-box; border-bottom: 4upx solid #EEEEEE; >image { flex: none; width: 32upx; height: 32upx; margin-right: 15upx; } >view { flex: 1; font-size: 28upx; font-weight: 400; color: #020B18; .numb { font-size: 28upx; color: #178AF2; } } } .viewnum { height: 100upx; display: flex; align-items: center; justify-content: space-around; >view { font-size: 28upx; font-weight: 400; color: #020B18; } } // 提交按钮 .submitButton { position: fixed; color: #fff; background-color: $buttonColor; width: 50%; bottom: 30upx; left: 50%; transform: translateX(-50%); } // 弹出层 .popUp { width: 100vw; height: 100vh; background: #00000033; position: fixed; top: 0; left: 0; display: flex; align-items: center; justify-content: center; .container { width: 70%; height: 35%; background: #fff; border-radius: 10upx; padding: 20upx; display: flex; flex-direction: column; justify-content: space-between; .button { margin: 0 20upx; } } } </style>