| <template>  | 
|     <view class="main_app">  | 
|         <view class="main_head">  | 
|             <view class="tabs">  | 
|                 <view class="tab" :class="{ active: activeTab == 0 }" @click="tabsClick(0)">  | 
|                     <text>未盘({{ info.unFinishAmount || 0 }})</text>  | 
|                     <text class="border"></text>  | 
|                 </view>  | 
|                 <view class="tab" :class="{ active: activeTab == 1 }" @click="tabsClick(1)">  | 
|                     <text>已盘({{ info.finishAmount || 0 }})</text>  | 
|                     <text class="border"></text>  | 
|                 </view>  | 
|             </view>  | 
|             <view class="head_wrap">  | 
|                 <view class="search_wrap">  | 
|                     <image class="mr12 search" src="@/static/home/ic_search@2x.png" mode="widthFix"></image>  | 
|                     <input v-model="param.materialCode" @confirm="handleQuery()" type="text" placeholder="搜索物料编码/物料名称"  | 
|                         placeholder-class="placeholder9" />  | 
|                 </view>  | 
|             </view>  | 
|             <!--  -->  | 
|             <scroll-view scroll-y="true" class="scroll_Y" @scrolltolower="scrolltolower">  | 
|                 <view class="list">  | 
|                     <view class="item" v-for="item in list" @click="itemClick(item)">  | 
|                         <view class="head">  | 
|                             <view class="title">{{ item.materialName }}</view>  | 
|                             <view class="status red" v-if="item.type == 1">盘亏</view>  | 
|                             <view class="status primaryColor" v-if="item.type == 2">盘盈</view>  | 
|                         </view>  | 
|                         <view class="line">物料编码:{{ item.materialCode }}</view>  | 
|                         <view class="line">条码:{{ item.materialQrcode }}</view>  | 
|                         <view class="line">规格型号:{{ item.materialAttr }}</view>  | 
|                         <view class="line" v-if="item.status == 0">  | 
|                             <view class="">账面数量:{{ item.stock }}{{ item.materialUnitName }}</view>  | 
|                             <view @click.stop="openEheck(item)" class="btn">执行盘点</view>  | 
|                         </view>  | 
|                         <view class="static" v-if="item.status == 1">  | 
|                             <view class="ite">  | 
|                                 <view class="la">账面数量:</view>  | 
|                                 <view class="val">{{ item.stock }}</view>  | 
|                             </view>  | 
|                             <view class="spi"></view>  | 
|                             <view class="ite">  | 
|                                 <view class="la">实际数量:</view>  | 
|                                 <view class="val" :class="{  | 
|                                     primaryColor: item.type == 2,  | 
|                                     red: item.type == 1,  | 
|                                 }">{{ item.actStock }}</view>  | 
|                             </view>  | 
|                         </view>  | 
|                     </view>  | 
|                 </view>  | 
|             </scroll-view>  | 
|             <view class="footer_btn">  | 
|                 <view @click="openQrcode" v-if="activeTab == 0 && info.status == 1" class="sweep">  | 
|                     <image src="@/static/side/ic_saoma@2x.png" mode=""></image>  | 
|                     <view class="">扫码盘点</view>  | 
|                 </view>  | 
|                 <view @click="showTip = true" v-if="activeTab == 1 && info.status == 1" class="sweep sub_result">  | 
|                     <view class="">提交盘点结果</view>  | 
|                 </view>  | 
|             </view>  | 
|             <!--  -->  | 
|             <u-popup :show="showModal" :round="10" @close="showModal = false" closeOnClickOverlay>  | 
|                 <view class="modal_wrap">  | 
|                     <view class="modal_title">执行盘点</view>  | 
|                     <view class="title">{{ modalForm.materialName }}</view>  | 
|                     <view class="item">物料编码:{{ modalForm.materialCode }}</view>  | 
|                     <view class="item">条码:{{ modalForm.materialQrcode }}</view>  | 
|                     <view class="item">品牌:{{ modalForm.materialBrand }}</view>  | 
|                     <view class="item">规格型号:{{ modalForm.materialAttr }}</view>  | 
|                     <view class="item">所在仓库:{{ modalForm.warehouseName }}</view>  | 
|                     <view class="content">  | 
|                         <view class="line">  | 
|                             <view class="la">账面数量:</view>  | 
|                             <view class="val">  | 
|                                 <view class="wrap">{{ modalForm.stock }}</view>  | 
|                                 <view class="unit">{{ modalForm.materialUnitName }}</view>  | 
|                             </view>  | 
|                         </view>  | 
|                         <view class="line">  | 
|                             <view class="la">盘点数量:</view>  | 
|                             <view class="val">  | 
|                                 <view class="wrap"> | 
|                                     <template v-if="!modalForm.handleType"> | 
|                                         <image v-if="!modalForm.actStock" src="@/static/side/btn_jian_grey@2x.png" mode=""></image> | 
|                                         <image v-else @click="changeAct(-1)" src="@/static/side/btn_jian@3x.png" mode=""></image> | 
|                                     </template>  | 
|                                     <input :disabled="Boolean(modalForm.handleType && modalForm.handleType == 'detail')" type="digit" v-model="modalForm.actStock"></input>  | 
|                                     <image v-if="!modalForm.handleType" @click="changeAct(1)" src="@/static/side/btn_jia@3x.png" mode=""></image>  | 
|                                 </view>  | 
|                                 <view class="unit">{{ modalForm.materialUnitName }}</view>  | 
|                             </view>  | 
|                         </view>  | 
|                     </view>  | 
|                     <view class="remark">  | 
|                         <view class="la">备注:</view>  | 
|                         <textarea v-model="modalForm.remark" :disabled="Boolean(modalForm.handleType && modalForm.handleType == 'detail')" placeholder="请填写备注" :maxlength="-1" placeholder-class="placeholder9"  | 
|                             cols="30" rows="10"></textarea>  | 
|                     </view>  | 
|                     <view v-if="!modalForm.handleType" class="btns">  | 
|                         <view class="btn" @click="showModal = false">取消</view>  | 
|                         <view class="btn sub" @click="onSubmit">提交</view>  | 
|                     </view>  | 
|                 </view>  | 
|             </u-popup>  | 
|             <!--  -->  | 
|             <u-popup :show="showTip" mode="center" :round="10" @close="showTip = false" closeOnClickOverlay>  | 
|                 <view class="modal_t">  | 
|                     <view class="h1">温馨提示</view>  | 
|                     <view class="content">  | 
|                         <view v-if="info.unFinishAmount > 0">还有<text class="red">{{ info.unFinishAmount }}</text>项物料未盘点</view>  | 
|                         <view>提交后将无法修改</view>  | 
|                     </view>  | 
|                     <view class="btns">  | 
|                         <view class="btn" @click="showTip = false">取消</view>  | 
|                         <view class="btn sub" @click="tipSub">确认提交</view>  | 
|                     </view>  | 
|                 </view>  | 
|             </u-popup>  | 
|         </view>  | 
|         <!--  -->  | 
|         <view class="reader-box" @click="stopScan" v-if="isScaning">  | 
|             <view class="reader" id="reader"></view>  | 
|         </view>  | 
|     </view>  | 
| </template>  | 
|   | 
| <script>  | 
| import {  | 
|     ywStocktakingDetail,  | 
|     getYwStocktakingRecord,  | 
|     takingDataOpen,  | 
|     ywStocktaFinishById  | 
| } from '@/api'  | 
| import {  | 
|     Html5Qrcode  | 
| } from 'html5-qrcode'  | 
| export default {  | 
|     data() {  | 
|         return {  | 
|             param: {},  | 
|             info: {},  | 
|             id: '',  | 
|             activeTab: 0,  | 
|   | 
|             list: [],  | 
|             page: 0,  | 
|             total: 0,  | 
|   | 
|             showModal: false,  | 
|             showTip: false,  | 
|             modalForm: {},  | 
|   | 
|             html5Qrcode: null,  | 
|             isScaning: false,  | 
|   | 
|         }  | 
|     },  | 
|     onLoad(op) {  | 
|         this.id = op.id  | 
|         this.getDetail()  | 
|         this.getList()  | 
|     },  | 
|     methods: { | 
|         itemClick(item) { | 
|             if(item.status == 1){ | 
|                 this.showItem(item) | 
|             } | 
|         }, | 
|         showItem(item){ | 
|             this.showModal = true | 
|             this.modalForm = { | 
|                 ...item, | 
|                 handleType: this.info.status != 1 ? 'detail' : '' | 
|             } | 
|             console.log('modalForm', this.modalForm); | 
|         },  | 
|         getDetail() {  | 
|             const {  | 
|                 id  | 
|             } = this  | 
|             ywStocktakingDetail(id).then(res => {  | 
|                 this.info = res.data  | 
|   | 
|             })  | 
|         },  | 
|         handleQuery(str) {  | 
|             this.list = []  | 
|             this.page = 1  | 
|             this.getList(str)  | 
|         },  | 
|         getList(str) {  | 
|             const {  | 
|                 page,  | 
|                 activeTab,  | 
|                 id,  | 
|                 param  | 
|             } = this  | 
|             getYwStocktakingRecord({  | 
|                 capacity: 20,  | 
|                 page,  | 
|                 model: {  | 
|                     status: str || activeTab,  | 
|                     stocktakingId: id,  | 
|                     ...param  | 
|                 }  | 
|             }).then(res => {  | 
|                 this.list = [...this.list, ...res.data.records]  | 
|                 this.total = res.data.total  | 
|                 if (this.param.materialQrcode && this.list.length == 1) {  | 
|                     this.openEheck(this.list[0])  | 
|                     this.$set(this.param, 'materialQrcode', null)  | 
|                 }  | 
|             })  | 
|         },  | 
|         scrolltolower() {  | 
|             const {  | 
|                 total,  | 
|                 list  | 
|             } = this  | 
|             if (list.length < total) {  | 
|                 this.page = this.page + 1  | 
|                 this.getList()  | 
|             } else {  | 
|                 this.showToast('暂无更多数据')  | 
|             }  | 
|         },  | 
|         openEheck(item) {  | 
|             this.modalForm = {  | 
|                 ...item  | 
|             }  | 
|             this.showModal = true  | 
|         },  | 
|         onSubmit() {  | 
|             const {  | 
|                 modalForm  | 
|             } = this  | 
|             if (!modalForm.actStock) return this.showToast('请输入正确的盘点数量')  | 
|             takingDataOpen({  | 
|                 ...modalForm  | 
|             }).then(res => {  | 
|                 if (res.code == 200) {  | 
|                     this.showToast('提交成功')  | 
|                     this.handleQuery()  | 
|                     this.getDetail()  | 
|                     this.showModal = false  | 
|                 }  | 
|             })  | 
|         },  | 
|         changeAct(val) {  | 
|             const actStock = this.modalForm.actStock || 0  | 
|             this.$set(this.modalForm, 'actStock', actStock + val)  | 
|         },  | 
|         tabsClick(val) {  | 
|             this.activeTab = val  | 
|             this.page = 0  | 
|             this.list = []  | 
|             this.getList()  | 
|         },  | 
|         tipSub() {  | 
|             const { info } = this  | 
|             ywStocktaFinishById(info.id).then(res => {  | 
|                 this.showTip = false  | 
|                 uni.navigateBack()  | 
|             })  | 
|   | 
|         },  | 
|         openQrcode() {  | 
|             this.isScaning = true  | 
|             Html5Qrcode.getCameras().then((devices) => {  | 
|                 if (devices && devices.length) {  | 
|                     this.html5Qrcode = new Html5Qrcode('reader')  | 
|                     this.html5Qrcode.start({  | 
|                         facingMode: 'environment'  | 
|                     }, {  | 
|                         focusMode: 'continuous', //设置连续聚焦模式  | 
|                         fps: 5, //设置扫码识别速度  | 
|                         qrbox: 280 //设置二维码扫描框大小  | 
|                     },  | 
|                         (decodeText, decodeResult) => {  | 
|                             if (decodeText) { //这里decodeText就是通过扫描二维码得到的内容  | 
|                                 this.stopScan()  | 
|                                 this.$set(this.param, 'materialQrcode', decodeText)  | 
|                                 this.handleQuery('null')  | 
|                             }  | 
|                         },  | 
|                         (err) => {  | 
|                             // console.log(err);  //错误信息  | 
|                         }  | 
|                     )  | 
|                 }  | 
|             })  | 
|         },  | 
|   | 
|         stopScan() {  | 
|             console.log('停止扫码')  | 
|             this.isScaning = false  | 
|             if (this.html5Qrcode) {  | 
|                 this.html5Qrcode.stop()  | 
|             }  | 
|         }  | 
|     }  | 
| }  | 
| </script>  | 
|   | 
| <style lang="scss">  | 
| .main_app {  | 
|     padding: 0 30rpx;  | 
|     overflow: hidden;  | 
| }  | 
|   | 
| .tabs {  | 
|     display: flex;  | 
|     width: 750rpx;  | 
|     margin: 12rpx -30rpx 20rpx;  | 
|     border-bottom: 1rpx solid #E5E5E5;  | 
|   | 
|     .tab {  | 
|         font-size: 30rpx;  | 
|         color: #666666;  | 
|         flex: 1;  | 
|         display: flex;  | 
|         flex-direction: column;  | 
|         align-items: center;  | 
|         justify-content: flex-end;  | 
|         height: 72rpx;  | 
|   | 
|         .name {  | 
|             display: flex;  | 
|             align-items: center;  | 
|         }  | 
|   | 
|         .border {  | 
|             width: 54rpx;  | 
|             height: 6rpx;  | 
|             background-color: #fff;  | 
|             border-radius: 3rpx;  | 
|             margin-top: 12rpx;  | 
|         }  | 
|     }  | 
|   | 
|     .active {  | 
|         font-weight: 600;  | 
|         font-size: 32rpx;  | 
|         color: #222222;  | 
|   | 
|         .border {  | 
|             background-color: $primaryColor;  | 
|         }  | 
|   | 
|     }  | 
|   | 
| }  | 
|   | 
| .head_wrap {  | 
|     display: flex;  | 
|     align-items: center;  | 
|     margin-bottom: 36rpx;  | 
|   | 
|     .search_wrap {  | 
|         display: flex;  | 
|         align-items: center;  | 
|         width: 100%;  | 
|         height: 76rpx;  | 
|         background: #F7F7F7;  | 
|         border-radius: 38rpx;  | 
|         padding-left: 30rpx;  | 
|   | 
|         input {  | 
|             flex: 1;  | 
|         }  | 
|   | 
|         .search {  | 
|             width: 28rpx;  | 
|             height: 28rpx;  | 
|         }  | 
|     }  | 
|   | 
| }  | 
|   | 
| .scroll_Y {  | 
|     height: calc(100vh - 350rpx);  | 
| }  | 
|   | 
| .list {  | 
|   | 
|     .item {  | 
|         border-bottom: 1rpx solid #E5E5E5;  | 
|         padding-bottom: 24rpx;  | 
|         margin-bottom: 16rpx;  | 
|   | 
|         .title {  | 
|             font-weight: 600;  | 
|             font-size: 34rpx;  | 
|             color: #222222;  | 
|             margin-bottom: 10rpx; | 
|             flex: 1;  | 
|         }  | 
|         .head{ | 
|             display: flex; | 
|             // align-items: center; | 
|             justify-content: space-between; | 
|             color: #666666; | 
|             .status{ | 
|                 width: 76rpx; | 
|                 text-align: right; | 
|                 padding-top: 3rpx; | 
|             } | 
|         }  | 
|         .line {  | 
|             height: 60rpx;  | 
|             display: flex;  | 
|             align-items: center;  | 
|             justify-content: space-between;  | 
|             color: #666666; | 
|               | 
|             .btn {  | 
|                 display: flex;  | 
|                 align-items: center;  | 
|                 justify-content: center;  | 
|                 height: 60rpx;  | 
|                 padding: 0 20rpx;  | 
|                 background: #0068FF;  | 
|                 box-shadow: 0rpx 4rpx 12rpx 0rpx rgba(0, 104, 255, 0.3);  | 
|                 border-radius: 30rpx;  | 
|                 font-size: 26rpx;  | 
|                 color: #FFFFFF;  | 
|             }  | 
|         }  | 
|   | 
|         .static {  | 
|             display: flex;  | 
|             height: 84rpx;  | 
|             background: #F7F7F7;  | 
|             font-size: 30rpx;  | 
|             margin-top: 12rpx;  | 
|             padding: 16rpx 0;  | 
|   | 
|             .spi {  | 
|                 border: 1rpx solid #E5E5E5;  | 
|             }  | 
|   | 
|             .ite {  | 
|                 flex: 1;  | 
|                 display: flex;  | 
|                 align-items: center;  | 
|                 justify-content: center;  | 
|   | 
|                 .val {  | 
|                     font-weight: 500;  | 
|                 }  | 
|             }  | 
|         }  | 
|     }  | 
| }  | 
|   | 
| .footer_btn {  | 
|     padding: 20rpx 40rpx 0;  | 
|     border-top: 1px solid #e5e5e5;  | 
|     width: 750rpx;  | 
|     margin: 0 -30rpx;  | 
|   | 
|     .sweep {  | 
|         display: flex;  | 
|         align-items: center;  | 
|         justify-content: center;  | 
|         font-size: 32rpx;  | 
|         font-weight: 500;  | 
|         width: 670rpx;  | 
|         height: 88rpx;  | 
|         background: #0068FF;  | 
|         box-shadow: 0rpx 8rpx 20rpx 0rpx rgba(0, 104, 255, 0.3);  | 
|         border-radius: 44rpx;  | 
|         color: #FFFFFF;  | 
|     }  | 
|   | 
|     .sub_result {  | 
|         background-color: #fff;  | 
|         color: #FF0000;  | 
|         border: 1rpx solid #FF0000;  | 
|         box-shadow: none  | 
|     }  | 
|   | 
|     image {  | 
|         width: 32rpx;  | 
|         height: 32rpx;  | 
|         margin-right: 6rpx;  | 
|     }  | 
| }  | 
|   | 
| .modal_wrap {  | 
|     padding: 36rpx 30rpx;  | 
|   | 
|     .modal_title {  | 
|         font-weight: 500;  | 
|         font-size: 32rpx;  | 
|         color: #222222;  | 
|         margin-bottom: 40rpx;  | 
|         text-align: center;  | 
|     }  | 
|   | 
|     .title {  | 
|         font-weight: 600;  | 
|         font-size: 34rpx;  | 
|         color: #222222;  | 
|     }  | 
|   | 
|     .item {  | 
|         font-size: 28rpx;  | 
|         color: #666666;  | 
|         height: 56rpx;  | 
|         display: flex;  | 
|         align-items: center;  | 
|     }  | 
|   | 
|     .content {  | 
|         border-top: 1rpx solid #E5E5E5;  | 
|         margin-top: 16rpx;  | 
|   | 
|         .line {  | 
|             height: 84rpx;  | 
|             display: flex;  | 
|             align-items: center;  | 
|             justify-content: space-between;  | 
|   | 
|             .la {  | 
|                 font-weight: 500;  | 
|                 font-size: 32rpx;  | 
|                 color: #222222;  | 
|             }  | 
|   | 
|             .val {  | 
|                 display: flex;  | 
|                 justify-content: flex-end;  | 
|                 align-items: center;  | 
|                 flex: 1;  | 
|   | 
|                 .wrap {  | 
|                     display: flex;  | 
|                     align-items: center;  | 
|   | 
|                     input {  | 
|                         width: 120rpx;  | 
|                         height: 72rpx;  | 
|                         border-radius: 8rpx;  | 
|                         border: 2rpx solid #0068FF;  | 
|                         margin: 0 16rpx;  | 
|                         padding: 0 10rpx;  | 
|                         text-align: center;  | 
|                     }  | 
|                 }  | 
|   | 
|                 .unit {  | 
|                     font-size: 30rpx;  | 
|                     color: #666666;  | 
|                     margin-left: 20rpx;  | 
|                 }  | 
|             }  | 
|   | 
|             image {  | 
|                 width: 72rpx;  | 
|                 height: 72rpx;  | 
|             }  | 
|         }  | 
|     }  | 
|   | 
|     .remark {  | 
|         margin-top: 16rpx;  | 
|   | 
|         .la {  | 
|             font-size: 30rpx;  | 
|             color: #222222;  | 
|             margin-bottom: 16rpx;  | 
|         }  | 
|   | 
|         textarea {  | 
|             width: 690rpx;  | 
|             height: 240rpx;  | 
|             background: #F7F7F7;  | 
|             border-radius: 12rpx;  | 
|             padding: 10rpx 20rpx;  | 
|         }  | 
|     }  | 
|   | 
|     .btns {  | 
|         display: flex;  | 
|         justify-content: space-between;  | 
|         align-items: center;  | 
|         margin-top: 80rpx;  | 
|   | 
|         .btn {  | 
|             width: 336rpx;  | 
|             height: 88rpx;  | 
|             border-radius: 44rpx;  | 
|             border: 2rpx solid $primaryColor;  | 
|             display: flex;  | 
|             align-items: center;  | 
|             justify-content: center;  | 
|             font-size: 32rpx;  | 
|             color: $primaryColor;  | 
|         }  | 
|   | 
|         .sub {  | 
|             background-color: $primaryColor;  | 
|             color: #fff;  | 
|         }  | 
|     }  | 
| }  | 
|   | 
|   | 
| .modal_t {  | 
|     width: 520rpx;  | 
|     text-align: center;  | 
|     display: flex;  | 
|     flex-direction: column;  | 
|   | 
|     .h1 {  | 
|         height: 86rpx;  | 
|         font-weight: 500;  | 
|         font-size: 32rpx;  | 
|         color: #333333;  | 
|         display: flex;  | 
|         align-items: flex-end;  | 
|         justify-content: center;  | 
|     }  | 
|   | 
|     .content {  | 
|         flex: 1;  | 
|         display: flex;  | 
|         flex-direction: column;  | 
|         justify-content: center;  | 
|         align-items: center;  | 
|         padding: 30rpx 0;  | 
|     }  | 
|   | 
|     .btns {  | 
|         height: 102rpx;  | 
|         display: flex;  | 
|         align-items: center;  | 
|         border-top: 1rpx solid #E5E5E5;  | 
|   | 
|         .btn {  | 
|             height: 102rpx;  | 
|             flex: 1;  | 
|             display: flex;  | 
|             align-items: center;  | 
|             justify-content: center;  | 
|             border-right: 1rpx solid #E5E5E5;  | 
|             font-weight: 400;  | 
|             font-size: 32rpx;  | 
|             color: #999999;  | 
|   | 
|             &:nth-last-child(1) {  | 
|                 border-right: none;  | 
|             }  | 
|         }  | 
|   | 
|         .sub {  | 
|             color: $primaryColor;  | 
|         }  | 
|     }  | 
| }  | 
|   | 
| .reader-box {  | 
|     position: fixed;  | 
|     top: 0;  | 
|     bottom: 0;  | 
|     left: 0;  | 
|     right: 0;  | 
|     background-color: rgba(0, 0, 0, 0.5);  | 
| }  | 
|   | 
| .reader {  | 
|     width: 100%;  | 
|     // width: 540rpx;  | 
|     // height: 540rpx;  | 
|     position: absolute;  | 
|     top: 50%;  | 
|     left: 50%;  | 
|     transform: translate(-50%, -50%);  | 
| }  | 
| </style> |