소스 검색

0814-1454-h01

Zory 1 개월 전
부모
커밋
d22f3ab935

+ 26 - 0
奥莱优品/App.vue

@@ -38,6 +38,32 @@ export default {
 	},
 	onHide: function() {
 		console.log('App Hide')
+	},
+	methods: {
+		getPhoneNumber: function({ params, success, fail }) {
+			const { iv, encryptedData } = params;
+			tt.login({
+				force:true,
+				success(lres){
+					tt.request({
+						url:"https://tran.jsshuita.cn/v2/home/mobile",
+						data:{iv:iv,encryptedData:encryptedData,code:lres.code},
+						method:"POST",
+						success(res){
+							var resp = res.data;
+							if (resp.code == 0) return ;
+							success({ phoneNumber: resp.data.mobile })
+						},
+						fail(res){
+
+						}
+					})
+				},
+				fail(res){
+
+				}
+			})
+		},
 	}
 }
 </script>

+ 12 - 0
奥莱优品/api/model/auth.js

@@ -6,5 +6,17 @@ export default {
 		post: async function(data={}) {
 			return await request.request(this.url,"POST",data,false,true,false)
 		}
+	},
+	nick: {
+		url: `/auth/nick`,
+		post: async function(data={}) {
+			return await request.request(this.url,"POST",data,false,true,false)
+		}
+	},
+	check: {
+		url: `/auth/check`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,false)
+		}
 	}
 }

+ 22 - 0
奥莱优品/api/model/goods.js

@@ -0,0 +1,22 @@
+import request from '@/static/js/request.js'
+
+export default {
+	detail: {
+		url: `/goods/data`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	},
+	license: {
+		url: `/home/license`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	},
+	goods: {
+		url: `/home/goods`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	}
+}

+ 22 - 0
奥莱优品/api/model/home.js

@@ -0,0 +1,22 @@
+import request from '@/static/js/request.js'
+
+export default {
+	data: {
+		url: `/home/data`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	},
+	license: {
+		url: `/home/license`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	},
+	goods: {
+		url: `/home/goods`,
+		get: async function(data={}) {
+			return await request.request(this.url,"GET",data,false,true,true)
+		}
+	}
+}

+ 2 - 1
奥莱优品/components/kfService/kfService.vue

@@ -40,8 +40,9 @@ export default {
 				this.$refs.servicePop.close()
 			}
 		},
-		open() {
+		open(data) {
 			uni.hideTabBar();
+			this.storeData = data;
 			this.$nextTick(()=>{
 				this.$refs.servicePop.open()
 			})

+ 12 - 3
奥莱优品/components/login/halfScreen.vue

@@ -46,7 +46,9 @@ export default {
 			this.checkTrueState = !this.checkTrueState;
 		},
 		toWeb(type){
-
+			uni.navigateTo({
+				url:"/pages/web/web?type="+type
+			})
 		},
 		toLoginCheck(){
 			if (!this.checkTrueState) {
@@ -59,7 +61,13 @@ export default {
 		},
 		getPhoneNumberData(event){
 			uni.login({
-				success: async (resp)=> {
+				success: async (resp)=> {
+					if (event.detail.errNo) {
+						return uni.showToast({
+							title: "请重试一次",
+							icon:"none"
+						})
+					}
 					var detail = event.detail
 					detail.login = resp.code;
 					var aresp = await this.$api.auth.mobile.post(detail);
@@ -70,7 +78,8 @@ export default {
 					uni.showTabBar()
 					this.$nextTick(()=>{
 						this.$refs.loginPop.close()
-					})
+					})
+					this.$emit('success',aresp.data.access_token);
 				}
 			})
 		},

+ 18 - 0
奥莱优品/pages.json

@@ -47,6 +47,24 @@
 					"pay-button-sdk": "tta5a3d31e3aecfb9b11://pay-button"
 				}
 			}
+		},
+		{
+			"path": "pages/web/web",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+		},
+		{
+			"path": "pages/order/tips",
+			"style": {
+				"navigationBarTitleText": ""
+			}
+		},
+		{
+			"path": "pages/user/license",
+			"style": {
+				"navigationBarTitleText": "服务资质"
+			}
 		}
 	],
 	"globalStyle": {

+ 524 - 7
奥莱优品/pages/goods/detail.vue

@@ -1,6 +1,6 @@
 <template>
 	<view class="content">
-		<block v-if="loading">
+		<block v-if="isLoading">
 			<view class="skeleton-line max animate" style="height: 400rpx;"></view>
 			<view class="skeleton">
 				<view class="skeleton-line animate mt15"></view>
@@ -12,6 +12,113 @@
 		</block>
 		<view class="goods-content" v-else>
 			<scroll-view class="goods-body" scroll-y scroll-with-animation>
+				<view class="home-banner" v-if="bannerData.length>0">
+					<swiper class="swiper" circular :indicator-dots="indicatorDots" :style="{ height: swiperHeight + 'px' }" :current="currIndex" @change="changeSwiper" :autoplay="false" :interval="2000" :duration="200">
+						<swiper-item class="swiper-item" v-for="(item,idex) in bannerData" :key="idex">
+							<image :src="item.url" :id="'wrap' + idex" mode="widthFix"></image>
+						</swiper-item>
+					</swiper>
+				</view>
+				<view class="goods-top" v-if="goodsData">
+					<view class="price">
+						<view class="price-sale">{{ goodsData.price?$dialog.formatMoney(goodsData.price):'0.00'}}</view>
+						<view class="sale">{{$dialog.disFormat(goodsData.price,goodsData.line_price)}}折</view>
+						<view class="line-price">{{ goodsData.line_price ? $dialog.formatMoney(goodsData.line_price) : '0.00'}}</view>
+						<view class="desc-num">已售{{goodsData.sale_stock}}</view>
+					</view>
+					<view class="goods-info">
+						<view class="title">{{goodsData.product_name}}</view>
+						<view class="goods-rule" @click="openRule(1)">
+							购买须知<view class="right">
+							<span class="mix-item" v-if="goodsData.use_date_type==1">
+								自购买之日起{{ goodsData.day_duration }}天有效
+							</span>
+							<span class="mix-item" v-if="goodsData.use_date_type==2">
+								有效期:{{ $dialog.dateFormat(goodsData.use_time_start,'yyyy-MM-dd') }}至{{ $dialog.dateFormat(goodsData.use_time_end,'yyyy-MM-dd') }}
+							</span>
+							 <image src="/static/image/right-black.png"></image></view>
+						</view>
+						<view class="goods-safe">
+							<view class="safe-item"><image src="/static/image/check.png"></image>过期退</view>
+							<view class="safe-item"><image src="/static/image/check.png"></image>随时退</view>
+						</view>
+					</view>
+					<view class="goods-store" v-if="goodsData.poi">
+						<view class="title">适用门店</view>
+						<view class="store-info">
+							<view class="store-left">
+								<view class="name">{{goodsData.poi?goodsData.poi.poi_name:'-'}}</view>
+								<view class="address">{{goodsData.poi?goodsData.poi.poi_address:'-'}}</view>
+							</view>
+							<view class="store-right">
+								<view class="right-item" @click="toMap">
+									<image src="/static/image/amap.png"></image>
+									<view class="desc">导航</view>
+								</view>
+							</view>
+						</view>
+					</view>
+
+					<view class="buy-rule">
+						<view class="title">购买须知</view>
+						<view class="rule-list">
+							<view class="rule-item">
+								<view class="icon"><image src="/static/image/rule-date.png"></image></view>
+								<view class="item-top">
+									<view class="name">可用日期</view>
+									<view class="desc">
+										<span class="mix-item" v-if="goodsData.use_date_type==1">
+											自购买之日起{{ goodsData.day_duration }}天有效
+										</span>
+										<span class="mix-item" v-if="goodsData.use_date_type==2">
+											有效期:{{ $dialog.dateFormat(goodsData.use_time_start,'yyyy-MM-dd') }}至{{ $dialog.dateFormat(goodsData.use_time_end,'yyyy-MM-dd') }}
+										</span>
+									</view>
+								</view>
+							</view>
+							<view class="rule-item">
+								<view class="icon"><image src="/static/image/rule-time.png"></image></view>
+								<view class="item-top">
+									<view class="name">可用时间</view>
+									<view class="desc" v-if="goodsData.can_no_use_date==1">商家营业时间可用</view>
+								</view>
+							</view>
+							<view class="rule-item">
+								<view class="icon"><image src="/static/image/rule-rule.png"></image></view>
+								<view class="item-top">
+									<view class="name">预约规则</view>
+									<view class="desc" v-if="goodsData.booking_type==1">无需预约,高峰期可能需要排队</view>
+									<view class="desc" v-if="goodsData.booking_type==2">
+										需要提前<span>{{ goodsData.booking_date }}</span>{{ goodsData.booking_unit==1?'天':'小时' }}预约
+									</view>
+								</view>
+							</view>
+							<view class="rule-item">
+								<view class="icon"><image src="/static/image/rule-refund.png"></image></view>
+								<view class="item-top">
+									<view class="name">退款政策<view class="tips">随时退/过期退</view></view>
+									<view class="desc">随时退款:未核销的商品支持随时申请退款;过期自动退:商品若在有效时间内未核销使用,到期之后系统将自动发起退款</view>
+								</view>
+							</view>
+						</view>
+					</view>
+
+					<view class="other-content">
+						<view class="title">更多详情</view>
+						<view class="rule-content">
+							<template v-if="goodsData.content">
+								<view class="content-data" v-html="goodsData.content"></view>
+							</template>
+							<template v-if="otherImg.length > 0">
+								<view class="rule-img" v-for="(item,indx) in otherImg" :key="indx">
+									<image :src="item" mode="widthFix"></image>
+								</view>
+							</template>
+						</view>
+					</view>
+
+				</view>
+				<view class="line-height"></view>
 			</scroll-view>
 			<view class="footer">
 				<view class="footer-op">
@@ -26,7 +133,58 @@
 				<view class="footer-safe"></view>
 			</view>
 		</view>
-		<halfLogin ref="loginCom"></halfLogin>
+		<uni-popup ref="buypopup" type="bottom" border-radius="10px 10px 0 0" background-color="#ffffff" :mask-click="false">
+			<view class="service-popup popup-flex popup-height" v-if="goodsData">
+				<view class="tags-top">
+					<view class="tags">
+						<view class="safe-item"><image src="/static/image/check.png"></image>过期退</view>
+						<view class="safe-item"><image src="/static/image/check.png"></image>随时退</view>
+					</view>
+					<view class="close" @click="buyOrder(2)"><image src="/static/image/close.png"></image></view>
+				</view>
+				<view class="buy-godos-top">
+					<view class="goods-top-info">
+						<view class="imgs"><image :src="buyGoods.img" mode="widthFix"></image></view>
+						<view class="price-body">
+							<view class="title">{{goodsData.product_name}}</view>
+							<view class="price">
+								<view class="price-sale">{{ buyGoods.price?$dialog.formatMoney(buyGoods.price):'0.00'}}</view>
+								<view class="sale">{{$dialog.disFormat(buyGoods.price,buyGoods.line_price)}}折</view>
+								<view class="line-price">{{ buyGoods.line_price ? $dialog.formatMoney(buyGoods.line_price) : '0.00'}}</view>
+							</view>
+							<view class="name">已选:{{ buyGoods.name }}</view>
+						</view>
+					</view>
+				</view>
+				<view class="buy-godos-mib">
+					<view class="mib-title">规格</view>
+					<view class="mib-body" v-if="goodsData.mult_sku==2">
+						<view :class="indx==skuIndex?'mib-body-item active':'mib-body-item'" v-for="(item,indx) in skuSpecs" :key="indx" @click="checkSku(item,indx)">{{item.name}}</view>
+					</view>
+					<view class="mib-body" v-else>
+						<view class="mib-body-item active">默认</view>
+					</view>
+				</view>
+				<view class="buy-godos-footer">
+					<!-- <view class="btn-item-c">
+						<button class="cancel-btn" @click="buyOrder(2)">再看看</button>
+					</view> -->
+					<view class="btn-item fex1">
+						<pay-button-sdk
+							class="pay-button"
+							:mode="2"
+							:goods-type="1"
+							:goods-id="goodsData.goods_id"
+							bind:getgoodsinfo="getGoodsInfo"
+							bind:placeorder="userLogin"
+							bind:error="onErrors"
+							bind:pay="onPay"
+						></pay-button-sdk>
+					</view>
+				</view>
+			</view>
+		</uni-popup>
+		<halfLogin ref="loginCom" @success="loginSuccess"></halfLogin>
 		<kfService ref="kfService"></kfService>
 	</view>
 </template>
@@ -38,8 +196,12 @@ export default {
 		return {
 			options:null,
 			isLogin:null,
-			loading:false,
-			goodsData:null
+			isLoading:false,
+			goodsData:null,
+			bannerData:[],
+			buyGoods:null,
+			currIndex:0,
+			swiperHeight:0
 		}
 	},
 	onLoad(options) {
@@ -48,13 +210,165 @@ export default {
 		options.scene = data.scene
 		app.options = options
 		app.isLogin = uni.getStorageSync("user_token");
+		app.getDetail()
 	},
-	methods: {
+	created() {
+		this.$scope.getGoodsInfo = this.getGoodsInfo;
+		this.$scope.userLogin = this.userLogin;
+		this.$scope.onErrors = this.onErrors;
+		this.$scope.onPay = this.onPay;
+	},
+	methods: {
+		getGoodsInfo(){
+			return new Promise(resolve => {
+				resolve({
+					minLimits: 1,
+					maxLimits: app.goodsData.limit_rule_type==1?99:app.goodsData.limit_rule,
+					dateRule: '周一至周日可用',
+					relationType: 1,
+					goodsLabels:[
+						{type: 'EXPIRED_RETURNS'}, // 过期退
+						{type: 'REFUND_ANYTIME'}, // 随时退
+					],
+					validation: {
+						phoneNumber: {
+							required: true  // 手机号是否必填
+						}
+					},
+					extra:app.buyGoods,
+					// 在 bind:getgoodsinfo 返回的 promise 的 resolve 函数中新增 marketingVersion 字段
+					marketingVersion: 2,
+				});
+			})
+		},
+		userLogin(){
+			return new Promise((resolve, reject) => {
+				tt.login({
+					success(){
+						console.log("next")
+						resolve()
+					},
+					fail: () => reject()
+				});
+			});
+		},
+		onErrors(){},
+		onPay(event){
+			const { status, outOrderNo, result } = event.detail;
+			console.log(status, outOrderNo, result)
+			const { code } = result;
+			app.buyOrder(2)
+			if (code === 0) { // 支付成功
+				app.$dialog.showSuccess("支付成功","none",function(){
+					uni.redirectTo({
+						url:"usr://pages/order/detail?order="+outOrderNo
+					})
+				})
+			} else {
+				app.$dialog.showSuccess("支付失败","none",function(){
+					uni.redirectTo({
+						url:"usr://pages/order/detail?order="+outOrderNo
+					})
+				})
+				// 继续支付失败(超时、取消、关闭)
+			}
+		},
+		buyOrder(type){
+			if (!app.isLogin) {
+				return ;
+			}
+			if (type == 1) {
+				app.$refs.buypopup.open()
+			} else {
+				app.$refs.buypopup.close()
+			}
+			return ;
+		},
+		toMap(){
+			var poi = app.goodsData.poi;
+			uni.openLocation({
+				latitude:poi.latitude,
+				longitude:poi.longitude,
+				name:poi.poi_name,
+				address:poi.poi_address,
+				success() {
+					console.log("open success")
+				},
+				fail(err) {
+					app.$dialog.showSuccess("打开导航失败")
+					console.log(err)
+				}
+			})
+		},
+		async getDetail(){
+			app.isLoading = true;
+			var res = await app.$api.goods.detail.get(app.options);
+			app.isLoading = false;
+			if (res.code && res.code == 0) {
+				return app.$dialog.showSuccess(res.msg);
+			}
+			if (!app.storeData) {
+				app.storeData = res.data.poi;
+				uni.setStorageSync("contact",res.data.poi);
+			}
+			uni.setStorageSync("poiId",res.data.poi.poi_id);
+			app.goodsData = res.data;
+			app.bannerData = res.data.image_list
+			if (res.data.skuSpecs.length > 0) {
+				var skuSpecs = app.skuSpecs[0]
+				var buyGoods = {
+					img:skuSpecs.image,
+					price:skuSpecs.price,
+					line_price:skuSpecs.line_price,
+					name:skuSpecs.name,
+					number:1,
+					product_id:skuSpecs.product_id,
+					sku_id:skuSpecs.sku_id,
+					goods_id:skuSpecs.goods_id,
+					scene:app.scene
+				}
+			} else {
+				var buyGoods = {
+					img:res.data.image_list[0].url,
+					price:res.data.price,
+					line_price:res.data.line_price,
+					name:"默认",
+					number:1,
+					product_id:res.data.product_id,
+					sku_id:res.data.product_id,
+					goods_id:res.data.goods_id,
+					scene:app.scene
+				}
+			}
+			app.buyGoods = buyGoods
+			setTimeout(function(){
+				app.setSwiperHeight(); // 动态设置 swiper 的高度
+			},800)
+		},
+		/* 切换 swiper 滑块 */
+		changeSwiper(e) {
+			app.currIndex = e.detail.current;
+			app.$nextTick(() => {
+				app.setSwiperHeight(); // 动态设置 swiper 的高度
+			});
+		},
+		/* 动态设置 swiper 的高度 */
+		setSwiperHeight() {
+			const element = "#wrap" + app.currIndex;
+			const query = uni.createSelectorQuery().in(this);
+			query.select(element).boundingClientRect();
+			query.exec(res => {
+				if (res && res[0]) this.swiperHeight = res[0].height==0?res[0].width:res[0].height;
+			});
+		},
 		toLogin(){
 			this.$refs.loginCom.open();
 		},
 		kfPop(){
-			this.$refs.kfService.open();
+			this.$refs.kfService.open(app.storeData);
+		},
+		loginSuccess(token){
+			app.isLogin = token;
 		},
 		toNav(type) {
 			var url = "";
@@ -76,13 +390,210 @@ export default {
 </script>
 
 <style lang="scss" scoped>
+.tags-top {
+	display: flex;
+	align-items: center;
+	justify-content: space-between;
+	position: relative;
+	padding: 20rpx;
+	.tags{
+		display: flex;
+		align-items: center;
+		justify-content: center;
+		gap: 20rpx;
+		flex: 1;
+		.safe-item{
+			display: flex;align-items: center;
+			image{width: 30upx;height: 30upx;margin-right: 10upx;}
+		}
+	}
+	.close{
+		margin-left: auto;margin-right: 0;display: flex;align-items: center;justify-content: center;
+		image{width: 40upx;height: 40upx;}
+	}
+}
+.buy-godos-top{
+	display: flex;padding: 30rpx 15rpx 15rpx;align-items: start;
+	.close{
+		margin-left: auto;margin-right: 0;display: flex;align-items: center;justify-content: center;
+		image{width: 40upx;height: 40upx;}
+	}
+	.imgs{
+		height: 200upx;overflow: hidden;
+		image{width: 200upx;border-radius: 10upx;}
+	}
+	.goods-top-info{
+		display: flex;align-items: center;gap: 20rpx;
+		.price-body {
+			flex: 1;
+			.title{
+				font-size: 32rpx;color: #000;font-weight: bold;
+			}
+		}
+		.price{
+			display: flex;align-items: self-end;flex: 1;gap:20rpx;
+			.line-price{color: #999999;font-size: 24rpx;text-decoration-line: line-through;}
+			.price-sale{color: #FF4747;font-size: 32rpx;font-weight: bold;}
+			.sale{background-color: #FDEBE5;border: 4rpx;font-size: 22rpx;color: #FF4747;padding: 10rpx;display: inline-block;}
+		}
+		.desc-num{color: #999;font-size: 24upx;margin-left: auto;margin-right: 0;}
+		.name{font-size: 22rpx;margin-top: 15upx;color: #666;}
+	}
+}
+.buy-godos-footer{
+	padding: 20upx;display: flex;align-items: center;justify-content: space-between;gap: 20upx;
+	.btn-item {
+		&.fex1{flex: 1;}
+		.pay-button{
+			width: 100% !important;
+			background-color: $main-color;
+		}
+	}
+	.cancel-btn{
+		font-size: 32upx;
+		border-radius: 10upx;
+		color: #333;
+		background-color: #fff;
+		border: 2upx solid #ddd;
+		height: 48px;
+		line-height: 48px;
+	}
+	.cancel-btn::after{border: 0;}
+}
+.buy-godos-mib{
+	padding: 20upx;flex: 1;
+	.mib-number{margin-top: 20upx;display: flex;align-items: center;justify-content: space-between;font-size: 28upx;color: #666;}
+	.mib-title{font-size: 28upx;color: #666;}
+	.mib-body{
+		margin-top: 15upx;display: flex;align-items: center;flex-wrap: wrap;gap: 20upx;
+		.mib-body-item{
+			font-size: 24upx;color: #666;padding: 10upx;background-color: #f8f8f8;border-radius: 5upx;
+			&.active{background-color: #007aff;color: #fff;}
+		}
+	}
+}
 .content {
-	background-color: #fff;
+	background-color: #f8f8f8;
 	height: 100vh;
 	.skeleton{
 		width: 95%;
 		margin: 0 auto;
 	}
+	.line-height{
+		height: 40rpx;
+		width: 100%;
+	}
+	.goods-top{
+		border-radius: 20rpx 20rpx 0 0;
+		.other-content{
+			background-color: #fff;
+			width: 95%;
+			margin:20rpx auto;
+			padding: 20rpx;
+			border-radius: 20rpx;
+			.title{
+				line-height: 80upx;font-size: 32rpx;color: #333;font-weight: bold;display: flex;align-items: center;
+				border-bottom: 2upx solid #f8f8f8;
+				margin-bottom: 20rpx;
+			}
+		}
+		.buy-rule{
+			background-color: #fff;
+			width: 95%;
+			margin:20rpx auto;
+			padding: 20rpx;
+			border-radius: 20rpx;
+			.title{
+				line-height: 80upx;font-size: 32rpx;color: #333;font-weight: bold;display: flex;align-items: center;
+				border-bottom: 2upx solid #f8f8f8;
+			}
+			.rule-item{
+				display: flex;margin-top: 40upx;align-items: start;gap:20rpx;
+				image{width: 50upx;height: 50upx;}
+				.name{
+					font-size: 28rpx;color: #333;font-weight: bold;margin-bottom: 10upx;display: flex;align-items: center;
+					.tips{color: #333;border: 2upx solid #ddd;border-radius: 5upx;font-size: 22rpx;font-weight: normal;margin-left: 40upx;background-color: #fff;padding: 5upx 10upx;}
+				}
+			}
+		}
+		.goods-store{
+			background-color: #fff;
+			width: 95%;
+			margin:20rpx auto;
+			padding: 20rpx;
+			border-radius: 20rpx;
+			.title{
+				line-height: 80upx;
+				font-size: 32rpx;
+				color: #333;
+				font-weight: bold;
+				display: flex;
+				align-items: center;
+				border-bottom: 2upx solid #f8f8f8;
+			}
+			.store-info{
+				display: flex;align-items: center;padding: 20upx 0;
+				.store-right{
+					margin-left: auto;margin-right: 0;font-size: 24rpx;color: #999;
+					image{width: 50upx;height: 50upx;margin-bottom: 10upx;}
+				}
+				.store-left {
+					.name{font-size: 30rpx;color: #333;font-weight: bold;line-height: 80upx;}
+					.address{font-size: 24rpx;color: #999;}
+				}
+			}
+		}
+		.goods-info{
+			background-color: #fff;
+			width: 95%;
+			margin:0 auto;
+			padding: 20rpx;
+			border-radius: 20rpx;
+			.title{
+				font-size: 32rpx;color: #000;font-weight: bold;
+			}
+			.goods-rule{
+				margin: 20upx 0;display: flex;align-items: center;font-size: 24rpx;color: #999;height: 80upx;line-height: 80upx;
+				.right{
+					display: flex;align-items: center;flex: 1;color: #000;margin-left: 40upx;
+					image{width: 30upx;height: 30upx;margin-left: auto;margin-right: 0;}
+				}
+			}
+			.goods-safe{
+				display: flex;align-items: center;font-size: 24rpx;color: #999;gap: 40upx;
+				.safe-item{
+					display: flex;align-items: center;
+					image{width: 30upx;height: 30upx;margin-right: 10upx;}
+				}
+			}
+		}
+		.price{
+			display: flex;
+			align-items: self-end;
+			padding: 20rpx 30rpx;
+			gap: 20rpx;
+			.price-sale{
+				font-size: 38rpx;
+				font-weight: 800;
+				color: $main-color;
+			}
+			.sale{
+				background-color: #FDEBE5;
+				border: 4rpx;font-size: 22rpx;
+				color: #FF4747;
+				padding: 10rpx;
+				display: inline-block;
+			}
+			.line-price{
+				color: #999999;
+				font-size: 24rpx;
+				text-decoration-line: line-through;
+			}
+			.desc-num{
+				color: #999;font-size: 24upx;margin-left: auto;margin-right: 0;
+			}
+		}
+	}
 	.goods-content{
 		position: fixed;
 		z-index: 1;
@@ -97,6 +608,12 @@ export default {
 	.goods-body{
 		height: 0;
 		flex: 1;
+		.home-banner {
+			.swiper{
+				height: 380upx;
+				image{width: 100%;height: auto;}
+			}
+		}
 	}
 	.footer{
 		background-color: #fff;padding: 20upx 20upx 0 20upx;border-top: 2upx solid #f8f8f8;

+ 138 - 48
奥莱优品/pages/index/index.vue

@@ -1,81 +1,161 @@
 <template>
 	<view class="content">
-		<view class="store-header">
-			<view class="home-store">
-				<view class="store-logo"><image src="/static/logo.jpg"></image></view>
-				<view class="store-info">
-					<view class="name">桃奢妍商业广场</view>
-					<view class="desc">广东省/广州市/增城区</view>
+		<template v-if="isLoading">
+			<view class="store-header">
+				<view class="home-store">
+					<view class="store-logo" style="width: 100rpx;"><view class="skeleton-line animate"></view></view>
+					<view class="store-info">
+						<view class="name"><view class="skeleton-line animate"></view></view>
+						<view class="desc"><view class="skeleton-line animate"></view></view>
+					</view>
+					<view class="store-kf" style="width: 100rpx;"><view class="skeleton-line animate"></view></view>
 				</view>
-				<view class="store-kf" @click="kfPop">联系客服</view>
-			</view>
-			<view class="store-address">
-				<view class="address-info">
-					<image src="/static/image/location.svg"></image>
-					<view class="address">天乐社区服务中心蜀山新产业园区海亮九玺海亮九玺南区</view>
+				<view class="store-address">
+					<view class="address-info">
+						<view class="address"><view class="skeleton-line animate"></view></view>
+					</view>
+					<view class="store-time"><view class="skeleton-line animate"></view></view>
 				</view>
-				<view class="store-time">营业 08:00–22:30</view>
 			</view>
-		</view>
-
-		<scroll-view class="home-goods" scroll-y scroll-with-animation>
-			<view class="goods-title">
-				<view class="title-left">
-					<text>HOT DEALS</text>
-					<view class="name">正在抢购</view>
+			<scroll-view class="home-goods" scroll-y scroll-with-animation>
+				<view class="goods-list">
+					<view class="list-item" v-for="(item,index) in 4" :key="index">
+						<view class="image">
+							<view class="skeleton-line animate"></view>
+						</view>
+						<view class="info">
+							<view class="title"><view class="skeleton-line animate"></view></view>
+							<view class="tags"></view>
+							<view class="tags"><view class="skeleton-line animate"></view></view>
+							<view class="price-btn">
+								<view class="price"><view class="skeleton-line animate"></view></view>
+								<view class="price-line"><view class="skeleton-line animate"></view></view>
+							</view>
+						</view>
+					</view>
+				</view>
+			</scroll-view>
+		</template>
+		<template v-else>
+			<view class="store-header">
+				<view class="home-store">
+					<view class="store-logo"><image :src="storeData.poi_logo"></image></view>
+					<view class="store-info">
+						<view class="name">{{ storeData.poi_name }}</view>
+						<view class="desc">{{ storeData.poi_city }}</view>
+					</view>
+					<view class="store-kf" @click="kfPop">联系客服</view>
+				</view>
+				<view class="store-address">
+					<view class="address-info">
+						<image src="/static/image/location.svg"></image>
+						<view class="address">{{ storeData.poi_address }}</view>
+					</view>
+					<view class="store-time">营业 {{ storeData.start_at?storeData.start_at:'-' }} - {{ storeData.end_at?storeData.end_at:'-' }}</view>
 				</view>
-				<view class="title-more">全部商品 <image src="/static/image/right.svg"></image> </view>
 			</view>
-			<view class="goods-list">
-				<view class="list-item" v-for="(item,index) in 10" :key="index" @click="toDetail(index)">
-					<view class="image">
-						<image src="https://washmy.oss-cn-guangzhou.aliyuncs.com/storage/20260727/2e9fd491e2def96b0dd0677f43d7a31913cf959e.png"></image>
-						<text>2.7折</text>
+
+			<scroll-view class="home-goods" scroll-y scroll-with-animation>
+				<view class="goods-title">
+					<view class="title-left">
+						<text>HOT DEALS</text>
+						<view class="name">正在抢购</view>
 					</view>
-					<view class="info">
-						<view class="title">赫莲娜/HR黑绷带50ml小露珠200ml两件套 线下兑换券</view>
-						<view class="tags"></view>
-						<view class="tags">已售0</view>
-						<view class="price-btn">
-							<view class="price">¥799.00</view>
-							<view class="price-line">¥2,999.00</view>
-							<view class="buy-btn">立即抢购</view>
+					<view class="title-more">全部商品 <image src="/static/image/right.svg"></image> </view>
+				</view>
+				<view class="goods-list">
+					<view class="list-item" v-for="(item,index) in goodsData" :key="index" @click="toDetail(item.goods_id)">
+						<view class="image">
+							<image :src="item.image_list[0].url"></image>
+							<text>{{$dialog.disFormat(item.price,item.line_price)}}折</text>
+						</view>
+						<view class="info">
+							<view class="title">{{item.product_name}}</view>
+							<view class="tags"></view>
+							<view class="tags">已售{{item.sale_stock}}</view>
+							<view class="price-btn">
+								<view class="price">{{$dialog.formatMoney(item.price)}}</view>
+								<view class="price-line">{{$dialog.formatMoney(item.line_price)}}</view>
+								<view class="buy-btn">立即抢购</view>
+							</view>
 						</view>
 					</view>
 				</view>
-			</view>
-		</scroll-view>
-		<halfLogin ref="loginCom"></halfLogin>
+			</scroll-view>
+		</template>
+		<halfLogin ref="loginCom" @success="loginSuccess"></halfLogin>
 		<kfService ref="kfService"></kfService>
 	</view>
 </template>
 
 <script>
+var app;
 export default {
 	data() {
 		return {
-			title: 'Hello'
+			optionData: null,
+			storeId:"",
+			isLoading:true,
+			storeData:null,
+			goodsData:[],
+			isLogin:null
 		}
 	},
-	onLoad() {
-
+	onLoad(options) {
+		app = this;
+		const tokenPoi = uni.getStorageSync("contact");
+		if (options.store != null) {
+		    app.storeId = options.store;
+		} else if (tokenPoi && tokenPoi.poi_id != null) {
+		    app.storeId = tokenPoi.poi_id;
+		} else {
+		    app.storeId = "7644106137976965139";
+		}
+		app.isLogin = uni.getStorageSync("user_token");
+		app.optionData = options;
+		app.getData()
 	},
-	methods: {
-		test(){
-			this.$refs.loginCom.open();
+	methods: {
+		loginSuccess(token){
+			app.isLogin = token;
+		},
+		async getData(){
+			if (!app.storeId) return ;
+			app.isLoading = true;
+			app.optionData.store = app.storeId;
+			var res = await app.$api.home.data.get(app.optionData);
+			app.isLoading = false;
+			if (res.code !== 1) {
+				return app.$dialog.showSuccess(res.msg)
+			}
+			uni.setStorageSync("poiId",res.data.store.poi_id);
+			app.storeData = res.data.store;
+			uni.setStorageSync("contact",res.data.store);
+			app.getGoods();
+		},
+		async getGoods(){
+			app.optionData.store = app.storeId;
+			var resp = await app.$api.home.goods.get(app.optionData);
+			if (resp.code !== 200) {
+				return app.$dialog.showSuccess(resp.msg)
+			}
+			app.goodsData = resp.data.rows;
 		},
 		toDetail(id){
-			const isLogin = uni.getStorageSync("user_token");
-			if (!isLogin) {
+			if (!app.isLogin) {
 				this.$refs.loginCom.open();
 				return ;
 			}
+			// uni.navigateTo({
+			// 	url:`/pages/goods/detail?goods=${id}`
+			// })
 			uni.navigateTo({
-				url:`/pages/goods/detail?id=${id}`
+				url:`/pages/order/tips?goods=${id}`
 			})
 		},
-		kfPop(){
-			this.$refs.kfService.open();
+		kfPop(){
+			const data = uni.getStorageSync("contact");
+			this.$refs.kfService.open(data);
 		}
 	}
 }
@@ -93,6 +173,16 @@ export default {
 	display: flex;
 	flex-direction: column;
 }
+.home-load{
+	.store-header{
+		display: flex;
+		gap: 20upx;
+		border-bottom: 2upx solid #f8f8f8;
+		border-top: 2upx solid #f8f8f8;
+		align-items: center;
+		padding: 20upx;
+	}
+}
 .home-store{
 	background-color: $main-color;
 	padding: 20rpx;

+ 4 - 0
奥莱优品/pages/order/order.vue

@@ -50,12 +50,16 @@
 </template>
 
 <script>
+var app;
 export default {
 	data() {
 		return {
 			orderState:0
 		}
 	},
+	onLoad() {
+		app = this;
+	},
 	methods: {
 		orderStatus(state) {
 			this.orderState = state

+ 33 - 0
奥莱优品/pages/order/tips.vue

@@ -0,0 +1,33 @@
+<template>
+	<view>
+
+	</view>
+</template>
+
+<script>
+export default {
+	data() {
+		return {
+
+		}
+	},
+	onLoad() {
+		uni.enableAlertBeforeUnload({
+			message: "是否确认返回",
+			  success(res) {
+			    console.log("开启页面返回询问对话框成功", res);
+			  },
+			  fail(err) {
+			    console.log("开启页面返回询问对话框失败", err);
+			  },
+		})
+	},
+	methods: {
+
+	}
+}
+</script>
+
+<style>
+
+</style>

+ 68 - 0
奥莱优品/pages/user/license.vue

@@ -0,0 +1,68 @@
+<template>
+	<view>
+		<block v-if="loading">
+			<view class="skeleton">
+				<view class="skeleton-line max animate" style="height: 200upx;"></view>
+				<view class="skeleton-line animate"></view>
+				<view class="skeleton-line min animate"></view>
+				<view class="skeleton-line min animate"></view>
+				<view class="skeleton-line max animate" style="height: 200upx;"></view>
+				<view class="skeleton-line max animate" style="height: 200upx;"></view>
+			</view>
+		</block>
+		<block v-else>
+		<view class="info-item">
+			<view class="title">营业执照</view>
+			<view class="img"><image :src="license" mode="widthFix"></image></view>
+		</view>
+		<view class="info-item">
+			<view class="title">特别提示</view>
+			<view class="info">商家资质图片为官方展示<text>严禁下载复印</text>,违者后果自负</view>
+		</view>
+		</block>
+	</view>
+</template>
+
+<script>
+var app;
+import {
+	openimg
+} from '@/utils/js/index.js';
+export default {
+	data() {
+		return {
+			loading:true,
+			license:""
+		}
+	},
+	onLoad() {
+		app = this;
+		app.getLicense()
+	},
+	methods: {
+		showImg(){
+			return openimg(0,[app.license])
+		},
+		async getLicense(){
+			app.loading = true;
+			var res = await app.$api.home.license.get();
+			app.loading = false;
+			if (res.code !== 1) {
+				return app.$dialog.showSuccess(res.msg,function(){
+					uni.navigateBack()
+				})
+			}
+			app.license = res.data.img;
+		}
+	}
+}
+</script>
+
+<style>
+page{background-color: #f8f8f8;}
+.info-item{background-color: #fff;padding: 20upx;margin-bottom: 20upx;}
+.info-item .title{font-size: 30upx;color: #333;font-weight: bold;line-height: 80upx;border-bottom: 2upx solid #f8f8f8;}
+.info-item .info{font-size: 28upx;color: #666;line-height: 60upx;}
+.info-item .info text{color: #f00;}
+.info-item image{width: 100%;}
+</style>

+ 9 - 1
奥莱优品/pages/user/user.vue

@@ -15,7 +15,7 @@
 					<view class="name">我的投诉</view>
 					<view class="right"><image src="/static/image/right.svg"></image></view>
 				</view>
-				<view class="menu-item">
+				<view class="menu-item" @click="kfPop">
 					<view class="icon"><image src="/static/image/service.png"></image></view>
 					<view class="name">商家客服</view>
 					<view class="right"><image src="/static/image/right.svg"></image></view>
@@ -34,6 +34,8 @@
 				</view>
 			</view>
 		</view>
+		<halfLogin ref="loginCom" @success="loginSuccess"></halfLogin>
+		<kfService ref="kfService"></kfService>
 	</view>
 </template>
 
@@ -45,7 +47,13 @@ export default {
 		}
 	},
 	methods: {
+		loginSuccess(token){
 
+		},
+		kfPop(){
+			const data = uni.getStorageSync("contact");
+			this.$refs.kfService.open(data);
+		}
 	}
 }
 </script>

+ 22 - 0
奥莱优品/pages/web/web.vue

@@ -0,0 +1,22 @@
+<template>
+	<view>
+		
+	</view>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				
+			}
+		},
+		methods: {
+			
+		}
+	}
+</script>
+
+<style>
+
+</style>

BIN
奥莱优品/static/image/amap.png


BIN
奥莱优品/static/image/check.png


BIN
奥莱优品/static/image/close.png


BIN
奥莱优品/static/image/right-black.png


BIN
奥莱优品/static/image/rule-date.png


BIN
奥莱优品/static/image/rule-refund.png


BIN
奥莱优品/static/image/rule-time.png


+ 1 - 1
奥莱优品/static/js/request.js

@@ -16,7 +16,7 @@ const axg = {
 		// #endif
 		// #ifdef MP
 		// return 'https://tran.jsshuita.cn/v2'
-		return 'http://127.0.0.1:9881/v2'
+		return 'http://192.168.3.16:9881/v2'
 		// #endif
 	},
 	toast: function(text, duration, success) {

+ 39 - 0
奥莱优品/uni_modules/uni-number-box/changelog.md

@@ -0,0 +1,39 @@
+## 1.2.8(2024-04-26)
+- 修复 在vue2下H5黑边的bug
+## 1.2.7(2024-04-26)
+- 修复 在vue2手动输入后失焦导致清空数值的严重bug
+## 1.2.6(2024-02-22)
+- 新增 设置宽度属性width(单位:px)
+## 1.2.5(2024-02-21)
+- 修复 step步长小于1时,键盘类型为number的bug
+## 1.2.4(2024-02-02)
+- 修复 加减号垂直位置偏移样式问题
+## 1.2.3(2023-05-23)
+- 更新示例工程
+## 1.2.2(2023-05-08)
+- 修复 change 事件执行顺序错误的问题
+## 1.2.1(2021-11-22)
+- 修复 vue3中某些scss变量无法找到的问题
+## 1.2.0(2021-11-19)
+- 优化 组件UI,并提供设计资源,详见:[https://uniapp.dcloud.io/component/uniui/resource](https://uniapp.dcloud.io/component/uniui/resource)
+- 文档迁移,详见:[https://uniapp.dcloud.io/component/uniui/uni-number-box](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+## 1.1.2(2021-11-09) 
+- 新增 提供组件设计资源,组件样式调整
+## 1.1.1(2021-07-30)
+- 优化 vue3下事件警告的问题
+## 1.1.0(2021-07-13)
+- 组件兼容 vue3,如何创建vue3项目,详见 [uni-app 项目支持 vue3 介绍](https://ask.dcloud.net.cn/article/37834)
+## 1.0.7(2021-05-12)
+- 新增 组件示例地址
+## 1.0.6(2021-04-20)
+- 修复 uni-number-box 浮点数运算不精确的 bug
+- 修复 uni-number-box change 事件触发不正确的 bug
+- 新增 uni-number-box v-model 双向绑定
+## 1.0.5(2021-02-05)
+- 调整为uni_modules目录规范
+
+## 1.0.7(2021-02-05)
+- 调整为uni_modules目录规范
+- 新增 支持 v-model
+- 新增 支持 focus、blur 事件
+- 新增 支持 PC 端

+ 232 - 0
奥莱优品/uni_modules/uni-number-box/components/uni-number-box/uni-number-box.vue

@@ -0,0 +1,232 @@
+<template>
+	<view class="uni-numbox">
+		<view @click="_calcValue('minus')" class="uni-numbox__minus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue <= min || disabled }"
+				:style="{color}">-</text>
+		</view>
+		<input :disabled="disabled" @focus="_onFocus" @blur="_onBlur" class="uni-numbox__value"
+			:type="step<1?'digit':'number'" v-model="inputValue" :style="{background, color, width:widthWithPx}" />
+		<view @click="_calcValue('plus')" class="uni-numbox__plus uni-numbox-btns" :style="{background}">
+			<text class="uni-numbox--text" :class="{ 'uni-numbox--disabled': inputValue >= max || disabled }"
+				:style="{color}">+</text>
+		</view>
+	</view>
+</template>
+<script>
+	/**
+	 * NumberBox 数字输入框
+	 * @description 带加减按钮的数字输入框
+	 * @tutorial https://ext.dcloud.net.cn/plugin?id=31
+	 * @property {Number} value 输入框当前值
+	 * @property {Number} min 最小值
+	 * @property {Number} max 最大值
+	 * @property {Number} step 每次点击改变的间隔大小
+	 * @property {String} background 背景色
+	 * @property {String} color 字体颜色(前景色)
+	 * @property {Number} width 输入框宽度(单位:px)
+	 * @property {Boolean} disabled = [true|false] 是否为禁用状态
+	 * @event {Function} change 输入框值改变时触发的事件,参数为输入框当前的 value
+	 * @event {Function} focus 输入框聚焦时触发的事件,参数为 event 对象
+	 * @event {Function} blur 输入框失焦时触发的事件,参数为 event 对象
+	 */
+
+	export default {
+		name: "UniNumberBox",
+		emits: ['change', 'input', 'update:modelValue', 'blur', 'focus'],
+		props: {
+			value: {
+				type: [Number, String],
+				default: 1
+			},
+			modelValue: {
+				type: [Number, String],
+				default: 1
+			},
+			min: {
+				type: Number,
+				default: 0
+			},
+			max: {
+				type: Number,
+				default: 100
+			},
+			step: {
+				type: Number,
+				default: 1
+			},
+			background: {
+				type: String,
+				default: '#f5f5f5'
+			},
+			color: {
+				type: String,
+				default: '#333'
+			},
+			disabled: {
+				type: Boolean,
+				default: false
+			},
+			width: {
+				type: Number,
+				default: 40,
+			}
+		},
+		data() {
+			return {
+				inputValue: 0
+			};
+		},
+		watch: {
+			value(val) {
+				this.inputValue = +val;
+			},
+			modelValue(val) {
+				this.inputValue = +val;
+			}
+		},
+		computed: {
+			widthWithPx() {
+				return this.width + 'px';
+			}
+		},
+		created() {
+			if (this.value === 1) {
+				this.inputValue = +this.modelValue;
+			}
+			if (this.modelValue === 1) {
+				this.inputValue = +this.value;
+			}
+		},
+		methods: {
+			_calcValue(type) {
+				if (this.disabled) {
+					return;
+				}
+				const scale = this._getDecimalScale();
+				let value = this.inputValue * scale;
+				let step = this.step * scale;
+				if (type === "minus") {
+					value -= step;
+					if (value < (this.min * scale)) {
+						return;
+					}
+					if (value > (this.max * scale)) {
+						value = this.max * scale
+					}
+				}
+
+				if (type === "plus") {
+					value += step;
+					if (value > (this.max * scale)) {
+						return;
+					}
+					if (value < (this.min * scale)) {
+						value = this.min * scale
+					}
+				}
+
+				this.inputValue = (value / scale).toFixed(String(scale).length - 1);
+				// TODO vue2 兼容
+				this.$emit("input", +this.inputValue);
+				// TODO vue3 兼容
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_getDecimalScale() {
+
+				let scale = 1;
+				// 浮点型
+				if (~~this.step !== this.step) {
+					scale = Math.pow(10, String(this.step).split(".")[1].length);
+				}
+				return scale;
+			},
+			_onBlur(event) {
+				this.$emit('blur', event)
+				let value = event.detail.value;
+				if (isNaN(value)) {
+					this.inputValue = this.value;
+					return;
+				}
+				value = +value;
+				if (value > this.max) {
+					value = this.max;
+				} else if (value < this.min) {
+					value = this.min;
+				}
+				const scale = this._getDecimalScale();
+				this.inputValue = value.toFixed(String(scale).length - 1);
+				this.$emit("input", +this.inputValue);
+				this.$emit("update:modelValue", +this.inputValue);
+				this.$emit("change", +this.inputValue);
+			},
+			_onFocus(event) {
+				this.$emit('focus', event)
+			}
+		}
+	};
+</script>
+<style lang="scss">
+	$box-height: 26px;
+	$bg: #f5f5f5;
+	$br: 2px;
+	$color: #333;
+
+	.uni-numbox {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+	}
+
+	.uni-numbox-btns {
+		/* #ifndef APP-NVUE */
+		display: flex;
+		/* #endif */
+		flex-direction: row;
+		align-items: center;
+		justify-content: center;
+		padding: 0 8px;
+		background-color: $bg;
+		/* #ifdef H5 */
+		cursor: pointer;
+		/* #endif */
+	}
+
+	.uni-numbox__value {
+		margin: 0 2px;
+		background-color: $bg;
+		width: 40px;
+		height: $box-height;
+		text-align: center;
+		font-size: 14px;
+		border-width: 0;
+		color: $color;
+	}
+
+	.uni-numbox__minus {
+		border-top-left-radius: $br;
+		border-bottom-left-radius: $br;
+	}
+
+	.uni-numbox__plus {
+		border-top-right-radius: $br;
+		border-bottom-right-radius: $br;
+	}
+
+	.uni-numbox--text {
+		// fix nvue
+		line-height: 20px;
+		margin-bottom: 2px;
+		font-size: 20px;
+		font-weight: 300;
+		color: $color;
+	}
+
+	.uni-numbox .uni-numbox--disabled {
+		color: #c0c0c0 !important;
+		/* #ifdef H5 */
+		cursor: not-allowed;
+		/* #endif */
+	}
+</style>

+ 83 - 0
奥莱优品/uni_modules/uni-number-box/package.json

@@ -0,0 +1,83 @@
+{
+  "id": "uni-number-box",
+  "displayName": "uni-number-box 数字输入框",
+  "version": "1.2.8",
+  "description": "NumberBox 带加减按钮的数字输入框组件,用户可以控制每次点击增加的数值,支持小数。",
+  "keywords": [
+    "uni-ui",
+    "uniui",
+    "数字输入框"
+],
+  "repository": "https://github.com/dcloudio/uni-ui",
+  "engines": {
+    "HBuilderX": ""
+  },
+  "directories": {
+    "example": "../../temps/example_temps"
+  },
+"dcloudext": {
+    "sale": {
+      "regular": {
+        "price": "0.00"
+      },
+      "sourcecode": {
+        "price": "0.00"
+      }
+    },
+    "contact": {
+      "qq": ""
+    },
+    "declaration": {
+      "ads": "无",
+      "data": "无",
+      "permissions": "无"
+    },
+    "npmurl": "https://www.npmjs.com/package/@dcloudio/uni-ui",
+    "type": "component-vue"
+  },
+  "uni_modules": {
+    "dependencies": ["uni-scss"],
+    "encrypt": [],
+    "platforms": {
+      "cloud": {
+        "tcb": "y",
+        "aliyun": "y",
+        "alipay": "n"
+      },
+      "client": {
+        "App": {
+          "app-vue": "y",
+          "app-nvue": "y"
+        },
+        "H5-mobile": {
+          "Safari": "y",
+          "Android Browser": "y",
+          "微信浏览器(Android)": "y",
+          "QQ浏览器(Android)": "y"
+        },
+        "H5-pc": {
+          "Chrome": "y",
+          "IE": "y",
+          "Edge": "y",
+          "Firefox": "y",
+          "Safari": "y"
+        },
+        "小程序": {
+          "微信": "y",
+          "阿里": "y",
+          "百度": "y",
+          "字节跳动": "y",
+          "QQ": "y"
+        },
+        "快应用": {
+          "华为": "u",
+          "联盟": "u"
+        },
+        "Vue": {
+            "vue2": "y",
+            "vue3": "y"
+        }
+      }
+    }
+  }
+}

+ 13 - 0
奥莱优品/uni_modules/uni-number-box/readme.md

@@ -0,0 +1,13 @@
+
+
+## NumberBox 数字输入框
+> **组件名:uni-number-box**
+> 代码块: `uNumberBox`
+
+
+带加减按钮的数字输入框。
+
+### [查看文档](https://uniapp.dcloud.io/component/uniui/uni-number-box)
+#### 如使用过程中有任何问题,或者您对uni-ui有一些好的建议,欢迎加入 uni-ui 交流群:871950839 
+
+