shish 11 bulan lalu
induk
melakukan
3c341dbaa4

+ 275 - 0
hdApp/src/admin/billing/components/app-commodity2.vue

@@ -0,0 +1,275 @@
+<template>
+	<view class="item-cmd_bx" @click.stop="showAddModelFn()">
+		<view class="img_bx" style="background:#eeeeee">
+			<block v-if="info.frontHide == 1">
+				<view class="sold-out">
+					<view class="hide">隐</view>
+				</view>
+			</block>
+			<image :src="info.cover" lazy-load="true" :lazy-load-margin="0"></image>
+			<view style="width:30upx;height:30upx;top:0upx;left:0upx;position: absolute;" @click.stop="delProduct(info)"> </view>
+		</view>
+		<view class="cmd-info_bx">
+			<view class="tit" >
+				<text style="font-size:22upx;border:1upx solid #3385ff;color:white;background-color:#3385ff;margin-right:5upx;padding-left:5upx;padding-right:5upx;" 
+				v-if="info.frontHide && info.frontHide == 1">隐</text>
+				<text style="font-size:22upx;border:1upx solid #3385ff;color:white;background-color:#3385ff;margin-right:5upx;padding-left:5upx;padding-right:5upx;" 
+				v-if="info.presell == 1">预售</text>
+				{{ info.name || "" }}
+				<text v-if="info.variety && info.variety ==1" class="show-color"></text>
+			</view>
+			<view class="kc" style="position:absolute;top:55upx;z-index:99" @click.stop="copyCreate()">		
+				<block v-if="info.ratioType == 0">{{info.ratio}}{{info.smallUnit}}/{{info.bigUnit}}</block>
+				<block v-else>若干{{info.smallUnit}}/{{info.bigUnit}}</block>
+			</view>
+			<view class="kc num-open_bx flex-end">
+				<view class="price" style="position:absolute;top:55upx;font-weight:bold;">
+					¥{{ parseFloat(info.price) }}
+					<text v-if="info.reachNum && info.reachNum>0 && info.reachNumDiscount && info.reachNumDiscount>0" style="font-weight:normal;color:#3385FF;margin-left:20upx;">
+						满{{info.reachNum}}↓{{info.reachNumDiscount?parseFloat(info.reachNumDiscount):0}}
+					</text>
+				</view>
+				<view style="text-align: right;margin-right:20upx;" >
+					<view class="open-bx" >
+						<i class="iconfont iconjian" @click.stop="reduceItemFn()" v-if="bigCount > 0 || smallCount > 0"></i>
+						<text class="num" >
+							<text style="font-weight:bold;color:#3385ff;" v-if="bigCount > 0">{{ `${bigCount}` }}</text>
+							<text v-if="smallCount > 0">{{ `${smallCount}` }}</text>
+						</text>
+						<i class="iconfont iconzeng" @click.stop="addItemFn()"></i>
+					</view>
+					<text v-if="parseFloat((Number(info.stock)+Number(info.onStock)).toFixed(2)) > Number(info.stockWarning)" style="color:#333;margin-right:65upx;">还剩 {{ parseFloat(info.stock) }}</text>
+					<text v-else style="color:red;font-weight:bold;margin-right:65upx;">还剩 {{ parseFloat(info.stock) }}</text>
+				</view>
+			</view>
+		</view>
+	</view>
+</template>
+<script>
+export default {
+	name: "Commodity",
+	components: {},
+	mixins: [],
+	props: {
+		info: {
+			required: true,
+			type: Object,
+			default() {
+				return {};
+			}
+		},
+		scrollTop: {
+			type: Number,
+			default: 0
+		},
+		autoPrice: {},
+		isActive: {
+			type: Boolean,
+			default: false
+		},
+		checkStock: {
+			type: Boolean,
+			default: false
+		},
+		isAlterPrice: {
+			type: Boolean,
+			default: false
+		},
+		selectJobType:{
+			type: String,
+			default: ''
+		}
+	},
+	data() {
+		return {
+			ifFocus:false,
+			bigCount:0,
+			smallCount:0,
+			userPrice:0,
+			remark:''
+		};
+	},
+	watch:{
+		info:{
+			handler(newValue){
+				this.bigCount = newValue.bigCount
+				this.smallCount = newValue.smallCount
+				this.userPrice = newValue.userPrice
+				this.remark = newValue.remark||''
+			},
+			deep:true
+		}
+	},
+	created() {},
+	computed: {
+	},
+	mounted() {
+		this.bigCount = this.info.bigCount
+		this.smallCount = this.info.smallCount
+		this.userPrice = this.info.userPrice
+		this.remark = this.info.remark||''
+	},
+	methods: {
+		copyCreate(){
+			this.pageTo({url: '/admin/item/copy?id='+this.info.id})
+		},
+		delProduct(info){
+			this.$emit("delProduct", info)
+		},
+		addItemFn () {
+			if(this.info && this.info.variety == 1 && this.selectJobType == 'bill'){
+				//小菊多颜色选择页
+				this.$emit("goToSpecialVariety", this.info);
+				return false
+			}
+			this.$emit("replaceItemFn", this.info,0,'add')
+		},
+		reduceItemFn() {
+			if(this.info && this.info.variety == 1 && this.selectJobType == 'bill'){
+				//小菊多颜色选择页
+				this.$emit("goToSpecialVariety", this.info);
+				return false
+			}
+			this.$emit("replaceItemFn", this.info,0,'sub')
+		},
+		showAddModelFn() {
+			if(this.info && this.info.variety == 1 && this.selectJobType == 'bill'){
+				//小菊多颜色选择页
+				this.$emit("goToSpecialVariety", this.info);
+				return false
+			}
+			this.$emit("showAddModelFn", { ...this.info, bigCount: this.bigCount, smallCount: this.smallCount, userPrice: this.userPrice,remark:this.remark})
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.item-cmd_bx {
+	position: relative;
+	margin-bottom: 20upx;
+	.img_bx {
+		height: 140upx;
+		width: 140upx;
+		position: absolute;
+		left: 0upx;
+		top: 0upx;
+		image{
+			width: 100%;
+			height: 100%;
+		}
+		.sold-out{
+			z-index:10;
+			width:140upx;
+			height:140upx;
+			background-color:black;
+			position:absolute;
+			top:0;
+			left:0;
+			opacity: 0.6;
+			color:white;
+			text-align:center;
+			.sold-out-xj{
+				line-height:160upx;
+				font-size:28upx;
+			}
+			.hide{
+				line-height:160upx;
+				font-size:30upx;
+			}
+		}
+	}
+	.cmd-info_bx {
+		padding-left: 160upx;
+		padding-bottom: 30upx;
+		& .tit {
+			font-size: 32upx;
+			font-weight: 700;
+			color: #333333;
+			overflow: hidden;
+			white-space: nowrap;
+			text-overflow: ellipsis;
+			width:380upx;
+		}
+		.show-color{
+			display:inline-block;
+			width:25upx;
+			height:25upx;
+			background-color:rgb(9, 199, 9);
+			border-radius:15upx;
+			border:none;
+			margin-left:16upx;
+		}
+		& .kc {
+			position: relative;
+			color: #999999;
+			font-size: 24upx;
+			.price{
+				position: absolute;
+				left: 0;
+				bottom: 0;
+			}
+		}
+		& .num-open_bx {
+			display: flex;
+			align-items: center;
+			& .price {
+				font-size: 28upx;
+				color: #ff2842;
+				flex: 1;
+			}
+			& .open-bx {
+				display: flex;
+				align-items: center;
+				& .iconfont {
+					color: #3385ff;
+					font-size: 55upx;
+				}
+				.position{
+					display: block;
+					width: 70upx;
+					text-align: center;
+				}
+				.iconcachu {
+					margin: 0 6upx 0 20upx;
+					color: #ccc;
+					&.edit {
+						color: #3385ff;
+					}
+				}
+				& > .num {
+					display: inline-block;
+					width: 100upx;
+					height:50upx;
+					line-height:50upx;
+					text-align:center;
+					margin: 0 20upx;
+					color: #868686;
+					border-radius: 22upx;
+					background-color: #f5f5f5;
+					font-size: 28upx;
+				}
+				.change-input {
+					width: 164upx;
+					height: 60upx;
+					line-height: 60upx;
+					text-align: center;
+					background: #ffffff;
+					border: 1upx solid #dddddd;
+					border-radius: 4upx;
+					font-size: 25upx;
+				}
+				.btn-box{
+					width: 100upx;
+					height: 60upx;
+					line-height: 60upx;
+					color: #ffffff;
+					background: #3385ff;
+					text-align: center;
+					border-radius: 10upx;
+				}
+			}
+		}
+	}
+}
+</style>

+ 364 - 0
hdApp/src/admin/billing/hs.vue

@@ -0,0 +1,364 @@
+<template>
+<view class="app-content">
+	<view class="billing_box_bg">
+		<view class="input-wrap" >
+			<view style="padding:0upx 0upx 0upx 0upx;margin-right:15upx;" >
+				<button class="admin-button-com middle blue" @click="selectFlowerNumFn()">图片分类</button>
+			</view>
+			<view class="search-bar">
+				<app-search-module ref="globalSearchRef" v-model="globalPy" placeholder="这里搜索" @input="globalSearch" />
+			</view>
+			<view style="float:right;margin-left:15upx;">
+				<button class="admin-button-com middle blue" @click="removeFromSave(option.customId)">清空购物车</button>
+			</view>
+		</view>
+
+		<button class="admin-button-com middle blue" @click="confirmToSave" style="position: absolute;top:120upx;right:24upx;z-index:99;">选好了</button>
+
+		<view class="scroll-middle_bx">
+			<scroll-view scroll-y scroll-with-animation class="tab-view">
+				<!--分类-->
+				<div v-for="(item, index) in globalClassData" :key="index" class="tab-bar-item" :class="globalClassIndex == index ? 'active' : ''" :data-current="index" @tap.stop="globalSwitchClass(index,item)">
+					<text style="text-align: center;">{{ item.name || "" }}</text>
+				</div>
+				<view style="height: 120upx"></view>
+			</scroll-view>
+			<scroll-view scroll-y class="right-box" :scroll-top="globalScrollTopPlace" @scroll="globalGetScroll" 
+			:scroll-into-view="scroll_into_view" scroll-with-animation="true" lower-threshold="100" @scrolltolower="globalScrollBottom">
+				<!--花材列表-->
+				<block v-if="!$util.isEmpty(globalItemData)">
+					<view class="item_list_bx selectAll">
+						<view v-if="!$util.isEmpty(globalItemData)">
+							<template v-for="(productItem, productIndex) in globalItemData" :key="productIndex">
+								<view class="item_list_title" v-if="productItem.className && productItem.className!=''">{{ productItem.className }}</view>
+								<view style="height: 175upx">
+									<Commondity
+										:globalCheckStock="true"
+										:selectJobType="selectJobType"
+										:info="productItem"
+										@showAddModelFn="showAddModelFn"
+										@replaceItemFn="replaceItemFn"
+										@goToSpecialVariety="goToSpecialVariety"
+										@delProduct="delProduct"
+									></Commondity>
+								</view>
+							</template>
+						</view>
+						<view v-else>
+							<view style="height:260upx;text-align:center;color:#CCCCCC;position: relative;">
+								<view style="position: absolute;margin:auto;top:130upx;left:0;right:0;bottom:0;">暂无花材</view>
+							</view>
+						</view>
+					</view>
+				</block>
+				<block v-else>
+					<app-wrapper-empty title="加载中" :is-empty="$util.isEmpty(globalItemData)" />
+				</block>
+			</scroll-view>
+
+		</view>
+
+		<modal-module :show="isAddModel" @cancel="addItemModelHidden" @click="confirmAddItemModel" :title="customData.name" color="#333" :size="32" padding="30rpx 30rpx" >
+			<template slot="customContent">
+				<view class="select-cmd_bx" v-if="customData">
+					<view class="kc">
+						<text>库存 {{ customData.stock?parseFloat(customData.stock):0 }}</text>
+						<text style="margin-left:14upx;">¥{{ parseFloat(customData.price) }}</text>
+						<text style="margin-left:14upx;">{{customData.ratio}}{{customData.smallUnit}}/{{customData.bigUnit}}</text>
+						<text style="margin-left:14upx;">成本 {{customData.cost?parseFloat(customData.cost):0}}</text>
+					</view>
+					<view class="num_bx">
+						<input style="width:280upx" v-model="customData.userPrice" @focus="customData.userPrice = null" :class="[Number(customData.cost) > Number(customData.userPrice) ? 'warning-price' : '']"
+						:disabled="false" type="digit" placeholder="单价" />
+						<text style="font-size:35upx;font-weight:bold;color:#666666;">元</text>
+					</view>
+					<view class="num_bx">
+
+						<!-- #ifdef APP-PLUS -->
+						<input style="width: 280upx" v-model="customData.bigCount" v-if="globalUnitType == 0" type="number" />
+						<text style="font-size:35upx;font-weight:bold;color:#666666;" v-if="globalUnitType == 0">{{customData.bigUnit}}</text>
+						<input style="width: 280upx" v-model="customData.smallCount" v-if="globalUnitType == 1" type="number" />
+						<text style="font-size:35upx;font-weight:bold;color:#666666;" v-if="globalUnitType == 1">{{customData.smallUnit}}</text>
+						<!-- #endif -->
+
+						<!-- #ifdef MP-WEIXIN -->
+						<input style="width: 280upx" v-model="customData.bigCount" v-if="globalUnitType == 0" :focus="isAddInputFocus" type="number" />
+						<text style="font-size:35upx;font-weight:bold;color:#666666;" v-if="globalUnitType == 0">{{customData.bigUnit}}</text>
+						<input style="width: 280upx" v-model="customData.smallCount" v-if="globalUnitType == 1" :focus="isAddInputFocus" type="number" />
+						<text style="font-size:35upx;font-weight:bold;color:#666666;" v-if="globalUnitType == 1">{{customData.smallUnit}}</text>
+						<!-- #endif -->
+
+						<image @click="switchGlobalUnitType" :src="`${constant.imgUrl}/icon/switch/switch128.png`" 
+						style="width:86upx;height:86upx;position:absolute;top:300upx;right:40upx;" mode="widthFix"></image>
+
+						<button class="admin-button-com mini-btn" @click="customData.userPrice=0.01;customData.bigCount=1" style="position:absolute;top:200upx;right:33upx;">赠送</button>
+					</view>
+					<view class="num_bx">
+						<input style="width: 280upx;height:40upx;font-size:25upx;" v-model="customData.remark" type="text" placeholder="备注" />
+					</view>
+				</view>
+			</template>
+		</modal-module>
+
+		<footer-cart :price="allPrice" :count="allCount" @confirm="confirmToSave" ></footer-cart>
+
+		<uni-popup ref="globalClassImgRef" background-color="#fff" type="center" :animation="false" class="class-popup-style">
+			<view style="display:flex;padding:20upx;height:auto;justify-content: space-between;align-items:center;flex-wrap:wrap;max-height:100vh;overflow:auto;">
+				<view v-for="(item, index) in globalClassData" :key="index" @tap.stop="globalChangeClass(index,item)" style="margin-bottom:20upx;margin-left:3upx;">
+				<image :src="item.cover" style="width:120upx;height:120upx;border-radius:10upx;"></image>
+				<view style="margin-top:5upx;overflow: hidden;white-space: nowrap;width:120upx;text-align:center;">{{item.name}}</view>
+				</view>
+			</view>
+		</uni-popup>
+	</view>
+</view>
+</template>
+
+<script>	
+import AppSearchModule from "@/components/module/app-search";
+import AppTabs from "@/components/plugin/tabs";
+import AppWrapperEmpty from "@/components/app-wrapper-empty";
+import Commondity from "./components/app-commodity2";
+import FooterCart from "@/components/module/app-footer-cart";
+import ModalModule from "@/components/plugin/modal";
+import { COMMODITY_TYPE } from "@/utils/declare";
+import hsMins from "@/mixins/hs";
+import { delStatusUpdate } from '@/api/product';
+import { mapGetters } from "vuex";
+export default {
+	name: "hs",
+	components: {
+		AppTabs,
+		AppSearchModule,
+		AppWrapperEmpty,
+		Commondity,
+		ModalModule,
+		FooterCart,
+	},
+	mixins: [hsMins],
+	data() {
+		return {
+			COMMODITY_TYPE,
+			isSmallCount:false,
+			globalCheckStock:true,
+			autoLoad: false,
+			xjData:{},
+			xjDataInfo:{},
+		};
+	},
+	computed: {
+		...mapGetters(["getLoginInfo"]),
+	},
+	onShow() {
+		//小菊等多颜色
+		if(this.xjData.hasUpdate == 1){
+			this.customData = this.xjDataInfo
+			if(this.xjData.cancel == 1){
+				this.customData.bigCount = 0
+				this.customData.smallCount = 0
+				this.replaceItemFn(this.customData,1)
+			}else{
+				this.customData.bigCount = this.xjData.stock
+				this.customData.smallCount = 0
+				this.customData.bigPrice = this.xjData.price
+				this.customData.price = this.xjData.price
+				this.customData.itemPrice = this.xjData.price
+				this.customData.userPrice = this.xjData.price
+				this.confirmAddItemModel(this.customData)
+			}
+		}
+		this.xjData = {}
+	},
+	onLoad () {
+		let that = this
+		if(this.option.customName){
+			uni.setNavigationBarTitle({ title: this.option.customName })
+		}
+		if (this.option.customId){
+			this.selectJobId = this.option.customId
+			this.globalCustomId = this.option.customId
+		}
+		let book = this.option.book ? this.option.book : 0
+		let getAll = this.option.getAll ? this.option.getAll : 0
+		if(book == 0){
+			this.globalRequestType = 'kd'
+			this.initData()
+		}else{
+			this.globalCheckStock = false
+			if(getAll == 1){
+				this.globalRequestType = 'book'
+			}else{
+				this.globalRequestType = 'kd'
+			}
+			this.globalRequestType = 'book'
+			this.initData()
+		}
+	},
+	methods: {
+		delProduct(info){
+			let that = this
+			that.$util.confirmModal({content:'确认删除?'},() => {
+				delStatusUpdate({id:info.id,delStatus:1}).then(res=>{
+					if(res.code == 1){
+						that.$msg('删除成功')
+					}
+				})
+			})
+		},
+		//小菊多颜色选择页
+		goToSpecialVariety(info){
+			this.xjDataInfo = info
+			if(info.stock <= 0){
+				uni.showToast({title:"没有库存",icon:"none"})
+			}else{
+				let userPrice = info.userPrice ? parseFloat(info.userPrice) : 0
+				let price = info.price ? parseFloat(info.price) : 0
+				this.$util.pageTo({url: "/admin/item/xj?stock="+info.stock+"&price="+price+"&customId="+this.option.customId+"&userPrice="+userPrice+"&productId="+info.id+"&ptItemId="+info.itemId})
+			}
+		},
+		selectFlowerNumFn(){
+			this.$refs.globalClassImgRef.open('top')
+		},
+		confirmToSave() {
+			if(this.$util.isEmpty(this.selectList)){
+				this.$msg('请选择花材')
+				return false
+			}
+			if (this.$util.isEmpty(this.option.customId)){
+				this.$msg("请选择客户")
+				return
+			}
+			let customName = this.option.customName ? this.option.customName : '';
+			let orderId = this.option.orderId  ? this.option.orderId : 0
+			let book = this.option.book ? this.option.book : 0
+			let customId = this.option.customId?this.option.customId:0
+			let reduceStock = this.option.reduceStock?this.option.reduceStock:0
+			this.$util.pageTo({ url: '/admin/billing/affirm?customId='+customId+'&customName='+customName+'&orderId='+orderId+'&book='+book+'&reduceStock='+reduceStock,type:2})
+		}
+	}
+};
+</script>
+
+<style lang="scss" scoped>
+.billing_box_bg {
+	background: white;
+	height: 100%;
+	display: flex;
+	flex-direction: column;
+	.input-wrap {
+		display: flex;
+		padding: 22upx 20upx 22upx 13upx;
+		.search-bar {
+			flex: 1;
+		}
+	}
+	.scroll-middle_bx {
+		flex: 1;
+		display: flex;
+		width: 100%;
+		height: 100%;
+		overflow: hidden;
+	}
+	.tab-view {
+		position: relative;
+		height: calc(100vh - 140upx);
+		width: 170upx;
+		flex-shrink: 0;
+		background-color: #f0f2f6;
+		.tab-bar-item {
+			position: relative;
+			width: 170upx;
+			height: 90upx;
+			box-sizing: border-box;
+			display: flex;
+			align-items: center;
+			justify-content: center;
+			font-size: 26upx;
+			color: #444;
+			font-weight: 400;
+			.tag {
+				display: flex;
+				padding: 0 20upx;
+				align-items: center;
+				position: absolute;
+				right: 0;
+				top: 0;
+				height: 32upx;
+				background: #ff2842;
+				border-radius: 16upx;
+				color: #fff;
+				font-size: 20upx;
+			}
+      &:last-child{
+        margin-bottom: 110upx;
+      }
+		}
+		.active {
+			position: relative;
+			color: $mainColor;
+			font-size: 26upx;
+			background: #fff;
+		}
+		.active::before {
+			content: "";
+			position: absolute;
+			border-left: 8upx solid $mainColor;
+			height: 100%;
+			left: 0;
+		}
+	}
+	.right-box {
+		height: calc(100vh - 140upx);
+		flex: 1;
+		box-sizing: border-box;
+	}
+	.item_list_bx {
+		padding: 40upx 16upx;
+		//padding: 0 16upx;
+    &:last-child{
+      margin-bottom: 70upx;
+    }
+	}
+	.item_list_title {
+		margin-bottom: 20upx;
+		font-size: 24upx;
+		font-weight: 600;
+		color: #666666;
+	}
+	.select-cmd_bx {
+		& .kc {
+			color: #999999;
+			font-size: 28upx;
+			font-weight: 400;
+			margin-bottom: 40upx;
+			text-align: center;
+			margin-top: 30upx;
+			.unit_price{
+				padding-right:25upx;
+			}
+		}
+		& .num_bx {
+			display: flex;
+			align-items: center;
+			margin-bottom: 40upx;
+			padding-left:110upx;
+			& > input {
+				width: 212upx;
+				height: 80upx;
+				border: 1upx solid #dddddd;
+				border-radius: 4upx;
+				text-align: center;
+				margin-right: 24upx;
+				font-size: 40upx;
+			}
+		}
+	}
+}
+.class-popup-style{
+	z-index:999999;
+}
+.warning-price{
+	color:red;
+	font-weight:bold;
+}
+</style>

+ 0 - 1
hdApp/src/admin/billing/index2.vue

@@ -123,7 +123,6 @@ import FooterCart from "@/components/module/app-footer-cart";
 import ModalModule from "@/components/plugin/modal";
 import { COMMODITY_TYPE } from "@/utils/declare";
 import productMins from "@/mixins/product2";
-import { getClassRemind,hasClassRemind,getMenu } from "@/api/item-class";
 import { delStatusUpdate } from '@/api/product';
 import { mapGetters } from "vuex";
 export default {

+ 7 - 2
hdApp/src/admin/custom/selectCustom.vue

@@ -106,8 +106,11 @@
         let style = this.option.style ? this.option.style : 1
         this.selectStyle = style
         if(style == 1){
-          //选择客户并开单情况
-            this.$util.pageTo({url: '/admin/billing/index2?customId='+item.id+'&customName='+item.name,type:2})
+          //花材开单
+          this.$util.pageTo({url: '/admin/billing/index2?customId='+item.id+'&customName='+item.name,type:2})
+        }else if(style == 3){
+          //花束开单
+          this.$util.pageTo({url: '/admin/billing/hs?customId='+item.id+'&customName='+item.name,type:2})
         }else if(style == 2){
           //用于选择客户并且需要返回的情况
           let pages = getCurrentPages();
@@ -115,6 +118,8 @@
           prevPage.$vm.form.customId = item.id;
           prevPage.$vm.form.customName = item.name;
           uni.navigateBack({})
+        }else{
+          //无操作
         }
       },
       init() {

+ 16 - 20
hdApp/src/admin/home/workbench.vue

@@ -85,13 +85,13 @@
               </view>
               <view class="icon-text">图集</view>
             </view>
-            <view class="icon-item" @click="goPage({url: '/admin/order/workOrder'})">
+            <view class="icon-item" @click="goHsKd">
               <view class="icon-wrapper">
                 <image class="icon-image" :src="`${constant.hostUrl}/image/ghs/home/shop2.png`" mode="aspectFit"></image>
               </view>
               <view class="icon-text" style="color:#3385FF;font-weight:bold;">开单</view>
             </view>
-            <view class="icon-item" @click="goPage({url: '/admin/order/quickOrder'})">
+            <view class="icon-item" @click="goHsKjKd">
               <view class="icon-wrapper">
                 <image class="icon-image" :src="`${constant.hostUrl}/image/ghs/home/shop2.png`" mode="aspectFit"></image>
               </view>
@@ -144,13 +144,13 @@
               </view>
               <view class="icon-text">改价</view>
             </view>
-            <view class="icon-item" @click="goShKd()">
+            <view class="icon-item" @click="goItemKd()">
               <view class="icon-wrapper">
                 <image class="icon-image" :src="`${constant.hostUrl}/image/ghs/home/shop2.png`" mode="aspectFit"></image>
               </view>
               <view class="icon-text" style="color:#3385FF;font-weight:bold;">开单</view>
             </view>
-            <view class="icon-item" @click="goKjKd()">
+            <view class="icon-item" @click="goItemKjKd()">
               <view class="icon-wrapper">
                 <image class="icon-image" :src="`${constant.hostUrl}/image/ghs/home/shop2.png`" mode="aspectFit"></image>
               </view>
@@ -555,16 +555,26 @@ export default {
         }
       })
     },
-    goKjKd(){
+    goItemKjKd(){
       if(this.myShopInfo && Number(this.myShopInfo.defaultCustomId)>0){
         this.$util.pageTo({url:'/admin/billing/index2?customId='+this.myShopInfo.defaultCustomId})
       }else{
         this.$msg('请设置快捷开单的对应客户')
       }
     },
-    goShKd(){
+    goItemKd(){
       this.$util.pageTo({url:'/admin/custom/selectCustom'})
     },
+    goHsKjKd(){
+      if(this.myShopInfo && Number(this.myShopInfo.defaultCustomId)>0){
+        this.$util.pageTo({url:'/admin/billing/hs?customId='+this.myShopInfo.defaultCustomId})
+      }else{
+        this.$msg('请设置快捷开单的对应客户')
+      }
+    },
+    goHsKd(){
+      this.$util.pageTo({url:'/admin/custom/selectCustom?style=3'})
+    },
     setRecharge(){
       this.$util.pageTo({url:'/admin/recharge/discount'})
     },
@@ -786,20 +796,6 @@ export default {
         this.showAd = res.data.showAd ? res.data.showAd : 0
       })
     },
-    goGd(){
-      //选择花材生成制作单和订单
-      this.$util.pageTo({url:'/admin/order/workOrder'})
-    },
-    goKjKd(){
-      if(this.myShopInfo && Number(this.myShopInfo.defaultCustomId)>0){
-        this.$util.pageTo({url:'/admin/billing/index2?customId='+this.myShopInfo.defaultCustomId})
-      }else{
-        this.$msg('请设置快捷开单的对应客户')
-      }
-    },
-    goShKd(){
-      this.$util.pageTo({url:'/admin/custom/selectCustom'})
-    },
     goPage (item) {
       if(this.getLoginInfo.pfShopId && Number(this.getLoginInfo.pfShopId)>0){
         if(item.pf == 0){

+ 564 - 0
hdApp/src/mixins/hs.js

@@ -0,0 +1,564 @@
+import { mapGetters, mapActions } from "vuex";
+import { copyObject } from "@/utils/util"
+import { allProduct } from '@/api/product'
+import { getMenu } from "@/api/item-class";
+import { getItemList } from '@/api/item';
+export default {
+	data() {
+		return {
+			selectJobType: "bill",//业务类型,开单、采购、损耗、盘点
+			selectJobId:0,//业务类型对应的主体ID等
+			isCut:false,
+			productInfoList: [], //商品信息
+			globalClassIndex: 0, //当前商品类别下标
+			py: "", //拼音搜索条件
+			type: "", //库存预警时,固定为waring,其他情况不传或者传空
+			autoLoad: true, //自动获取商品信息
+			allFilterProductInfo:'',
+			top_list:'',
+			scroll_into_view:"",
+			timeFun:"",
+			kdType:'HIT',//点击和扫码开单,HIT SCAN
+			globalCheckStock:true,// 考虑库存,盘点不需要考虑库存
+			isAddModel:false,
+			isAddInputFocus:false,
+			customData: { bigCount: 0, smallCount: 0, userPrice: 0,aboutPrice:0,totalPrice:0,remark:'',assignSeat:1},
+			globalItemList:[],
+			globalUnitType:0,
+			globalAllProduct:[],
+			calc:'add',
+			globalRequestType:'kd',
+			globalCustomId:0,
+			globalClassData:[],
+			globalClassId:0,
+			globalClassDataIndex:[],
+			globalFinishGetItem:0,
+			globalPage:1,
+			globalPy:'',
+			globalItemData:[],
+			globalScrollTopPlace:0,
+			globalScrollTopOldPlace:0,
+			globalIsRequesting:false,
+			globalCgMyCharge:0,
+			globalLookStock:0
+		};
+	},
+	onLoad(options) {
+		const { selectJobType } = options;
+		if (selectJobType) {
+			this.selectJobType = selectJobType;
+		}
+	},
+	onUnload() {},
+	computed: {
+		...mapGetters(["getSelectInfo"]),
+		selectList() {
+			let selectInfo = this.getSelectInfo;
+			return selectInfo[this.selectJobType+'_'+this.selectJobId] || []
+		},
+		scrollClassId() {
+			const curClass = this.productInfoList[this.globalClassIndex];
+			if (curClass) {
+				return `class_${curClass.classId}`;
+			}
+			return "";
+		},
+		allPrice() {
+			let price = 0;
+			if (this.selectList) {
+				for (const item of this.selectList) {
+					const itemInfo = this.getSelectItemById(item.id, item.classId);
+					if (itemInfo && !this.$util.isEmpty(itemInfo.bigPrice) && !this.$util.isEmpty(itemInfo.smallPrice)) {
+						if(item.userPrice>0){
+							if(Number(item.bigCount) > 0){
+								price += Number(item.bigCount) * Number(itemInfo.userPrice);
+							}
+							if(Number(item.smallCount) > 0){
+								price += Number(item.smallCount) * Number(itemInfo.userPrice);	
+							}
+						}else{
+							if(Number(item.bigCount) > 0){
+								price += Number(item.bigCount) * Number(itemInfo.bigPrice);
+							}
+							if(Number(item.smallCount) > 0){
+								price += Number(item.smallCount) * Number(itemInfo.smallPrice);	
+							}
+						}
+					}
+				}
+			}
+			return Math.round(price * 100) / 100;
+		},
+		allCount() {
+			let bigLength = 0;
+			let smallLength = 0;
+			let weight = 0
+			if (this.selectList) {
+				for (const item of this.selectList) {
+					bigLength += Number(item.bigCount)
+					smallLength += Number(item.smallCount)
+					let thisWeight = item.weight ? item.weight : 0
+					let currentWeight = Number(thisWeight)*Number(item.bigCount)
+					weight = Number(weight) + Number(currentWeight)
+				}
+				weight = weight.toFixed(2)
+				weight = parseFloat(weight)
+			}
+			return {bigLength:bigLength,smallLength:smallLength,weight:weight};
+		},
+		hasNoStock() {
+			let has = false;
+			if (this.selectList) {
+				for (const item of this.selectList) {
+					const {
+						bigCount,
+						smallCount,
+						bigNum,
+						smallNum,
+						ratio
+					} = item;
+					const ratioNum = Number(ratio);
+					if (
+						Number(bigCount) * ratioNum + Number(smallCount) >
+						Number(bigNum) * ratioNum + Number(smallNum)
+					) {
+						has = true;
+						break;
+					}
+				}
+			}
+			return has;
+		}
+	},
+	onShow(){
+
+	},
+	methods: {
+		...mapActions(["setSelectInfo", "reSetSelectInfo"]),
+		init(){
+			if (this.autoLoad) {
+				this.initData();
+			}
+		},
+		initData() {
+			let that = this
+			getMenu().then(res=>{
+				if(res.code == 1){
+					that.globalClassData = res.data.class ? res.data.class : []
+					that.globalClassDataIndex = res.data.classIndex ? res.data.classIndex : []
+					if(that.globalClassData[0]){
+						that.globalClassId = that.globalClassData[0].id
+						//保存到仓库
+						let currentInfo = uni.getStorageSync('selectList_'+that.selectJobType+'_target_'+that.selectJobId)
+						if(!that.$util.isEmpty(currentInfo)){
+							that.setSelectInfo({ selectJobType: that.selectJobType, info: currentInfo,selectJobId:that.selectJobId })
+						}
+						that.getGlobalProductList()
+					}
+				}
+			})
+		},
+		reGetGlobalProductList(){
+			this.globalGoToTop()
+            this.globalPage = 1
+			this.globalFinishGetItem = 0
+			this.getGlobalProductList()
+		},
+        getGlobalProductList(){
+            if(this.globalFinishGetItem == 1){
+                return false
+            }
+            let that = this
+			getItemList({classId:this.globalClassId,requestType:this.globalRequestType,page:this.globalPage,
+				search:this.globalPy,customId:this.globalCustomId,globalCgMyCharge:this.globalCgMyCharge,lookStock:this.globalLookStock}).then(res=>{
+				if(res.code == 1){
+					that.globalItemData = that.globalPage == 1 ? res.data.list : that.globalItemData.concat(res.data.list)
+                    if(res.data.moreData == 1){
+                        that.globalPage++
+                    }else{
+                        that.globalFinishGetItem = 1
+                    }
+					that.globalIsRequesting = false
+					that.globalRememberRefresh()
+				}
+			})
+        },
+		sorts_fun(arr) {
+			return function(a, b) {
+				var v1 = a[arr];
+				var v2 = b[arr];
+				return v1 - v2;
+			}
+		},
+		globalRememberRefresh(){
+			let that = this
+			if(that.$util.isEmpty(that.globalItemData)){
+				return false
+			}
+			let selectListData = []
+			if(!that.$util.isEmpty(that.selectList)){
+				that.selectList.forEach((i)=>{
+					selectListData[i.id] = i
+				})
+			}
+			//修改数据需要复制一份,否则不会生效
+			that.globalItemData = copyObject(that.globalItemData);
+
+			that.globalItemData = that.globalItemData.sort(this.sorts_fun('classId'))
+			let hasExists = []
+			for (let i=0;i<that.globalItemData.length;i++){
+				let currentProduct = that.globalItemData[i]
+				let currentPId = currentProduct.id
+				let currentClassId = currentProduct.classId||0
+				let selectProduct = selectListData[currentPId] || []
+				if(!that.$util.isEmpty(selectProduct)){
+					that.globalItemData[i].bigCount = selectProduct.bigCount || 0
+					that.globalItemData[i].userPrice = selectProduct.userPrice || 0
+					that.globalItemData[i].smallCount = selectProduct.smallCount || 0
+					that.globalItemData[i].totalPrice = selectProduct.totalPrice || 0
+					that.globalItemData[i].aboutPrice = selectProduct.aboutPrice || 0
+					that.globalItemData[i].remark = selectProduct.remark || ''
+					that.globalItemData[i].assignSeat = selectProduct.assignSeat
+				}else{
+					that.globalItemData[i].bigCount = 0
+					that.globalItemData[i].userPrice = 0
+					that.globalItemData[i].smallCount = 0
+					that.globalItemData[i].totalPrice = 0
+					that.globalItemData[i].aboutPrice = 0
+					that.globalItemData[i].remark = ''
+					that.globalItemData[i].assignSeat = 1
+				}
+				let cName = ''
+				if(hasExists[currentClassId]){
+					//无操作
+				}else{
+					let currentClass = this.globalClassDataIndex[currentClassId] ? this.globalClassDataIndex[currentClassId] : null
+					cName = currentClass.name ? currentClass.name : ''
+					hasExists[currentClassId] = 1
+				}
+				that.globalItemData[i].className = cName
+			}
+		},
+		globalSwitchClass(cur,item) {
+			this.globalGoToTop()
+			this.globalClassIndex = cur
+            this.globalPage = 1
+			this.globalPy = ''
+			this.$refs.globalSearchRef.search = ''
+            this.globalClassId = item.id
+            this.globalFinishGetItem = 0
+            this.getGlobalProductList()
+		},
+		pushToSave(selectData){
+			this.setSelectInfo({ selectJobType: this.selectJobType, info: selectData,selectJobId:this.selectJobId })
+			uni.setStorageSync('selectList_'+this.selectJobType+'_target_'+this.selectJobId, selectData)
+		},
+		globalChangeClass(index,item){
+			this.$refs.globalClassImgRef.close()
+			this.globalSwitchClass(index,item)
+		},
+		removeFromSave(){
+			let that = this
+			that.$util.confirmModal({content:'确认清除花材?'},() => {
+				that.removeFromSaveDirect()
+				that.$msg('已清除')
+            })
+		},
+		removeFromSaveDirect(){
+			let that = this
+			//删除仓库
+			uni.removeStorageSync('selectList_'+that.selectJobType+'_target_'+that.selectJobId)
+			that.reSetSelectInfo({selectJobType:that.selectJobType,selectJobId:that.selectJobId})
+			//删除多颜色
+			if(that.selectJobType == 'bill'){
+				uni.removeStorageSync("xj"+that.selectJobId)
+			}
+			//删除显示
+			if(!this.$util.isEmpty(this.globalItemData)){
+				this.globalItemData.forEach((item,index,arr) =>{
+					arr[index].bigCount = 0;
+					arr[index].smallCount = 0;
+					arr[index].userPrice = 0;
+					arr[index].remark = '';
+					arr[index].assignSeat = 1
+				})
+				this.$forceUpdate()
+			}
+		},
+        globalSearch(){
+			this.globalPage = 1
+            if(!this.$util.isEmpty(this.globalPy)){
+				this.globalGoToTop()
+                this.globalClassIndex = -1
+                this.globalFinishGetItem = 0
+                this.getGlobalProductList()
+            }
+        },
+		globalGoToTop(){
+			let that = this
+			this.globalScrollTopPlace = this.globalScrollTopOldPlace
+			this.$nextTick(()=>{
+				that.globalScrollTopPlace = 0
+			})
+		},
+		globalGetScroll(event){
+			this.globalScrollTopOldPlace = event.detail.scrollTop
+		},
+		globalScrollBottom(){
+			if(this.globalIsRequesting == true){
+				return false
+			}
+			this.globalIsRequesting = true
+			this.getGlobalProductList()
+        },
+		getSelectItemById(id, classId) {
+			let info = { bigCount: null, smallCount: null, autoPrice: null, itemPrice: null }
+			const item = this.selectList && this.selectList.find(ele => { return ele.id == id && ele.classId == classId })
+			if (item) {
+				info = { ...item, bigCount: Number(item.bigCount), smallCount: Number(item.smallCount), autoPrice: Number(item.autoPrice), itemPrice: Number(item.itemPrice)}
+			}
+			return info;
+		},
+		//添加删除和修改花材
+		//multiple 0一个一个加减 1弹框方式,多个加减
+		//calc 当multiple=0时,add表示加,sub表示减
+		replaceItemFn(product,multiple=0,calc='add',scan=0) {
+			let item = copyObject(product)
+			if(multiple == 0){
+				if(Number(item.smallCount)>0){
+					if(calc == 'add'){
+						item.smallCount++
+					}
+					if(calc == 'sub'){
+						item.smallCount--
+					}
+				}else{
+					if(calc == 'add'){
+						item.bigCount++
+					}
+					if(calc == 'sub'){
+						item.bigCount--
+					}					
+				}
+			}
+
+			const list = this.selectList
+
+			let index = list.findIndex(element => element.id == item.id)
+
+			//扫码数量累加
+			if(index != -1 && scan == 1){
+				item.bigCount = parseInt(Number(item.bigCount)+Number(list[index].bigCount))
+				item.smallCount = parseInt(Number(item.smallCount)+Number(list[index].smallCount))
+			}
+
+			//扫码会出现负数
+			if(Number(item.bigCount)<0 || Number(item.smallCount)<0){
+				return false
+			}
+
+			if(this.globalCheckStock){
+				let currentCount = Number(item.bigCount) * item.ratio + Number(item.smallCount)
+				currentCount = currentCount.toFixed(2)
+				let currentNum = Number(item.bigNum) * item.ratio + Number(item.smallNum)
+				currentNum = currentNum.toFixed(2)
+				if (Number(currentCount) > Number(currentNum)) {
+					this.$util.noStockRemind()
+					this.$msg("库存不足哦")
+					return
+				}
+			}
+
+			if(index == -1){
+				if(this.$util.isEmpty(item.userPrice) || Number(item.userPrice) == 0){
+					item.userPrice = item.bigPrice
+				}
+				list.push(item)			
+			}else{
+				if(item.bigCount <= 0 && item.smallCount <= 0){
+					//删除花材
+					list.splice(index,1)
+				}else{
+					list[index].bigCount = item.bigCount
+					list[index].smallCount = item.smallCount
+					list[index].userPrice = item.userPrice
+					list[index].aboutPrice = item.aboutPrice||0
+					list[index].totalPrice = item.totalPrice||0
+					list[index].remark = item.remark||''
+					list[index].assignSeat = item.assignSeat
+				}
+			}
+			//点击要响声
+			if(this.kdType == 'HIT' && multiple ==0){
+				this.$util.hitRemind()
+			}
+			//扫码要响声
+			if(scan == 1){
+				this.$util.hitRemind()
+			}
+			//数据放到仓库
+			this.pushToSave(list)
+			this.globalRememberRefresh()
+		},
+		delSelectedItem(product){
+			let item = copyObject(product)
+			const list = this.selectList
+			let index = list.findIndex(element => element.id == item.id)
+			if(index != -1){
+				list.splice(index,1)
+			}
+		},
+		listenScanItem(){
+			let that = this
+			// #ifdef APP-PLUS
+			//避免重复,每次进来先移除全局自定义事件监听器
+			uni.$off('listenGetScanCode')
+			uni.$on('listenGetScanCode',function(data){
+				that.takeItem(data.code)
+			})
+			// #endif
+			allProduct().then(res=>{
+				if(res.code == 1){
+					that.globalAllProduct = res.data.list
+					console.log('载入最新花材...')
+				}
+			})
+    	},
+		takeItem(code){
+			if(this.$util.isEmpty(code)){
+				return false
+			}
+			let current = null
+			let unitPrice = 0
+			let unitName = ''
+			//花材
+			current = this.globalAllProduct.find(function(val){
+				return Number(val.itemId) == Number(code)
+			})
+			if(current == undefined){
+				return false
+			}
+			if(this.$util.isEmpty(current)){
+				return false
+			}
+			unitName = current.bigUnit
+			unitPrice = current.bigPrice
+			let num = this.calc == 'add' ? 1 : -1
+			let params = {...current,unitName:unitName,userPrice:unitPrice,bigCount:num,smallCount:0}
+			this.replaceItemFn(params,1,'add',1)
+		},
+		//大小单位切换
+		switchGlobalUnitType(){
+			if(this.globalUnitType == 0){
+				this.globalUnitType = 1
+				this.customData.userPrice = parseFloat(this.customData.smallPrice)
+				this.customData.bigCount = null
+			}else{
+				this.globalUnitType = 0
+				this.customData.userPrice = parseFloat(this.customData.bigPrice)
+				this.customData.smallCount = null
+			}
+		},
+		//显示可以修改花材的弹框
+		showAddModelFn(info) {
+			if(info && info.variety == 1 && this.selectJobType == 'bill'){
+				let curPage = getCurrentPages();
+				let route = curPage[curPage.length - 1].route;
+				if(route == 'admin/billing/affirm'){
+					this.$msg('多颜色花材,请返回修改')
+					return false
+				}
+			}
+			if(info.bigNum <= 0 && info.smallNum <= 0){
+				if(this.globalCheckStock){
+					this.$util.noStockRemind()
+					this.$msg('库存不足哦..')
+					return false
+				}
+			}
+			//弹框时默认显示的单位
+			if(Number(info.smallCount)>0){
+				this.globalUnitType = 1
+				this.cgUnitType = 1
+			}else{
+				this.globalUnitType = 0
+				this.cgUnitType = 0
+			}
+			this.isAddModel = true;
+			this.customData = copyObject(info)
+			this.isAddInputFocus = false;
+			this.$nextTick(()=>{
+				this.customData.smallCount = this.customData.smallCount==0?null:this.customData.smallCount;
+				this.customData.bigCount = this.customData.bigCount==0?null:this.customData.bigCount;
+				if(this.selectJobType == 'bill'){
+					if(this.customData.userPrice == null || this.customData.userPrice == 0){
+						this.customData.userPrice =	parseFloat(this.customData.bigPrice)
+					}
+				}else{
+					this.customData.userPrice = this.customData.userPrice==0 ? null : parseFloat(this.customData.userPrice)
+				}
+				if(this.selectJobType == 'purchase'){
+					this.customData.totalPrice = this.customData.totalPrice ? Number(this.customData.totalPrice) : null
+					this.customData.aboutPrice = this.customData.aboutPrice||0
+				}
+				this.isAddInputFocus = true;
+			})
+		},
+		confirmAddItemModel(val) {
+			if (val.index === 0) {
+				this.addItemModelHidden();
+				return false
+			}
+
+			//二个都不是数值
+			if(/(^[1-9]\d*$)/.test(this.customData.bigCount) == false && /(^[1-9]\d*$)/.test(this.customData.smallCount) == false){
+				uni.showToast({title:"请填写数值",icon:"none"})
+				return;
+			}
+
+			if(/(^[1-9]\d*$)/.test(this.customData.bigCount)){
+				if(this.customData.bigCount<=0){
+					uni.showToast({title:"数量要大于0",icon:"none"})
+					return;
+				}
+			}
+
+			if(/(^[1-9]\d*$)/.test(this.customData.smallCount)){
+				if(this.customData.smallCount<=0){
+					uni.showToast({title:"数量要大于0",icon:"none"})
+					return;
+				}
+			}
+			//只有开单和采购需要使用价格
+			if(this.selectJobType == 'bill' || this.selectJobType == 'purchase'){
+				if(/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(this.customData.userPrice) == false){
+					uni.showToast({title:"金额错误",icon:"none"})
+					return;
+				}
+				if(this.customData.userPrice <=0){
+					uni.showToast({title:"金额要大于0",icon:"none"})
+					return;
+				}
+			}
+			if(this.selectJobType == 'purchase'){
+				if(this.customData.aboutPrice == 1){
+					if(Number(this.customData.totalPrice)<=0){
+						uni.showToast({title:"请填写总金额"+this.customData.totalPrice,icon:"none"})
+						return;
+					}
+					if(/(^[1-9]([0-9]+)?(\.[0-9]{1,2})?$)|(^(0){1}$)|(^[0-9]\.[0-9]([0-9])?$)/.test(this.customData.totalPrice) == false){
+						uni.showToast({title:"请填写总金额哦",icon:"none"})
+						return;
+					}
+				}
+			}
+
+			this.replaceItemFn(this.customData,1)
+			this.addItemModelHidden()			
+		},
+		addItemModelHidden() {
+			this.isAddModel = false;
+			this.customData = {};
+		}
+	}
+}

+ 1 - 0
hdApp/src/pages.json

@@ -376,6 +376,7 @@
 			"pages": [
 				{ "path": "index", "style": { "navigationBarTitleText": "开单" } },
 				{ "path": "index2", "style": { "navigationBarTitleText": "开单" } },
+				{ "path": "hs", "style": { "navigationBarTitleText": "开单" } },
 				{ "path": "customerPlace", "style": { "navigationBarTitleText": "开单" } },
 				{ "path": "priceChange", "style": { "navigationBarTitleText": "改价", "enablePullDownRefresh": true } },
 				{ "path": "result", "style": { "navigationBarTitleText": "开单状态" } },