hwb0 3 vuotta sitten
vanhempi
commit
5e374b8ce5

+ 55 - 13
components/pay-popup/pay-popup.vue

@@ -82,31 +82,73 @@
 				this.$emit('close')
 			},
 			
-			pay(){
-				if(!this.checked){
+			success(){
+				this.checked = false
+				this.$emit('success')
+			},
+
+			pay() {
+				let _this = this
+				let payIng = false
+				if (!this.checked) {
 					uni.$u.toast('请同意《盲票购买须知》!');
 					return
 				}
-				$http.post('/api/v1/mp/user/ticket/order/submit', {}).then(res=>{
-					console.log(res);
-					if(res.code == 0){
-						if(res.data.needPay == 1){
+				if (payIng) return
+				$http.post('/api/v1/mp/user/ticket/order/submit', {}).then(res => {
+					payIng = true
+					if (res.code == 0) {
+						if (res.data.needPay == 1) {
 							$http.post('/api/v1/mp/user/ticket/order/pay', {
 								orderId: res.data.orderId,
 								payType: 2
-							}).then(res=>{
-								if(res.code == 0){
-									uni.$u.toast('支付成功');
-								}else{
+							}).then(ele => {
+								if (ele.code == 0) {
+									uni.requestPayment({
+										timeStamp: ele.data.timeStamp,
+										nonceStr: ele.data.nonceStr,
+										package: ele.data.package,
+										signType: ele.data.signType,
+										paySign: ele.data.paySign,
+										success() {
+											uni.showToast({
+												title: '支付成功',
+												icon: 'success',
+												duration: 2000
+											})
+											_this.success(res.data.orderId)
+										},
+										fail() {
+											payIng = false
+											_this.close()
+										}
+									})
+								} else {
+									payIng = false
+									_this.close()
 									uni.$u.toast('支付失败!');
 								}
-							}).catch(()=>{
+							}).catch(() => {
+								payIng = false
+								_this.close()
 								uni.$u.toast('支付失败!');
 							})
-						} else{
-							uni.$u.toast('支付成功');
+						} else {
+							uni.showToast({
+								title: '支付成功',
+								icon: 'success',
+								duration: 2000
+							})
+							_this.close()
 						}
+					}else{
+						payIng = false
+						_this.close()
+						uni.$u.toast('支付失败!');
 					}
+				}).catch(() => {
+					payIng = false
+					uni.$u.toast('支付失败!');
 				})
 			},
 		},

+ 9 - 1
manifest.json

@@ -43,7 +43,15 @@
             /* ios打包配置 */
             "ios" : {},
             /* SDK配置 */
-            "sdkConfigs" : {}
+            "sdkConfigs" : {
+                "payment" : {
+                    "weixin" : {
+                        "__platform__" : [ "ios", "android" ],
+                        "appid" : "",
+                        "UniversalLinks" : ""
+                    }
+                }
+            }
         }
     },
     /* 快应用特有相关 */

+ 6 - 0
pages.json

@@ -39,6 +39,12 @@
 		"path": "pages/ticketBox/detail"
 	}, {
 		"path": "pages/lucky/index"
+	}, {
+		"path": "pages/prizeGoods/detail"
+	}, {
+		"path": "pages/process/index"
+	}, {
+		"path": "pages/choice/index"
 	}],
 	"tabBar": {
 		"custom": true,

+ 197 - 0
pages/choice/index.vue

@@ -0,0 +1,197 @@
+<template>
+	<view>
+		<u-navbar title="选择奖品" :border="true" :placeholder="true" :autoBack="true" bgColor="#fff" />
+		<view class="choice">
+			<view class="choice-title">恭喜你获得</view>
+			<view class="choice-all" v-if="total > 1">以下奖品任选其一</view>
+			<view class="flex choice-list">
+				<view class="choice-list-item" v-for="(item, index) in prizeList" :key="index"
+					@click="selectPrize(item, index)">
+					<view
+						:class="{'flex action': actionIndex == index, 'flex confirm': actionIndex != index, 'flex null': item.remainQty == 0}">
+						<view class="info">
+							<image :src="item.picUrl" mode="aspectFill"></image>
+							<view class="title">{{ item.title }}</view>
+							<view class="tip" v-if="item.remainQty == 0">已兑完</view>
+						</view>
+					</view>
+				</view>
+			</view>
+			<view class="flex btn">
+				<view class="confirm" @click="confirmPrize">确认</view>
+			</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
+	export default {
+		data() {
+			return {
+				ticketId: '',
+				prizeList: [],
+				total: 0,
+				actionIndex: 0,
+			};
+		},
+		onLoad(options) {
+			this.ticketId = options.id
+			this.getPrizeList()
+		},
+		methods: {
+			getPrizeList() {
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post('/api/v1/mp/user/ticket/queryHitPrizeList', {
+					ticketId: this.ticketId
+				}).then(res => {
+					uni.hideLoading();
+					if (res.code == 0) {
+						res.data.forEach(item => {
+							item.picUrl = env.filePublic + item.picUrl
+						})
+						this.prizeList = res.data
+						this.total = res.data.length
+						console.log(this.total);
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
+			selectPrize(item, index) {
+				if (item.remainQty == 0) {
+					uni.$u.toast('该奖品已兑完!');
+					return
+				}
+				this.actionIndex = index
+				console.log(item, index);
+			},
+
+			confirmPrize() {
+				let _this = this
+				let item = _this.prizeList[_this.actionIndex]
+				console.log(item);
+				uni.showModal({
+					title: '提示',
+					content: '确定选择该奖品吗?',
+					success(res) {
+						if (res.confirm) {
+							$http.post('/api/v1/mp/user/ticket/cashPrize', {
+								ticketId: _this.ticketId,
+								awardsId: item.awardsId,
+								prizeId: item.prizeId
+							}).then(res => {
+								if (res.code == 0) {
+									uni.$u.toast('兑换成功');
+									setTimeout(() => {
+										uni.switchTab({
+											url: '/pages/index/index'
+										})
+									}, 500)
+								}
+							})
+						}
+					}
+				})
+
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.choice {
+		width: 100%;
+		min-height: calc(100vh - 50px);
+		background: url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic3.zhimg.com%2F50%2Fv2-a6f5c8b5b66fe87e4e79c1fc82a61a36_hd.jpg&refer=http%3A%2F%2Fpic3.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1649658373&t=f216ee4825d5b36e62aa3a490516bfb1) center center;
+		padding-bottom: 150rpx;
+
+		&-title {
+			padding-top: 100rpx;
+			font-size: 56rpx;
+			font-weight: bold;
+			text-align: center;
+			line-height: 84rpx;
+			margin-bottom: 12rpx;
+		}
+
+		&-all {
+			text-align: center;
+			line-height: 40rpx;
+		}
+
+		&-list {
+			justify-content: space-around;
+			flex-wrap: wrap;
+			margin-top: 60rpx;
+			margin-bottom: 60rpx;
+
+			&-item {
+				width: 40%;
+				height: 440rpx;
+				margin-bottom: 40rpx;
+
+				.confirm {
+					height: 100%;
+					background: none;
+					box-shadow: none;
+					border: none;
+				}
+
+				.action {
+					height: 100%;
+					background-color: #4cd964;
+					box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.4);
+					border: 1px solid rgba(187, 187, 187, 54);
+				}
+
+				.null {
+					height: 100%;
+					background: #918b8d;
+					box-shadow: 0px 2px 6px 0px rgba(0, 0, 0, 0.4);
+					border: 1px solid rgba(187, 187, 187, 54);
+				}
+
+				.info {
+					width: 80%;
+					height: 80%;
+					background-color: #C0C0C0;
+				}
+
+				image {
+					width: 100%;
+					height: 60%;
+				}
+
+				.title {
+					margin-top: 20rpx;
+					color: #FFFFFF;
+					text-align: center;
+				}
+
+				.tip {
+					margin-top: 20rpx;
+					color: red;
+					text-align: center;
+				}
+			}
+		}
+
+		.btn {
+			.confirm {
+				width: 320rpx;
+				height: 60rpx;
+				line-height: 60rpx;
+				border-radius: 8px;
+				background-color: rgba(235, 112, 9, 100);
+				color: rgba(255, 255, 255, 100);
+				font-size: 28rpx;
+				text-align: center;
+			}
+		}
+	}
+</style>

+ 46 - 8
pages/core/index.vue

@@ -7,12 +7,13 @@
 		</u-navbar>
 		<view class="core">
 			<view class="flex core-list">
-				<navigator url="/pages/goods/detail" class="core-list-item" hover-class="navigator-hover">
+				<navigator :url="`/pages/goods/detail?id=${ item.goodsId }`" class="core-list-item" hover-class="navigator-hover"
+					v-for="(item, index) in list" :key="index">
 					<view class="flex iamge-wrap">
-						<image src="../../static/logo.png" mode="scaleToFill"></image>
+						<image :src="item.picUrl" mode="aspectFill"></image>
 					</view>
-					<view class="title">Apple iMac 24英寸 4.5K屏 新款八核M1芯片(7核图形处理</view>
-					<view class="bean">900</view>
+					<view class="title">{{ item.title }}</view>
+					<view class="bean">{{ item.exchangePrice }}</view>
 				</navigator>
 				<view class="core-list-item"></view>
 			</view>
@@ -31,14 +32,51 @@
 		},
 		data() {
 			return {
-
+				pageNum: 1,
+				total: 0,
+				list: [],
 			};
 		},
+		onLoad(opthios) {
+			this.getList()
+		},
 		onShow() {
 
 		},
 		methods: {
-
+			getList() {
+				uni.showLoading({
+					title: '加载中'
+				});
+				let data = {
+					categoryId: '',
+				}
+				$http.post(`/api/v1/mp/user/exchange/goods/list?pageNum=${this.pageNum}&pageSize=20`, data).then(
+					res => {
+						uni.hideLoading();
+						if (res.code == 0) {
+							res.rows.forEach(item => {
+								item.picUrl = env.filePublic + item.picUrl
+							})
+							this.total = res.total
+							this.list = this.list.concat(res.rows)
+						}
+					}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+		},
+		
+		onReachBottom() {
+			// 判断是否有数据
+			if (this.total > this.pageNum * 20) {
+				setTimeout(() => {
+					++this.pageNum
+					this.getList()
+				}, 500)
+			} else {
+				uni.$u.toast('没有更多数据了')
+			}
 		},
 	}
 </script>
@@ -86,8 +124,8 @@
 					color: #EB7009;
 				}
 			}
-			
-			&-item:last-child{
+
+			&-item:last-child {
 				padding: 0;
 			}
 		}

+ 46 - 21
pages/goods/detail.vue

@@ -6,13 +6,16 @@
 				<u-swiper :list="picUrlArr" height="348" :indicator="true" :circular="true"></u-swiper>
 			</view>
 			<view class="detail-title">
-				<view class="txt">Apple iPhone 13 (A2634) 128GB 星光色 支持移动联通电信5G 双卡双待手机</view>
+				<view class="txt">{{ info.title }}</view>
 				<view class="coin">
 					<image src="../../static/logo.png" mode=""></image>
-					<view>x 6800</view>
+					<view>x {{ info.exchangePrice }}</view>
 				</view>
 			</view>
 			<view class="detail-goods">商品详情</view>
+			<view class="detail-description">
+				<view class="" v-html="description"></view>
+			</view>
 		</view>
 		<view class="footer-fixed">
 			<view class="flex btn">
@@ -80,14 +83,10 @@
 		data() {
 			return {
 				boxId: '',
-				picUrlArr: [
-					'https://cdn.uviewui.com/uview/swiper/swiper1.png',
-					'https://cdn.uviewui.com/uview/swiper/swiper2.png',
-					'https://cdn.uviewui.com/uview/swiper/swiper3.png',
-				],
+				picUrlArr: [],
 				info: {},
 				prizeList: [],
-
+				description: '',
 				choiceShow: false,
 
 				value: 1,
@@ -95,28 +94,21 @@
 			};
 		},
 		onLoad(opthios) {
-			// this.getDetail(opthios.boxId)
+			this.getDetail(opthios.id)
 		},
 		methods: {
 			getDetail(id) {
-				$http.post('/api/v1/mp/channel/mall/ticket/detail', {
-					boxId: id
+				$http.post('/api/v1/mp/user/exchange/goods/detail', {
+					goodsId: id
 				}).then(res => {
 					if (res.code == 0) {
 						this.info = res.data
-
 						let picUrlArr = res.data.picUrl.split(',')
 						picUrlArr.forEach(item => {
 							this.picUrlArr.push(env.filePublic + item)
 						})
-
-						let prizeList = res.data.prizeList
-
-						prizeList.forEach(item => {
-							item.picUrl = env.filePublic + item.picUrl
-						})
-
-						this.prizeList = prizeList
+						// 处理富文本
+						this.description = this.formatRichText(res.data.description);
 					}
 				})
 			},
@@ -131,7 +123,34 @@
 
 			valChange(e) {
 				console.log(e);
-			}
+			},
+			
+			/**
+			 * 处理富文本里的图片宽度自适应
+			 * 1.去掉img标签里的style、width、height属性
+			 * 2.img标签添加style属性:max-width:100%;height:auto
+			 * 3.修改所有style里的width属性为max-width:100%
+			 * 4.去掉<br/>标签
+			 * @param html
+			 * @returns {void|string|*}
+			 */
+			formatRichText(html) { //控制小程序中图片大小
+				let newContent = html.replace(/<img[^>]*>/gi, function(match, capture) {
+					match = match.replace(/style="[^"]+"/gi, '').replace(/style='[^']+'/gi, '');
+					match = match.replace(/width="[^"]+"/gi, '').replace(/width='[^']+'/gi, '');
+					match = match.replace(/height="[^"]+"/gi, '').replace(/height='[^']+'/gi, '');
+					return match;
+				});
+				newContent = newContent.replace(/style="[^"]+"/gi, function(match, capture) {
+					match = match.replace(/width:[^;]+;/gi, 'max-width:100%;').replace(/width:[^;]+;/gi,
+						'max-width:100%;');
+					return match;
+				});
+				newContent = newContent.replace(/<br[^>]*\/>/gi, '');
+				newContent = newContent.replace(/\<img/gi,
+					'<img style="max-width:100%;height:auto;margin:10rpx auto;"');
+				return newContent;
+			},
 		}
 	}
 </script>
@@ -187,6 +206,12 @@
 			font-weight: bold;
 			background-color: #FFFFFF;
 		}
+		
+		&-description {
+			image{
+				width: 100%;
+			}
+		}
 	}
 
 	.choiceShow-wrap {

+ 24 - 12
pages/index/index.vue

@@ -34,12 +34,12 @@
 					<text>立即</text>
 					<text>开刮</text>
 				</view>
-				<view class="box-start-all">所有盲票</view>
+				<view class="box-start-all" @click="toTicket">所有盲票</view>
 			</view>
 		</view>
 		<custom-tab-bar :activeValue="'index'" />
 
-		<pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" />
+		<pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" @success="toProcess" />
 	</view>
 </template>
 
@@ -58,7 +58,6 @@
 		data() {
 			return {
 				imgList: [],
-				id: '',
 				value: 1,
 				payShow: false,
 				checked: false,
@@ -72,12 +71,14 @@
 				payInfo: {}
 			};
 		},
-		onLoad(opthios) {
-			this.id = opthios.id
+		onShow(opthios) {
 			this.getList()
 		},
 		methods: {
 			getList() {
+				uni.showLoading({
+					title: '加载中'
+				});
 				let data = {
 					categoryId: '',
 					tagId: '',
@@ -86,21 +87,23 @@
 				}
 				$http.post(`/api/v1/mp/user/mall/ticket/list?pageNum=${this.pageNum}&pageSize=100`, data).then(
 					res => {
+						uni.hideLoading();
 						if (res.code == 0) {
 							res.rows.forEach(item => {
 								let picUrlArr = item.picUrl.split(',')
 								item.picUrl = env.filePublic + picUrlArr[0]
 							})
 							this.total = res.total
-							this.imgList = this.imgList.concat(res.rows)
+							this.imgList = res.rows
 						}
-					})
+					}).catch(() => {
+					uni.hideLoading();
+				})
 			},
 
 			selectedBanner(item, index) {
-				console.log('馃', item, index)
 				uni.navigateTo({
-					url: '/pages/ticketBox/detail'
+					url: `/pages/ticketBox/detail?id=${ item.boxId }`
 				})
 			},
 
@@ -113,11 +116,14 @@
 				this.payShow = false
 			},
 
-			exchange() {
+			toProcess(id) {
+				this.payShow = false
 				uni.navigateTo({
-					url: '/pages/lucky/index'
+					url: `/pages/process/index?id=${ id }`
 				})
-				return
+			},
+
+			exchange() {
 				this.payInfo = this.imgList[this.currentIndex]
 				let data = {
 					couponIds: [],
@@ -140,6 +146,12 @@
 					uni.$u.toast('开刮失败,请重试!');
 				})
 			},
+
+			toTicket() {
+				uni.navigateTo({
+					url: '/pages/ticketBox/index'
+				})
+			},
 		}
 	}
 </script>

+ 8 - 0
pages/login/index.vue

@@ -32,6 +32,9 @@
 		},
 		methods: {
 			getPhoneNumber(e) {
+				uni.showLoading({
+					title: '登录中'
+				});
 				$http.post('/api/v1/mp/user/wxauth/mobile', {
 					code: e.detail.code,
 					identity: 1
@@ -40,6 +43,8 @@
 						uni.setStorageSync('token', res.token)
 						this.getBaseInfo()
 					}
+				}).catch(()=>{
+					uni.hideLoading();
 				})
 			},
 
@@ -55,6 +60,7 @@
 
 			getBaseInfo() {
 				$http.post('/api/v1/mp/user/getLoginUserinfo', {}).then(res => {
+					uni.hideLoading();
 					if (res.code == 0) {
 						uni.setStorageSync('userInfo', res.data)
 						if (res.data.openId) {
@@ -68,6 +74,8 @@
 							this.authShow = true
 						}
 					}
+				}).catch(()=>{
+					uni.hideLoading();
 				})
 			},
 		}

+ 82 - 30
pages/lucky/index.vue

@@ -1,12 +1,12 @@
 <template>
 	<view>
-		<u-navbar title="幸运数字" :border="true" :placeholder="true" :autoBack="true" bgColor="#fff" />
+		<u-navbar leftIconSize="0" title="幸运数字" :border="true" :placeholder="true" :autoBack="true" bgColor="#fff" />
 		<view class="lucky">
 			<view class="lucky-number">
 				<view class="flex lucky-number-circle">
 					<view class="title">幸运数字</view>
 					<view class="num" v-if="info.status == 1">?</view>
-					<view class="">{{ info.plainLuckyNum }}</view>
+					<view class="luckyNum" v-else>{{ info.plainLuckyNum }}</view>
 				</view>
 			</view>
 			<view class="lucky-title">
@@ -14,11 +14,13 @@
 				<view class="id">盲票序列号:{{ info.serialNo }}</view>
 			</view>
 			<view class="flex lucky-btn">
-				<view class="pay" @click="pay">支付{{ info.facePrice / 100 }}元 立即查看</view>
+				<view class="pay" @click="pay" v-if="info.status == 1">支付{{ info.facePrice / 100 }}元 立即查看</view>
+				<view class="pay" @click="screen" v-else>保存至手机相册</view>
 			</view>
+			<view class="index" @click="toIndex">去首页</view>
 		</view>
-		
-		<pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" />
+
+		<pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" @success="getDetailInfo" />
 	</view>
 </template>
 
@@ -27,7 +29,7 @@
 	import $http from '@/utils/request.js'
 	import PayPopup from '../../components/pay-popup/pay-popup.vue'
 	export default {
-		components:{
+		components: {
 			PayPopup
 		},
 		data() {
@@ -46,42 +48,78 @@
 
 		methods: {
 			getDetail() {
+				uni.showLoading({
+					title: '加载中'
+				});
 				$http.post('/api/v1/mp/user/ticket/queryLuckyNum', {
-					serialNo: 'T2200044-0003-0000021',
+					serialNo: this.serialNo,
 					noToken: true
 				}).then(res => {
-					console.log(res);
+					uni.hideLoading();
 					if (res.code == 0) {
-						this.info = res.data
+						if(res.data.status == 1){
+							this.info = res.data
+						}else{
+							uni.redirectTo({
+								url: `/pages/choice/index?id=${ res.data.ticketId }`
+							})
+						}
 					}
+				}).catch(() => {
+					uni.hideLoading();
 				})
 			},
 			
+			getDetailInfo() {
+				this.payShow = false
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post('/api/v1/mp/user/ticket/queryLuckyNum', {
+					serialNo: this.serialNo,
+					noToken: true
+				}).then(res => {
+					uni.hideLoading();
+					if (res.code == 0) {
+						this.info = res.data
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
 			close() {
 				this.payShow = false
 			},
-			
-			pay(){
+
+			pay() {
 				let data = {
-					couponIds: [],
-					autoCoupon: 1,
-					boxId: this.info.boxId,
 					ticketId: this.info.ticketId,
-					orderNum: 1
+					autoCoupon: 1
 				}
 				$http.post('/api/v1/mp/user/ticket/order/settle', data).then(res => {
 					console.log(res);
 					if (res.code == 0) {
 						let info = {
-							... res.data,
-							picUrl: env.filePublic + picUrl,
+							...res.data,
+							picUrl: env.filePublic + res.data.picUrl,
 						}
 						this.payInfo = info
 						this.payShow = true
 						console.log(info);
 					}
 				})
-			}
+			},
+
+			screen() {
+
+			},
+
+			toIndex() {
+				uni.switchTab({
+					url: '/pages/index/index'
+				})
+			},
 		}
 	}
 </script>
@@ -94,7 +132,8 @@
 
 		&-number {
 			padding-top: 400rpx;
-			&-circle{
+
+			&-circle {
 				box-sizing: border-box;
 				flex-direction: column;
 				width: 336rpx;
@@ -102,35 +141,41 @@
 				background-color: $uni-bg-color;
 				border-radius: 50%;
 				margin: auto;
-				
-				.title{
+
+				.title {
 					margin-bottom: 20rpx;
 				}
-				
-				.num{
+
+				.num {
 					font-size: 100rpx;
 				}
+
+				.luckyNum {
+					font-size: 36rpx;
+				}
 			}
 		}
-		
-		&-title{
+
+		&-title {
 			margin-top: 40rpx;
 			margin-bottom: 70rpx;
-			.txt{
+
+			.txt {
 				text-align: center;
 				font-size: 36rpx;
 				font-weight: bold;
 				line-height: 50rpx;
 				margin-bottom: 8rpx;
 			}
-			.id{
+
+			.id {
 				line-height: 40rpx;
 				text-align: center;
 			}
 		}
-		
-		&-btn{
-			.pay{
+
+		&-btn {
+			.pay {
 				width: 400rpx;
 				height: 60rpx;
 				line-height: 60rpx;
@@ -140,5 +185,12 @@
 				text-align: center;
 			}
 		}
+		
+		.index{
+			margin: 60rpx 0;
+			text-align: center;
+			font-weight: bold;
+			color: $uni-color-primary;
+		}
 	}
 </style>

+ 40 - 0
pages/prize/index.vue

@@ -103,6 +103,8 @@
 </template>
 
 <script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
 	export default {
 		data() {
 			return {
@@ -114,9 +116,45 @@
 				state: 0,
 				checked: false,
 
+				pageNum: 1,
+				total: 0,
+				list: [],
 			};
 		},
+		onLoad() {
+			this.getList()
+		},
 		methods: {
+			getList() {
+				let url = this.state == 0 ? '/api/v1/mp/user/mine/prize/list' : '/api/v1/mp/user/mine/coupon/list'
+				let data = this.state == 0 ? {} : {
+					status: 1
+				}
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post(`${ url }?pageNum=${this.pageNum}&pageSize=20`, data).then(res => {
+					uni.hideLoading();
+					console.log(res);
+					return
+					if (res.code == 0) {
+						res.rows.forEach(item => {
+							item.picUrl = env.filePublic + item.picUrl
+						})
+						this.total = res.total
+						this.list = this.list.concat(res.rows)
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
+			pageList() {
+				this.pageNum = 1
+				this.list = []
+				this.getList()
+			},
+
 			// 切换奖品
 			changeTab(e) {
 				if (e.index == 0) {
@@ -124,6 +162,7 @@
 				} else if (e.index == 1) {
 					this.state = 1
 				}
+				this.pageList()
 			},
 
 			changeChecked() {
@@ -153,6 +192,7 @@
 		width: 100%;
 		padding-bottom: 16rpx;
 		z-index: 10;
+		box-shadow: 0 5rpx 5rpx #ececec;
 	}
 
 	.prize-goods {

+ 123 - 0
pages/prizeGoods/detail.vue

@@ -0,0 +1,123 @@
+<template>
+	<view>
+		<u-navbar :placeholder="true" bgColor="#fff" :autoBack="true" :border="true" title="奖品详情"></u-navbar>
+		<view class="detail">
+			<view class="detail-top">
+				<u-swiper :list="picUrlArr" height="320" :indicator="true" :circular="true"></u-swiper>
+			</view>
+			<view class="detail-info">
+				<view class="content">零跑C11电动汽车新能源车整车国产中型SUV C11性能版</view>
+			</view>
+			<view class="detail-title">商品详情</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
+	export default {
+		data() {
+			return {
+				boxId: '',
+				picUrlArr: [
+					'https://cdn.uviewui.com/uview/swiper/swiper1.png',
+					'https://cdn.uviewui.com/uview/swiper/swiper2.png',
+					'https://cdn.uviewui.com/uview/swiper/swiper3.png',
+				],
+				info: {},
+				prizeList: [],
+
+				payShow: false,
+				payInfo: {}
+			};
+		},
+		onLoad(opthios) {
+			// this.getDetail(opthios.id)
+		},
+		methods: {
+			getDetail(id) {
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post('/api/v1/mp/channel/mall/ticket/detail', {
+					boxId: id
+				}).then(res => {
+					uni.hideLoading();
+					console.log(res);
+					if (res.code == 0) {
+						this.info = res.data
+						let picUrlArr = res.data.picUrl.split(',')
+						picUrlArr.forEach(item => {
+							this.picUrlArr.push(env.filePublic + item)
+						})
+
+						let prizeList = res.data.prizeList
+						console.log(prizeList);
+
+						prizeList.forEach(item => {
+							item.picUrl = env.filePublic + item.picUrl
+						})
+
+						this.prizeList = prizeList
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
+			close() {
+				this.payShow = false
+			},
+
+			exchange() {
+				let data = {
+					couponIds: [],
+					autoCoupon: 1,
+					boxId: this.info.boxId,
+					ticketId: this.info.ticketId,
+					orderNum: 1
+				}
+				$http.post('/api/v1/mp/user/ticket/order/settle', data).then(res => {
+					console.log(res);
+					if (res.code == 0) {
+						let info = {
+							...res.data,
+							...this.info,
+							picUrl: env.filePublic + res.data.picUrl,
+						}
+						this.payInfo = info
+						this.payShow = true
+						console.log(info);
+					}
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.detail {
+		padding-bottom: 100rpx;
+		
+		&-info{
+			padding: 50rpx 20rpx 50rpx;
+			margin-bottom: 10rpx;
+			background-color: #fff;
+			
+			.content{
+				font-size: 32rpx;
+				font-weight: bold;
+			}
+		}
+		
+		&-title{
+			height: 88rpx;
+			text-align: center;
+			line-height: 88rpx;
+			font-weight: bold;
+			background-color: #FFFFFF;
+		}
+
+	}
+</style>

+ 93 - 0
pages/process/index.vue

@@ -0,0 +1,93 @@
+<template>
+	<view>
+		<u-navbar title="兑奖" :border="true" :placeholder="true" :autoBack="true" bgColor="#fff" />
+		<view class="process">
+			<view class="flex box-wrap">
+				<view class="box">
+					<view class="hand">
+						<view class="ing" @click="toChoice">刮开测手气</view>
+					</view>
+				</view>
+			</view>
+			<view class="btn" @click="put">放入我的票包,暂不兑奖</view>
+		</view>
+	</view>
+</template>
+
+<script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
+	export default {
+		data() {
+			return {
+				id: ''
+			};
+		},
+		onLoad(options) {
+			this.id = options.id
+		},
+		methods: {
+			put() {
+				uni.navigateBack({
+					delta: 1
+				})
+			},
+
+			toChoice() {
+				uni.redirectTo({
+					url: `/pages/choice/index?id=${ this.id }`
+				})
+			},
+		}
+	}
+</script>
+
+<style lang="scss" scoped>
+	.process {
+		width: 100%;
+		height: calc(100vh - 50px);
+		background: url(https://gimg2.baidu.com/image_search/src=http%3A%2F%2Fpic3.zhimg.com%2F50%2Fv2-a6f5c8b5b66fe87e4e79c1fc82a61a36_hd.jpg&refer=http%3A%2F%2Fpic3.zhimg.com&app=2002&size=f9999,10000&q=a80&n=0&g=0n&fmt=auto?sec=1649658373&t=f216ee4825d5b36e62aa3a490516bfb1) center center;
+	}
+
+	.box-wrap {
+		padding: 100rpx 0 100rpx;
+
+		.box {
+			position: relative;
+			width: 80%;
+			height: 900rpx;
+			background-color: $uni-bg-color;
+		}
+
+		.hand {
+			position: absolute;
+			bottom: 20rpx;
+			width: 100%;
+			height: 100rpx;
+
+			.ing {
+				margin: auto;
+				width: 80%;
+				height: 100rpx;
+				text-align: center;
+				line-height: 100rpx;
+				font-size: 50rpx;
+				font-weight: bold;
+				background-color: #FFFFFF;
+			}
+		}
+	}
+
+	.btn {
+		margin: auto;
+		width: 380rpx;
+		height: 60rpx;
+		line-height: 60rpx;
+		border-radius: 8rpx;
+		color: rgba(140, 140, 140, 100);
+		font-size: 28rpx;
+		text-align: center;
+		border: 1px solid rgba(140, 140, 140, 100);
+		background-color: #FFFFFF;
+	}
+</style>

+ 76 - 14
pages/ticket/index.vue

@@ -16,25 +16,30 @@
 		<!-- 兑奖列表 -->
 		<view class="prize-coupon">
 			<view class="prize-coupon-list">
-				<view class="flex prize-coupon-list-item">
-					<image src="../../static/logo.png" mode=""></image>
+				<view class="flex prize-coupon-list-item" v-for="(item, index) in list" :key="index">
+					<image :src="item.picUrl" mode="aspectFill"></image>
 					<view class="flex info">
 						<view class="flex desc">
-							<view class="title">零跑汽车盲票</view>
-							<view class="txt">面值:10元</view>
-							<view class="txt">序列号:1212121212121212</view>
+							<view class="title">{{ item.title }}</view>
+							<view class="txt">面值:{{ item.facePrice / 100 }}元</view>
+							<view class="txt">序列号:{{ item.serialNo }}</view>
 						</view>
 						<view class="flex btn">
-							<view class="action">立即开刮</view>
+							<view class="action" @click="toChoice(item)" v-if="item.status == '2'">立即开刮</view>
 						</view>
 					</view>
 				</view>
 			</view>
+			<view class="flex empty" v-if="!list.length">
+				<u-empty text="数据为空" mode="order" />
+			</view>
 		</view>
 	</view>
 </template>
 
 <script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
 	export default {
 		data() {
 			return {
@@ -43,22 +48,74 @@
 				}, {
 					name: '已兑奖',
 				}],
-				state: 0,
+				state: 2,
+				pageNum: 1,
+				total: 0,
+				list: [],
 			};
 		},
+		onShow() {
+			this.pageList()
+		},
 		methods: {
+			getList() {
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post(`/api/v1/mp/user/mine/ticket/list?pageNum=${this.pageNum}&pageSize=20`, {
+					status: this.state
+				}).then(res => {
+					uni.hideLoading();
+					console.log(res);
+					if (res.code == 0) {
+						res.rows.forEach(item => {
+							item.picUrl = env.filePublic + item.picUrl
+						})
+						this.total = res.total
+						this.list = this.list.concat(res.rows)
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
+			pageList() {
+				this.pageNum = 1
+				this.list = []
+				this.getList()
+			},
+
+			toChoice(item) {
+				uni.navigateTo({
+					url: `/pages/choice/index?id=${ item.ticketId }`
+				})
+			},
+
 			changeTab(e) {
 				if (e.index == 0) {
-					this.state = 0
+					this.state = 2
 				} else if (e.index == 1) {
-					this.state = 1
+					this.state = 3
 				}
+				this.pageList()
 			},
 
 			changeChecked() {
 
 			},
-		}
+		},
+
+		onReachBottom() {
+			// 判断是否有数据
+			if (this.total > this.pageNum * 20) {
+				setTimeout(() => {
+					++this.pageNum
+					this.getList()
+				}, 500)
+			} else {
+				uni.$u.toast('没有更多数据了')
+			}
+		},
 	}
 </script>
 
@@ -69,11 +126,12 @@
 		width: 100%;
 		padding-bottom: 16rpx;
 		z-index: 10;
+		box-shadow: 0 5rpx 5rpx #ececec;
 	}
 
 	.prize-coupon {
 		margin-top: 104rpx;
-		padding: 40rpx 30rpx 100rpx;
+		padding: 40rpx 30rpx 140rpx;
 
 		&-list {
 
@@ -82,7 +140,7 @@
 				background-color: #FFFFFF;
 				padding: 40rpx 20rpx;
 				border-radius: 10rpx;
-				margin-bottom: 40rpx;
+				margin-bottom: 24rpx;
 
 				image {
 					width: 124rpx;
@@ -120,8 +178,8 @@
 				text {
 					font-size: 24rpx;
 				}
-				
-				.action{
+
+				.action {
 					width: 124rpx;
 					height: 40rpx;
 					line-height: 40rpx;
@@ -138,4 +196,8 @@
 			}
 		}
 	}
+
+	.empty {
+		height: 60vh;
+	}
 </style>

+ 55 - 31
pages/ticketBox/detail.vue

@@ -15,14 +15,15 @@
 					<view class="tip">图片仅供参考,请以实物为准</view>
 				</view>
 				<view class="detail-info__right">
-					<text class="money">¥{{ $numberFormat(info.pkgSalePrice) }}</text>
+					<text class="money">¥{{ $numberFormat(info.salePrice) }}</text>
 					<text>销量 {{ info.saleQty }}</text>
 				</view>
 			</view>
 			<view class="detail-goods">
-				<view class="detail-goods-title">可获得品</view>
+				<view class="detail-goods-title">可获得品</view>
 				<view class="detail-goods-list">
-					<view class="detail-goods-list-item" v-for="(item, index) in prizeList" :key="index">
+					<navigator :url="`/pages/prizeGoods/detail?id=${ item.prizeId }`" class="detail-goods-list-item"
+						hover-class="navigator-hover" v-for="(item, index) in prizeList" :key="index">
 						<view class="detail-goods-list-item__value">
 							<view class="flex image-wrap">
 								<image :src="item.picUrl" mode="scaleToFill"></image>
@@ -34,7 +35,7 @@
 							</view>
 							<view class="name">{{ item.name }}</view>
 						</view>
-					</view>
+					</navigator>
 				</view>
 			</view>
 		</view>
@@ -43,8 +44,8 @@
 				<button type="default" @click="exchange">10元 立即开刮</button>
 			</view>
 		</view>
-		
-		<pay-popup :pay-show="payShow" @close="close" />
+
+		<pay-popup :pay-show="payShow" :pay-info="payInfo" @close="close" @success="toProcess" />
 	</view>
 </template>
 
@@ -59,35 +60,27 @@
 		data() {
 			return {
 				boxId: '',
-				picUrlArr: ['https://z3.ax1x.com/2021/03/05/6ehghR.jpg', 'https://z3.ax1x.com/2021/03/05/6ehghR.jpg'],
-				info: {
-					title: '测试11',
-					saleCommRate: 12,
-					pkgSalePrice: 12,
-					saleQty: 1234,
-					pkgUnit: 123,
-					facePrice: 1234,
-					
-				},
-				prizeList: [{
-					title: '测试1',
-					value: 1000,
-					picUrl: 'https://z3.ax1x.com/2021/03/05/6ehghR.jpg',
-					hitRate: 0.11,
-					name: '测试一'
-				}],
-				
+				picUrlArr: [],
+				info: {},
+				prizeList: [],
+
 				payShow: false,
+				payInfo: {}
 			};
 		},
 		onLoad(opthios) {
-			// this.getDetail(opthios.boxId)
+			this.getDetail(opthios.id)
 		},
 		methods: {
 			getDetail(id) {
+				uni.showLoading({
+					title: '加载中'
+				});
 				$http.post('/api/v1/mp/channel/mall/ticket/detail', {
 					boxId: id
 				}).then(res => {
+					uni.hideLoading();
+					console.log(res);
 					if (res.code == 0) {
 						this.info = res.data
 						let picUrlArr = res.data.picUrl.split(',')
@@ -96,6 +89,7 @@
 						})
 
 						let prizeList = res.data.prizeList
+						console.log(prizeList);
 
 						prizeList.forEach(item => {
 							item.picUrl = env.filePublic + item.picUrl
@@ -103,6 +97,8 @@
 
 						this.prizeList = prizeList
 					}
+				}).catch(() => {
+					uni.hideLoading();
 				})
 			},
 
@@ -110,8 +106,34 @@
 				this.payShow = false
 			},
 			
+			toProcess(id) {
+				this.payShow = false
+				uni.navigateTo({
+					url: `/pages/process/index?id=${ id }`
+				})
+			},
+
 			exchange() {
-				this.payShow = true
+				let data = {
+					couponIds: [],
+					autoCoupon: 1,
+					boxId: this.info.boxId,
+					ticketId: this.info.ticketId,
+					orderNum: 1
+				}
+				$http.post('/api/v1/mp/user/ticket/order/settle', data).then(res => {
+					console.log(res);
+					if (res.code == 0) {
+						let info = {
+							...res.data,
+							...this.info,
+							picUrl: env.filePublic + res.data.picUrl,
+						}
+						this.payInfo = info
+						this.payShow = true
+						console.log(info);
+					}
+				})
 			},
 		}
 	}
@@ -156,8 +178,8 @@
 					justify-content: flex-start;
 					margin: 20rpx 0;
 				}
-				
-				.tip{
+
+				.tip {
 					font-size: 24rpx;
 				}
 			}
@@ -212,12 +234,13 @@
 			}
 
 			&-list {
-				background-color: #FFFFFF;
 
 				&-item {
 					position: relative;
-					margin: 16rpx 0;
-					border-bottom: 1px solid rgba(236, 236, 236, 100);
+					background-color: #FFFFFF;
+					margin-bottom: 40rpx;
+					border-radius: 10rpx;
+
 
 					&__value {
 						display: flex;
@@ -238,6 +261,7 @@
 						position: absolute;
 						line-height: 28rpx;
 						padding: 6rpx 20rpx;
+						color: #FFFFFF;
 						background-color: $uni-bg-color;
 					}
 

+ 110 - 2
pages/ticketBox/index.vue

@@ -1,19 +1,127 @@
 <template>
 	<view>
 		<u-navbar :placeholder="true" bgColor="#fff" :autoBack="true" :border="true" title="盲票列表"></u-navbar>
+		<view class="ticket-box">
+			<view class="flex ticket-box-list">
+				<navigator :url="`/pages/ticketBox/detail?id=${ item.boxId }`" class="flex ticket-box-list-item"
+					hover-class="navigator-hover" v-for="(item, index) in list" :key="index">
+					<image :src="item.picUrl" mode="aspectFill"></image>
+					<view class="info">
+						<view class="title">{{ item.title }}</view>
+						<view class="price">¥{{ $numberFormat(item.salePrice) }}</view>
+					</view>
+				</navigator>
+				<view class="ticket-box-list-item"></view>
+			</view>
+			<view class="flex empty" v-if="!list.length">
+				<u-empty text="数据为空" mode="order" />
+			</view>
+		</view>
 	</view>
 </template>
 
 <script>
+	import env from '../../config/env.js'
+	import $http from '@/utils/request.js'
 	export default {
 		data() {
 			return {
-				
+				pageNum: 1,
+				total: 0,
+				list: [],
 			};
-		}
+		},
+		onLoad() {
+			this.getList()
+		},
+		methods: {
+			getList() {
+				uni.showLoading({
+					title: '加载中'
+				});
+				let data = {
+					categoryId: '',
+					tagId: '',
+					type: 'online',
+					noToken: true
+				}
+				$http.post(`/api/v1/mp/user/mall/ticket/list?pageNum=${this.pageNum}&pageSize=20`, data).then(
+					res => {
+						uni.hideLoading();
+						if (res.code == 0) {
+							res.rows.forEach(item => {
+								let picUrlArr = item.picUrl.split(',')
+								item.picUrl = env.filePublic + picUrlArr[0]
+							})
+							this.total = res.total
+							this.list = this.list.concat(res.rows)
+						}
+					}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+		},
+
+		onReachBottom() {
+			// 判断是否有数据
+			if (this.total > this.pageNum * 20) {
+				setTimeout(() => {
+					++this.pageNum
+					this.getList()
+				}, 500)
+			} else {
+				uni.$u.toast('没有更多数据了')
+			}
+		},
 	}
 </script>
 
 <style lang="scss">
+	.ticket-box {
+		margin: 30rpx 0;
+
+		&-list {
+			justify-content: space-around;
+			flex-wrap: wrap;
+			padding-bottom: 100rpx;
+
+			&-item {
+				flex-direction: column;
+				box-sizing: border-box;
+				padding: 20rpx;
+				width: 330rpx;
+				border-radius: 10rpx;
+				margin-bottom: 40rpx;
+				border: 1px solid rgba(187, 187, 187, 25);
+
+				image {
+					width: 300rpx;
+					height: 430rpx;
+					border-radius: 5px;
+				}
+
+				.info {
+					width: 100%;
+				}
 
+				.title {
+					line-height: 42rpx;
+					margin: 10rpx 0 10rpx;
+				}
+
+				.price {
+					line-height: 42rpx;
+					color: #EB7009;
+				}
+			}
+
+			&-item:last-child {
+				border: none;
+			}
+		}
+		
+		.empty{
+			height: 60vh;
+		}
+	}
 </style>

+ 34 - 15
pages/user/index.vue

@@ -14,15 +14,15 @@
 			</view>
 			<view class="flex account-info" v-if="loginState">
 				<navigator url="/pages/prize/index" class="flex account-info-item" hover-class="navigator-hover">
-					<view>7</view>
+					<view>{{ initData.prizeNum }}</view>
 					<view>我的奖品库</view>
 				</navigator>
 				<navigator url="/pages/ticket/index" class="flex account-info-item" hover-class="navigator-hover">
-					<view>7</view>
+					<view>{{ initData.ticketNum }}</view>
 					<view>我的盲票包</view>
 				</navigator>
 				<navigator url="/pages/bean/index" class="flex account-info-item" hover-class="navigator-hover">
-					<view>7</view>
+					<view>{{ initData.coinNum }}</view>
 					<view>我的盲豆</view>
 				</navigator>
 			</view>
@@ -56,7 +56,7 @@
 		</view>
 
 		<custom-tab-bar :activeValue="'user'" />
-		
+
 	</view>
 </template>
 
@@ -79,6 +79,7 @@
 				certifyStatus: {},
 				info: {},
 				authShow: false,
+				initData: {},
 			};
 		},
 
@@ -86,47 +87,65 @@
 			this.loginState = uni.getStorageSync('token') ? true : false
 			this.userInfo = uni.getStorageSync('userInfo')
 			this.avatar = env.filePublic + this.userInfo.avatar
+			if (this.loginState) {
+				this.getInit()
+			}
 		},
 
 		methods: {
+			// 我的数据
+			getInit() {
+				uni.showLoading({
+					title: '加载中'
+				});
+				$http.post('/api/v1/mp/user/mine/init', {}).then(res => {
+					uni.hideLoading();
+					if (res.code == 0) {
+						this.initData = res.data
+					}
+				}).catch(() => {
+					uni.hideLoading();
+				})
+			},
+
 			// 跳转登录
 			toLogin() {
 				uni.navigateTo({
 					url: "/pages/login/index"
 				})
 			},
-			
+
 			// 我的订单
-			toOrder(){
-				if(!this.loginState){
+			toOrder() {
+				if (!this.loginState) {
 					uni.$u.toast('请登录!');
 					return
 				}
 				uni.navigateTo({
-					url:'/pages/order/index'
+					url: '/pages/order/index'
 				})
 			},
-			
+
 			// 我的地址
-			toAddress(){
-				if(!this.loginState){
+			toAddress() {
+				if (!this.loginState) {
 					uni.$u.toast('请登录!');
 					return
 				}
 				uni.navigateTo({
-					url:'/pages/address/index'
+					url: '/pages/address/index'
 				})
 			},
-			
+
 			// 没有登录
-			notLogin(){
+			notLogin() {
 				uni.$u.toast('请登录!');
 			},
 
 			// 注销登录
 			logout() {
 				let _this = this
-				if(!this.loginState){
+				if (!this.loginState) {
 					uni.$u.toast('已注销登录!');
 					return
 				}

+ 2 - 1
utils/request.js

@@ -37,7 +37,8 @@ const $http = (url, data, methods) => {
 					uni.removeStorageSync('token')
 					uni.showModal({
 						title: '提示',
-						content: '登录身份已过期,请重新登录!',
+						content: '您未登录或登录失效!',
+						confirmText: '去登录',
 						success(res) {
 							if (res.confirm) {
 								uni.navigateTo({