shish 2 месяцев назад
Родитель
Сommit
45dc28feef

+ 167 - 40
ghsPad/src/mixins/product.js

@@ -11,6 +11,7 @@ export default {
 			currentJobId:0,//业务类型对应的主体ID等
 			currentBackJobId:1,
 			globalHasHand:0,
+			globalHandOrderList:[],
 			isCut:false,
 			productInfoList: [], //商品信息
 			classIndex: 0, //当前商品类别下标
@@ -46,6 +47,9 @@ export default {
 			let selectInfo = this.getSelectInfo;
 			return selectInfo[this.currentJobType+'_'+this.currentJobId] || []
 		},
+		handOrderCount() {
+			return Array.isArray(this.globalHandOrderList) ? this.globalHandOrderList.length : 0
+		},
 		allPrice() {
 			let price = 0;
 			if(!this.$util.isEmpty(this.selectList)){
@@ -96,61 +100,184 @@ export default {
 			this.setSelectInfo({ currentJobType: this.currentJobType, info: selectData,currentJobId:this.currentJobId })
 			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, selectData)
 		},
+		getHandOrderStorageKey(){
+			return 'handOrderList_'+this.currentJobType
+		},
+		cloneHandOrderData(data){
+			if(this.$util.isEmpty(data)){
+				return Array.isArray(data) ? [] : {}
+			}
+			try{
+				return JSON.parse(JSON.stringify(data))
+			}catch(e){
+				return data
+			}
+		},
+		createHandOrderId(){
+			return Date.now()+'_'+Math.floor(Math.random()*100000)
+		},
+		normalizeHandOrderList(list){
+			if(!Array.isArray(list)){
+				return []
+			}
+			return list.filter(order => {
+				return order && !this.$util.isEmpty(order.selectList)
+			}).map(order => {
+				return {
+					...order,
+					id: order.id || this.createHandOrderId(),
+					createTime: order.createTime || Date.now(),
+					selectList: Array.isArray(order.selectList) ? order.selectList : [],
+					xj: Array.isArray(order.xj) ? order.xj : []
+				}
+			})
+		},
+		refreshHandOrderList(){
+			let list = this.normalizeHandOrderList(uni.getStorageSync(this.getHandOrderStorageKey()))
+			let legacyInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
+			if(!this.$util.isEmpty(legacyInfo)){
+				let legacyXj = uni.getStorageSync("xj_hand_"+this.currentBackJobId)
+				list.unshift({
+					id: this.createHandOrderId(),
+					createTime: Date.now(),
+					selectList: this.cloneHandOrderData(legacyInfo),
+					xj: this.$util.isEmpty(legacyXj) ? [] : this.cloneHandOrderData(legacyXj),
+					customId: this.customId || 0,
+					customName: this.customName || ''
+				})
+				uni.removeStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
+				uni.removeStorageSync("xj_hand_"+this.currentBackJobId)
+			}
+			return this.saveHandOrderList(list)
+		},
+		saveHandOrderList(list){
+			let saveList = this.normalizeHandOrderList(list)
+			uni.setStorageSync(this.getHandOrderStorageKey(), saveList)
+			this.globalHandOrderList = saveList
+			this.globalHasHand = saveList.length > 0 ? 1 : 0
+			return saveList
+		},
+		getHandOrderTotalNum(order){
+			if(!order || this.$util.isEmpty(order.selectList)){
+				return 0
+			}
+			return order.selectList.reduce((total,item) => {
+				return Number(total)+Number(item.currentNum || 0)
+			},0)
+		},
+		getHandOrderTotalPrice(order){
+			if(!order || this.$util.isEmpty(order.selectList)){
+				return 0
+			}
+			let price = order.selectList.reduce((total,item) => {
+				return Number(total)+Number(item.currentNum || 0)*Number(item.unitPrice || 0)
+			},0)
+			return parseFloat(price.toFixed(2))
+		},
+		formatHandOrderTime(order){
+			let time = order && order.createTime ? Number(order.createTime) : Date.now()
+			if(isNaN(time)){
+				time = Date.now()
+			}
+			let date = new Date(time)
+			let pad = num => Number(num) < 10 ? '0'+Number(num) : String(num)
+			return pad(date.getMonth()+1)+'-'+pad(date.getDate())+' '+pad(date.getHours())+':'+pad(date.getMinutes())
+		},
+		getHandOrderTitle(order,index){
+			let customName = order.customName || '快捷开单'
+			let itemCount = order.selectList ? order.selectList.length : 0
+			return (index+1)+'. '+customName+' '+itemCount+'项 ¥'+this.getHandOrderTotalPrice(order)
+		},
 		handOrder(){
-			let that = this
 			this.$util.hitVoice()
-			let has = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-			if(!this.$util.isEmpty(has)){
-				this.$msg('已挂了一单')
-				return false
-			}
-
 			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId)
 			if(this.$util.isEmpty(currentInfo)){
 				this.$msg('没有花材要挂单')
 				return false
 			}
-			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId, currentInfo)
-
-			//多颜色也要挂单
+			let list = this.refreshHandOrderList()
+			let custom = this.custom ? this.cloneHandOrderData(this.custom) : {}
 			let xjInfo = uni.getStorageSync("xj")
-			if (!this.$util.isEmpty(xjInfo)) {
-				uni.setStorageSync("xj_hand_"+this.currentBackJobId, xjInfo)
-				uni.removeStorageSync("xj")
-			}
-
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentJobId)
-			that.reSetSelectInfo({currentJobType:that.currentJobType,currentJobId:that.currentJobId})
-
-			this.globalHasHand = 1
+			list.unshift({
+				id: this.createHandOrderId(),
+				createTime: Date.now(),
+				selectList: this.cloneHandOrderData(currentInfo),
+				xj: this.$util.isEmpty(xjInfo) ? [] : this.cloneHandOrderData(xjInfo),
+				customId: this.customId || 0,
+				customName: this.customName || custom.name || '',
+				custom
+			})
+			this.saveHandOrderList(list)
+			this.removeFromSaveDirect()
+			this.$msg('已挂单')
+			return true
 		},
 		getHandOrder(){
-			let that = this
 			this.$util.hitVoice()
-			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-			if(this.$util.isEmpty(currentInfo)){
+			let list = this.refreshHandOrderList()
+			if(this.$util.isEmpty(list)){
 				this.$msg('没有挂单')
 				return false
 			}
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentJobId)
-			that.reSetSelectInfo({currentJobType:that.currentJobType,currentJobId:that.currentJobId})
-
-			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, currentInfo)
-			if(!this.$util.isEmpty(currentInfo)){
-				this.setSelectInfo({ currentJobType: this.currentJobType, info: currentInfo,currentJobId:this.currentJobId })
+			if(list.length == 1){
+				return this.takeHandOrder(list[0].id)
 			}
-
-			//清除挂单
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentBackJobId)
-
-			//多颜色的处理
-			let xjInfo = uni.getStorageSync("xj_hand_"+this.currentBackJobId)
-			if (!this.$util.isEmpty(xjInfo)) {
-				uni.setStorageSync("xj", xjInfo)
-				uni.removeStorageSync("xj_hand_"+this.currentBackJobId)
+			uni.showActionSheet({
+				itemList: list.map((order,index) => this.getHandOrderTitle(order,index)),
+				success: res => {
+					let order = this.globalHandOrderList[res.tapIndex]
+					if(order){
+						this.takeHandOrder(order.id)
+					}
+				}
+			})
+			return true
+		},
+		takeHandOrder(id){
+			let list = this.refreshHandOrderList()
+			let index = list.findIndex(order => String(order.id) === String(id))
+			if(index == -1){
+				this.$msg('挂单不存在')
+				return false
 			}
-
-			this.globalHasHand = 0
+			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId)
+			if(!this.$util.isEmpty(currentInfo) || !this.$util.isEmpty(this.selectList)){
+				this.$msg('请先挂单或清空当前花材')
+				return false
+			}
+			let order = list[index]
+			let currentInfoList = this.cloneHandOrderData(order.selectList)
+			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, currentInfoList)
+			this.setSelectInfo({ currentJobType: this.currentJobType, info: currentInfoList,currentJobId:this.currentJobId })
+			uni.removeStorageSync('xj')
+			if(!this.$util.isEmpty(order.xj)){
+				uni.setStorageSync("xj", this.cloneHandOrderData(order.xj))
+			}
+			if(order.customId !== undefined){
+				this.$emit('update:customId', Number(order.customId) || 0)
+			}
+			if(order.customName !== undefined){
+				this.$emit('update:customName', order.customName || '')
+			}
+			if(order.custom !== undefined){
+				this.$emit('update:custom', this.cloneHandOrderData(order.custom || {}))
+			}
+			list.splice(index,1)
+			this.saveHandOrderList(list)
+			this.$msg('已取单')
+			return true
+		},
+		deleteHandOrder(id){
+			let list = this.refreshHandOrderList()
+			let index = list.findIndex(order => String(order.id) === String(id))
+			if(index == -1){
+				this.$msg('挂单不存在')
+				return false
+			}
+			list.splice(index,1)
+			this.saveHandOrderList(list)
+			this.$msg('已删除')
+			return true
 		},
 		removeFromSave(){
 			let that = this
@@ -494,4 +621,4 @@ export default {
             this.globalShowCatItem()
         }
 	}
-}
+}

+ 147 - 16
ghsPad/src/pages/home/components/console.vue

@@ -3,8 +3,8 @@
 	<view class="active" @click="openBox">开箱</view>
 	<view class="active" @click="toWastage" style="border:1upx solid #f1a313;color:#f1a313;">报损</view>
 	<view class="active2" :class="[fastAction==1 ? 'clear-fast' : 'clear']" style="" @click="beginSettle">结算</view>
-	<view class="active2" :class="[fastAction==1 ? 'hand-fast' : 'hand']" @click="handOrder()" v-if="globalHasHand == 0">挂</view>
-	<view class="active2" :class="[fastAction==1 ? 'out-fast' : 'out']" @click="getHandOrder()" v-else>取单</view>
+	<view class="active2" :class="[fastAction==1 ? 'hand-fast' : 'hand']" @click="handOrder()">挂</view>
+	<view class="active2" :class="[fastAction==1 ? 'out-fast' : 'out']" @click="openHandOrderPop">取</view>
 	<view class="active" @click="showCustomPop" style="background-color:#3385FF;color:white;">选客</view>
 	<view class="active" @click="part()" style="border:1upx solid black;color:black">拆散</view>
 	<view class="active" @click="fastCreate" style="font-size:8upx;">快捷开单</view>
@@ -22,6 +22,29 @@
 		</view>
 	</uni-popup>
 
+	<uni-popup ref="handOrderRef" background-color="#fff" type="center" :animation="false">
+		<view class="hand-order-pop">
+			<view class="hand-order-head">
+				<view class="hand-order-title">挂单列表</view>
+				<view class="hand-order-close" @click="closeHandOrderPop">×</view>
+			</view>
+			<scroll-view v-if="handOrderCount > 0" class="hand-order-scroll" scroll-y="true">
+				<view class="hand-order-item" v-for="(order,index) in globalHandOrderList" :key="order.id">
+					<view class="hand-order-main" @click="confirmTakeHandOrder(order.id)">
+						<view class="hand-order-name">{{ order.customName || '快捷开单' }}</view>
+						<view class="hand-order-meta">{{ formatHandOrderTime(order) }} · {{ order.selectList.length }}项 · {{ getHandOrderTotalNum(order) }}件</view>
+					</view>
+					<view class="hand-order-price">¥{{ getHandOrderTotalPrice(order) }}</view>
+					<view class="hand-order-actions">
+						<button class="admin-button-com mini-btn default" @click.stop="confirmTakeHandOrder(order.id)">取单</button>
+						<button class="admin-button-com mini-btn default danger" @click.stop="removeHandOrderFromPop(order.id)">删除</button>
+					</view>
+				</view>
+			</scroll-view>
+			<view v-else class="hand-order-empty">暂无挂单</view>
+		</view>
+	</uni-popup>
+
     <uni-popup ref="logoutRef" type="dialog">
         <uni-popup-dialog type="info" cancelText="取消" confirmText="确认" title="提示" content="确认退出?" @confirm="confirmLogout"></uni-popup-dialog>
     </uni-popup>
@@ -150,17 +173,39 @@ export default {
 		}
     },
 	created(){
-
-		//判断是否有单可取
-		let has = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-		if(!this.$util.isEmpty(has)){
-			this.globalHasHand = 1
-		}
-
+		this.refreshHandOrderList()
 	},
 	destroyed(){
 	},
     methods:{
+		openHandOrderPop(){
+			this.$util.hitVoice()
+			this.refreshHandOrderList()
+			if(this.$util.isEmpty(this.globalHandOrderList)){
+				this.$msg('没有挂单')
+				return false
+			}
+			this.$refs.handOrderRef.open('center')
+		},
+		closeHandOrderPop(){
+			this.$refs.handOrderRef.close()
+		},
+		confirmTakeHandOrder(id){
+			this.$util.hitVoice()
+			let success = this.takeHandOrder(id)
+			if(success){
+				this.closeHandOrderPop()
+			}
+		},
+		removeHandOrderFromPop(id){
+			this.$util.hitVoice()
+			this.$util.confirmModal({content:'确认删除挂单?'},() => {
+				let success = this.deleteHandOrder(id)
+				if(success && this.$util.isEmpty(this.globalHandOrderList)){
+					this.closeHandOrderPop()
+				}
+			})
+		},
 		part(){
 			this.$util.hitVoice()
 			if(this.$util.isEmpty(this.selectList)) {
@@ -433,22 +478,22 @@ export default {
 		font-weight:bold;
 	}
 	& .clear-fast{
-		background-color:#3385FF;color:white;border-color:#3385FF;position:fixed;left:135upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
+		background-color:#3385FF;color:white;border-color:#3385FF;position:fixed;left:142upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
 	}
 	& .hand-fast{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color: #3385FF;border-color: #3385FF;
+		position:fixed;left:33upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: #3385FF;border-color: #3385FF;background-color:#fff;
 	}
 	& .out-fast{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color:white;background-color: #3385FF;
+		position:fixed;left:84upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: #3385FF;border-color: #3385FF;background-color:#fff;
 	}
 	& .clear{
-		background-color:orange;color:white;border-color:orange;position:fixed;left:135upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
+		background-color:orange;color:white;border-color:orange;position:fixed;left:142upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
 	}
 	& .hand{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color: orange;border-color: orange;
+		position:fixed;left:36upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: orange;border-color: orange;background-color:#fff;
 	}
 	& .out{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color:white;background-color: orange;border-color: orange;
+		position:fixed;left:90upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: orange;border-color: orange;background-color:#fff;
 	}
 	& .custom-fast{
 		position:fixed;left:32upx;bottom:66upx;width:189upx;height:20upx;line-height:5upx;font-size:13upx;background-color:white;color:#3385FF;font-weight:bold;border:none;
@@ -457,4 +502,90 @@ export default {
 		position:fixed;left:32upx;bottom:66upx;width:189upx;height:20upx;line-height:5upx;font-size:13upx;background-color:white;color:orange;font-weight:bold;border:none;
 	}
 }
-</style>
+.hand-order-pop{
+	width: 500upx;
+	max-height: 90vh;
+	background-color: #fff;
+	border-radius: 8upx;
+	padding: 24upx;
+	box-sizing: border-box;
+}
+.hand-order-head{
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 18upx;
+}
+.hand-order-title{
+	font-size: 24upx;
+	font-weight: bold;
+	color: #222;
+}
+.hand-order-close{
+	width: 42upx;
+	height: 42upx;
+	line-height: 38upx;
+	text-align: center;
+	border-radius: 50%;
+	color: #666;
+	background-color: #f3f5f7;
+	font-size: 24upx;
+}
+.hand-order-scroll{
+	max-height: 58vh;
+}
+.hand-order-item{
+	display: flex;
+	align-items: center;
+	padding: 18upx 0;
+	border-bottom: 1upx solid #eee;
+}
+.hand-order-main{
+	flex: 1;
+	min-width: 0;
+}
+.hand-order-name{
+	font-size: 20upx;
+	font-weight: bold;
+	color: #222;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+.hand-order-meta{
+	margin-top: 8upx;
+	font-size: 16upx;
+	color: #888;
+}
+.hand-order-price{
+	width: 110upx;
+	text-align: right;
+	font-size: 20upx;
+	font-weight: bold;
+	color: #f39800;
+}
+.hand-order-actions{
+	display: flex;
+	margin-left: 16upx;
+}
+.hand-order-actions .mini-btn{
+	margin-left: 10upx;
+	font-size: 16upx;
+	line-height: 32upx;
+	height: 36upx;
+	min-width: 58upx;
+	padding: 0 10upx;
+}
+.hand-order-actions .danger{
+	color: #d93025;
+	border-color: #d93025;
+}
+.hand-order-empty{
+	height: 180upx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	color: #999;
+	font-size: 20upx;
+}
+</style>

+ 172 - 27
hdPad/src/mixins/product.js

@@ -10,6 +10,7 @@ export default {
 			currentJobId:0,//业务类型对应的主体ID等
 			currentBackJobId:1,
 			globalHasHand:0,
+			globalHandOrderList:[],
 			isCut:false,
 			productInfoList: [], //商品信息
 			classIndex: 0, //当前商品类别下标
@@ -44,6 +45,9 @@ export default {
 			let selectInfo = this.getSelectInfo;
 			return selectInfo[this.currentJobType+'_'+this.currentJobId] || []
 		},
+		handOrderCount() {
+			return Array.isArray(this.globalHandOrderList) ? this.globalHandOrderList.length : 0
+		},
 		allPrice() {
 			let price = 0;
 			if(!this.$util.isEmpty(this.selectList)){
@@ -94,47 +98,184 @@ export default {
 			this.setSelectInfo({ currentJobType: this.currentJobType, info: selectData,currentJobId:this.currentJobId })
 			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, selectData)
 		},
+		getHandOrderStorageKey(){
+			return 'handOrderList_'+this.currentJobType
+		},
+		cloneHandOrderData(data){
+			if(this.$util.isEmpty(data)){
+				return Array.isArray(data) ? [] : {}
+			}
+			try{
+				return JSON.parse(JSON.stringify(data))
+			}catch(e){
+				return data
+			}
+		},
+		createHandOrderId(){
+			return Date.now()+'_'+Math.floor(Math.random()*100000)
+		},
+		normalizeHandOrderList(list){
+			if(!Array.isArray(list)){
+				return []
+			}
+			return list.filter(order => {
+				return order && !this.$util.isEmpty(order.selectList)
+			}).map(order => {
+				return {
+					...order,
+					id: order.id || this.createHandOrderId(),
+					createTime: order.createTime || Date.now(),
+					selectList: Array.isArray(order.selectList) ? order.selectList : [],
+					xj: Array.isArray(order.xj) ? order.xj : []
+				}
+			})
+		},
+		refreshHandOrderList(){
+			let list = this.normalizeHandOrderList(uni.getStorageSync(this.getHandOrderStorageKey()))
+			let legacyInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
+			if(!this.$util.isEmpty(legacyInfo)){
+				let legacyXj = uni.getStorageSync("xj_hand_"+this.currentBackJobId)
+				list.unshift({
+					id: this.createHandOrderId(),
+					createTime: Date.now(),
+					selectList: this.cloneHandOrderData(legacyInfo),
+					xj: this.$util.isEmpty(legacyXj) ? [] : this.cloneHandOrderData(legacyXj),
+					customId: this.customId || 0,
+					customName: this.customName || ''
+				})
+				uni.removeStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
+				uni.removeStorageSync("xj_hand_"+this.currentBackJobId)
+			}
+			return this.saveHandOrderList(list)
+		},
+		saveHandOrderList(list){
+			let saveList = this.normalizeHandOrderList(list)
+			uni.setStorageSync(this.getHandOrderStorageKey(), saveList)
+			this.globalHandOrderList = saveList
+			this.globalHasHand = saveList.length > 0 ? 1 : 0
+			return saveList
+		},
+		getHandOrderTotalNum(order){
+			if(!order || this.$util.isEmpty(order.selectList)){
+				return 0
+			}
+			return order.selectList.reduce((total,item) => {
+				return Number(total)+Number(item.currentNum || 0)
+			},0)
+		},
+		getHandOrderTotalPrice(order){
+			if(!order || this.$util.isEmpty(order.selectList)){
+				return 0
+			}
+			let price = order.selectList.reduce((total,item) => {
+				return Number(total)+Number(item.currentNum || 0)*Number(item.unitPrice || 0)
+			},0)
+			return parseFloat(price.toFixed(2))
+		},
+		formatHandOrderTime(order){
+			let time = order && order.createTime ? Number(order.createTime) : Date.now()
+			if(isNaN(time)){
+				time = Date.now()
+			}
+			let date = new Date(time)
+			let pad = num => Number(num) < 10 ? '0'+Number(num) : String(num)
+			return pad(date.getMonth()+1)+'-'+pad(date.getDate())+' '+pad(date.getHours())+':'+pad(date.getMinutes())
+		},
+		getHandOrderTitle(order,index){
+			let customName = order.customName || '快捷开单'
+			let itemCount = order.selectList ? order.selectList.length : 0
+			return (index+1)+'. '+customName+' '+itemCount+'项 ¥'+this.getHandOrderTotalPrice(order)
+		},
 		handOrder(){
-			let that = this
 			this.$util.hitVoice()
-			let has = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-			if(!this.$util.isEmpty(has)){
-				this.$msg('已挂了一单')
-				return false
-			}
-
 			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId)
 			if(this.$util.isEmpty(currentInfo)){
 				this.$msg('没有花材要挂单')
 				return false
 			}
-			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId, currentInfo)
-
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentJobId)
-			that.reSetSelectInfo({currentJobType:that.currentJobType,currentJobId:that.currentJobId})
-
-			this.globalHasHand = 1
+			let list = this.refreshHandOrderList()
+			let custom = this.custom ? this.cloneHandOrderData(this.custom) : {}
+			let xjInfo = uni.getStorageSync("xj")
+			list.unshift({
+				id: this.createHandOrderId(),
+				createTime: Date.now(),
+				selectList: this.cloneHandOrderData(currentInfo),
+				xj: this.$util.isEmpty(xjInfo) ? [] : this.cloneHandOrderData(xjInfo),
+				customId: this.customId || 0,
+				customName: this.customName || custom.name || '',
+				custom
+			})
+			this.saveHandOrderList(list)
+			this.removeFromSaveDirect()
+			this.$msg('已挂单')
+			return true
 		},
 		getHandOrder(){
-			let that = this
 			this.$util.hitVoice()
-			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-			if(this.$util.isEmpty(currentInfo)){
+			let list = this.refreshHandOrderList()
+			if(this.$util.isEmpty(list)){
 				this.$msg('没有挂单')
 				return false
 			}
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentJobId)
-			that.reSetSelectInfo({currentJobType:that.currentJobType,currentJobId:that.currentJobId})
-
-			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, currentInfo)
-			if(!this.$util.isEmpty(currentInfo)){
-				this.setSelectInfo({ currentJobType: this.currentJobType, info: currentInfo,currentJobId:this.currentJobId })
+			if(list.length == 1){
+				return this.takeHandOrder(list[0].id)
 			}
-
-			//清除挂单
-			uni.removeStorageSync('selectList_'+that.currentJobType+'_target_'+that.currentBackJobId)
-
-			this.globalHasHand = 0
+			uni.showActionSheet({
+				itemList: list.map((order,index) => this.getHandOrderTitle(order,index)),
+				success: res => {
+					let order = this.globalHandOrderList[res.tapIndex]
+					if(order){
+						this.takeHandOrder(order.id)
+					}
+				}
+			})
+			return true
+		},
+		takeHandOrder(id){
+			let list = this.refreshHandOrderList()
+			let index = list.findIndex(order => String(order.id) === String(id))
+			if(index == -1){
+				this.$msg('挂单不存在')
+				return false
+			}
+			let currentInfo = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId)
+			if(!this.$util.isEmpty(currentInfo) || !this.$util.isEmpty(this.selectList)){
+				this.$msg('请先挂单或清空当前花材')
+				return false
+			}
+			let order = list[index]
+			let currentInfoList = this.cloneHandOrderData(order.selectList)
+			uni.setStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentJobId, currentInfoList)
+			this.setSelectInfo({ currentJobType: this.currentJobType, info: currentInfoList,currentJobId:this.currentJobId })
+			uni.removeStorageSync('xj')
+			if(!this.$util.isEmpty(order.xj)){
+				uni.setStorageSync("xj", this.cloneHandOrderData(order.xj))
+			}
+			if(order.customId !== undefined){
+				this.$emit('update:customId', Number(order.customId) || 0)
+			}
+			if(order.customName !== undefined){
+				this.$emit('update:customName', order.customName || '')
+			}
+			if(order.custom !== undefined){
+				this.$emit('update:custom', this.cloneHandOrderData(order.custom || {}))
+			}
+			list.splice(index,1)
+			this.saveHandOrderList(list)
+			this.$msg('已取单')
+			return true
+		},
+		deleteHandOrder(id){
+			let list = this.refreshHandOrderList()
+			let index = list.findIndex(order => String(order.id) === String(id))
+			if(index == -1){
+				this.$msg('挂单不存在')
+				return false
+			}
+			list.splice(index,1)
+			this.saveHandOrderList(list)
+			this.$msg('已删除')
+			return true
 		},
 		removeFromSave(){
 			let that = this
@@ -162,6 +303,10 @@ export default {
 				})
 				this.$forceUpdate()
 			}
+
+			//多颜色也需要删除
+			uni.removeStorageSync('xj')
+
 		},
 		//取出缓存数据
 		initDataFromStorage() {

+ 146 - 14
hdPad/src/pages/home/components/console.vue

@@ -3,9 +3,9 @@
 	<view class="active" @click="changeProperty(1)">花材</view>
 	<view class="active" @click="changeProperty(0)">花束</view>
 	<view class="active" @click="openBox">开箱</view>
-	<view class="active" :class="[fastAction==1 ? 'clear-fast' : 'clear']" @click="goSettleCommit">结算</view>
-	<view class="active2" :class="[fastAction==1 ? 'hand-fast' : 'hand']" @click="handOrder()" v-if="globalHasHand == 0">挂</view>
-	<view class="active2" :class="[fastAction==1 ? 'out-fast' : 'out']" @click="getHandOrder()" v-else>取单</view>
+	<view class="active2" :class="[fastAction==1 ? 'clear-fast' : 'clear']" @click="goSettleCommit">结算</view>
+	<view class="active2" :class="[fastAction==1 ? 'hand-fast' : 'hand']" @click="handOrder()">挂</view>
+	<view class="active2" :class="[fastAction==1 ? 'out-fast' : 'out']" @click="openHandOrderPop">取</view>
     <view class="active" @click="toWastage" style="color:#f1a313;border:1upx solid #f1a313;">报损</view>
 	<view class="active" @click="showCustomPop()" style="background-color: #09C567;border:1upx sold #09C567;color:white;">选客</view>
 	<view class="active" @click="part()" style="border:1upx solid black;color:black">拆散</view>
@@ -25,6 +25,28 @@
 		</view>
 	</uni-popup>
 
+	<uni-popup ref="handOrderRef" background-color="#fff" type="center" :animation="false">
+		<view class="hand-order-pop">
+			<view class="hand-order-head">
+				<view class="hand-order-title">挂单列表</view>
+				<view class="hand-order-close" @click="closeHandOrderPop">×</view>
+			</view>
+			<scroll-view v-if="handOrderCount > 0" class="hand-order-scroll" scroll-y="true">
+				<view class="hand-order-item" v-for="(order,index) in globalHandOrderList" :key="order.id">
+					<view class="hand-order-main" @click="confirmTakeHandOrder(order.id)">
+						<view class="hand-order-name">{{ order.customName || '快捷开单' }}</view>
+						<view class="hand-order-meta">{{ formatHandOrderTime(order) }} · {{ order.selectList.length }}项 · {{ getHandOrderTotalNum(order) }}件</view>
+					</view>
+					<view class="hand-order-price">¥{{ getHandOrderTotalPrice(order) }}</view>
+					<view class="hand-order-actions">
+						<button class="admin-button-com mini-btn default" @click.stop="confirmTakeHandOrder(order.id)">取单</button>
+						<button class="admin-button-com mini-btn default danger" @click.stop="removeHandOrderFromPop(order.id)">删除</button>
+					</view>
+				</view>
+			</scroll-view>
+			<view v-else class="hand-order-empty">暂无挂单</view>
+		</view>
+	</uni-popup>
 
     <uni-popup ref="logoutRef" type="dialog">
         <uni-popup-dialog type="info" cancelText="取消" confirmText="确认" title="提示" content="确认退出?" @confirm="confirmLogout"></uni-popup-dialog>
@@ -166,11 +188,7 @@ export default {
 		}
     },
 	created(){
-		//判断是否有单可取
-		let has = uni.getStorageSync('selectList_'+this.currentJobType+'_target_'+this.currentBackJobId)
-		if(!this.$util.isEmpty(has)){
-			this.globalHasHand = 1
-		}
+		this.refreshHandOrderList()
 	},
 	mounted(){
 
@@ -178,6 +196,34 @@ export default {
 	destroyed(){
 	},
     methods:{
+		openHandOrderPop(){
+			this.$util.hitVoice()
+			this.refreshHandOrderList()
+			if(this.$util.isEmpty(this.globalHandOrderList)){
+				this.$msg('没有挂单')
+				return false
+			}
+			this.$refs.handOrderRef.open('center')
+		},
+		closeHandOrderPop(){
+			this.$refs.handOrderRef.close()
+		},
+		confirmTakeHandOrder(id){
+			this.$util.hitVoice()
+			let success = this.takeHandOrder(id)
+			if(success){
+				this.closeHandOrderPop()
+			}
+		},
+		removeHandOrderFromPop(id){
+			this.$util.hitVoice()
+			this.$util.confirmModal({content:'确认删除挂单?'},() => {
+				let success = this.deleteHandOrder(id)
+				if(success && this.$util.isEmpty(this.globalHandOrderList)){
+					this.closeHandOrderPop()
+				}
+			})
+		},
 		part(){
 			this.$util.hitVoice()
 			if(this.$util.isEmpty(this.selectList)) {
@@ -495,25 +541,111 @@ export default {
 		position:fixed;left:32upx;bottom:66upx;width:189upx;height:20upx;line-height:5upx;font-size:13upx;background-color:white;color:#09C567;font-weight:bold;border:none;
 	}
 	& .clear-fast{
-		background-color:#09C567;color:white;border-color:#09C567;position:fixed;left:135upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
+		background-color:#09C567;color:white;border-color:#09C567;position:fixed;left:137upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
 	}
 	& .hand-fast{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color: #09C567;border-color: #09C567;
+		position:fixed;left:34upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: #09C567;border-color: #09C567;background-color:#fff;
 	}
 	& .out-fast{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color:white;background-color: #09C567;
+		position:fixed;left:85upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: #09C567;border-color: #09C567;background-color:#fff;
 	}
 	& .custom{
 		position:fixed;left:32upx;bottom:66upx;width:189upx;height:20upx;line-height:5upx;font-size:13upx;background-color:white;color:orange;font-weight:bold;border:none;
 	}
 	& .clear{
-		background-color:orange;color:white;border-color:orange;position:fixed;left:135upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
+		background-color:orange;color:white;border-color:orange;position:fixed;left:148upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:16upx;
 	}
 	& .hand{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color: orange;border-color: orange;
+		position:fixed;left:36upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: orange;border-color: orange;background-color:#fff;
 	}
 	& .out{
-		position:fixed;left:36upx;bottom:13upx;width:84upx;height:50upx;line-height:30upx;font-size:15upx;color:white;background-color: orange;
+		position:fixed;left:90upx;bottom:13upx;width:50upx;height:50upx;box-sizing:border-box;padding:0;display:flex;align-items:center;justify-content:center;line-height:1;font-size:22upx;color: orange;border-color: orange;background-color:#fff;
 	}
 }
+.hand-order-pop{
+	width: 500upx;
+	max-height: 90vh;
+	background-color: #fff;
+	border-radius: 8upx;
+	padding: 24upx;
+	box-sizing: border-box;
+}
+.hand-order-head{
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	margin-bottom: 18upx;
+}
+.hand-order-title{
+	font-size: 24upx;
+	font-weight: bold;
+	color: #222;
+}
+.hand-order-close{
+	width: 42upx;
+	height: 42upx;
+	line-height: 38upx;
+	text-align: center;
+	border-radius: 50%;
+	color: #666;
+	background-color: #f3f5f7;
+	font-size: 24upx;
+}
+.hand-order-scroll{
+	max-height: 58vh;
+}
+.hand-order-item{
+	display: flex;
+	align-items: center;
+	padding: 18upx 0;
+	border-bottom: 1upx solid #eee;
+}
+.hand-order-main{
+	flex: 1;
+	min-width: 0;
+}
+.hand-order-name{
+	font-size: 20upx;
+	font-weight: bold;
+	color: #222;
+	overflow: hidden;
+	text-overflow: ellipsis;
+	white-space: nowrap;
+}
+.hand-order-meta{
+	margin-top: 8upx;
+	font-size: 16upx;
+	color: #888;
+}
+.hand-order-price{
+	width: 110upx;
+	text-align: right;
+	font-size: 20upx;
+	font-weight: bold;
+	color: #f39800;
+}
+.hand-order-actions{
+	display: flex;
+	margin-left: 16upx;
+}
+.hand-order-actions .mini-btn{
+	margin-left: 10upx;
+	font-size: 16upx;
+	line-height: 32upx;
+	height: 36upx;
+	min-width: 58upx;
+	padding: 0 10upx;
+}
+.hand-order-actions .danger{
+	color: #d93025;
+	border-color: #d93025;
+}
+.hand-order-empty{
+	height: 180upx;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+	color: #999;
+	font-size: 20upx;
+}
 </style>