zs 2 yıl önce
ebeveyn
işleme
fff4235ade

+ 23 - 0
pages.json

@@ -285,6 +285,29 @@
 				}
 
 			]
+		},
+		{
+			"root": "pagesIntegral",
+			"pages": [{
+					"path": "home/index",
+					"style": {
+						"navigationBarTitleText": "尊荣专区",
+						"enablePullDownRefresh": true
+					}
+				},
+				{
+					"path": "order/detail",
+					"style": {
+						"navigationBarTitleText": "商品详情"
+					}
+				},
+				{
+					"path": "order/index",
+					"style": {
+						"navigationBarTitleText": "商品兑换"
+					}
+				}
+			]
 		}
 	],
 	"globalStyle": {

+ 255 - 0
pagesIntegral/home/index.vue

@@ -0,0 +1,255 @@
+<template>
+	<mobile-frame>
+		<view class="main">
+			<view class="one">
+				<input type="text" v-model="searchInfo.name" @blur="toInput" placeholder="搜索商品">
+			</view>
+			<view class="two">
+				<scroll-view scroll-y="true" class="scroll-view" @scrolltolower="toPage" @scroll="toScroll">
+					<view class="list-scroll-view">
+						<view class="two_1">
+							<view class="list" v-for="(item,index) in list" :key="index">
+								<image class="image" :src="item.file&&item.file.length>0?item.file[0].url:''" mode="">
+								</image>
+								<view class="name textOver">
+									{{item.name}}
+								</view>
+								<view class="other">
+									<view class="money">
+										<text>¥</text>
+										<text>{{item.sell_money}}</text>
+									</view>
+									<view class="btn">
+										<button type="default" size="mini" @click="toBuy(item)">兑换</button>
+									</view>
+								</view>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="is_bottom" v-if="is_bottom">
+				<text>{{config.bottom_title}}</text>
+			</view>
+		</view>
+	</mobile-frame>
+</template>
+
+<script>
+	export default {
+		data() {
+			return {
+				// 系统设置
+				config: {},
+				searchInfo: {},
+				list: [],
+				total: 0,
+				page: 0,
+				skip: 0,
+				limit: 6,
+				// 数据是否触底
+				is_bottom: false,
+				scrollTop: 0
+			};
+		},
+		onLoad: async function(e) {
+			const that = this;
+			that.searchConfig();
+			await that.searchOther();
+			await that.search();
+		},
+		methods: {
+			// 查询基本设置
+			searchConfig() {
+				const that = this;
+				uni.getStorage({
+					key: 'config',
+					success: function(res) {
+						if (res.data) that.$set(that, `config`, res.data)
+					},
+					fail: function(err) {
+						console.log(err);
+					}
+				})
+			},
+			async searchOther() {
+				const that = this;
+			},
+			async search() {
+				const that = this;
+				let info = {
+					skip: that.skip,
+					limit: that.limit,
+				}
+				const res = await that.$api(`/viewGoods/indexGoodsList`, `GET`, {
+					...info,
+					...that.searchInfo
+				})
+				if (res.errcode == '0') {
+					let list = [...that.list, ...res.data]
+					that.$set(that, `list`, list)
+					that.$set(that, `total`, res.total)
+				} else {
+					uni.showToast({
+						title: res.errmsg,
+					});
+				}
+			},
+			// 分页
+			toPage() {
+				const that = this;
+				let list = that.list;
+				let limit = that.limit;
+				if (that.total > list.length) {
+					uni.showLoading({
+						title: '加载中',
+						mask: true
+					})
+					let page = that.page + 1;
+					that.$set(that, `page`, page)
+					let skip = page * limit;
+					that.$set(that, `skip`, skip)
+					that.search();
+					uni.hideLoading();
+
+				} else that.$set(that, `is_bottom`, true)
+			},
+			toScroll(e) {
+				const that = this;
+				let up = that.scrollTop;
+				that.$set(that, `scrollTop`, e.detail.scrollTop);
+				let num = Math.sign(up - e.detail.scrollTop);
+				if (num == 1) that.$set(that, `is_bottom`, false);
+			},
+
+			// 输入框
+			toInput(e) {
+				const that = this;
+				if (e.detail.value) that.$set(that.searchInfo, `name`, e.detail.value);
+				that.clearPage();
+				that.search();
+			},
+			toBuy(e) {
+				uni.navigateTo({
+					url: `/pagesIntegral/order/detail?id=${e.id||e._id}`
+				})
+			},
+			// 清空列表
+			clearPage() {
+				const that = this;
+				that.$set(that, `list`, [])
+				that.$set(that, `skip`, 0)
+				that.$set(that, `limit`, 6)
+				that.$set(that, `page`, 0)
+			}
+		},
+		onPullDownRefresh: async function() {
+			const that = this;
+			that.$set(that, `list`, [])
+			that.$set(that, `skip`, 0)
+			that.$set(that, `limit`, 6)
+			that.$set(that, `page`, 0)
+			await that.search();
+			uni.stopPullDownRefresh();
+		}
+	}
+</script>
+
+<style lang="scss">
+	.main {
+		display: flex;
+		flex-direction: column;
+		width: 100vw;
+		height: 100vh;
+
+		.one {
+			border-bottom: 1px solid var(--f85Color);
+			padding: 2vw;
+
+			input {
+				padding: 2vw;
+				background-color: var(--f1Color);
+				font-size: var(--font14Size);
+				border-radius: 5px;
+			}
+		}
+
+		.two {
+			position: relative;
+			flex-grow: 1;
+
+			.two_1 {
+				display: flex;
+				justify-content: space-between;
+				flex-wrap: wrap;
+
+				.list {
+					// break-inside: avoid;
+					width: 43vw;
+					background: #fff;
+					padding: 2vw;
+					border-radius: 5px;
+					margin: 0 0 2vw 0;
+
+
+					.image {
+						width: 100%;
+						height: 50vw;
+					}
+
+					.name {
+						font-size: var(--font15Size);
+						margin: 0 0 2vw 0;
+					}
+
+					.other {
+						display: flex;
+						flex-direction: row;
+						justify-content: space-between;
+
+						.money {
+							color: var(--ff0Color);
+
+							text:nth-child(1) {
+								font-size: var(--font12Size);
+							}
+						}
+
+						.btn {
+							button {
+								border-radius: 25px;
+								color: var(--fffColor);
+								background-color: var(--ff0Color);
+								font-size: var(--font12Size);
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+
+	.scroll-view {
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+
+		.list-scroll-view {
+			display: flex;
+			flex-direction: column;
+		}
+	}
+
+	.is_bottom {
+		text-align: center;
+
+		text {
+			padding: 2vw 0;
+			display: inline-block;
+			color: #858585;
+			font-size: 14px;
+		}
+	}
+</style>

+ 780 - 0
pagesIntegral/order/detail.vue

@@ -0,0 +1,780 @@
+<template>
+	<mobile-frame>
+		<view class="main">
+			<view class="onemain">
+				<scroll-view scroll-y="true" class="scroll-view" scroll-with-animation :scroll-into-view="topItem"
+					@scroll="handleScroll">
+					<view class="list-scroll-view" id="top">
+						<view class="one">
+							<swiper class="swiper" circular :indicator-dots="true" indicator-color="#ffffff"
+								indicator-active-color="#FB1438" :autoplay="true" :interval="3000" :duration="1000">
+								<swiper-item class="list" v-for="(item,index) in bannerList" :key="index">
+									<image class="image" :src="item.url" mode="aspectFit">
+									</image>
+								</swiper-item>
+							</swiper>
+						</view>
+						<view class="two">
+							<view class="two_1">
+								<view class="money_1">
+									<text>¥</text>
+									<text>{{specs&&specs.length>0?specs[0].sell_money:0}}</text>
+								</view>
+								<view class="money_2">
+									<text>¥</text>
+									<text>{{specs&&specs.length>0?specs[0].flow_money:0}}</text>
+								</view>
+							</view>
+							<view class="two_2">{{info.name}}</view>
+							<view class="two_3">{{info.shot_brief}}</view>
+							<view class="two_4">
+								<text>运费{{specs&&specs.length>0?specs[0].freight:0}}元</text>
+								<text>{{info.send_time}}内发货</text>
+							</view>
+						</view>
+						<view class="thr">
+							<view v-if="comment" class="thr_1" @click="toAppraise(info)">
+								<view class="title">商品评价({{comment||0}})</view>
+								<text class="iconfont icon-jiantouyou"></text>
+							</view>
+							<view v-else class="thr_1">
+								<view class="title">暂无评价</view>
+								<text class="iconfont icon-jiantouyou"></text>
+							</view>
+						</view>
+						<view class="four">
+							<view class="four_1">
+								<image class="image" :src="shop.logo&&shop.logo.length>0?shop.logo[0].url:''"></image>
+								<view class="other">
+									<view class="name">{{shop.name}}</view>
+									<view class="other_1"><text>宝贝数</text>{{shop.goods_num||0}}</view>
+								</view>
+							</view>
+							<view class="four_2">
+								<view class="grade">商品:<text>{{shop.goods_score||5}}</text></view>|
+								<view class="grade">发货:<text>{{shop.send_score||5}}</text></view>|
+								<view class="grade">服务:<text>{{shop.service_score||5}}</text></view>
+							</view>
+							<view class="four_2">
+								<view class="btn" @tap="toShop('pagesHome/shop/index')">进入店铺</view>
+								<view class="btn" @tap="shopCollect">{{shop_collect==true?'已关注':'关注'}}</view>
+							</view>
+						</view>
+						<view class="five">
+							<view class="five_1">
+								<!-- <u-parse :content="info.brief"></u-parse> -->
+								<rich-text :nodes="info.brief"></rich-text>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="foot">
+				<uni-goods-nav :options="options" :button-group="buttonGroup" @click="onClick"
+					@buttonClick="buttonClick" />
+			</view>
+		</view>
+		<view class="menu">
+			<text @click="toMenu" class="iconfont icon-gengduo"></text>
+		</view>
+		<view class="menu_1" v-if="menu">
+			<view class="title" v-for="(item,index) in barList" :key="index" @click="toPath(item)">
+				<image class="image" :src="item.normal"></image>
+				<view class="name">{{item.name}}</view>
+			</view>
+		</view>
+		<view class="backTop" v-if="isShow==true">
+			<text @click="backTop" class="iconfont icon-fanhuidingbu"></text>
+		</view>
+		<uni-popup ref="popup" background-color="#fff" type="bottom">
+			<view class="content">
+				<view class="one">
+					<image class="image" v-if="specsInfo.file&&specsInfo.file.length>0"
+						:src="specsInfo.file&&specsInfo.file.length>0?specsInfo.file[0].url:''"></image>
+					<image class="image" v-else :src="info.file&&info.file.length>0?info.file[0].url:''"></image>
+					<view class="other">
+						<view class="money">
+							<text>¥</text>
+							<text>{{specsInfo.sell_money}}</text>
+						</view>
+						<view class="other_1">
+							已选: <text>{{specsInfo.name}}</text>
+						</view>
+					</view>
+					<view class="button">
+						<text @click="toClose" class="iconfont icon-shanchu"></text>
+					</view>
+				</view>
+				<view class="two">
+					<view class="two_1">规格</view>
+					<view class="two_2">
+						<text v-for="(item,index) in specs" :key="index" @click="toStyle(item,index)"
+							:class="{ 'style': isActive==index}">{{item.name}}
+						</text>
+					</view>
+				</view>
+				<!-- <view class="thr">
+					<text>数量</text>
+					<view class="count">
+						<uni-number-box :min="1" :max="specsInfo.num" :disabled="disabled" v-model="num"
+							@change="toCount">
+						</uni-number-box>
+					</view>
+					<text>库存{{specsInfo.num||0}}</text>
+				</view> -->
+				<view class="btn" @click="toBuy">
+					立即兑换
+				</view>
+			</view>
+		</uni-popup>
+	</mobile-frame>
+</template>
+
+<script>
+	export default {
+		components: {},
+		data() {
+			return {
+				barList: [{
+						name: '首页',
+						route: 'pages/home/index',
+						normal: require('@/static/shouye.png'),
+					},
+					{
+						name: '微店',
+						route: 'pages/store/index',
+						normal: require('@/static/store.png'),
+					},
+					{
+						name: '购物车',
+						route: 'pages/market/index',
+						normal: require('@/static/market.png'),
+					},
+					{
+						name: '我的',
+						route: 'pages/my/index',
+						normal: require('@/static/my.png'),
+					},
+				],
+				options: [
+					// {
+					// 	icon: 'shop',
+					// 	text: '店铺',
+					// 	route: 'pagesHome/shop/index',
+					// },
+					// {
+					// 	icon: 'cart',
+					// 	text: '购物车',
+					// 	route: 'pages/market/index',
+					// },
+					// {
+					// 	icon: 'chat',
+					// 	text: '客服',
+					// }
+				],
+				buttonGroup: [{
+					text: '立即兑换',
+					backgroundColor: 'linear-gradient(90deg, #EF1224, #EF1224)',
+					color: '#fff',
+				}],
+				// 商品id
+				id: '',
+				user: {},
+				// 轮播图
+				bannerList: [],
+				// 商品详情
+				info: {},
+				// 商店详情
+				shop: {},
+				// 规格情况
+				specs: [],
+				// 已选
+				specsInfo: {},
+				// 是否显示返回顶部
+				isShow: false,
+				topItem: '',
+				// 商品收藏
+				collection: false,
+				// 店铺收藏
+				shop_collect: false,
+				// 菜单显示
+				menu: false,
+				disabled: true,
+				// 显示文字判断
+				type: '0',
+				// 选择规格
+				isActive: -1,
+				// 计数器
+				num: 1,
+				// 评论数
+				comment: 0,
+			};
+		},
+		onLoad: async function(e) {
+			const that = this;
+			that.$set(that, `id`, e.id || '');
+		},
+		onShow: async function() {
+			const that = this;
+			await that.search();
+			await that.configShare();
+		},
+		methods: {
+			//店铺,
+			// 购物车,客服跳转
+			onClick(e) {
+				const that = this;
+				if (e.index == '0' && e.content.route) {
+					// 进入店铺
+					that.toShop();
+				} else {
+					uni.reLaunch({
+						url: `/${e.content.route}`
+					})
+				}
+			},
+			// 进入店铺
+			toShop() {
+				const that = this;
+				uni.navigateTo({
+					url: `/pagesHome/shop/index?id=${that.shop._id}`
+				})
+			},
+			// 商品评价
+			toAppraise(e) {
+				const that = this;
+				uni.navigateTo({
+					url: `/pagesHome/order/appraise?id=${that.id}`
+				})
+			},
+			// 关注商铺
+			async shopCollect() {
+				const that = this;
+				let user = that.user;
+				if (user && user._id) {
+					let res = await that.$api(`/storeShop`, `POST`, {
+						customer: user._id,
+						shop: that.shop._id
+					});
+					if (res.errcode == '0') {
+						uni.showToast({
+							title: res.data.msg,
+							icon: 'none'
+						})
+						that.$set(that, `shop_collect`, res.data.result)
+					}
+				} else {
+					uni.showToast({
+						title: '无用户登录无法关注商铺',
+						icon: 'none'
+					})
+				}
+			},
+			//主菜单跳转
+			toPath(e) {
+				if (e && e.route) uni.reLaunch({
+					url: `/${e.route}`
+				})
+			},
+			// 菜单展开
+			toMenu() {
+				const that = this;
+				that.menu = !that.menu
+			},
+			// 计算高度
+			handleScroll(e) {
+				const that = this;
+				let scrollTop = e.detail.scrollTop;
+				that.isShow = scrollTop > 500;
+				that.topItem = '';
+			},
+			// 返回顶部
+			backTop() {
+				const that = this;
+				that.topItem = 'top'
+			},
+			//立即兑换弹窗
+			buttonClick(e) {
+				const that = this;
+				that.$refs.popup.open();
+			},
+			// 修改样式
+			toStyle(e, index) {
+				const that = this;
+				that.$set(that, `isActive`, index)
+				that.$set(that, `specsInfo`, e)
+				that.disabled = false;
+			},
+			// 计数器
+			toCount(e) {
+				const that = this;
+				that.num = e;
+			},
+			// 立即兑换
+			toBuy(e) {
+				const that = this;
+				uni.getStorage({
+					key: 'token',
+					success: async function(res) {
+						let user = that.$jwt(res.data);
+						that.$set(that, `user`, user)
+						if (that.specsInfo._id) {
+							let specs_id = that.specsInfo._id
+							let data = {
+								customer: user._id,
+								shop: that.shop._id,
+								goods: that.info._id,
+								goodsSpec: specs_id,
+								num: that.num
+							}
+							let arr = await that.$api(`/util/checkCanBuy`, 'POST', data)
+							if (arr.errcode == '0') {
+								if (arr.data.result == true) {
+									uni.navigateTo({
+										url: `/pagesIntegral/order/index?key=${arr.data.key}`
+									})
+								} else {
+									uni.showToast({
+										title: arr.data.msg,
+										icon: 'none'
+									})
+								}
+							} else {
+								uni.showToast({
+									title: arr.errmsg,
+									icon: 'none'
+								})
+							}
+						} else {
+							uni.showModal({
+								title: '提示',
+								content: '请选择规格',
+								confirmColor: '#ff0000',
+								showCancel: false,
+								success: function(res) {}
+							});
+						}
+					},
+					fail: function(err) {
+						uni.navigateTo({
+							url: `/pages/login/index`
+						})
+					}
+				});
+			},
+			// 关闭弹框
+			toClose() {
+				const that = this;
+				that.$refs.popup.close()
+			},
+			// 详情数据
+			async search() {
+				const that = this;
+				uni.getStorage({
+					key: 'token',
+					success: function(res) {
+						let user = that.$jwt(res.data);
+						if (user) that.$set(that, `user`, user);
+						that.searchOther();
+					},
+					fail: function(err) {}
+				});
+				let res = await that.$api(`/viewGoods/goodsDetail`, `POST`, {
+					id: that.id
+				});
+				if (res.errcode == '0') {
+					let data = res.data;
+					if (data.goods.brief) data.goods.brief = data.goods.brief.replace(/\<img/gi,
+						'<img class="rich-img"');
+					that.$set(that, `info`, data.goods)
+					that.$set(that, `specs`, data.specs)
+					that.$set(that, `shop`, data.shop)
+					if (data.specs.length > 0) that.$set(that.specsInfo, `sell_money`, data.specs[0].sell_money)
+					that.$set(that, `bannerList`, data.goods.file)
+					let con = await that.$api(`/goodsRate`, `GET`, {
+						goods: data.goods._id
+					})
+					if (con.errcode == '0') {
+						that.$set(that, `comment`, con.total)
+					}
+				}
+			},
+			async searchOther() {
+				const that = this;
+				let user = that.user;
+				// 商铺是否收藏
+				let arr = await that.$api(`/storeShop/check`, `GET`, {
+					customer: user._id,
+					shop: that.shop._id
+				});
+				if (arr.errcode == '0') {
+					that.$set(that, `shop_collect`, arr.data)
+				}
+			},
+			// 配置分享内容
+			configShare() {
+				const that = this;
+				let user_id = that.user && that.user._id ? that.user._id : '';
+				let id = that.info && that.info._id ? that.info._id : '';
+				that.$config.share = {
+					title: that.info.name,
+					path: `/pagesHome/order/detail?id=${id}&user_id=${user_id}`,
+					imageUrl: that.info.file[0].url
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.scrollView {
+		height: 100vh;
+	}
+
+	.main {
+		display: flex;
+		flex-direction: column;
+		width: 100vw;
+		height: 100vh;
+
+		.onemain {
+			position: relative;
+			flex-grow: 1;
+			background-color: var(--f1Color);
+
+			.one {
+				swiper {
+					height: 70vw;
+				}
+
+				.list {
+					border-radius: 5px;
+
+					.image {
+						width: 100%;
+						height: 100%;
+						border-radius: 5px;
+						background-color: #fff;
+					}
+				}
+			}
+
+			.two {
+				padding: 0 0 2vw 0;
+				background-color: var(--mainColor);
+
+				.two_1 {
+					display: flex;
+					align-items: center;
+					border-bottom: 0.5vw solid var(--f9Color);
+					padding: 2vw;
+
+					.money_1 {
+						color: var(--ff0Color);
+
+						text {
+							margin: 0 1vw 0 0;
+						}
+
+						text:last-child {
+							font-size: var(--font20Szie);
+							font-weight: bold;
+						}
+					}
+
+					.money_2 {
+						text-decoration: line-through;
+						color: var(--f99Color);
+
+						text {
+							margin: 0 1vw 0 0;
+						}
+
+						text:last-child {
+							font-size: var(--font16Size);
+						}
+					}
+				}
+
+				.two_2 {
+					font-size: var(--font18Szie);
+					font-weight: bold;
+					padding: 1vw 2vw;
+				}
+
+				.two_3 {
+					font-size: var(--font16Szie);
+					color: var(--f85Color);
+					padding: 1vw 2vw;
+				}
+
+				.two_4 {
+					font-size: var(--font12Size);
+					color: var(--fcColor);
+					padding: 1vw 2vw;
+
+					text {
+						margin: 0 2vw 0 0;
+					}
+				}
+			}
+
+			.thr {
+				.thr_1 {
+					display: flex;
+					flex-direction: row;
+					justify-content: space-between;
+					margin: 2vw 0 2vw 0;
+					padding: 2vw;
+					background-color: var(--mainColor);
+				}
+			}
+
+			.four {
+				padding: 2vw;
+				background-color: var(--mainColor);
+
+				.four_1 {
+					display: flex;
+					justify-content: space-between;
+
+					.image {
+						width: 15vw;
+						height: 15vw;
+						border: 0.1vw solid var(--fcColor);
+					}
+
+					.other {
+						flex-grow: 1;
+						margin: 0 0 0 2vw;
+
+						.name {
+							font-size: var(--font16Szie);
+						}
+
+						.other_1 {
+							font-size: var(--font12Size);
+
+							text {
+								color: var(--fcColor);
+								margin: 0 2vw 0 0;
+							}
+						}
+					}
+				}
+
+				.four_2 {
+					display: flex;
+					flex-direction: row;
+					justify-content: space-evenly;
+					padding: 2vw 0;
+					color: var(--f99Color);
+
+					.grade {
+						font-size: var(--font14Size);
+						color: var(--f85Color);
+
+						text {
+							color: var(--ff0Color);
+						}
+					}
+
+					.btn {
+						border: 0.1vw solid var(--fcColor);
+						padding: 1vw 6vw;
+						border-radius: 1vw;
+						color: var(--f00Color);
+					}
+
+					.btn:last-child {
+						padding: 1vw 10vw;
+					}
+				}
+			}
+
+			.five {
+				margin: 2vw 0 0 0;
+
+				.five_1 {
+					background-color: var(--mainColor);
+					padding: 2vw;
+
+					.rich-img {
+						width: 100% !important;
+						display: block;
+					}
+				}
+			}
+		}
+	}
+
+	.scroll-view {
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+
+		.list-scroll-view {
+			display: flex;
+			flex-direction: column;
+		}
+	}
+
+	.scrollView {
+		height: 100vh;
+	}
+
+	.menu {
+		position: fixed;
+		bottom: 30vw;
+		right: 5vw;
+
+		text {
+			font-size: 30px;
+			background-color: #0000005f;
+			border-radius: 90px;
+		}
+	}
+
+	.menu_1 {
+		position: fixed;
+		bottom: 40vw;
+		right: 5vw;
+		background-color: var(--mainColor);
+		padding: 2vw;
+
+		.title {
+			display: flex;
+			padding: 2vw;
+			border-bottom: 0.1vw solid var(--fcColor);
+
+			.image {
+				width: 7vw;
+				height: 6vw;
+			}
+
+			.name {
+				margin: 0 0 0 1vw;
+				font-size: var(--font14Size);
+			}
+
+		}
+	}
+
+	.backTop {
+		position: fixed;
+		bottom: 20vw;
+		right: 5vw;
+
+		text {
+			font-size: 30px;
+			background-color: #0000005f;
+			border-radius: 90px;
+		}
+	}
+
+	uni-popup {
+		z-index: 999999 !important;
+	}
+
+	.content {
+		height: 100vw;
+
+		.one {
+			display: flex;
+			flex-direction: row;
+			justify-content: space-between;
+			margin: 2vw;
+			padding: 2vw 0;
+			border-bottom: 1px solid var(--f9Color);
+
+			.image {
+				width: 25vw;
+				height: 25vw;
+				margin: 0 2vw 0 0;
+			}
+
+			.other {
+				display: flex;
+				flex-direction: column;
+				flex-grow: 1;
+				margin: 0 0 0 2vw;
+
+				.money {
+					color: var(--fFB1Color);
+					font-size: var(--font20Szie);
+					padding: 2vw 0;
+				}
+
+				.other_1 {
+					font-size: var(--font14Size);
+
+					text {
+						padding: 0 2vw;
+						color: var(--f85Color);
+					}
+				}
+			}
+		}
+
+		.two {
+			margin: 0 2vw;
+			padding: 2vw 0;
+			font-size: var(--font12Size);
+			border-bottom: 1px solid var(--f9Color);
+
+			.two_2 {
+				display: flex;
+				flex-wrap: wrap;
+				padding: 1vw;
+				margin: 1vw 0 0 0;
+
+				text {
+					margin: 1vw 2vw 0 0;
+					padding: 1vw;
+					border-radius: 1vw;
+					background-color: var(--f9Color);
+				}
+
+				.style {
+					color: var(--mainColor);
+					background-color: var(--ff0Color);
+				}
+			}
+		}
+
+		.thr {
+			display: flex;
+			justify-content: flex-start;
+			margin: 0 2vw;
+			padding: 2vw 0;
+
+			text {
+				margin: 0 2vw 0 0;
+			}
+
+			text:last-child {
+				margin: 0 0 0 2vw;
+				font-size: var(--font12Size);
+				color: var(--f85Color);
+			}
+		}
+
+		.btn {
+			position: fixed;
+			bottom: 0;
+			width: 100vw;
+			padding: 4vw 0;
+			background-color: var(--fFB1Color);
+			text-align: center;
+			font-size: var(--font18Szie);
+			color: var(--mainColor);
+		}
+
+	}
+
+	.uni-tab__cart-sub-left {
+		padding: 0 !important;
+	}
+</style>

+ 678 - 0
pagesIntegral/order/index.vue

@@ -0,0 +1,678 @@
+<template>
+	<mobile-frame>
+		<view class="main">
+			<view class="one">
+				<scroll-view scroll-y="true" class="scroll-view">
+					<view class="list-scroll-view">
+						<view class="one_1" @click="toChoose">
+							<text class="localicon iconfont icon-dingweixiao"></text>
+							<view class="other" v-if="address._id">
+								<view class="name">
+									<text>{{address.name}},</text>{{address.phone}}
+								</view>
+								<view class="other_1">
+									<text>{{address.province}}</text><text>{{address.city}}</text>
+									<text>{{address.area}}</text><text>{{address.address}}</text>
+								</view>
+							</view>
+							<view class="address" v-else><text>请选择一个收货地址</text></view>
+							<text class="iconfont icon-jiantouyou"></text>
+						</view>
+						<view class="one_2">
+							<view class="list" v-for="(item,index) in orderList" :key="index">
+								<view class="list_1">
+									<view class="l">
+										<text class="iconfont icon-shangdian"></text>
+										<text>{{item.shop_name}}</text>
+									</view>
+								</view>
+								<view class="list_2" v-for="(tag,index) in item.goods" :key="index">
+									<view class="l">
+										<image class="image" :src="tag.file&&tag.file.length>0?tag.file[0].url:''"
+											mode=""></image>
+									</view>
+									<view class="c">
+										<view class="name">
+											{{tag.goods_name}}
+										</view>
+										<view class="Spec">
+											规格:{{tag.goodsSpec_name}}
+										</view>
+									</view>
+									<view class="r">
+										<view class="price" v-if="type=='0'">
+											¥{{tag.money}}
+										</view>
+										<view v-else class="price">
+											¥{{tag.group_sell_money}}
+										</view>
+										<view class="num">
+											×{{tag.num}}
+										</view>
+									</view>
+								</view>
+								<view class="list_3">
+									<view class="other">
+										<view class="other_1">配送方式</view>
+										<view class="other_2"><text class="iconfont icon-duihao"></text>快递配送</view>
+									</view>
+									<view class="other">
+										<view class="other_1">运费</view>
+										<view class="other_2" v-if="!item.freight_total==0">¥{{item.freight_total}}
+										</view>
+										<view class="other_2" v-else>包邮</view>
+									</view>
+									<view class="other">
+										<view class="other_1">订单备注</view>
+										<view class="other_3">
+											<input type="text" v-model="item.remarks" placeholder="选填,可填写您与卖家达成一致的要求" />
+										</view>
+									</view>
+								</view>
+							</view>
+							<view class="other" v-if="type=='0'">
+								<view class="other_1">积分</view>
+								<view class="other_2" @click="toCoupon" v-if="couponList.length">
+									{{coupon_name||'请选择积分'}}
+								</view>
+								<view class="other_2" v-else>暂无积分使用</view>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="two">
+				<view class="two_1">
+					<view>实付金额:</view>
+					<view>¥{{goods_total}}</view>
+				</view>
+				<view class="two_2">
+					<text @click="toSubmit">提交订单</text>
+				</view>
+			</view>
+		</view>
+		<uni-popup ref="popup" background-color="#fff" type="bottom">
+			<view class="popup" v-if="popup.type=='1'">
+				<scroll-view scroll-y="true" class="scroll-view">
+					<view class="list" v-for="(item,index) in addressList" :key="index">
+						<view class="one">
+							<view class="one_1">
+								<view class="name">
+									<text>{{item.name}},</text>{{item.phone}}
+								</view>
+								<view class="address">
+									<text>{{item.province}}</text><text>{{item.city}}</text>
+									<text>{{item.area}}</text><text>{{item.address}}</text>
+								</view>
+							</view>
+							<text class="iconfont icon-jiantouyou"></text>
+						</view>
+						<view class="two">
+							<view class="two_1">
+								<checkbox-group @change="toCheckbox">
+									<label>
+										<checkbox :value="item._id" :checked="item.checked"
+											style="transform:scale(0.7)" />
+										选择地址
+									</label>
+								</checkbox-group>
+							</view>
+							<view class="two_2">
+								<text class="text" v-if="item.is_default=='1'">默认</text>
+								<text @click="toDel(item)" class="iconfont icon-del"></text>
+							</view>
+						</view>
+					</view>
+				</scroll-view>
+			</view>
+			<view class="popup" v-else-if="popup.type=='2'">
+				<scroll-view scroll-y="true" class="scroll-view">
+					<discount :Style="Style" :couponList="couponList" @toDiscount="toDiscount"></discount>
+				</scroll-view>
+			</view>
+		</uni-popup>
+	</mobile-frame>
+</template>
+
+<script>
+	import discount from '@/components/discount/index.vue';
+	export default {
+		components: {
+			discount
+		},
+		data() {
+			return {
+				popup: {
+					type: '1'
+				},
+				Style: {
+					btn: true
+				},
+				user: {},
+				key: '',
+				address: {},
+				orderList: [],
+				shop: [],
+				goods_total: 0,
+				// 金额明细
+				total_detail: {},
+				// 收货地址
+				addressList: [],
+				// 优惠劵
+				couponList: [],
+				coupon: [],
+				// 优惠劵名称
+				coupon_name: '',
+				// 是否开团
+				type: '0',
+				// 团id
+				group_id: '',
+			};
+		},
+		onLoad: async function(e) {
+			const that = this;
+			that.$set(that, `key`, e.key || '');
+			that.$set(that, `group_id`, e.group_id || '');
+			that.watchLogin()
+		},
+		methods: {
+			// 使用优惠劵
+			toDiscount(e) {
+				const that = this;
+				that.$set(that, 'coupon_name', e.name)
+				that.coupon.push(e._id)
+				that.$refs.popup.close();
+				this.computedTotal();
+			},
+			// 选择收货地址
+			toChoose() {
+				const that = this;
+				if (that.addressList.length > 0) {
+					that.$set(that.popup, 'type', '1')
+					that.$refs.popup.open();
+				} else {
+					uni.showToast({
+						title: `暂无收货地址`,
+						icon: 'none'
+					})
+				}
+			},
+			// 选择优惠劵
+			toCoupon() {
+				const that = this;
+				that.$set(that.popup, 'type', '2')
+				that.$set(that, 'coupon', [])
+				that.$refs.popup.open();
+			},
+			// 是否选中
+			toCheckbox(e) {
+				const that = this;
+				var addressList = that.addressList;
+				var values = e.detail.value;
+				for (var i = 0, lenI = addressList.length; i < lenI; ++i) {
+					const item = addressList[i]
+					if (values.includes(item._id)) {
+						that.$set(item, 'checked', true)
+						that.$set(that, `address`, item);
+					} else {
+						that.$set(item, 'checked', false)
+					}
+				}
+				that.$refs.popup.close();
+			},
+			// 删除收货地址
+			toDel(e) {
+				const that = this;
+				uni.showModal({
+					title: '提示',
+					content: '确定删除该地址吗?',
+					success: async function(res) {
+						if (res.confirm) {
+							const arr = await that.$api(`/address/${e._id}`, 'DELETE');
+							if (arr.errcode == '0') {
+								uni.showToast({
+									title: '删除信息成功',
+									icon: 'none'
+								})
+								that.search();
+							} else {
+								uni.showToast({
+									title: arr.errmsg,
+									icon: 'none'
+								})
+							}
+						}
+					}
+				});
+			},
+			// 提交订单
+			async toSubmit() {
+				const that = this;
+				if (that.address) {
+					let data = {
+						address: that.address,
+						goods: that.orderList,
+						total_detail: that.total_detail,
+						coupon: that.coupon,
+						type: that.type,
+					}
+					if (that.group_id) {
+						data.group = that.group_id
+					}
+					const arr = await that.$api(`/order`, 'POST', data)
+					if (arr.errcode == '0') {
+						uni.getStorage({
+							key: 'system',
+							success: async function(res) {
+								// 微信小程序支付
+								if (res.data.uniPlatform == "mp-weixin") {
+									uni.showLoading({
+										title: '加载中'
+									})
+									const res = await that.$api('/pay/toPayOrder', 'POST', {
+										order_id: arr.data,
+										type: '0'
+									})
+									uni.requestPayment({
+										"provider": "wxpay",
+										...res.data,
+										async success(res) {
+											const group = await that.$api('/group/getGroup',
+												'GET', {
+													order_id: arr.data,
+												})
+											if (group.errcode == '0') {
+												if (group.data) {
+													uni.hideLoading();
+													uni.reLaunch({
+														url: `/pagesHome/group/share?id=${group.data}`
+													})
+												} else {
+													uni.hideLoading();
+													uni.reLaunch({
+														url: `/pagesMy/order/index?status=${'1'}`
+													})
+												}
+											} else {
+												uni.showToast({
+													title: group.errmsg,
+													icon: 'none'
+												})
+											}
+										},
+										fail(e) {
+											uni.showToast({
+												title: `支付失败`,
+												icon: 'none'
+											})
+											uni.hideLoading();
+											uni.reLaunch({
+												url: `/pagesMy/order/index?status=${'0'}`
+											})
+										}
+									})
+								} else if (res.data.uniPlatform == "app") {
+									// app支付
+									uni.requestPayment({
+										provider: 'alipay',
+										orderInfo: 'orderInfo', //微信、支付宝订单数据 【注意微信的订单信息,键值应该全部是小写,不能采用驼峰命名】
+										success: function(res) {
+											console.log('success:' + JSON.stringify(res));
+										},
+										fail: function(err) {
+											console.log('fail:' + JSON.stringify(err));
+										}
+									});
+								} else {
+									uni.showToast({
+										title: `平台不支持支付`,
+										icon: 'none'
+									})
+								}
+							},
+							fail: function(err) {}
+						})
+					} else {
+						uni.showToast({
+							title: arr.data.errmsg || '下单失败!',
+							icon: 'none'
+						})
+					}
+				} else {
+					uni.showToast({
+						title: `没有收货地址`,
+						icon: 'none'
+					})
+				}
+			},
+			// 监听用户是否登录
+			watchLogin() {
+				const that = this;
+				uni.getStorage({
+					key: 'token',
+					success: function(res) {
+						let user = that.$jwt(res.data);
+						that.$set(that, `user`, user);
+						that.search()
+					},
+					fail: function(err) {
+						uni.reLaunch({
+							url: `/pages/login/index`
+						})
+					}
+				})
+			},
+			// 查询列表
+			async search() {
+				const that = this;
+				let user = that.user;
+				const res = await that.$api(`/address`, 'GET', {
+					customer: user._id
+				})
+				if (res.errcode == '0') {
+					that.$set(that, `addressList`, res.data.reverse());
+				}
+				const arr = await that.$api(`/order/toMakeOrder`, 'POST', {
+					key: that.key
+				})
+				if (arr.errcode == '0') {
+					that.$set(that, `address`, arr.data.address);
+					that.$set(that, `orderList`, arr.data.goodsData);
+					that.$set(that, `total_detail`, arr.data.orderTotal);
+					that.$set(that, `type`, arr.data.type);
+					this.computedTotal();
+					that.$set(that, `couponList`, arr.data.couponList);
+				}
+			},
+			async computedTotal() {
+				const total_detail = this.total_detail;
+				let total = this.$plus(total_detail.freight_total, total_detail.goods_total)
+				if (this.coupon.length > 0) {
+					let discount = 0;
+					for (const coupon of this.coupon) {
+						const r = this.couponList.find(f => f._id === coupon)
+						if (!r) continue;
+						const {
+							discount_config,
+							discount_type
+						} = r;
+						if (discount_type === 'min') {
+							const min = discount_config.min;
+							discount = this.$plus(discount, min)
+						} else if (discount_type === 'discount') {
+							const min = discount_config.min || 0;
+							let discount_money = 0;
+							const max = discount_config.max || 0;
+							// TODO 现在是平台发放的优惠券,所以可以直接用总价*折扣,如果是店铺的折扣券,则需要将金额分开,对应店铺计算折扣
+							// const dm = min / 10 * total;
+							const dm = this.$multiply(this.divide(min, 10), total)
+							if (max !== 0) {
+								if (max > dm) discount_money = dm;
+								else discount_money = max
+							}
+							discount += discount_money
+						}
+					}
+					total = this.$minus(total, discount)
+				}
+				if (total >= 0) {
+					this.$set(this, `goods_total`, total);
+				} else {
+					uni.showToast({
+						title: `实付金额不能为负数 不能使用该优惠劵`,
+						icon: 'none'
+					})
+				}
+			}
+		}
+	}
+</script>
+
+<style lang="scss">
+	.main {
+		display: flex;
+		flex-direction: column;
+		width: 100vw;
+		height: 100vh;
+
+		.one {
+			position: relative;
+			flex-grow: 1;
+			background-color: var(--f1Color);
+
+			.one_1 {
+				display: flex;
+				justify-content: space-between;
+				align-items: center;
+				width: 100vw;
+				padding: 2vw;
+				border-bottom: 1vw dashed var(--fcColor);
+
+				.address {
+					flex-grow: 1;
+					margin: 0 0 0 2vw;
+					font-size: var(--font14Size);
+					color: var(--f85Color);
+				}
+
+				.iconfont {
+					font-size: var(--font20Szie);
+				}
+
+				.other {
+					width: 82vw;
+					padding: 0 2vw;
+
+					.name {
+						font-size: var(--font16Size);
+					}
+
+					.other_1 {
+						font-size: var(--font14Size);
+						color: var(--f85Color);
+
+						text {
+							margin: 0 1vw 0 0;
+						}
+					}
+				}
+			}
+
+			.one_2 {
+				margin: 2vw 0 0 0;
+
+				.list {
+					width: 100vw;
+					margin: 2vw 0;
+
+					.list_1 {
+						padding: 2vw;
+						background-color: var(--mainColor);
+						border-bottom: 0.1vw solid var(--fcColor);
+
+						text {
+							padding: 0 0 0 1vw;
+						}
+					}
+
+					.list_2 {
+						padding: 2vw;
+						display: flex;
+						background-color: var(--mainColor);
+
+						.l {
+							width: 20vw;
+
+							.image {
+								width: 100%;
+								height: 20vw;
+								border-radius: 5px;
+							}
+						}
+
+						.c {
+							width: 60vw;
+							padding: 0 2vw;
+
+							.Spec {
+								font-size: var(--font12Size);
+								color: var(--f85Color);
+							}
+						}
+
+						.r {
+							width: 15vw;
+							text-align: right;
+						}
+					}
+
+					.list_3 {
+						width: 96vw;
+						padding: 2vw;
+						background-color: var(--mainColor);
+
+						.other {
+							display: flex;
+							justify-content: space-between;
+							border-bottom: 0.1vw solid var(--fcColor);
+							margin: 0 0 2vw 0;
+							padding: 2vw 0;
+
+							.other_1 {
+								font-size: var(--font16Size);
+								color: var(--f85Color);
+							}
+
+							.other_3 {
+								flex-grow: 1;
+								margin: 0 0 0 2vw;
+								font-size: var(--font12Size);
+							}
+
+							text {
+								padding: 0 1vw 0 0;
+								font-size: var(--font20Szie);
+							}
+						}
+					}
+				}
+
+				.other {
+					display: flex;
+					justify-content: space-between;
+					background-color: var(--mainColor);
+					border-bottom: 0.1vw solid var(--fcColor);
+					margin: 0 0 2vw 0;
+					width: 96vw;
+					padding: 2vw;
+
+					.other_1 {
+						font-size: var(--font16Size);
+						color: var(--f85Color);
+					}
+
+					.other_3 {
+						flex-grow: 1;
+						margin: 0 0 0 2vw;
+						font-size: var(--font12Size);
+					}
+
+					text {
+						padding: 0 1vw 0 0;
+						font-size: var(--font20Szie);
+					}
+				}
+			}
+		}
+
+		.two {
+			display: flex;
+			justify-content: space-between;
+			border-top: 0.1vw solid var(--fcColor);
+
+			.two_1 {
+				display: flex;
+				align-items: center;
+				padding: 0 2vw;
+				font-size: var(--font16Size);
+
+				view:last-child {
+					margin: 0 0 0 2vw;
+					color: var(--ff0Color);
+					font-weight: bold;
+				}
+			}
+
+			.two_2 {
+				padding: 3vw 4vw;
+				color: var(--mainColor);
+				font-size: var(--font16Size);
+				background-color: var(--ff0Color);
+			}
+		}
+	}
+
+	.scroll-view {
+		position: absolute;
+		top: 0;
+		left: 0;
+		right: 0;
+		bottom: 0;
+
+		.list-scroll-view {
+			display: flex;
+			flex-direction: row;
+			flex-wrap: wrap;
+		}
+	}
+
+	.popup {
+		display: flex;
+		flex-direction: column;
+		height: 100vw;
+		overflow-x: hidden;
+		background-color: var(--f5Color);
+		padding: 2vw;
+
+		.list {
+			.one {
+				display: flex;
+				justify-content: space-between;
+				margin: 2vw 0 0 0;
+				padding: 2vw;
+				background-color: var(--mainColor);
+
+				.name {
+					font-size: var(--font16Size);
+				}
+
+				.address {
+					font-size: var(--font14Size);
+				}
+
+				.iconfont {
+					line-height: 15vw;
+					font-size: var(--font20Szie);
+				}
+			}
+
+			.two {
+				display: flex;
+				justify-content: space-between;
+				border-top: 0.1vw solid var(--fcColor);
+				padding: 2vw;
+				background-color: var(--mainColor);
+				font-size: var(--font14Size);
+
+				.text {
+					margin: 0 2vw 0 0;
+					border: 0.1vw solid var(--fFB1Color);
+					padding: 1vw;
+					font-size: var(--font12Size);
+					border-radius: 2vw;
+					color: var(--fFB1Color);
+				}
+			}
+		}
+	}
+</style>