feat(mall): 添加抽奖功能及部分页面和接口

- 新增奖品领取页面及其相关接口。
- 添加抽奖页面及中奖结果展示页面。
- 实现抽奖规则和已获奖品的展示功能。
- 相应地在pages.json中注册了新增的页面。
- 调整了.env.development中的API基础URL。
- 优化了部分页面的样式和布局。
- 代码中删除了未使用的奖品图片资源。

BREAKING CHANGE: 删除了部分奖品图片资源,如果前端仍然引用这些图片,需要做相应的调整。
main
lenovo008\lenovo 4 months ago
parent 5a07db3cdb
commit c70765bdf6

@ -1 +1,2 @@
SHOPRO_DEV_BASE_URL = https://yanghaodong.51vip.biz # SHOPRO_DEV_BASE_URL = https://yanghaodong.51vip.biz
SHOPRO_DEV_BASE_URL = http://192.168.1.129:48080

@ -261,6 +261,42 @@
"group": "用户中心" "group": "用户中心"
} }
}, },
{
"path": "prize",
"style": {
"navigationBarTitleText": "抽奖"
},
"meta": {
"auth": true,
"sync": true,
"title": "抽奖活动",
"group": "用户中心"
}
},
{
"path": "PrizesWon",
"style": {
"navigationBarTitleText": "已获奖品"
},
"meta": {
"auth": true,
"sync": true,
"title": "抽奖活动",
"group": "用户中心"
}
},
{
"path": "ActivityRules",
"style": {
"navigationBarTitleText": "活动规则"
},
"meta": {
"auth": true,
"sync": true,
"title": "活动规则",
"group": "用户中心"
}
},
{ {
"path": "goods-collect", "path": "goods-collect",
"style": { "style": {

@ -0,0 +1,39 @@
<template>
<view>
<s-layout class="set-wrap" title="抽奖规则" :bgStyle="{ color: '#FFF' }">
<!-- <view class="ss-p-30">
<mp-html class="richtext" :content="state.content" />
</view> -->
<rich-text :nodes="data"></rich-text>
</s-layout>
</view>
</template>
<script setup>
import { ref } from 'vue'
import MineApi from '@/sheep/api/prize/index'
import { onLoad, onReachBottom, onShow, onUnload, onHide } from '@dcloudio/uni-app';
const data = ref()
const getActivityRules = async () => {
const res = await MineApi.ActivityRules()
data.value = res.data.name
// data.value = res.data.value = res.result.content.replace(
// /<img(.*?)\s*width=".*?"\s*height=".*?"\s*\/?>/g,
// '<img$1 style="max-width: 100%;" />'
// )
// data.value = data.value.replace(/style="display: block; margin-left: auto; margin-right: auto;"/g, '')
}
onShow(() => {
getActivityRules()
})
</script>
<style lang="scss" scoped>
</style>

@ -0,0 +1,186 @@
<template>
<s-layout class="set-wrap" title="已获奖品" :bgStyle="{ color: '#FFF' }">
<view>
<view class="_thWrap" v-for="(item, index) in list" :key="item.id">
<view class="_cont">
<view class="_left">
<image class="_img" :src="item.imgUrl"></image>
</view>
<view class="_right">
<view class="_h4">
<text>奖品名称{{ item.name }}</text>
</view>
<view class="_h4">
<text>获得时间{{ formattedDateTime(item.createTime) }}</text>
</view>
</view>
</view>
</view>
</view>
</s-layout>
</template>
<script setup>
import { ref, } from 'vue'
import MineApi from '@/sheep/api/prize/index'
// import layOut from '@/components/layout.vue'
import { onLoad, onReachBottom, onShow, onUnload, onHide } from '@dcloudio/uni-app';
const list = ref()
//
const getPrizesWon = async () => {
const r = await MineApi.ActivityRules()
let HDid = r.data?.id
const res = await MineApi.PrizesWon(HDid)
list.value = res.data
}
const formattedDateTime = (timestampInMilliseconds) => {
const date = new Date(timestampInMilliseconds);
const year = date.getFullYear();
const month = ('0' + (date.getMonth() + 1)).slice(-2);
const day = ('0' + date.getDate()).slice(-2);
const hours = ('0' + date.getHours()).slice(-2);
const minutes = ('0' + date.getMinutes()).slice(-2);
const seconds = ('0' + date.getSeconds()).slice(-2);
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
};
onShow(async () => {
await getPrizesWon()
})
</script>
<style lang="scss" scoped>
page {
background-color: white;
}
.tabs {
display: flex;
justify-content: space-evenly;
height: 100rpx;
line-height: 90rpx;
font-size: 28rpx;
border-radius: 10rpx;
box-shadow: 0 4rpx 5rpx rgba(200, 200, 200, 0.3);
color: #333;
background-color: #fff;
z-index: 9;
.text {
margin: 0 20rpx;
position: relative;
font-size: 32rpx;
}
.active {
&::after {
content: '';
width: 70rpx;
height: 5rpx;
transform: translate(-50%);
background-color: #4376f5;
position: absolute;
left: 50%;
bottom: 24rpx;
}
}
}
._thWrap {
width: 100%;
border-bottom: 2rpx solid rgba(242, 242, 242, 1);
padding: 20rpx 0;
}
._cont {
display: flex;
justify-content: space-between;
background: #ffffff;
border-radius: 10px;
box-shadow: 0 0 10rpx 5rpx rgba(200, 200, 200, 0.3);
padding: 10px;
flex: 1;
._left {
width: 266rpx;
height: 260rpx;
border: 2rpx solid rgba(242, 242, 242, 1);
text-align: center;
._img {
width: 265rpx;
height: 250rpx;
}
}
._right {
margin-left: 30rpx;
padding-top: 10rpx;
._h4 {
padding-top: 50rpx;
._h5 {
margin-bottom: 10rpx;
}
._h5Two {
font-size: 35rpx;
margin-bottom: 10rpx;
}
._tips {
color: #aaaaaa;
font-size: 22rpx;
}
._tipsTwo {
color: #565353;
font-size: 30rpx;
}
}
.danjia {
display: block;
color: red;
font-size: 25rpx;
// font-weight: bolder;
margin-top: 60rpx;
text {
font-size: 15rpx;
}
}
}
// ._bo {
// margin-top: 20rpx;
// display: flex;
// justify-content: space-between;
// align-items: center;
// ._money {
// color: red($color: #a9a8a8);
// // font-weight: bold;
// font-size: 20rpx;
// margin-right: 16rpx;
// text {
// font-size: 28rpx;
// }
// }
// ._btn {
// width: 192rpx;
// height: 62rpx;
// line-height: 62rpx;
// text-align: center;
// border-radius: 100rpx;
// color: white;
// font-weight: bold;
// background-color: $color-gray-Main;
// }
// }
}
</style>

@ -0,0 +1,421 @@
<template>
<s-layout class="set-wrap" title="活动" :bgStyle="{ color: '#FFF' }">
<view class="_bgc">
<view class="_bg1">
<!-- <text class="_jf">5积分抽奖一次</text>
<view class="_cont">
<view class="_left">
<image src="https://obs-sdwh.cucloud.cn/cdz/jinbi.png" class="_jinbi"></image>
<text>开心贷</text>
</view>
<view class="_mid">抽到99元优惠券</view>
<view class="_right">4秒前</view>
</view> -->
</view>
<view class="container">
<!-- <view class="container_circle" v-for="(v, i) in circleList" :key="i"
:style="{ 'top': v.topCircle + 'rpx', 'left': v.leftCircle + 'rpx', 'background-color': (i % 2 == 0) ? oneCircleColor : twoCircleColor }">
</view> -->
<view class="container_content">
<view class="content_out" v-for="(v, i) in prizeList" :key="i" :style="{
top: v.topAward + 'rpx',
left: v.leftAward + 'rpx',
background: i == indexSelect ? prizeCheckColor : '',
animation: 'animatebox 4s linear infinite'
}">
<image class="award_image" :src="v.Img"></image>
<!-- {{ v.name }} -->
</view>
<view class="content_btn" @tap="handleStart"
:style="{ 'background-color': isRunning ? '#55ffff' : '' }">
<view class="_diji">点击</view>
<view>抽奖</view>
</view>
</view>
<!-- <view class="container_num">剩余抽奖次数{{ luckDrawNum }}</view> -->
</view>
<view class="_btnWrap">
<view class="_btn" @tap="sheep.$router.go('/pages/user/PrizesWon')"></view>
<view class="_btn" @tap="sheep.$router.go('/pages/user/ActivityRules')"></view>
</view>
</view>
</s-layout>
</template>
<script setup>
import { ref } from 'vue'
import { onLoad, onReachBottom, onShow, onUnload, onHide } from '@dcloudio/uni-app';
import MineApi from '@/sheep/api/prize/index'
import sheep from '@/sheep';
const prizeList = ref([]) //
const prizeCheckColor = ref('linear-gradient(72.5deg, #aa0000, #ff0000, #ff00ff, #550000, #ffaaff, #aa0000, #ff0000)') //
const indexSelect = ref(0) //index
const isRunning = ref(false) //
const imgList = ref([
'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202209261921_a1b840c267bd26bcf4dc654d52f259e5.png?w=800&h=800',
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/0bcd64f412dfb5e15695fa96d21ecb23.png?w=800&h=800',
'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202208111030_e3554c41e0484da99b16bb9e02142e68.png?w=800&h=800',
'https://cdn.cnbj0.fds.api.mi-img.com/b2c-shopapi-pms/pms_1653393310.29013051.png',
'https://cdn.cnbj1.fds.api.mi-img.com/nr-pub/202209261921_a1b840c267bd26bcf4dc654d52f259e5.png?w=800&h=800',
'https://cdn.cnbj0.fds.api.mi-img.com/b2c-shopapi-pms/9E253411E26FD16C7215D7E74321FA45.png',
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/cc0be95d45d0063b0aa8bb541be22c77.png?w=800&h=800',
'https://cdn.cnbj1.fds.api.mi-img.com/mi-mall/0c4b5e30d14ca8b51dc6fa6917295ff5.png?w=800&h=800'
]) //
const prizelist = ref([]) //
let showFloag = ref(true)
let HDid = ref()
onLoad(async () => {
const r = await MineApi.ActivityRules()
HDid.value = r.data?.id
const res = await MineApi.prizeImg(HDid.value)
prizelist.value = res.data
imgList.value = []
res.data.forEach((value, index) => {
imgList.value.push(value.imgUrl)
})
for (let i = 0; i < 24; i++) {
let prizeList_on = []
//,.
let topAward = 10
let leftAward = 10
for (let j = 0; j < 8; j++) {
if (j == 0) {
topAward = 5
leftAward = 10
} else if (j < 3) {
topAward = topAward
//166.6666.15.
leftAward = leftAward + 176.6666 + 15
} else if (j < 5) {
leftAward = leftAward
//150,15,
topAward = topAward + 160 + 15
} else if (j < 7) {
leftAward = leftAward - 176.6666 - 15
topAward = topAward
} else if (j < 8) {
leftAward = leftAward
topAward = topAward - 160 - 15
}
// let imgList = this.imgList[j];
let Img = imgList.value[j]
prizeList_on.push({ topAward, leftAward, Img, id: res.data[j].id, name: res.data[j].name })
}
prizeList.value = prizeList_on
}
})
//
const handleStart = async () => {
console.log('抽奖开始,');
if (isRunning.value) return
const res = await MineApi.lottery(HDid.value)
isRunning.value = true
let floag = ref()
for (let i = 0; i < prizelist.value.length; i++) {
if (prizelist.value[i]?.id == res.data?.id) {
floag.value = res.data.id
break
}
}
indexSelect.value = 0
let indexSelect_med = 0
let i = 0
let timer = setInterval(() => {
console.log('floag', floag.value);
//
if (!showFloag.value) {
clearInterval(timer)
isRunning.value = false
}
indexSelect_med++
//
indexSelect_med = indexSelect_med % 8
indexSelect.value = indexSelect_med
i += 30
let randomNum = 1000 + Math.ceil(Math.random() * 1000) //
if (i > randomNum && prizeList.value[indexSelect.value].id === floag.value) {
//
clearInterval(timer)
//
// if (showFloag.value) {
// if (!res.data?.id) {
// uni.showModal({
// title: '',
// content: '',
// showCancel: false,
// success: (res) => {
// if (res.confirm) {
// isRunning.value = false
// }
// }
// })
// return
// }
uni.showModal({
// title: '',
// content: '' + (indexSelect.value) + '',
content: '抽中' + (res.data.name) + '',
showCancel: false,
success: (res) => {
if (res.confirm) {
isRunning.value = false
}
}
})
// }
isRunning.value = false
}
}, 200 + i)
}
onHide(() => {
showFloag.value = false
})
onUnload(() => {
showFloag.value = false
})
onShow(() => {
showFloag.value = true
})
</script>
<style lang="scss" scoped>
._bg1 {
background-image: url('https://obs-sdwh.cucloud.cn/cdz/beijing1.png');
width: 80%;
height: 150rpx;
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
margin: 370rpx auto 0;
font-size: 22rpx;
position: relative;
._jf {
position: absolute;
left: 240rpx;
top: 40rpx;
color: white;
}
._cont {
display: flex;
justify-content: space-around;
align-items: center;
color: white;
letter-spacing: 2rpx;
height: 100%;
margin-top: 35rpx;
._left {
display: flex;
align-items: center;
._jinbi {
width: 40rpx;
height: 40rpx;
margin-right: 10rpx;
}
}
}
}
._bgc {
background-image: url('https://obs-sdwh.cucloud.cn/cdz/cjBg.png');
width: 100%;
height: 100vh;
background-repeat: no-repeat;
background-size: 100% 100%;
overflow: hidden;
}
.container {
position: relative;
height: 600rpx;
width: 650rpx;
margin: 0 auto;
border-radius: 40rpx;
// background: linear-gradient(72.5deg, #e9f78c, #ffffb9, #cc55e5, #ef9bcb, #e5b8d8, #ffb140, #f7ed54);
// background-color: #FFB62F;
background-image: url('https://obs-sdwh.cucloud.cn/cdz/beijing2.png');
background-repeat: no-repeat;
background-size: 100% 100%;
// background-size: 400%;
animation: animatebox 4s linear infinite;
@keyframes animatebox {
0% {
background-position: 0%;
}
50% {
background-position: 100%;
}
100% {
background-position: 0%;
}
}
.container_circle {
position: absolute;
display: block;
border-radius: 50%;
height: 20rpx;
width: 20rpx;
}
.container_content {
position: absolute;
left: 0;
right: 0;
top: 0;
bottom: 0;
width: 580rpx;
height: 530rpx;
background-color: #ca2c01;
border-radius: 40rpx;
margin: auto;
// background: linear-gradient(72.5deg, #ef499c, #cc55e5, #ffb140, #f7ed54, #ffb140, #cc55e5, #ef499c);
background-size: 400%;
animation: animate1 4s linear infinite;
@keyframes animate1 {
0% {
background-position: 0%;
}
50% {
background-position: 100%;
}
100% {
background-position: 0%;
}
}
.content_out {
position: absolute;
height: 160rpx;
width: 176.6666rpx;
// background-color: #f5f0fc;
background-image: url('https://obs-sdwh.cucloud.cn/cdz/g1.png');
background-repeat: no-repeat;
background-size: 100% 100%;
border-radius: 15rpx;
box-shadow: 0 5px 0 #ff8327;
.award_image {
position: absolute;
margin: auto;
top: 0;
left: 0;
bottom: 0;
right: 0;
height: 140rpx;
width: 130rpx;
background-repeat: no-repeat;
background-size: 100% 100%;
background-image: url('https://obs-sdwh.cucloud.cn/cdz/xxcy.png');
}
}
.content_btn {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 15rpx;
height: 160rpx;
width: 176.6666rpx;
background-color: #ffe400;
box-shadow: 0 5rpx 0 #e7930a;
color: white;
text-align: center;
font-size: 44rpx;
font-weight: bolder;
background-color: #ff8859;
// line-height: 150rpx;
// background: linear-gradient(72.5deg, #f7a0ec, #ffb140, #e58da0, #ef7ecb, #ab9ae5, #ffec8a, #f6f7a6);
// background-size: 400%;
background-image: url('https://obs-sdwh.cucloud.cn/cdz/g5.png');
background-size: 100% 100%;
background-repeat: no-repeat;
animation: animate 4s linear infinite;
._diji {
margin-top: 14rpx;
}
@keyframes animate {
0% {
background-position: 0%;
}
50% {
background-position: 100%;
}
100% {
background-position: 0%;
}
}
}
}
.container_num {
position: absolute;
top: -130rpx;
left: 50%;
transform: translateX(-50%);
color: white;
// background-image: -webkit-linear-gradient(left, #083a96, #e63609 25%, #083a96 50%, #e63609 75%, #083a96);
// -webkit-text-fill-color: transparent;
background-clip: text;
background-size: 200% 100%;
animation: masked-animation 4s infinite linear;
@keyframes masked-animation {
0% {
background-position: 0 0;
}
100% {
background-position: -100% 0;
}
}
}
}
._btnWrap {
display: flex;
align-items: center;
justify-content: space-around;
margin-top: 40rpx;
._btn {
background-image: url('https://obs-sdwh.cucloud.cn/cdz/anniu.png');
background-repeat: no-repeat;
background-size: 100% 100%;
width: 40%;
height: 100rpx;
text-align: center;
line-height: 90rpx;
color: white;
font-weight: bold;
font-size: 32rpx;
}
}
</style>

@ -0,0 +1,43 @@
import request from '@/sheep/request';
const PayOrderApi = {
// 开始抽奖
lottery: (id) => {
return request({
url: '/promotion/prize-draw/lottery',
method: 'GET',
params: { activityId: id },
});
},
// 已获奖品
PrizesWon: (id) => {
return request({
url: '/promotion/prize-draw/getMyPrizeLogDO',
method: 'GET',
params: { activityId: id },
});
},
// 获得抽奖照片
prizeImg: (id) => {
return request({
url: '/promotion/prize-draw/activity-prize/list-by-activity-id',
method: 'GET',
params: { activityId:id },
});
},
// 规则
ActivityRules: (params) => {
return request({
url: '/promotion/prize-draw/getOne',
method: 'GET',
params,
});
},
};
export default PayOrderApi;

@ -68,7 +68,6 @@ const getShareInfo = (
// 构造spm分享参数 // 构造spm分享参数
const buildSpmQuery = (params) => { const buildSpmQuery = (params) => {
const user = $store('user'); const user = $store('user');
console.log(user, 'user123');
let shareId = '0'; // 设置分享者用户ID let shareId = '0'; // 设置分享者用户ID
if (typeof params.shareId === 'undefined') { if (typeof params.shareId === 'undefined') {
if (user.isLogin) { if (user.isLogin) {

Loading…
Cancel
Save