lilei преди 2 години
родител
ревизия
242096935c

+ 1 - 1
App.vue

@@ -5,7 +5,7 @@
 			token: '',
 			changeOrg:'',
 			version: '', // 当前版本号
-			buildType: 'dev', // 打包环境对应类型,pro 生产 uat 预发布 dev 本地开发
+			buildType: 'uat', // 打包环境对应类型,pro 生产 uat 预发布 dev 本地开发
 			envTips: '', // 环境文字提示
 			theme: 'default', // 主题,default
 			isIphoneXup: false //是否iphonex以及以上的版本

+ 9 - 0
pages.json

@@ -598,6 +598,15 @@
             }
             
         }
+        ,{
+            "path" : "pages/batchShelves/batchPrint/batchPrint",
+            "style" :                                                                                    
+            {
+                "navigationBarTitleText": "批量打印",
+                "enablePullDownRefresh": false
+            }
+            
+        }
     ],
 	"globalStyle": {
 		"navigationBarTextStyle": "black",

+ 261 - 0
pages/batchShelves/batchPrint/batchPrint.vue

@@ -0,0 +1,261 @@
+<template>
+	<view class="batchPrint-manualPrint-wrap">
+		<view v-if="type=='search'" class="productList-search">
+			<view class="search flex align_center">
+				<view class="input">
+					<u-search 
+					focus
+					v-model="queryWord" 
+					@input="$u.debounce(searchList, 800)"
+					@custom="$u.debounce(searchList, 500)" 
+					@search="$u.debounce(searchList, 500)" 
+					@clear="clearSearch" 
+					bg-color="#fff" 
+					:show-action="false"
+					placeholder="请输入产品编码查询"></u-search>
+				</view>
+			</view>
+		</view>
+		<view class="batchPrint-manualPrint-body">
+			<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>
+			</view>
+			<view>
+				<kk-printer ref="kkprinter" defaultText="开始打印" @startPrint="startPrint"></kk-printer>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import { clzConfirm, numberToFixed } from '@/libs/tools';
+	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: [],
+				allList:[],
+				allChecked: false,
+				printIndex: 0,
+				isParinting: false,
+				type: '',
+				queryWord: ''
+			}
+		},
+		onReady() {
+			if(this.type == 'manual'){
+				uni.showLoading({
+					title: '正在加载...'
+				})
+				this.$refs.productList.setData(this.partList)
+				setTimeout(()=>{
+					uni.hideLoading()
+					this.allCheckeChange({value:true})
+					this.allChecked = true
+				},3000)
+			}
+		},
+		onLoad(option) {
+			this.basicInfoData = JSON.parse(decodeURIComponent(option.data));
+			this.type = option.type
+			// 批量打印
+			if(this.type == 'manual'){
+				this.partList = this.$store.state.vuex_tempPrintList
+			}else{
+				this.allList = this.$store.state.vuex_tempPrintList
+			}
+			// 保持屏幕常亮
+			uni.setKeepScreenOn({
+				keepScreenOn: true
+			});
+			uni.setNavigationBarColor({
+				frontColor: '#ffffff',
+				backgroundColor: this.$config('primaryColor')
+			})
+			uni.setNavigationBarTitle({
+				title: this.type == 'search' ? '按编码搜索打印' : '批量打印——'+this.basicInfoData.layer+'层'
+			})
+		},
+		onUnload() {
+			this.partList = []
+			// 保持屏幕常亮
+			uni.setKeepScreenOn({
+				keepScreenOn: false
+			});
+			this.$store.state.vuex_tempPrintList = []
+		},
+		onBackPress(event){
+			if(event.from == 'backbutton'){
+				if(this.isParinting){
+					uni.showToast({
+						icon:'none',
+						title: '正在打印中...'
+					})
+				}else{
+					uni.navigateBack({delta: 1})
+				}
+				return true  // 阻止默认返回行为(会导致无限循环)
+			}
+		},
+		methods: {
+			searchList(e){
+				if(this.queryWord == ''){
+					this.clearSearch()
+					return
+				}
+				// 搜索
+				for(let key in this.allList){
+					const item = this.allList[key]
+					const ret = item.filter(a => a.productCode.indexOf(this.queryWord)>=0)
+					this.partList = this.partList.concat(ret)
+				}
+				this.$refs.productList.setData(this.partList)
+			},
+			clearSearch(){
+				this.partList = []
+				this.$refs.productList.setData(this.partList)
+			},
+			// 全选
+			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.product.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
+						uni.hideLoading()
+						clzConfirm({
+						  title: '提示',
+						  content: '打印已经结束,是否返回上页!',
+						  success (ret) {
+							if (ret.confirm || ret.index == 0) {
+								uni.navigateBack()
+							} 
+						  }
+						})
+					}
+				});
+			},
+			// 批量打印 
+			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
+					 uni.showLoading({
+					 	mask: true,
+					 	title: '正在打印中,请勿息屏或退出应用!'
+					 })
+					 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;
+	padding-top: 100upx;
+	.productList-search{
+		padding: 20rpx 30rpx;
+		background-color: #fff;
+		position: fixed;
+		left: 0;
+		top: 0;
+		width: 100%;
+		box-shadow: 3px 1px 7px #eee;
+		display: flex;
+		z-index: 10000;
+		.search{
+			padding: 0.1rem;
+			border-radius: 50rpx;
+			border:0.1rpx solid #eee;
+			width: 100%;
+			.input{
+				flex-grow: 1;
+				padding: 0.1rpx;
+			}
+			.icon{
+				width: 13%;
+				text-align: center;
+				font-size: 46rpx;
+				color: #999;
+			}
+		}
+	}
+	.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>

+ 230 - 0
pages/batchShelves/batchPrint/productList.vue

@@ -0,0 +1,230 @@
+<template>
+	<view class="partList-box flex flex_column">
+		<view class="partList-title flex align_center justify_between">
+			<text>{{title}}</text>
+			<view class="heji">
+				共 <text>{{partList.length}}</text> 产品
+			</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.product&&item.product.images?item.product.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.product.productName}}
+							</view>
+							<view class="ptxt flex align_center justify_end">
+								<view>
+								   本次上架:<text class="pnums">{{item.qty}}{{item.product&&item.product.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="1"></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: [],
+			}
+		},
+		methods: {
+			setData(list){
+				const _this = this
+				list.map(item => {
+					item.printQty = item.qty
+					item.checked = false
+				})
+				this.partList = JSON.parse(JSON.stringify(list))
+			},
+			// 全选
+			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: 30rpx;
+			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: #666;
+					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: 30rpx;
+				}
+				.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>

+ 38 - 3
pages/batchShelves/cartList.vue

@@ -82,6 +82,7 @@
 		</u-popup>
 		<!-- 上架确认 -->
 		<choose-type-modal v-if="chooseModal" :totalKs="totalKs" :totalNums="totalNums" :openModal="chooseModal" @confirm="confirmPut" @close="chooseModal = false" />
+		<printStickerModal v-if="showPrintModal" :layer="curTab" :openModal="showPrintModal" @confirm="confirmPrint" @close="showPrintModal = false"></printStickerModal>
 	</view>
 </template>
 
@@ -89,14 +90,17 @@
 	import { clzConfirm, numberToFixed } from '@/libs/tools';
 	import {queryMapList, queryCountList, shelfCartSave, shelfCartDelete, queryEmptyCostList, shelfCartConfirm} from '@/api/shelfCart.js'
 	import chooseTypeModal from './chooseTypeModal'
+	import printStickerModal from './printStickerModal'
 	export default {
 		components: {
-			chooseTypeModal
+			chooseTypeModal,
+			printStickerModal
 		},
 		data() {
 			return {
 				showPop: false,
 				chooseModal: false,
+				showPrintModal: false,
 				shelfSn: '',
 				shelfName: '',
 				shelfPlaceList: null,
@@ -139,7 +143,7 @@
 			}
 			// 打印贴签
 			if(e.index == 1){
-				
+				this.showPrintModal = true
 			}
 		},
 		methods: {
@@ -199,6 +203,37 @@
 					}
 				})
 			},
+			// 打印
+			confirmPrint(type){
+				this.showPrintModal = false
+				const shelfInfo = {
+					shelfSn: this.shelfSn,
+					shelfName: this.shelfName,
+					layer: this.curTab
+				}
+				// 打印当前层
+				if(type == 'manual'){
+					const list = this.shelfPlaceList[this.curTab]
+					this.$store.state.vuex_tempPrintList = list
+					if(shelfInfo&&list.length){
+						uni.navigateTo({
+							url: "/pages/batchShelves/batchPrint/batchPrint?type=manual&data="+encodeURIComponent(JSON.stringify(shelfInfo)) 
+						})
+					}else{
+						uni.showToast({
+							icon: 'none',
+							title: '没有可打印的产品',
+							duration: 5000
+						})
+					}
+				}else{
+					// 搜索打印
+					this.$store.state.vuex_tempPrintList = this.shelfPlaceList
+					uni.navigateTo({
+						url: "/pages/batchShelves/batchPrint/batchPrint?type=search&data="+encodeURIComponent(JSON.stringify(shelfInfo)) 
+					})
+				}
+			},
 			// 编辑
 			editRow(item){
 				this.$store.state.vuex_tempData = item
@@ -365,7 +400,7 @@
 						}
 						.pname{
 							color: #666;
-							font-size: 26rpx;
+							font-size: 30rpx;
 							font-weight: bold;
 						}
 					}

+ 154 - 0
pages/batchShelves/printStickerModal.vue

@@ -0,0 +1,154 @@
+<template>
+	<u-mask class="commonModal" :show="isShow" :mask-click-able="false">
+		<view class="modal-con">
+			<view class="modal-title">打印贴签</view>
+			<view class="modal-main">
+				<u-radio-group v-model="printType">
+					<u-radio name="manual">
+						<view class="print-con">
+							<u-image class="item-pic" src="../../static/default/icon_print_manual.png" width="80" height="80"></u-image>
+							<view class="print-main">
+								<text class="print-type">打印【{{layer}}】层</text>
+								<text class="print-exp">打印当前层的所有产品</text>
+							</view>
+						</view>
+					</u-radio>
+					<u-radio name="scan">
+						<view class="print-con">
+							<u-image class="item-pic" src="../../static/default/icon_search.png" width="80" height="80"></u-image>
+							<view class="print-main">
+								<text class="print-type">自选打印</text>
+								<text class="print-exp">按产品编码搜索后进行打印</text>
+							</view>
+						</view>
+					</u-radio>
+				</u-radio-group>
+			</view>
+			<view class="modal-footer">
+				<view class="button-cancel" @click="isShow=false">取消</view>
+				<view class="button-confirm" @click="handleConfirm">确定</view>
+			</view>
+		</view>
+	</u-mask>
+</template>
+
+<script>
+	export default {
+		props: {
+			openModal: { //  弹框显示状态
+				type: Boolean,
+				default: false
+			},
+			layer: {
+				type: String,
+				default:''
+			}
+		},
+		data() {
+			return {
+				isShow: this.openModal, //  是否打开弹框
+				printType: 'manual'
+			}
+		},
+		methods: {
+			// 确认
+			handleConfirm(){
+				this.$emit('confirm', this.printType)
+			}
+		},
+		watch: {
+			//  父页面传过来的弹框状态
+			openModal (newValue, oldValue) {
+				this.isShow = newValue
+			},
+			//  重定义的弹框状态
+			isShow (newValue, oldValue) {
+			  if (!newValue) {
+			    this.$emit('close')
+			  }
+			}
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.commonModal{
+		width: 100%;
+		height: 100%;
+		position: absolute;
+		left: 0;
+		top: 0;
+		.modal-con{
+			width: 70%;
+			margin: 50% auto 0;
+			background-color: #fff;
+			border-radius: 24upx;
+			font-size: 26upx;
+			.modal-title{
+				text-align: center;
+				font-size: 30upx;
+				color: #000;
+				padding: 30upx 30upx 0;
+			}
+			.modal-main{
+				margin: 20upx 0 30upx;
+				/deep/ .u-radio{
+					width: 94%!important;
+					flex-direction: row-reverse;
+					justify-content: space-between;
+					margin: 0 3%;
+				}
+				/deep/ .u-radio__icon-wrap{
+					flex-shrink: 0;
+				}
+				/deep/ .u-radio__label{
+					flex-grow: 1;
+					border-bottom: 2upx dashed #E5E5E5;
+					padding: 3% 0;
+				}
+				.print-con{
+					display: flex;
+					justify-content: space-between;
+					align-items: center;
+					.item-pic{
+						flex-shrink: 0;
+						margin-right: 20upx;
+					}
+					.print-main{
+						flex-grow: 1;
+						.print-type{
+							display: block;
+							font-size: 30upx;
+							color: #222;
+						}
+						.print-exp{
+							display: block;
+							font-size: 26upx;
+							color: #666E75;
+							line-height: 40upx;
+						}
+					}
+				}
+			}
+			.modal-footer{
+				font-size: 30upx;
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				text-align: center;
+				border-top: 1upx solid #E5E5E5;
+				.button-cancel{
+					color: #999;
+					border-right: 1upx solid #E5E5E5;
+					flex-grow: 1;
+					padding: 20upx 0;
+				}
+				.button-confirm{
+					color: #2A86F4;
+					flex-grow: 1;
+					padding: 20upx 0;
+				}
+			}
+		}
+	}
+</style>

+ 6 - 4
pages/shelfSetting/batchPrint.vue

@@ -1,7 +1,6 @@
 <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>
@@ -22,6 +21,7 @@
 </template>
 
 <script>
+	import { clzConfirm, numberToFixed } from '@/libs/tools';
 	import kkPrinter from '@/components/kk-printer/index.vue';
 	import productList from './productList.vue'
 	import {printTempl} from '@/libs/printTools.js'
@@ -29,7 +29,6 @@
 		components: { productList, kkPrinter },
 		data() {
 			return {
-				show: false,
 				basicInfoData:null,
 				partList: [],
 				allChecked: false,
@@ -118,7 +117,7 @@
 						_this.printIndex = 0
 						_this.$refs.kkprinter.onPrintSuccess()
 						_this.isParinting = false
-						_this.show = false
+						uni.hideLoading()
 						clzConfirm({
 						  title: '提示',
 						  content: '打印已经结束,是否返回上页!',
@@ -140,7 +139,10 @@
 					 	return
 					 }
 					 this.isParinting = true
-					 this.show = true
+					 uni.showLoading({
+					 	mask: true,
+						title: '正在打印中,请勿息屏或退出应用!'
+					 })
 					 this.printOnce(opt,tsc,blesdk,result[this.printIndex])
 				}else{
 					this.toashMsg("请选择产品!")

+ 2 - 2
pages/shelfSetting/productList.vue

@@ -177,7 +177,7 @@
 				flex-grow: 1;
 				padding-left: 20rpx;
 				.pname{
-					color: #191919;
+					color: #666;
 					margin-bottom: 10rpx;
 					text{
 						font-weight: normal;
@@ -191,7 +191,7 @@
 				}
 				.pname1{
 					font-weight: bold;
-					font-size: 32rpx;
+					font-size: 30rpx;
 				}
 				.pno{
 					background-color: rgba(3, 54, 146, 0.15);

BIN
static/default/icon_search.png