Эх сурвалжийг харах

1. 购物车提交限购提示,并把限购信息传递到确认订单信息页(affirmGhs.vue)
2. 确认订单信息限购信息提示
3. 计算价格修改:特价与限购结合时,超限购时会改用原价来计算

shizhongqi 2 сар өмнө
parent
commit
992ff1a214

+ 110 - 111
hdApp/src/admin/billing/affirmGhs.vue

@@ -15,33 +15,25 @@
 					<view class="commodity-view">
 						<view class="commodity-list">
 							<view class="commodity-item" :class="{'limit-exceed-item': isLimitExceededItem(item)}" v-for="(item, index) in selectList" :key="index">
-								<image class="item-icon" :src="item.cover" alt="" />
+								<image class="item-icon" :src="item.cover" mode="aspectFill" />
 								<view class="item-info">
-
-									<view class="info-line">
+									<view class="item-row-top">
 										<text class="item-name">{{ item.itemName }}</text>
-										<text class="item-price">
-											<text class="unit"></text>
-											<text class="price">
-												¥{{ Number(item.bigCount)>0 ? parseFloat(item.bigPrice) : parseFloat(item.smallPrice) }}
-											</text>
-										</text>
-									</view>
-
-									<view style="text-align:right;position:relative;">
-										<view class="open-bx" >
-											<text class="num">
-												<text v-if="item.bigCount > 0" style="font-size:30upx;font-weight:bold;color:#3385ff;">
-													{{ item.bigCount }}{{item.bigUnit}}
-												</text>
-												<text v-if="item.smallCount > 0" style="font-size:30upx;">
-													{{ item.smallCount }}{{item.smallUnit}}
-												</text>
-											</text>
+										<view class="item-price-block">
+											<text class="price-current">{{ affirmCommodityPriceParts[index].main }}</text>
+											<text v-if="affirmCommodityPriceParts[index].showStrike" class="price-original">{{ affirmCommodityPriceParts[index].strike }}</text>
 										</view>
 									</view>
-									<text v-if="isLimitExceededItem(item)" class="limit-exceed-tip">限购 {{ limitExceedLimitBuy }},超出 {{ limitExceedNum }}</text>
-									<text v-if="item.presell == 1" style="position:absolute;top:86upx;font-weight:bold;color:red;font-size:30upx;">预售花材下单不能退款</text>
+									<view class="item-row-qty">
+										<text v-if="item.bigCount > 0" class="qty-part qty-big">{{ item.bigCount }}{{ item.bigUnit }}</text>
+										<text v-if="item.bigCount > 0 && item.smallCount > 0" class="qty-sep">·</text>
+										<text v-if="item.smallCount > 0" class="qty-part qty-small">{{ item.smallCount }}{{ item.smallUnit }}</text>
+									</view>
+									<view v-if="isLimitExceededItem(item) || getLimitBuyPriceTip(item) || item.presell == 1" class="item-row-tips">
+										<text v-if="isLimitExceededItem(item)" class="limit-exceed-tip">限购 {{ limitExceedLimitBuy }},超出 {{ limitExceedNum }}</text>
+										<text v-if="getLimitBuyPriceTip(item)" class="limit-buy-price-tip">{{ getLimitBuyPriceTip(item) }}</text>
+										<text v-if="item.presell == 1" class="presell-tip">预售花材下单不能退款</text>
+									</view>
 								</view>
 							</view>
 						</view>
@@ -57,8 +49,6 @@
 				</view>
 
 				<view class="module-com input-line-wrap">
-
-
 					<block v-if="ghsInfo.pfLevel && ghsInfo.pfLevel == 1">
 
 						<tui-list-cell class="line-cell" :hover="false" :arrow="false" v-if="ghsInfo.shopId == 14636">
@@ -508,6 +498,11 @@ export default {
 	},
 	computed: {
 		...mapGetters(["getMerchantInfo", "getLoginInfo","getDictionariesInfo"]),
+		/** 确认页列表每行价格展示(与 selectList 顺序一致) */
+		affirmCommodityPriceParts() {
+			const list = this.selectList || [];
+			return list.map(item => this.getLimitBuyPriceDisplayParts(item));
+		},
 		displayAddress(){
 			if(this.form.sendType != 1){
 				return true
@@ -628,7 +623,7 @@ export default {
 		 * @returns {number}
 		 */
 		modifyPrice(){
-			let allPrice = this.allPrice.toFixed(2)
+			let allPrice = this.allPriceFun.toFixed(2)
 			allPrice = Number(allPrice)
 			let price = allPrice
 
@@ -1088,6 +1083,7 @@ export default {
 		confirmFn(options) {
 			createOrder(options).then(res => {
 				this.resetSelectInfoByType(this.pageType);
+				this.resetLimitBuyInfoByType(this.pageType);
 				const { data: { id, orderSn } } = res;
 				let url = `/admin/billing/result?orderId=${id}&orderSn=${orderSn}`;
 				uni.redirectTo({ url: url })
@@ -1154,6 +1150,7 @@ export default {
 						self.pageTo({url: '/pagesPurchase/wechatPay',query:{orderSn,realPrice,id}, type: 2})
 						setTimeout(() => {
 							self.removeMemory(self.ghsInfo.id)
+							self.resetLimitBuyInfoByType(self.pageType)
 						}, 600)
 						return true
 					}
@@ -1278,103 +1275,105 @@ export default {
 						flex-shrink: 0;
 						width: 140upx;
 						height: 140upx;
+						border-radius: 4upx;
+						background-color: #f5f5f5;
 					}
 					.item-info {
-						position: relative;
 						display: flex;
 						flex-direction: column;
-						justify-content: center;
+						justify-content: flex-start;
 						flex: 1;
 						margin-left: 20upx;
-						.limit-exceed-tip {
+						min-width: 0;
+						.item-row-top {
+							display: flex;
+							flex-direction: row;
+							align-items: center;
+							justify-content: space-between;
+							width: 100%;
+						}
+						.item-name {
+							flex: 1;
+							min-width: 0;
+							padding-right: 16upx;
+							color: #333333;
+							font-size: 30upx;
+							font-weight: bold;
+							overflow: hidden;
+							white-space: nowrap;
+							text-overflow: ellipsis;
+							line-height: 1.3;
+						}
+						.item-price-block {
+							flex-shrink: 0;
+							display: flex;
+							flex-direction: row;
+							align-items: baseline;
+							max-width: 48%;
+						}
+						.price-current {
+							font-size: 32upx;
+							font-weight: bold;
+							color: #333333;
+							white-space: nowrap;
+							line-height: 1.2;
+						}
+						.price-original {
+							margin-left: 12upx;
+							font-size: 26upx;
+							color: #999999;
+							text-decoration: line-through;
+							white-space: nowrap;
+							line-height: 1.2;
+						}
+						.item-row-qty {
+							display: flex;
+							flex-direction: row;
+							justify-content: flex-end;
+							align-items: center;
+							margin-top: 10upx;
+							flex-wrap: wrap;
+						}
+						.qty-sep {
+							margin: 0 8upx;
+							color: #cccccc;
+							font-size: 28upx;
+						}
+						.qty-part {
+							font-size: 28upx;
+							color: #666666;
+						}
+						.qty-big {
+							font-size: 30upx;
+							font-weight: bold;
+							color: #3385ff;
+						}
+						.item-row-tips {
+							display: flex;
+							flex-direction: column;
 							margin-top: 10upx;
+						}
+						.limit-exceed-tip {
+							margin-top: 4upx;
 							color: #ff4d4f;
 							font-size: 24upx;
 							font-weight: bold;
+							line-height: 1.45;
 						}
-						.info-line {
-							margin-bottom: 20upx;
-							display: flex;
-							justify-content: space-between;
-							align-items: flex-end;
-							.item-name {
-								color: #333333;
-								font-size: 32upx;
-								font-weight:bold;
-								overflow: hidden;
-								white-space: nowrap;
-								text-overflow: ellipsis;
-								width:400upx;
-							}
-							.item-price {
-								color: #333;
-								font-size: 22upx;
-								.price {
-									font-size: 32upx;
-									font-weight: bold;
-								}
-							}
-							.item-type {
-								color: #999;
-								font-size: 24upx;
-							}
-							.item-count {
-								color: #666;
-								font-size: 24upx;
-							}
+						.limit-buy-price-tip {
+							margin-top: 4upx;
+							color: #ff7a00;
+							font-size: 24upx;
+							font-weight: bold;
+							line-height: 1.45;
+						}
+						.presell-tip {
+							margin-top: 4upx;
+							color: #e53935;
+							font-size: 24upx;
+							font-weight: bold;
+							line-height: 1.45;
 						}
-
-
-			.open-bx {
-				align-items: center;
-				& .iconfont {
-					color: #3385ff;
-					font-size: 42upx;
-				}
-
-				.position{
-					display: block;
-					width: 70upx;
-					text-align: center;
-				}
-				.iconcachu {
-					margin: 0 6upx 0 20upx;
-					color: #ccc;
-					&.edit {
-						color: #3385ff;
-					}
-				}
-				& > .num {
-					display: inline-block;
-					width: 120upx;
-					height:45upx;
-					text-align:right;
-					margin: 0 8upx;
-					color: #868686;
-					padding: 3upx 0;
-					font-size: 25upx;
-				}
-				.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;
-				}
-			}
-
 					}
 				}
 			}

+ 4 - 0
hdApp/src/api/purchase/index.js

@@ -137,3 +137,7 @@ export const createOrder = data => {
 export const addVirtualCg = data => {
 	return https.post("/purchase/add-virtual-cg", data);
 };
+
+export const getLimitBuyInfo = data => {
+	return https.post("/purchase/limit-buy-info", data);
+};

+ 121 - 11
hdApp/src/mixins/cgProduct.js

@@ -51,11 +51,15 @@ export default {
 	},
 	onUnload() {},
 	computed: {
-		...mapGetters(["getSelectInfo"]),
+		...mapGetters(["getSelectInfo", "getLimitBuyInfo"]),
 		//当前页面选中的商品列表
 		selectList() {
 			return this.getSelectInfo[this.pageType] || [];
 		},
+		//当前页面限购信息列表
+		limitBuyList() {
+			return this.getLimitBuyInfo[this.pageType] || [];
+		},
 		scrollClassId() {
 			const curClass = this.productInfo[this.classIndex];
 			if (curClass) {
@@ -81,15 +85,7 @@ export default {
 			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)
-					) {
-						price += item.bigCount * Number(itemInfo.bigPrice);
-						price += item.smallCount * Number(itemInfo.smallPrice);
-					}
+					price += this.getLimitBuyPriceInfo(item).total;
 				}
 			}
 			return Math.round(price * 100) / 100;
@@ -193,7 +189,120 @@ export default {
 		}
 	},
 	methods: {
-		...mapActions(["setSelectInfoByType", "resetSelectInfoByType"]),
+		...mapActions(["setSelectInfoByType", "resetSelectInfoByType", "setLimitBuyInfoByType", "resetLimitBuyInfoByType"]),
+		isTrueValue(value) {
+			return value === true || value === 1 || value === "1";
+		},
+		toSafeNumber(value) {
+			const num = Number(value);
+			return isNaN(num) ? 0 : num;
+		},
+		getLimitBuyItemById(id) {
+			if (!Array.isArray(this.limitBuyList)) {
+				return null;
+			}
+			return this.limitBuyList.find(item => String(item.id) === String(id)) || null;
+		},
+		isLimitSpecialItem(item) {
+			const limitItem = this.getLimitBuyItemById(item.id);
+			return !!(limitItem && this.isTrueValue(limitItem.isLimit) && this.isTrueValue(limitItem.specialPrice));
+		},
+		getLimitBuyPriceInfo(item) {
+			const itemInfo = this.getSelectItemById(item.id, item.classId);
+			
+			const specialPrice = this.toSafeNumber(item.price);
+			const originalPrice = this.toSafeNumber(item.prePrice);
+			const result = {
+				total: 0, //总价
+				specialPrice: specialPrice, //特价
+				originalPrice: originalPrice, //原价
+				exceedNum: 0, //超出数量
+				limitBuy: 0, //限购数量
+				hasBuyNum: 0, //已购买数量
+				currentBuyNum: 0, //此次购买数量
+				isLimitSpecial: false
+			};
+
+			result.total = itemInfo.bigCount * specialPrice + itemInfo.smallCount * originalPrice;
+			const limitItem = this.getLimitBuyItemById(item.id);
+			if (!limitItem || !this.isLimitSpecialItem(item)) {
+				return result;
+			}
+			const exceedNum = this.toSafeNumber(limitItem.exceedNum) + this.toSafeNumber(limitItem.currentBuyNum);
+			result.exceedNum = exceedNum; //超出数量
+			result.limitBuy = this.toSafeNumber(limitItem.limitBuy);
+			result.hasBuyNum = this.toSafeNumber(limitItem.hasBuyNum);
+			result.currentBuyNum = this.toSafeNumber(limitItem.currentBuyNum);
+			result.isLimitSpecial = true;
+			
+			if (result.exceedNum <= 0) {
+				result.total = result.currentBuyNum * specialPrice;
+			} else if (result.exceedNum > 0 && result.hasBuyNum > result.limitBuy) {
+				result.total = result.currentBuyNum * originalPrice;
+			} else {
+				result.total = (result.currentBuyNum - result.exceedNum) * specialPrice + result.exceedNum * originalPrice;
+			}
+
+			return result;
+		},
+		/**
+		 * 确认页花材价格展示:主价 + 可选删除线原价(限购特价部分超出时)
+		 * @returns {{ main: string, strike: string, showStrike: boolean }}
+		 */
+		getLimitBuyPriceDisplayParts(item) {
+			const priceInfo = this.getLimitBuyPriceInfo(item);
+			const fmt = (n) => parseFloat(Number(n) || 0);
+			if (!priceInfo.isLimitSpecial) {
+				const big = Number(item.bigCount) > 0;
+				const p = big
+					? this.toSafeNumber(item.bigPrice)
+					: this.toSafeNumber(item.smallPrice);
+				return {
+					showStrike: false,
+					main: `¥${fmt(p)}`,
+					strike: ""
+				};
+			}
+			if (priceInfo.exceedNum <= 0) {
+				return {
+					showStrike: false,
+					main: `¥${fmt(priceInfo.specialPrice)}`,
+					strike: ""
+				};
+			}
+			if (priceInfo.exceedNum > 0 && priceInfo.hasBuyNum > priceInfo.limitBuy) {
+				return {
+					showStrike: false,
+					main: `¥${fmt(priceInfo.originalPrice)}`,
+					strike: ""
+				};
+			}
+			return {
+				showStrike: true,
+				main: `¥${fmt(priceInfo.specialPrice)}`,
+				strike: `¥${fmt(priceInfo.originalPrice)}`
+			};
+		},
+		getLimitBuyPriceText(item) {
+			const parts = this.getLimitBuyPriceDisplayParts(item);
+			if (parts.showStrike) {
+				return `${parts.main} ${parts.strike}`;
+			}
+			return parts.main;
+		},
+		getLimitBuyPriceTip(item) {
+			const priceInfo = this.getLimitBuyPriceInfo(item);
+			if (!priceInfo.isLimitSpecial) {
+				return "";
+			}
+			if (priceInfo.exceedNum <= 0) {
+				return `限购 ${priceInfo.limitBuy},未超限购,按特价计算`;
+			}
+			if (priceInfo.exceedNum > 0 && priceInfo.hasBuyNum > priceInfo.limitBuy) {
+				return `限购 ${priceInfo.limitBuy},已超出,按原价计算`;
+			}
+			return `限购 ${priceInfo.limitBuy},${priceInfo.currentBuyNum - priceInfo.exceedNum} 扎按特价,超出 ${priceInfo.exceedNum} 扎按原价`;
+		},
 		//记忆已选的花材
 		rememberProduct(){
 			//采购或预订的记忆花材
@@ -224,6 +333,7 @@ export default {
 				uni.removeStorageSync('selectList'+this.pageType);
 			}
 			this.resetSelectInfoByType(this.pageType);
+			this.resetLimitBuyInfoByType(this.pageType);
 		},
 		//大小单位切换
 		switchGlobalUnitType(){

+ 47 - 8
hdApp/src/pagesPurchase/ghsProduct.vue

@@ -139,6 +139,9 @@
 										</text>
 									</text>
 								</view>
+								<view class="limit-buy-tip" v-if="getLimitBuyWarn(item)">
+									{{ getLimitBuyWarn(item) }}
+								</view>
 								<view style="text-align:right;">
 									<view class="open-bx" >
 										<text class="iconfont iconjian" @click.stop="delItem(item)" v-if="item.bigCount > 0 || item.smallCount > 0"></text>
@@ -203,9 +206,10 @@ import FooterCart from "@/components/module/app-footer-cart";
 import ModalModule from "@/components/plugin/modal";
 import wangCg from "./components/wangCg";
 import productMins from "@/mixins/cgProduct";
-import { getGhsDataApi, ghsInfo, visitMall } from "@/api/ghs";
 import AppActivilyCoupon from "@/components/module/app-activily-coupon";
 import { mapGetters } from "vuex";
+import { getGhsDataApi, ghsInfo, visitMall } from "@/api/ghs";
+import { getLimitBuyInfo } from "@/api/purchase";
 export default {
 	name: "ghsProduct",
 	components: {
@@ -256,6 +260,7 @@ export default {
 			newCustomGift:{xrFlAmount:0},
 			isNewCustom:false,
 			cartItemShow:false,
+			limitBuyWarnList:[],
 			buyNotice:0,
 			backAction:'',
 			shareImgUrl:'',
@@ -286,7 +291,6 @@ export default {
 		}
 	},
 	onShow(){
-
 		if(this.backAction == 'login'){
 			this.init()
 		}
@@ -299,7 +303,6 @@ export default {
 		}
 
 		if(this.xjData.hasUpdate == 1){
-
 			this.customData = this.hasColorInfo
 
 			if(this.xjData.cancel == 1){
@@ -307,7 +310,6 @@ export default {
 				this.customData.smallCount = 0
 				this.affirm({index:0})
 			}else{
-
 				//判断list有没有数据,没有需要初始化
 				const list = this.selectList;
 				let has = false
@@ -441,6 +443,13 @@ export default {
 				}
 			}
 		},
+		getLimitBuyWarn(item){
+			const info = this.limitBuyWarnList.find(warnItem => warnItem.id == item.id)
+			if(!info){
+				return ''
+			}
+			return `超出限购${info.currentBuyNum + info.exceedNum}份`
+		},
 		getReadMe(shopId){
 			this.$util.pageTo({url:'/pagesPurchase/readMe?shopId='+shopId})
 		},
@@ -673,10 +682,31 @@ export default {
 					this.$msg("请选择花材")
 					return
 				}
-				this.setSelectInfoByType({ type: this.pageType, info: list });
-
-				this.pageTo({url: '/admin/billing/affirmGhs?id='+this.options.id,type: 2})
-
+                
+				// 请求后端接口,获取限购花材信息
+				let newList = list.map(item => {
+					return {
+						id: item.id,
+						bigCount: item.bigCount,
+						//smallCount: item.smallCount
+					}
+				})
+				getLimitBuyInfo({ghsId: this.options.id, list: newList}).then(res => {
+					const limitBuyInfo = Array.isArray(res.data) ? res.data : []
+					const warnList = limitBuyInfo.filter(item => item.specialPrice === false && item.reachLimitBuyNum === true)
+					if(warnList.length > 0){
+						this.limitBuyWarnList = warnList
+						this.cartItemShow = true
+						this.$msg("有花材超出限购")
+						return
+					}
+					this.limitBuyWarnList = []
+					this.setSelectInfoByType({ type: this.pageType, info: list});
+					this.setLimitBuyInfoByType({ type: this.pageType, info: limitBuyInfo });
+					this.pageTo({url: '/admin/billing/affirmGhs?id='+this.options.id, type: 1})
+				}).catch(() => {
+					this.$msg("限购信息获取失败,请稍后重试")
+				})
 			} else {
 				this.$msg("请选择花材");
 			}
@@ -954,6 +984,7 @@ export default {
 				justify-content: center;
 				flex: 1;
 				margin-left: 20upx;
+				position: relative;
 				.info-line {
 					margin-bottom: 20upx;
 					display: flex;
@@ -976,6 +1007,14 @@ export default {
 						}
 					}
 				}
+			.limit-buy-tip {
+				position: absolute;
+				left: 0;
+				top: 86upx;
+				color: red;
+				font-size: 24upx;
+				text-align: left;
+			}
 
 
 	.open-bx {

+ 17 - 1
hdApp/src/store/modules/product.js

@@ -1,10 +1,14 @@
 export default {
 	state: {
-		selectInfo: {} //选择商品信息  用页面pageType当key  查询对应模块选择的商品列表
+		selectInfo: {}, //选择商品信息  用页面pageType当key  查询对应模块选择的商品列表
+		limitBuyInfo: {} //限购信息  用页面pageType当key  查询对应模块限购列表
 	},
 	getters: {
 		getSelectInfo(state) {
 			return state.selectInfo || {};
+		},
+		getLimitBuyInfo(state) {
+			return state.limitBuyInfo || {};
 		}
 	},
 	actions: {
@@ -16,6 +20,15 @@ export default {
 		resetSelectInfoByType({ commit }, type) {
 			commit("SET_SELECTINFO_BY_TYPE", { type, info: [] });
 		},
+		
+		//设置不同类别限购信息(采购模块供确认页计价使用)
+		setLimitBuyInfoByType({ commit }, { type, info }) {
+			commit("SET_LIMITBUYINFO_BY_TYPE", { type, info });
+		},
+		//清空不同类别限购信息
+		resetLimitBuyInfoByType({ commit }, type) {
+			commit("SET_LIMITBUYINFO_BY_TYPE", { type, info: [] });
+		},
 
 		//重要!!!!selectJobType区分不同业务,如开单、损耗、调拨,selectJobId用于区分相同业务下的不同主体,如调拨给不同门店,开店给不同的客户
 
@@ -34,6 +47,9 @@ export default {
 		["SET_SELECTINFO_BY_TYPE"](state, { type, info }) {
 			state.selectInfo = {...state.selectInfo,[type]: info};
 		},
+		["SET_LIMITBUYINFO_BY_TYPE"](state, { type, info }) {
+			state.limitBuyInfo = {...state.limitBuyInfo,[type]: info};
+		},
 		//新写法
 		SET_SELECTED_ITEM(state, { selectJobType, info,selectJobId }) {
 			state.selectInfo = { ...state.selectInfo, [selectJobType+'_'+selectJobId]: info }