lilei 2 anni fa
parent
commit
4882b0f3cc

+ 10 - 0
api/shelf.js

@@ -11,6 +11,7 @@ export const getShelfList = (params) => {
 		method: 'post'
 	})
 }
+
 //  货架  保存
 export const shelfSave = (params) => {
   return axios.request({
@@ -46,6 +47,15 @@ export const getShelfProductList = (params) => {
 		method: 'post'
 	})
 }
+// 货位产品 列表 
+export const queryShelfProductList = (params) => {
+	let url = `shelf/placeProduct/queryShelfProductList`
+	return axios.request({
+		url: url,
+		data: params,
+		method: 'post'
+	})
+}
 // 修改完成标识
 export const modifFinishFlag = (params) => {
   return axios.request({

+ 25 - 4
pages.json

@@ -53,10 +53,22 @@
         }
         ,{
             "path" : "pages/latePlay/chooseProduct",
-            "style" :                                                                                    
-            {
-                "navigationBarTitleText": "补打贴签",
-                "enablePullDownRefresh": false
+            "style": {
+            	"navigationBarTitleText": "打印贴签",
+            	"navigationStyle":"custom",
+            	"app-plus":{
+            		"titleNView": {
+            			"titleAlign": "auto",
+            			"buttons": [ //原生标题栏按钮配置,
+            				{
+            					"text": "批量打印" ,//原生标题栏增加分享按钮,点击事件可通过页面的 onNavigationBarButtonTap 函数进行监听u
+            					"fontSize": "16",
+								"color":"#00aaff",
+            					"width":"100px"
+            				}
+            			]
+            		}
+            	}
             }
         },
 		{
@@ -403,6 +415,15 @@
             }
             
         }
+        ,{
+            "path" : "pages/shelfSetting/batchPrint",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "批量打印",
+                "enablePullDownRefresh": false
+            }
+            
+        }
     ],
 	"globalStyle": {
 		"navigationBarTextStyle": "black",

+ 4 - 2
pages/common/partList.vue

@@ -7,8 +7,10 @@
 		<view class="partList-list">
 			<view class="partList-list-box" v-for="item in partList" :key="item.id">
 				<view class="product flex align_center">
-					<view class="checkbox" v-if="model == 'checkbox'"><u-checkbox v-model="item.checked" :name="item.id" @change="checkChange" size="40" shape="circle"></u-checkbox></view>
-					<view class="flex align_center flex_1">
+					<view class="checkbox" v-if="model == 'checkbox'">
+						<u-checkbox v-model="item.checked" :name="item.id" @change="checkChange" size="40" shape="circle"></u-checkbox>
+					</view>
+					<view class="flex align_center flex_1" @click="checkChange({name:item.id})">
 						<view class="pimgs">
 							<u-image :src="item.product&&item.product.productMsg?item.product.productMsg:`../../static/${theme}/def_img@2x.png`" width="128" height="128" border-radius="10"></u-image>
 						</view>

+ 29 - 6
pages/common/printTag/printTag.vue

@@ -7,14 +7,23 @@
 				<u-number-box :min="1" v-model="printNum" color="#000" bg-color="#fff" size="30" :input-height="70" :input-width="100"></u-number-box>
 			</view>
 		</view>
+		<view class="print-radio" v-if="fromPage == 'bdtq'">
+			<u-radio-group v-model="printNum" @change="qtyChange">
+				<u-radio :name="infoData.qty">按当前库存打印</u-radio>
+				<u-radio :name="infoData.maxQty">按最大库容打印</u-radio>
+			</u-radio-group>
+		</view>
 		<view class="shelf-info">
 			<view class="shelf-info-title">
 				<view class="shelf-name">{{infoData&&infoData.shelfName || '--'}}</view>
 				<view class="pno">{{infoData&&infoData.shelfPlaceCode}}</view>
 			</view>
-			<view>产品编码:{{fromPage == 'smdy'?infoData.productCode : infoData.productEntity&&infoData.productEntity.code}}</view>
-			<view>产品名称:{{fromPage == 'smdy'?infoData.productName : infoData.productEntity&&infoData.productEntity.productName}}</view>
-			<view>{{fromPage == 'smdy'?'实发':'库存'}}数量:{{fromPage == 'smdy'?infoData.confirmQty : infoData.qty}}</view>
+			<view class="shelf-info-body">
+				<view>产品编码:{{fromPage == 'smdy'?infoData.productCode : infoData.productEntity&&infoData.productEntity.code}}</view>
+				<view>产品名称:{{fromPage == 'smdy'?infoData.productName : infoData.productEntity&&infoData.productEntity.productName}}</view>
+				<view>{{fromPage == 'smdy'?'实发数量':'当前库存'}}:{{fromPage == 'smdy'?infoData.confirmQty : infoData.qty}}{{infoData.productEntity&&infoData.productEntity.unit}}</view>
+				<view v-if="fromPage == 'bdtq'">最大库容:{{infoData.maxQty}}{{infoData.productEntity&&infoData.productEntity.unit}}</view>
+			</view>
 		</view>
 		<view class="buttons flex align_center justify_center">
 			<view v-if="fromPage == 'bdtq'"><u-button @click="cancel" shape="circle" plain>返回列表</u-button></view>
@@ -83,6 +92,9 @@
 			}
 		},
 		methods: {
+			qtyChange(v){
+				this.printNum = v
+			},
 			cancel(){
 				if(this.fromPage == 'bdtq'){  // 补打贴签
 					uni.navigateBack({delta: 1})
@@ -160,7 +172,7 @@
 	width: 100vh;
 	padding: 50rpx 30rpx;
 	.print-nums{
-		padding: 50rpx 30rpx;
+		padding: 50rpx 30rpx 10rpx;
 		color: #999;
 		font-size: 32rpx;
 		> view{
@@ -184,9 +196,12 @@
 			border-radius: 50rpx;
 		}
 	}
+	.print-radio{
+		padding: 20rpx 20rpx 50rpx;
+		text-align: center;
+	}
 	.shelf-info{
 		background-color: #f8f8f8;
-		padding: 30rpx;
 		border-radius: 12rpx;
 		color: #707070;
 		.shelf-info-title{
@@ -194,7 +209,9 @@
 			color: #222222;
 			display: flex;
 			justify-content: space-between;
-			margin-bottom: 10rpx;
+			border-bottom: 0.1rpx solid #eee;
+			padding: 15rpx 30rpx;
+			font-weight: bold;
 			.shelf-name{
 				flex:1;
 				margin-right: 10rpx;
@@ -209,6 +226,12 @@
 				margin-top:5rpx;
 			}
 		}
+		.shelf-info-body{
+			padding: 15rpx 30rpx;
+			> view{
+				padding: 5rpx 0;
+			}
+		}
 	}
 	.buttons{
 		padding: 50rpx 0;

+ 232 - 71
pages/latePlay/chooseProduct.vue

@@ -1,24 +1,29 @@
 <template>
 	<view class="moreShelfPart flex flex_column">
 		<view class="moreShelfPart-search">
-			<u-search
-			placeholder="请输入货位号/产品编码/产品名称搜索" 
-			v-model="queryWord" 
-			:show-action="isGobleSearch" 
-			@focus="isGobleSearch=true" 
-			@blur="isGobleSearch=false"
-			@custom="searchPart" 
-			@search="searchPart" 
-			@clear="clearSearch"
-			:action-style="{'color': '#fff', 'font-size': '24upx', 'background-color': '#57a3f3', 'border-radius': '6upx', 'padding': '12upx 0'}">
-			</u-search>
-			<view class="p-title">
-				<text></text>
-				{{shelfInfo.shelfName}}
+			<view class="p-title flex align_center">
+				<view class="shelfName flex align_center"><text></text>{{shelfInfo.shelfName}}</view>
+				<view class="btns" @click="showTab = true">筛选<u-icon name="more-circle"></u-icon></view>
+			</view>
+			<view class="search flex align_center">
+				<view class="input">
+					<u-search 
+					v-model="queryWord" 
+					@input="change"
+					@custom="searchPart" 
+					@search="searchPart" 
+					@clear="clearSearch" 
+					bg-color="#fff" 
+					:action-style="{border:'0.1rpx solid #00aaff',borderRadius:'50rpx',color:'#00aaff'}" 
+					placeholder="请输入货位号/产品编码/产品名称搜索"></u-search>
+				</view>
+				<view class="icon" @click="toScan">
+					<u-icon name="scan"></u-icon>
+				</view>
 			</view>
 		</view>
 		<view class="moreShelfPart-body">
-			<scroll-view class="nav-right" scroll-y @scrolltolower="onreachBottom">
+			<scroll-view class="nav-right" scroll-y>
 				<view class="partList-list-box" v-for="item in partList" :key="item.id">
 					<view class="product flex align_center">
 						<view class="flex align_center flex_1">
@@ -27,39 +32,51 @@
 							</view>
 							<view class="pinfo">
 								<view class="pname">
-									<text>{{item.shelfPlaceCode}}</text>{{item.productEntity&&item.productEntity.productName}}
+									<text>{{item.shelfPlaceCode}}</text>{{item.productCode}}
+								</view>
+								<view class="pname pname1">
+									{{item.productName}}
 								</view>
 								<view class="ptxt flex align_center justify_between">
 									<view>
-										<text class="pcode">{{item.productEntity&&item.productEntity.code}}</text>
+									  最大库容:<text class="pnums">{{item.maxQty}}{{item.productEntity&&item.productEntity.unit}}</text>
+									   / 当前库存:<text class="pnums">{{item.qty}}{{item.productEntity&&item.productEntity.unit}}</text>
 									</view>
-									<view>
-									  库存数量:<text class="pnums">{{item.qty}}{{item.productEntity&&item.productEntity.unit}}</text>
+									<view v-if="item.qty" class="print" @click.stop="print(item)">
+										<u-image :src="`/static/${$config('themePath')}/icon_printer@3x.png`" width="45" height="45"></u-image>
 									</view>
 								</view>
 							</view>
 						</view>
 					</view>
-					<view class="ptools flex align_center justify_between">
-						<view></view>
-						<view class="print" @click="print(item)">
-							<u-image :src="`/static/${$config('themePath')}/icon_printer@3x.png`" width="48" height="48"></u-image>
-						</view>
-					</view>
 				</view>
 				<view v-if="partList&&partList.length==0">
 					<u-empty v-if="status!='loading'" :src="`/static/${$config('themePath')}/def_no_data@3x.png`" icon-size="240" :text="noDataText" mode="list" :margin-top="50"></u-empty>
 				</view>
-				<view style="padding: 20upx;" v-if="total>pageSize || status=='loading'">
+				<view style="padding: 20upx;" v-if="status!='loadmore'">
 					<u-loadmore :status="status" />
 				</view>
 			</scroll-view>
 		</view>
+		<!-- 筛选项 -->
+		<u-popup v-model="showTab" mode="right" width="70%">
+			<view class="tabBox flex flex_column">
+				<view class="tabs">
+					<view class="flex">
+						<view :class="item==curTab?'active':''" v-for="item in placeTab" :key="item" @click="curTab=item">{{item}}层</view>
+					</view>
+				</view>
+				<view class="btns">
+					<u-button class="handle-btn" shape="circle" size="medium" hover-class="none" @click="handleClear">重置</u-button>
+					<u-button class="handle-btn" shape="circle" size="medium" hover-class="none" :custom-style="customBtnStyle" @click="clearSearch">查询</u-button>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
 <script>
-	import { getShelfProductList } from '@/api/shelf'
+	import { queryShelfProductList,getProductPlace } from '@/api/shelf'
 	export default {
 		data() {
 			return {
@@ -69,7 +86,7 @@
 				pageNo:1,
 				pageSize: 10,
 				total: 0, // 列表总数
-				noDataText: '暂无货架',
+				noDataText: '暂无数据',
 				status: 'loading',
 				vinstatus: 'loading',
 				shelfInfo: {
@@ -77,6 +94,14 @@
 					shelfName: ''
 				},
 				theme: '',
+				showTab: false,
+				placeTab: [],
+				curTab: '',
+				customBtnStyle: {  //  自定义按钮样式
+					borderColor: this.$config('primaryColor'),
+					backgroundColor: this.$config('primaryColor'),
+					color: '#fff'
+				},
 			}
 		},
 		onLoad(options) {
@@ -86,14 +111,55 @@
 				shelfName: options.shelfName
 			}
 			this.getpartList()
+			this.getShelfPlace()
+		},
+		// 批量打印
+		onNavigationBarButtonTap(e) {
+			const data = Object.assign(this.shelfInfo, {list:this.partList.filter(item => item.qty)})
+			console.log(data)
+			if(data.list.length){
+				uni.navigateTo({
+					url: "/pages/shelfSetting/batchPrint?page=bdtq&data="+encodeURIComponent(JSON.stringify(data)) 
+				})
+			}else{
+				uni.showToast({
+					icon: 'none',
+					title: '没有可打印的产品',
+					duration: 5000
+				})
+			}
 		},
 		methods: {
+			getShelfPlace(flag){
+				getProductPlace({ shelfSn: this.shelfInfo.shelfSn }).then(res => {
+				  if (res.status == 200) {
+					for(let a in res.data){
+						this.placeTab.push(a)
+					}
+					if(!flag){
+					  this.curTab = ''
+					}
+				  } else {
+				    this.placeTab = []
+				  }
+				})
+			},
+			handleClear(){
+				this.curTab = ''
+				this.clearSearch()
+			},
+			// -------------------
 			clearSearch(){
 				this.queryWord = ''
 				this.pageNo = 1
 				this.partList = []
 				this.getpartList()
 			},
+			change(v){
+				if(v==''){
+					this.clearSearch()
+				}
+			},
 			// 搜索配件
 			searchPart(){
 				this.getpartList()
@@ -102,16 +168,15 @@
 			getpartList(){
 				const _this = this
 				let params = {
-				    pageNo: this.pageNo,
-				    pageSize: this.pageSize,
 					shelfSn: this.shelfInfo.shelfSn,
-					queryWord: this.queryWord
+					queryWord: this.queryWord,
+					shelfPlaceCodeHead: this.curTab
 				}
 				_this.status = 'loading'
-				getShelfProductList(params).then(res => {
+				queryShelfProductList(params).then(res => {
 					uni.hideLoading()
 					if(res.status == 200){
-						let list = res.data.list
+						let list = res.data
 						console.log(list)
 						if (list && list.length){
 							// 分页 拼接数据
@@ -120,40 +185,79 @@
 							} else {
 								_this.partList = list
 							}
-							this.total = res.data.count
-							if (_this.partList.length == res.data.count) {
-								_this.status = 'nomore'
-							} else {
-								_this.status = 'loadmore'
-							}
+							_this.status = 'nomore'
 						} else {
 							_this.partList = list || []
-							this.total = 0
-							_this.status = 'nomore'
+							_this.status = 'loadmore'
 						}
-						_this.noDataText = '暂无配件'
+						_this.noDataText = '没有搜索到产品'
 					}else{
 						_this.status = 'loadmore'
 						_this.partList = []
 						_this.total = 0
 						_this.noDataText = res.message ? res.message : '网络似乎出错了,请稍后再试'
 					}
+					this.showTab = false
 				})
 			},
-			// 加载更多
-			onreachBottom () {
-				if(this.partList.length < this.total ){
-					if(this.isGobleSearch&&this.queryWord==''){
-						return
+			print(data){
+				uni.navigateTo({ url: "/pages/common/printTag/printTag?page=bdtq&data="+JSON.stringify(data)})
+			},
+			// 扫描
+			toScan(){
+				this.mpaasScanModule = uni.requireNativePlugin("wss-scan")
+				this.mpaasScanModule.scan(
+				{
+					"scanMode":"Customized",
+					"scanStyle":{
+						"scanFrameSizePlus":{"width":250,"height":250},
+						"scanFrameSize":200,
+						"scanLight":"visible",
+						"scanText":"对准条形码/二维码进行识别",
+						"scanTitle":"扫码打印",
 					}
-					this.pageNo++
-					this.getpartList()
+				},
+				(result) => {
+					console.log(result)
+					if(result.scanStatus == 1){
+						this.scanResult(result)
+					}
+				})
+			},
+			// 扫描结果
+			scanResult(data){
+				const params = {
+					shelfSn: this.shelfInfo.shelfSn,
+				}
+				// 二维码
+				if(data.scanType == 'QRCODE'){
+					const ret = data.scanValue.split("&")
+					params.queryWord = ret[1] // 产品编码
 				}else{
-					this.status = "nomore"
+					params.qrCode = data.scanValue
 				}
-			},
-			print(data){
-				uni.navigateTo({ url: "/pages/common/printTag/printTag?page=bdtq&data="+JSON.stringify(data) })
+				queryShelfProductList(params).then(res => {
+					console.log(res)
+					if(res.status == 200){
+						if(res.data&&res.data.length){
+							if(res.data[0].qty){
+								this.print(res.data[0])
+							}else{
+								uni.showToast({
+									icon: "none",
+									title: "产品库存不足,不能打印",
+									duration: 5000
+								})
+							}
+						}else{
+							uni.showToast({
+								icon: "none",
+								title: "产品不属于此货架,请重新扫描",
+								duration: 5000
+							})
+						}
+					}
+				})
 			}
 		}
 	}
@@ -164,23 +268,49 @@
 		width: 100%;
 		height: 100vh;
 		.moreShelfPart-search{
-			padding: 20rpx 20rpx 0;
+			padding: 0 10rpx;
 			background-color: #FFFFFF;
 			border-bottom: 2rpx solid #f5f5f5;
 		}
 		.p-title{
-			padding: 20rpx;
+			padding: 0 20rpx;
 			display: flex;
 			align-items: center;
 			color: #222;
 			font-size: 32rpx;
-			text{
-				display: block;
-				height: 32rpx;
-				width: 6rpx;
-				background: #0485F6;
-				margin-right: 10rpx;
-				border-radius: 10rpx;
+			.shelfName{
+				width: 80%;
+				flex-grow: 1;
+				font-weight: bold;
+				text{
+					display: block;
+					height: 30rpx;
+					width: 6rpx;
+					background: #0485F6;
+					margin-right: 10rpx;
+					border-radius: 10rpx;
+				}
+			}
+			.btns{
+				width:100rpx;
+				text-align: right;
+				font-size: 28rpx;
+			}
+		}
+		.search{
+			padding: 0.5rem;
+			.input{
+				flex-grow: 1;
+				border:0.1rpx solid #eee;
+				padding: 0.1rpx;
+				border-radius: 50rpx;
+				padding-right: 10rpx;
+			}
+			.icon{
+				width: 10%;
+				text-align: center;
+				font-size: 50rpx;
+				color: #999;
 			}
 		}
 		.moreShelfPart-body{
@@ -188,7 +318,7 @@
 			background-color: #fff;
 		}
 		.nav-right{
-			height: calc(100vh - 180rpx);
+			height: calc(100vh - 160rpx);
 			box-sizing: border-box;
 			
 			.partList-list-box{
@@ -206,20 +336,22 @@
 						flex-grow: 1;
 						padding-left: 20rpx;
 						.pname{
-							font-size: 32rpx;
 							color: #191919;
-							font-weight: bold;
 							margin-bottom: 10rpx;
 							text{
 								font-weight: normal;
 								margin-right: 6rpx;
-								padding: 0 10rpx;
+								padding: 0 20rpx;
 								background: rgba(3, 54, 146, 0.15);
 								border-radius: 100rpx;
 								color: #033692;
-								font-size: 28rpx;
+								font-size: 24rpx;
 							}
 						}
+						.pname1{
+							font-weight: bold;
+							font-size: 32rpx;
+						}
 						.pno{
 							background-color: rgba(3, 54, 146, 0.15);
 							border-radius: 50rpx;
@@ -237,11 +369,40 @@
 						}
 					}
 				}
-				.ptools{
-					margin-top: 20rpx;
-					.print{
-						padding: 0 10rpx;
+			}
+		}
+		
+		// 筛选
+		.tabBox{
+			height: 100vh;
+			.tabs{
+				flex-grow: 1;
+				overflow: auto;
+				padding: 20rpx;
+				> view{
+					flex-wrap: wrap;
+					justify-content: space-between;
+					> view{
+						width: 45%;
+						border: 0.1rpx solid #eee;
+						padding: 15rpx;
+						border-radius: 50rpx;
+						text-align: center;
+						margin-bottom: 15rpx;
 					}
+					.active{
+						border:0;
+						background-color: #0485F6;
+						color: #fff;
+					}
+				}
+			}
+			.btns{
+				display: flex;
+				padding: 20upx;
+				justify-content: space-between;
+				.handle-btn {
+					font-size: 28upx;
 				}
 			}
 		}

+ 42 - 11
pages/replenishmentManage/replenishmentList.vue

@@ -20,10 +20,17 @@
 						</view>
 						<view class="check-col">
 							<view>补货单号:{{item.replenishBillNo}}</view>
-							<view v-if="item.billState=='WAIT_CONFIRM' || item.billState=='CANCEL'">应发数量:{{item.totalQty}}</view>
-							<view v-if="item.billState=='WAIT_OUT_STOCK' || item.billState=='WAIT_CHECK'">实发数量:{{item.totalConfirmQty}}</view>
-							<view v-if="item.billState=='FINISH'">入库数量:{{item.totalPutQty}}</view>
-							<view>{{item.createDate}}</view>
+							<view class="flex align_center justify_between">
+								<view v-if="item.billState=='WAIT_CONFIRM' || item.billState=='CANCEL'">应发数量:{{item.totalQty}}</view>
+								<view v-if="item.billState=='WAIT_OUT_STOCK' || item.billState=='WAIT_CHECK'">实发数量:{{item.totalConfirmQty}}</view>
+								<view v-if="item.billState=='FINISH'">入库数量:{{item.totalPutQty}}</view>
+							</view>
+						</view>
+						<view class="ptools flex align_center justify_between">
+							<view><text>{{item.createDate}}</text></view>
+							<view class="print" @click.stop="print(item)">
+								<u-image :src="`/static/${$config('themePath')}/icon_printer@3x.png`" width="48" height="48"></u-image>
+							</view>
 						</view>
 					 </view>
 					 <u-empty :src="`/static/${$config('themePath')}/def_no_data@3x.png`" icon-size="240" :text="noDataText" img-width="120" v-if="list.length==0 && status!='loading'" mode="list"></u-empty>
@@ -33,13 +40,16 @@
 				</scroll-view>
 			</swiper-item>
 		</swiper>
+		<!-- 打印贴签 -->
+		<print-sticker-modal :openModal="printModal" @confirm="modalPrint" @close="printModal=false" />
 	</view>
 </template>
 
 <script>
+	import printStickerModal from './printStickerModal.vue'
 	import { shelfReplenishList, shelfReplenishStateCount } from '@/api/shelfReplenish'
 	export default {
-		components: {},
+		components: {printStickerModal},
 		data() {
 			return {
 				status: 'loadmore',
@@ -76,10 +86,12 @@
 				current: 0,
 				swiperCurrent: 0,
 				pageNo: 1,
-				pageSize: 6,
+				pageSize: 15,
 				list: [],
 				total: 0,
 				action:'swiperChange', // 操作类型,上划分页,或左右滑动
+				printModal: false,
+				tempData: null
 			}
 		},
 		onLoad(options) {
@@ -208,7 +220,20 @@
 				const _this = this
 				const index = this.tabList.findIndex(item => item.status == tab)
 				_this.tabsChange(index)
-			}
+			},
+			print(item){
+				this.tempData = item
+				this.printModal=true
+			},
+			// 打印贴签 confirm
+			modalPrint(type){
+				this.printModal = false
+				if(type == 'manual'){  // 手动打印
+					uni.navigateTo({ url: "/pages/replenishmentManage/manualPrint?sn="+this.tempData.replenishBillSn })
+				}else if(type == 'scan'){  // 扫码打印
+					uni.navigateTo({ url: "/pages/replenishmentManage/scanCodePrint?sn="+this.tempData.replenishBillSn })
+				}
+			},
 		}
 	}
 </script>
@@ -245,8 +270,8 @@
 		// 列表样式
 		.check-order-list{
 			background: #ffffff;
-			padding: 25upx 35upx;
-			margin: 25upx;
+			padding: 20upx 30upx;
+			margin: 20upx;
 			border-radius: 25upx;
 			box-shadow: 1px 1px 3px #EEEEEE;
 			.check-row{
@@ -268,8 +293,14 @@
 			.check-col{
 				> view{
 					padding: 2rpx 0;
-					color: #707070;
-					font-size: 26rpx;
+					font-size: 28rpx;
+					color: #666666;
+				}
+			}
+			.ptools{
+				color: #707070;
+				.print{
+					padding: 0 10rpx;
 				}
 			}
 		}

+ 4 - 0
pages/shelfSetting/addShelfHw.vue

@@ -192,12 +192,16 @@
 		.pinfo{
 			line-height:normal;
 			padding-left: 20rpx;
+			color: #666;
 			.ptxt{
 				padding-top:10rpx;
 			}
 			.pcode{
 				color:red;
 			}
+			.pname{
+				font-weight: bold;
+			}
 		}
 	}
 	.footer-btn{

+ 189 - 0
pages/shelfSetting/batchPrint.vue

@@ -0,0 +1,189 @@
+<template>
+	<view class="batchPrint-manualPrint-wrap">
+		<view class="batchPrint-manualPrint-body">
+			<u-alert-tips :show="show" @close="show = false" type="warning" description="正在打印中,请勿息屏或退出应用!"></u-alert-tips>
+			<view class="part-list">
+				<!-- 补货产品 -->
+				<productList :list="partList" title="产品列表" ref="productList" noDataText="暂无产品" @allChecked="allCheckedCallback"></productList>
+			</view>
+		</view>
+		<view class="batchPrint-manualPrint-footer">
+			<view>
+				<u-checkbox size="40" @change="allCheckeChange" v-model="allChecked" shape="circle">{{allChecked?'取消全选':'全选'}}</u-checkbox>
+			</view>
+			<view>
+				<kk-printer ref="kkprinter" defaultText="开始打印" @startPrint="startPrint"></kk-printer>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import kkPrinter from '@/components/kk-printer/index.vue';
+	import productList from './productList.vue'
+	import {printTempl} from '@/libs/printTools.js'
+	export default {
+		components: { productList, kkPrinter },
+		data() {
+			return {
+				show: false,
+				basicInfoData:null,
+				partList: [],
+				allChecked: false,
+				printIndex: 0,
+				isParinting: false
+			}
+		},
+		onReady() {
+			uni.setNavigationBarColor({
+				frontColor: '#ffffff',
+				backgroundColor: this.$config('primaryColor')
+			})
+			this.$refs.productList.setData(this.partList)
+		},
+		onLoad(option) {
+			this.basicInfoData = JSON.parse(decodeURIComponent(option.data));
+			this.partList = this.basicInfoData.list
+			// 保持屏幕常亮
+			uni.setKeepScreenOn({
+				keepScreenOn: true
+			});
+		},
+		onUnload() {
+			// this.$refs.kkprinter.closeConnect()
+			this.partList = []
+			// 保持屏幕常亮
+			uni.setKeepScreenOn({
+				keepScreenOn: false
+			});
+		},
+		onBackPress(event){
+			if(event.from == 'backbutton'){
+				if(this.isParinting){
+					uni.showToast({
+						icon:'none',
+						title: '正在打印中...'
+					})
+				}else{
+					uni.navigateBack({delta: 1})
+				}
+				return true  // 阻止默认返回行为(会导致无限循环)
+			}
+		},
+		methods: {
+			// 全选
+			allCheckeChange(e){
+				this.$refs.productList.allSelect(e.value)
+			},
+			allCheckedCallback(val){
+				this.allChecked = val
+			},
+			printOnce(opt,tsc,blesdk,data){
+				const _this = this
+				const dealer = this.$store.state.vuex_userData
+				// 60*40 打印模板
+				const command = printTempl(tsc,{
+					dealerName: dealer.orgName,
+					shelfName: data.shelfName || '',
+					productCode: data.productCode || '',
+					productName: data.productName || '',
+					shelfPlaceCode: data.shelfPlaceCode || '',
+					currentInven: data.printQty,
+					printDate: this.$u.timeFormat(this.timestamp, 'yyyy-mm-dd hh:MM'),
+					printUser: dealer.userNameCN,
+					barCode: `${data.shelfSn}&${data.productCode}&${data.productSn}&${data.shelfPlaceSn}`
+				})
+				// 开始批量打印 
+				blesdk.senBlData(
+				opt.deviceId, 
+				opt.serviceId, 
+				opt.writeId, 
+				command.getData(), 
+				function(){
+					const result =_this.$refs.productList.getAllChecked()
+					_this.printIndex = _this.printIndex + 1
+					if(_this.printIndex < result.length){
+						_this.printOnce(opt,tsc,blesdk,result[_this.printIndex])
+					}else{
+						_this.printIndex = 0
+						_this.$refs.kkprinter.onPrintSuccess()
+						_this.isParinting = false
+						_this.show = false
+					}
+				});
+			},
+			// 批量打印 
+			startPrint(opt,tsc,blesdk){
+				const result =this.$refs.productList.getAllChecked()
+				console.log(result,result.length)
+				if(result.length){
+					 if(this.isParinting){
+					 	return
+					 }
+					 this.isParinting = true
+					 this.show = true
+					 this.printOnce(opt,tsc,blesdk,result[this.printIndex])
+				}else{
+					this.toashMsg("请选择产品!")
+					this.$refs.kkprinter.onPrintFail()
+				}
+			},
+		}
+	}
+</script>
+
+<style lang="less">
+.batchPrint-manualPrint-wrap{
+	position: relative;
+	width: 100%;
+	height: 100%;
+	overflow: hidden;
+	padding-bottom: 102upx;
+	.p-title{
+		padding: 20rpx;
+		display: flex;
+		align-items: center;
+		color: #222;
+		font-size: 32rpx;
+		.shelfName{
+			width: 80%;
+			flex-grow: 1;
+			font-weight: bold;
+			text{
+				display: block;
+				height: 30rpx;
+				width: 6rpx;
+				background: #0485F6;
+				margin-right: 10rpx;
+				border-radius: 10rpx;
+			}
+		}
+		.btns{
+			width:100rpx;
+			text-align: right;
+			font-size: 28rpx;
+		}
+	}
+	.batchPrint-manualPrint-body{
+		.part-list{
+			padding: 10rpx 25rpx;
+			background-color: #fff;
+			margin-bottom: 20rpx;
+			border-radius: 25rpx;
+			box-shadow: 2rpx 3rpx 5rpx #eee;
+		}
+	}
+	.batchPrint-manualPrint-footer{
+		padding: 10upx 32upx 12upx;
+		background-color: #fff;
+		position: fixed;
+		left: 0;
+		bottom: 0;
+		width: 100%;
+		box-shadow: 3px 1px 7px #eee;
+		display: flex;
+		align-items: center;
+		justify-content: space-between;
+	}
+}
+</style>

+ 6 - 2
pages/shelfSetting/editShelfHw.vue

@@ -5,7 +5,7 @@
 				<u-form-item label="货位号">
 					<view class="flex align_center flex_1 justify_between">
 						<view style="width: 80%;">{{shelfPlaceCode}}</view>
-						<view style="width: 20%;text-align: center;" @click="editShelf"><u-icon name='edit-pen'></u-icon></view>
+						<view style="width: 20%;text-align: center;" @click="editShelf"><u-icon name='edit-pen'></u-icon>修改</view>
 					</view>
 				</u-form-item>
 				<view v-if="productEntity">
@@ -18,7 +18,7 @@
 								<view class="ptxt flex align_center justify_between">
 									<text>{{productEntity.code}}</text>
 									<text class="pcode" @click="toBindProduct">
-										<u-icon name='edit-pen'></u-icon>
+										<u-icon name='reload'></u-icon>
 										更换产品
 									</text>
 								</view>
@@ -239,12 +239,16 @@
 		.pinfo{
 			line-height:normal;
 			padding-left: 20rpx;
+			color: #666;
 			.ptxt{
 				padding-bottom:20rpx;
 			}
 			.pcode{
 				color:rgb(0, 170, 255);
 			}
+			.pname{
+				font-weight: bold;
+			}
 		}
 		.noproduct{
 			padding: 40rpx 20rpx;

+ 240 - 0
pages/shelfSetting/productList.vue

@@ -0,0 +1,240 @@
+<template>
+	<view class="partList-box flex flex_column">
+		<view class="partList-title flex align_center justify_between">
+			<text>{{title}}</text>
+			<view>
+				<u-radio-group v-model="printNum" @change="qtyChange">
+					<u-radio :name="0">按当前库存打印</u-radio>
+					<u-radio :name="1">按最大库容打印</u-radio>
+				</u-radio-group>
+			</view>
+		</view>
+		<view class="partList-list">
+			<view class="partList-list-box" v-for="item in partList" :key="item.id">
+				<view class="product flex align_center">
+					<view class="checkbox">
+						<u-checkbox v-model="item.checked" :name="item.id" @change="checkChange" size="40" shape="circle"></u-checkbox>
+					</view>
+					<view class="flex align_center flex_1" @click="checkChange({name:item.id})">
+						<view class="pimgs">
+							<u-image :src="item.productEntity&&item.productEntity.images?item.productEntity.images:`../../static/${$config('themePath')}/def_img@2x.png`" width="128" height="128" border-radius="10"></u-image>
+						</view>
+						<view class="pinfo">
+							<view class="pname">
+								<text>{{item.shelfPlaceCode}}</text>{{item.productCode}}
+							</view>
+							<view class="pname pname1">
+								{{item.productName}}
+							</view>
+							<view class="ptxt flex align_center justify_between">
+								<view>
+								  最大库容:<text class="pnums">{{item.maxQty}}{{item.productEntity&&item.productEntity.unit}}</text>
+								   / 当前库存:<text class="pnums">{{item.qty}}{{item.productEntity&&item.productEntity.unit}}</text>
+								</view>
+							</view>
+						</view>
+					</view>
+				</view>
+				<!-- 有复选框 -->
+				<view class="ptools flex align_center justify_between">
+					<view></view>
+					<view class="pcurnums flex align_center">
+						<text>打印数量</text>
+						<view class="u-ninput">
+							<u-number-box color="#000" bg-color="#fff" v-model="item.printQty" :min="0" :max="item.maxQty"></u-number-box>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="nodata" v-if="partList.length==0">
+				<u-empty :src="`/static/${$config('themePath')}/def_no_data@3x.png`" icon-size="120" :text="noDataText" img-width="120" mode="list"></u-empty>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	export default {
+		props: {
+			list: {
+				type: Array,
+				default: function(){
+					return []
+				}
+			},
+			noDataText: {
+				type: String,
+				default: '暂无产品'
+			},
+			title: {
+				type: String,
+				default: '列表'
+			},
+			// model: checkbox 可选择模式,view 只显示
+			model: {
+				type: String,
+				default: 'checkbox'
+			},
+		},
+		data() {
+			return {
+				partList: [],
+				printNum: 0
+			}
+		},
+		methods: {
+			setData(list){
+				const _this = this
+				list.map(item => {
+					item.printQty = this.printNum == 1 ? item.maxQty : item.qty
+					item.checked = false
+				})
+				this.partList = JSON.parse(JSON.stringify(list))
+			},
+			qtyChange(v){
+				this.partList.map(item => {
+					item.printQty = v == 1 ? item.maxQty : item.qty
+				})
+			},
+			// 全选
+			allSelect(val){
+				this.partList.map(item => {
+					item.checked = val
+				})
+				this.partList.splice()
+			},
+			checkChange(e){
+				const row = this.partList.find(item => item.id == e.name)
+				if(row){
+					row.checked = !row.checked
+					this.partList.splice()
+				}
+				// 判断是否全选
+				const isAllNoChecked = this.partList.filter(item => !item.checked)
+				this.$emit('allChecked',isAllNoChecked.length == 0)
+			},
+			// 获取所有选择的
+			getAllChecked(){
+				return this.partList.filter(item => item.checked && item.printQty)
+			},
+			// 获取所有数据
+			getAllData(){
+				return this.partList
+			},
+			// 数量 change
+			numberChange(value, index){
+				this.$emit('numberChange', value, index)
+			}
+		}
+	}
+</script>
+
+<style lang="less" scoped>
+.partList-box{
+	height: 100%;
+	position: relative;
+	.nodata{
+		padding: 10vh 0;
+	}
+	.partList-title{
+		padding: 10rpx 20rpx;
+		border-bottom: 0.1rpx solid #eee;
+		width: 100%;
+		position: fixed;
+		left: 0;
+		top: 0;
+		background-color: #fff;
+		z-index: 1000;
+		> text{
+			font-size: 32rpx;
+			color: #222222;
+		}
+		> view{
+			font-size: 32rpx;
+			text{
+				color: red;
+				margin: 0 5rpx;
+			}
+		}
+	}
+	.partList-list{
+		flex-grow: 1;
+		padding-top: 70upx;
+	}
+	.partList-list-box{
+		padding: 10px 0;
+		border-bottom: 2rpx solid #f5f5f5;
+		&:last-child{
+			border:0;
+		}
+		.product{
+			flex-grow: 1;
+			.checkbox{
+				width: 60rpx;
+			}
+			.pinfo{
+				flex-grow: 1;
+				padding-left: 20rpx;
+				.pname{
+					color: #191919;
+					margin-bottom: 10rpx;
+					text{
+						font-weight: normal;
+						margin-right: 6rpx;
+						padding: 0 20rpx;
+						background: rgba(3, 54, 146, 0.15);
+						border-radius: 100rpx;
+						color: #033692;
+						font-size: 24rpx;
+					}
+				}
+				.pname1{
+					font-weight: bold;
+					font-size: 32rpx;
+				}
+				.pno{
+					background-color: rgba(3, 54, 146, 0.15);
+					border-radius: 50rpx;
+					padding: 0 20rpx;
+					color: #033692;
+					font-size: 24rpx;
+					margin-right: 10rpx;
+				}
+				.ptxt{
+					font-size: 28rpx;
+					color: #999;
+					.pnums{
+						color: #222;
+						padding: 0 4upx;
+					}
+				}
+			}
+		}
+		.ptools{
+			margin-top: 20rpx;
+			.pcurnums{
+				> text{
+					margin-right: 20rpx;
+				}
+			}
+			.u-ninput{
+				border: 2rpx solid #eee;
+				border-radius: 50rpx;
+				padding: 0 6rpx;
+			}
+			/deep/ .u-icon-disabled{
+				background: #fff!important;
+			}
+			/deep/ .u-number-input{
+				margin: 0 0;
+				border: 2rpx solid #eee;
+				border-top: 0;
+				border-bottom: 0;
+			}
+			/deep/ .u-icon-plus, /deep/ .u-icon-minus{
+				border-radius: 50rpx;
+			}
+		}
+	}
+}
+</style>

+ 116 - 11
pages/shelfSetting/searchShelfHw.vue

@@ -1,7 +1,10 @@
 <template>
 	<view class="content flex flex_column">
 		<view class="searchBar">
-			<view class="shelfName">{{shelfName}}</view>
+			<view class="p-title flex align_center">
+				<view class="shelfName flex align_center"><text></text>{{shelfName}}</view>
+				<view class="btns" @click="showTab = true">筛选<u-icon name="more-circle"></u-icon></view>
+			</view>
 			<view class="search flex align_center">
 				<view class="input">
 					<u-search 
@@ -49,11 +52,25 @@
 				</view>
 			</scroll-view>
 		</view>
+		<!-- 筛选项 -->
+		<u-popup v-model="showTab" mode="right" width="70%">
+			<view class="tabBox flex flex_column">
+				<view class="tabs">
+					<view class="flex">
+						<view :class="item==curTab?'active':''" v-for="item in placeTab" :key="item" @click="curTab=item">{{item}}层</view>
+					</view>
+				</view>
+				<view class="btns">
+					<u-button class="handle-btn" shape="circle" size="medium" hover-class="none" @click="handleClear">重置</u-button>
+					<u-button class="handle-btn" shape="circle" size="medium" hover-class="none" :custom-style="customBtnStyle" @click="clearSearch">查询</u-button>
+				</view>
+			</view>
+		</u-popup>
 	</view>
 </template>
 
 <script>
-	import { getShelfProductList } from '@/api/shelf'
+	import { getShelfProductList,getProductPlace } from '@/api/shelf'
 	export default {
 		data() {
 			return {
@@ -65,13 +82,22 @@
 				total: 0, // 列表总数
 				noDataText: '暂无产品',
 				status: 'loading',
-				partList: []
+				partList: [],
+				showTab: false,
+				placeTab: [],
+				curTab: '',
+				customBtnStyle: {  //  自定义按钮样式
+					borderColor: this.$config('primaryColor'),
+					backgroundColor: this.$config('primaryColor'),
+					color: '#fff'
+				},
 			}
 		},
 		onLoad(opts) {
 			this.shelfName = opts.shelfName
 			this.shelfSn = opts.shelfSn
 			this.getpartList()
+			this.getShelfPlace()
 		},
 		methods: {
 			//编辑货位
@@ -82,6 +108,24 @@
 					url: "/pages/shelfSetting/editShelfHw?detailData="+encodeURIComponent(JSON.stringify(params))+"&type=" + type
 				})
 			},
+			getShelfPlace(flag){
+				getProductPlace({ shelfSn: this.shelfSn }).then(res => {
+				  if (res.status == 200) {
+					for(let a in res.data){
+						this.placeTab.push(a)
+					}
+					if(!flag){
+					  this.curTab = ''
+					}
+				  } else {
+				    this.placeTab = []
+				  }
+				})
+			},
+			handleClear(){
+				this.curTab = ''
+				this.clearSearch()
+			},
 			clearSearch(){
 				this.queryWord = ''
 				this.pageNo = 1
@@ -100,7 +144,8 @@
 				    pageNo: this.pageNo,
 				    pageSize: this.pageSize,
 					shelfSn: this.shelfSn,
-					queryWord: this.queryWord
+					queryWord: this.queryWord,
+					shelfPlaceCodeHead: this.curTab
 				}
 				_this.status = 'loading'
 				getShelfProductList(params).then(res => {
@@ -133,6 +178,7 @@
 						_this.total = 0
 						_this.noDataText = res.message ? res.message : '网络似乎出错了,请稍后再试'
 					}
+					this.showTab = false
 				})
 			},
 			// 加载更多
@@ -206,12 +252,34 @@
 	padding: 0 0.5rem;
 	background: #fff;
 	.searchBar{
-		padding: 0.5rem 0;
-		.shelfName{
-			font-weight: bold;
+		padding: 0 0.3rem;
+		.p-title{
+			padding: 0 20rpx;
+			display: flex;
+			align-items: center;
+			color: #222;
+			font-size: 32rpx;
+			.shelfName{
+				width: 80%;
+				flex-grow: 1;
+				font-weight: bold;
+				text{
+					display: block;
+					height: 30rpx;
+					width: 6rpx;
+					background: #0485F6;
+					margin-right: 10rpx;
+					border-radius: 10rpx;
+				}
+			}
+			.btns{
+				width:100rpx;
+				text-align: right;
+				font-size: 28rpx;
+			}
 		}
 		.search{
-			padding: 0.5rem;
+			padding: 0.5rem 0.5rem 0.3rem 0.5rem;
 			.input{
 				flex-grow: 1;
 				border:0.1rpx solid #eee;
@@ -241,8 +309,9 @@
 			}
 			.product{
 				flex-grow: 1;
-				.checkbox{
-					width: 60rpx;
+				&:active{
+					opacity: 0.6;
+					background-color: #f8f8f8;
 				}
 				.pinfo{
 					flex-grow: 1;
@@ -263,7 +332,8 @@
 					}
 					.ptxt{
 						font-size: 28rpx;
-						color: #666;
+						color: #333;
+						font-weight: bold;
 						.pnums{
 							color: #222;
 						}
@@ -272,5 +342,40 @@
 			}
 		} 
 	}
+	
+	// 筛选
+	.tabBox{
+		height: 100vh;
+		.tabs{
+			flex-grow: 1;
+			overflow: auto;
+			padding: 20rpx;
+			> view{
+				flex-wrap: wrap;
+				justify-content: space-between;
+				> view{
+					width: 45%;
+					border: 0.1rpx solid #eee;
+					padding: 15rpx;
+					border-radius: 50rpx;
+					text-align: center;
+					margin-bottom: 15rpx;
+				}
+				.active{
+					border:0;
+					background-color: #0485F6;
+					color: #fff;
+				}
+			}
+		}
+		.btns{
+			display: flex;
+			padding: 20upx;
+			justify-content: space-between;
+			.handle-btn {
+				font-size: 28upx;
+			}
+		}
+	}
 }
 </style>

+ 10 - 0
pages/shelfSetting/shelfSet.vue

@@ -101,6 +101,16 @@
 			// 更多操作
 			tapPopup(e){
 				console.log(e)
+				// 打印贴签
+				if(e.val == 1){
+					uni.navigateTo({
+						url: "/pages/latePlay/chooseProduct?shelfSn="+this.shelfSn+'&shelfName='+this.detailData.shelfName
+					})
+				}
+				// 快速补货
+				if(e.val == 0){
+					
+				}
 			},
 			showTip(){
 				uni.showModal({