6
0
Fork 0

调整抽奖页面

master
panliang 2026-04-27 15:22:25 +08:00
parent 270e3e6ce0
commit 2769ef550f
17 changed files with 43438 additions and 2019 deletions

View File

@ -1,4 +1,4 @@
ENV = 'development'
VUE_APP_BASE_API = 'https://jiqu-library.sk797.cn/api'
VUE_APP_BASE_API = 'http://local.jiqu-library.host/api'

View File

@ -1,6 +1,6 @@
ENV = 'production'
# VUE_APP_BASE_API = 'https://jiqu-library.peidikeji.cn/api'
VUE_APP_BASE_API = 'https://jiqu-library.sk797.cn/api'
# VUE_APP_BASE_API = 'http://local.jiqu-library.host/api'
VUE_APP_BASE_API = 'https://jiqu-library.peidikeji.cn/api'

24672
package-lock.json generated 100644

File diff suppressed because it is too large Load Diff

View File

@ -15,14 +15,14 @@
"build:mp-lark": "cross-env NODE_ENV=production UNI_PLATFORM=mp-lark vue-cli-service uni-build",
"build:mp-qq": "cross-env NODE_ENV=production UNI_PLATFORM=mp-qq vue-cli-service uni-build",
"build:mp-toutiao": "cross-env NODE_ENV=production UNI_PLATFORM=mp-toutiao vue-cli-service uni-build",
"build:mp-weixin": "cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:mp-weixin": "set NODE_OPTIONS=--openssl-legacy-provider && cross-env NODE_ENV=production UNI_PLATFORM=mp-weixin vue-cli-service uni-build",
"build:quickapp-native": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-native vue-cli-service uni-build",
"build:quickapp-webview": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview vue-cli-service uni-build",
"build:quickapp-webview-huawei": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-huawei vue-cli-service uni-build",
"build:quickapp-webview-union": "cross-env NODE_ENV=production UNI_PLATFORM=quickapp-webview-union vue-cli-service uni-build",
"dev:app-plus": "cross-env NODE_ENV=development UNI_PLATFORM=app-plus vue-cli-service uni-build --watch",
"dev:custom": "cross-env NODE_ENV=development uniapp-cli custom",
"dev:h5": "cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:h5": "set NODE_OPTIONS=--openssl-legacy-provider && cross-env NODE_ENV=development UNI_PLATFORM=h5 vue-cli-service uni-serve",
"dev:mp-360": "cross-env NODE_ENV=development UNI_PLATFORM=mp-360 vue-cli-service uni-build --watch",
"dev:mp-alipay": "cross-env NODE_ENV=development UNI_PLATFORM=mp-alipay vue-cli-service uni-build --watch",
"dev:mp-baidu": "cross-env NODE_ENV=development UNI_PLATFORM=mp-baidu vue-cli-service uni-build --watch",

15561
pnpm-lock.yaml 100644

File diff suppressed because it is too large Load Diff

View File

@ -15,7 +15,7 @@ export default {
this.$store.dispatch('app/getArticle');
/* #ifdef MP-WEIXIN */
// wxMnpLogin()
wxMnpLogin()
/* #endif */
// #ifdef APP-PLUS

View File

@ -1,6 +1,6 @@
{
"name" : "商城",
"appid" : "__UNI__EC894CF",
"name" : "积趣自然图书馆",
"appid" : "__UNI__828F200",
"description" : "",
"versionName" : "1.3.4",
"versionCode" : 134,
@ -164,7 +164,7 @@
"quickapp" : {},
/* */
"mp-weixin" : {
"appid" : "wx02a998127d65764c",
"appid" : "wx374270da1f0100da",
"setting" : {
"urlCheck" : false
},

View File

@ -1,123 +1,79 @@
<template>
<view class="h-full">
<loading-view v-if="isFirstLoading && isLogin "></loading-view>
<view
class="bg min-h-full overflow-hidden"
v-else-if="isLogin"
:style="{ backgroundImage: `url(${draw_activity.bg_image})`, backgroundColor: draw_activity.bg_color }"
>
<loading-view v-if="isFirstLoading && isLogin"></loading-view>
<view class="bg min-h-full overflow-hidden" v-else-if="isLogin"
:style="{ backgroundImage: `url(${draw_activity.bg_image})`, backgroundColor: draw_activity.bg_color }">
<view class="">
<view class="fixed top-0 left-0 w-full bg z-10" :style="{ backgroundImage: `url(${draw_activity.bg_image})` }">
<view :style="{ height: statusBarHeight + 'px' }"></view>
<view class="px-30rpx py-20rpx flex h-50px flex items-center relative">
<image
@click="onBack"
class="h-56rpx w-56rpx"
src="https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/back.png"
alt=""
srcset=""
></image>
<view class="absolute left-100rpx right-100rpx text-center text-52rpx text-white">{{draw_activity.name}}</view>
<image @click="onBack" class="h-56rpx w-56rpx" src="/static/images/back-white.png" alt="" srcset=""></image>
<view class="absolute left-100rpx right-100rpx text-center text-52rpx text-white">{{ draw_activity.name }}
</view>
</view>
</view>
<view class="w-full" :style="{ height: 50 + statusBarHeight + 'px' }"> </view>
</view>
<view class="h-300rpx w-full"></view>
<view class="w-full relative">
<view class="h-100rpx"></view>
<view class="absolute top-0 z-9 left-0 px-30rpx message w-full">
<view class="h-180rpx">
<swiper
vertical="vertical"
autoplay="play"
class="h-full"
previous-margin="60rpx"
next-margin="60rpx"
disable-touch
@change="change"
circular
:current="current"
>
<swiper-item v-for="(item, index) in logsAll" :key="index" class="h-full flex items-start flex-col justify-center">
<view
class="bg-hex-000 bg-opacity-30 text-white rounded-full px-20px h-44rpx leading-44rpx text-28rpx inline-block"
:class="index == current ? 'opacity1' : index + 1 == current ? 'opacity0' : index - 1 == current ? 'opacity2' :(current==logsAll.length-1 && index==0)?'opacity2' : 'opacity3'"
>
<text
>恭喜{{ item.user.nickname }}抽中<text class="text-hex-ffde58">{{ item.prize.name }}</text></text
>
</view>
</swiper-item>
</swiper>
</view>
<!-- <view v-for="item in logs" :key="item.id" class="opacity">
<view class="h-300rpx w-full"></view>
<view class="w-full relative">
<view class="h-100rpx"></view>
<view class="absolute top-0 z-9 left-0 px-30rpx message w-full">
<view class="h-180rpx">
<swiper vertical="vertical" autoplay="play" class="h-full" previous-margin="60rpx" next-margin="60rpx"
disable-touch @change="change" circular :current="current">
<swiper-item v-for="(item, index) in logsAll" :key="index"
class="h-full flex items-start flex-col justify-center">
<view
class="bg-hex-000 bg-opacity-30 text-white rounded-full px-20px h-44rpx leading-44rpx text-28rpx inline-block"
:class="index == current ? 'opacity1' : index + 1 == current ? 'opacity0' : index - 1 == current ? 'opacity2' : (current == logsAll.length - 1 && index == 0) ? 'opacity2' : 'opacity3'">
<text>恭喜{{ item.user.nickname }}抽中<text class="text-hex-ffde58">{{ item.prize.name }}</text></text>
</view>
</swiper-item>
</swiper>
</view>
<!-- <view v-for="item in logs" :key="item.id" class="opacity">
<view class="bg-hex-000 bg-opacity-30 text-white rounded-full px-20px h-44rpx leading-44rpx text-28rpx mb-10rpx inline-block">
<text
>恭喜{{ item.user.nickname }}抽中<text class="text-hex-ffde58">{{ item.prize.name }}</text></text
>
</view>
</view> -->
</view>
<almost-lottery
pointer-position="edge"
:lottery-size="lotteryConfig.lotterySize"
:action-size="lotteryConfig.actionSize"
:ring-count="8"
:duration="8"
:prize-list="prizeList"
:prize-index="prizeIndex"
@reset-index="prizeIndex = -1"
@draw-start="handleDrawStart"
@draw-end="handleDrawEnd"
@finish="handleDrawFinish"
v-if="prizeList.length"
stroke-color="#ffffff"
:strFontSize="28"
:strMaxLen="10"
:strFontColors="['#fb6056']"
:colors="['#ffeaa7', '#ffeaa7']"
:stroked="true"
:img-width="120"
:img-height="120"
:imgMarginStr="30"
:strMarginOutside="32"
:canvasCached="true"
:lotteryBg="lotteryBg"
:actionBg="actionBg"
/>
<view class="text-center mt-40rpx"
>今天还可以抽 <text class="text-error">{{ freeNum }}</text> </view
>
</view>
</view>
<almost-lottery pointer-position="edge" :lottery-size="lotteryConfig.lotterySize"
:action-size="lotteryConfig.actionSize" :ring-count="8" :duration="8" :prize-list="prizeList"
:prize-index="prizeIndex" @reset-index="prizeIndex = -1" @draw-start="handleDrawStart"
@draw-end="handleDrawEnd" @finish="handleDrawFinish" v-if="prizeList.length" stroke-color="#ffffff"
:strFontSize="28" :strMaxLen="10" :strFontColors="['#fb6056']" :colors="['#ffeaa7', '#ffeaa7']"
:stroked="true" :img-width="120" :img-height="120" :imgMarginStr="30" :strMarginOutside="32"
:canvasCached="true"
:lotteryBg="lotteryBg"
:actionBg="actionBg"
/>
<view class="text-center mt-40rpx">今天还可以抽 <text class="text-error">{{ freeNum }}</text> </view>
</view>
<view class="p-30rpx">
<u-parse :html="draw_activity.desc"></u-parse>
</view>
</block>
<view class="p-30rpx">
<u-parse :html="draw_activity.desc"></u-parse>
</view>
<u-mask :show="show">
<view class="flex items-center justify-center h-full">
<view class="">
<view class="pr-30rpx text-right">
<image src="/static/images/app/app_update_close.png" alt="" srcset="" class="w-48rpx h-48rpx" @click="show = false"></image>
<image src="/static/images/app/app_update_close.png" alt="" srcset="" class="w-48rpx h-48rpx"
@click="show = false"></image>
</view>
<view class="w-600rpx h-600rpx relative" v-if="prizeData.prize">
<image :src="prizeData.prize.type==0?results.goods:tips_image" class="w-full h-full"></image>
<block v-if="prizeData.prize.type!=0">
<image v-if="prizeData.prize.type == 0" :src="results.goods" class="w-full h-full"></image>
<block v-if="prizeData.prize.type != 0">
<view class="absolute top-178rpx left-0 right-0 text-center mx-auto mx-auto w-300rpx h-290rpx">
<image :src="results.goods" alt="" class="w-full h-full"></image>
</view>
<view
class="absolute top-136rpx left-0 right-0 text-center h-42rpx leading-40rpx text-30rpx text-hex-f74a2c bg-gradient-to-t to-hex-fff4e5 from-hex-ffd4b2 w-240rpx rounded-full mx-auto"
>
<view class="absolute top-116rpx left-0 right-0 text-center h-42rpx leading-40rpx text-30rpx text-hex-f74a2c bg-gradient-to-t to-hex-fff4e5 from-hex-ffd4b2 w-240rpx rounded-full mx-auto">
{{ results.name }}
</view>
<view
v-if="!!results.btn"
@click="onResults"
class="absolute top-466rpx left-0 right-0 text-center h-54rpx leading-54rpx text-28rpx text-white bg-img w-280rpx mx-auto"
>
<view v-if="!!results.btn" @click="onResults" class="absolute top-486rpx left-0 right-0 text-center h-54rpx leading-54rpx text-28rpx text-white bg-img w-280rpx mx-auto">
{{ results.btn }}
</view>
</block>
@ -186,9 +142,9 @@ export default {
// UI
// 稿
lotteryBg: 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/lottery-bg.png',
lotteryBg: "/static/images/almost-lottery__bg.png",
//
actionBg: 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/action-bg.png',
actionBg: "/static/images/almost-lottery__action.png",
//
prizeList: [],
//
@ -240,23 +196,23 @@ export default {
draw_activity() {
return this.config.draw_activity;
},
tips_image(){
tips_image() {
return this.draw_activity?.tips_image ?? 'https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/lucky-jg.png'
}
},
async onLoad({ id }) {
this.id = id;
setTimeout(()=>{
if(!this.isLogin){
setTimeout(() => {
if (!this.isLogin) {
this.$u.route({
type:'redirectTo',
url:`/pages/login/index?redirec=${encodeURIComponent(`/pageB/lucky/index?id=${id}`)}`
})
}else{
type: 'redirectTo',
url: `/pages/login/index?redirec=${encodeURIComponent(`/pageB/lucky/index?id=${id}`)}`
})
} else {
this.getConfig();
this.getLuckyLog();
}
},300)
}, 300)
},
//
@ -276,11 +232,11 @@ export default {
onBack() {
const pages = getCurrentPages()
const prevPage = pages[pages.length - 2]
if(prevPage){
if (prevPage) {
uni.navigateBack({})
}else{
} else {
uni.switchTab({
url:'/pages/index/index'
url: '/pages/index/index'
})
}
// uni.navigateBack();
@ -347,13 +303,13 @@ export default {
},
//
handleDrawStart() {
if(this.draw_activity.status == 4){
if (this.draw_activity.status == 4) {
return this.$u.toast('活动已结束');
}
if(this.draw_activity.status == 2){
if (this.draw_activity.status == 2) {
return this.$u.toast('活动未开始');
}
if(this.draw_activity.status != 3){
if (this.draw_activity.status != 3) {
return;
}
if (this.prizeing) return;
@ -434,20 +390,26 @@ page {
background-position: top;
background-repeat: no-repeat;
}
.bg-img {
background: url('https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/btn.png') no-repeat;
background-size: 100% auto;
// background: url('https://ystmp.oss-cn-beijing.aliyuncs.com/wechart/lucky/btn.png') no-repeat;
// background-size: 100% auto;
background-color: #FEAD6C;
color: white;
}
.opacity0 {
@apply opacity-60;
}
.opacity1 {
@apply opacity-80;
}
.opacity2 {
@apply opacity-100;
}
.opacity3 {
@apply opacity-80;
}

View File

@ -1,12 +1,18 @@
<template>
<view class="text-xl">
<view class="w-full bg-white p-base mb-20rpx">
<view class="flex justify-between flex-auto text-xxl">
<view class="flex justify-between flex-auto text-xxl mb-20rpx">
<view>门店</view>
<view :class="{'text-hex-c0c4cc': store ? false : true }" @tap="showStoreSelect">
{{ store ? store.title : '请选择门店' }}<u-icon name="arrow-right" class="text-hex-c0c4cc"></u-icon>
</view>
</view>
<view class="flex justify-between flex-auto text-xxl">
<view>备注</view>
<view :class="{'text-hex-c0c4cc': orderRemark ? false : true }" @tap="openOrderRemark">
{{ orderRemark ? orderRemark : "订单备注" }}
<u-icon name="arrow-right" class="text-hex-c0c4cc"></u-icon></view>
</view>
</view>
<view class="bg-white my-20rpx">
<view class="flex justify-between items-center p-20rpx border-b border-red">
@ -95,6 +101,14 @@
</view>
</u-modal>
<u-modal title="订单备注" ref="orderRemark" v-model="orderRemarkShow" :show-cancel-button="true" @confirm="closeOrderRemark" @cancel="closeOrderRemark">
<view class="p-base text-md">
<view class="p-26rpx border-b">
<u-input v-model="orderRemark" type="textarea" placeholder="请输入订单备注" />
</view>
</view>
</u-modal>
<!-- 商品分类选择器 -->
<u-select
v-model="productCategorySelect.visible"
@ -152,6 +166,10 @@
selector: [],
},
deleteOrderItemModalVisible: false,
//
orderRemarkShow: false,
orderRemark: '',
}
},
onShow() {
@ -165,17 +183,11 @@
},
methods: {
fetchStores() {
this.$api
.get(`/v1/store`, {
params: {
per_page: 100,
},
})
.then((res) => {
this.stores = res.data
})
.catch((err) => {
});
this.$api.get(`/v1/store`, { params: { per_page: 100 } }).then((res) => {
this.stores = res.data
})
.catch((err) => {
});
},
fetchProductCategories() {
this.$api
@ -311,27 +323,24 @@
discount: e.discount,
}))
this.$api
.post(`/v1/offline-order-previews`, {
store_id: this.store.id,
items: items,
}, {
custom: {
loading: true,
this.$api.post(`/v1/offline-order-previews`, { store_id: this.store.id, items: items, remark: this.orderRemark }, { custom: { loading: true } }).then((res) => {
this.$u.routeAuth({
url: '/pageB/offline_order/store/order_preview_qrcode',
type: 'redirectTo',
params: {
id: res.id,
},
})
.then((res) => {
this.$u.routeAuth({
url: '/pageB/offline_order/store/order_preview_qrcode',
type: 'redirectTo',
params: {
id: res.id,
},
})
})
.catch((err) => {
})
})
.catch((err) => {
})
},
openOrderRemark() {
this.orderRemarkShow = true
},
closeOrderRemark() {
this.orderRemarkShow = false
}
}
};
</script>

View File

@ -54,6 +54,15 @@
</view>
</view>
</view>
<view class="bg-white mt-base p-20rpx text-lg">
<view class="flex items-center justify-between text-txBase" @tap="openOrderRemark">
<view>订单备注</view>
<view>
{{ orderRemark }}
<u-icon name="arrow-right" size="20" class="ml-10rpx text-gray-400"></u-icon>
</view>
</view>
</view>
<cu-popup v-model="showPointDiscountDrawer" mode="bottom" border-radius="20" closeable close-icon-size="24">
<view>
@ -84,6 +93,14 @@
<view class="text-lg">合计:<text class="text-xl text-txSvip">{{ paymentAmount }}</text></view>
<view @tap="createOrder" class="btn btn-primary rounded-full text-lg px-40rpx py-10rpx">立即支付</view>
</view>
<u-modal title="订单备注" ref="orderRemark" v-model="orderRemarkShow" :show-cancel-button="true" @confirm="closeOrderRemark" @cancel="closeOrderRemark">
<view class="p-base text-md">
<view class="p-26rpx border-b">
<u-input v-model="orderRemark" type="textarea" placeholder="请输入订单备注" />
</view>
</view>
</u-modal>
</view>
</template>
@ -120,6 +137,10 @@
//
orderCreateBtnDisabled: false,
//
orderRemarkShow: false,
orderRemark: '',
}
},
onLoad({ id }) {
@ -200,6 +221,7 @@
.post(`/v1/offline-orders`, {
order_preview_id: this.id,
points: this.pointDiscount.points,
user_remark: this.orderRemark
}, {
custom: {
toast: false,
@ -242,6 +264,12 @@
},
});
},
openOrderRemark() {
this.orderRemarkShow = true
},
closeOrderRemark() {
this.orderRemarkShow = false
}
}
};
</script>

View File

@ -77,10 +77,10 @@
</view>
</view>
<!-- -->
<view class="w-full mt-30rpx h-88rpx bg-hex-404040 rounded-full text-center text-hex-f59e0b leading-88rpx text-32rpx" @click="onSumbit">
{{ user.is_vip ? '续费' : '立即开通' }}</view
>
<view class="w-full mt-30rpx h-88rpx bg-hex-404040 rounded-full text-center text-hex-f59e0b leading-88rpx text-32rpx" @click="openSelectStore">{{ user.is_vip ? '' : '' }}</view>
</view>
<u-select v-model="selectedStoreShow" :list="storeList" label-name="title" value-name="id" @confirm="handleSelectedStore" @cancel="closeSelectStore"></u-select>
</view>
</template>
@ -93,6 +93,9 @@ export default {
list: [],
Index: 0,
checked: true,
selectedStore: null,
selectedStoreShow: false,
storeList: []
};
},
computed: {
@ -107,10 +110,11 @@ export default {
},
},
onShow() {
this.getDate();
this.getData();
this.getStoreList();
},
methods: {
async getDate() {
async getData() {
try {
const resData = await this.$api.get('/v1/vip');
this.list = resData;
@ -121,8 +125,9 @@ export default {
},
async onSumbit() {
if (!this.checked) return this.$u.toast('请勾选协议');
if (!this.selectedStore) return this.$u.toast('请先选择门店')
try {
const resData = await this.$api.post('/v1/vip/buy', { vip_id: this.chooseVip.id });
const resData = await this.$api.post('/v1/vip/buy', { vip_id: this.chooseVip.id, store_id: this.selectedStore });
if (resData.status == 1) {
return this.success();
}
@ -140,6 +145,23 @@ export default {
setTimeout(() => {
uni.navigateBack({});
}, 300);
},
getStoreList () {
const params = {per_page: 100}
this.$api.get('/v1/store', {params}).then(res => {
this.storeList = res.data
})
},
openSelectStore() {
this.selectedStoreShow = true
},
closeSelectStore() {
this.selectedStoreShow = false
},
handleSelectedStore(list) {
if (list.length == 0) return this.$u.toast('请先选择门店')
this.selectedStore = list[0].value
this.onSumbit()
}
},
};

View File

@ -115,12 +115,13 @@ export default {
const { code } = e.detail;
if(!code) return
const invite_code = uni.getStorageSync('INVITE_CODE');
if(!this.$store.getters.token){
await wxMnpLogin(invite_code)
// if(!this.$store.getters.token){
// await wxMnpLogin(invite_code)
// }
const params = {
openid: uni.getStorageSync("openid"),
invite_code: invite_code
}
const params = {}
if(!!invite_code) params.inviter_code = invite_code
console.log(params.inviter_code);
const resData = await this.$api.post('/v1/wechat-mini/bind-phone', {
code:code,
...params
@ -139,9 +140,11 @@ export default {
this.$refs.uForm.validate(async (valid) => {
if (valid) {
const invite_code = uni.getStorageSync('INVITE_CODE');
const params = {}
const params = {
openid: uni.getStorageSync("openid"),
invite_code: invite_code
}
const code = await getWxCode();
if(!!invite_code) params.inviter_code = invite_code
try{
const resData = await this.$api.post('/v1/socialite/code-bind-user/wechat-mini',{
code,

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@ -39,5 +39,8 @@ async function silentLogin(data){
toast:false
}
})
store.commit('user/LOGIN', resData.token)
uni.setStorageSync("openid", resData.openid)
if (resData.token) {
store.commit('user/LOGIN', resData.token)
}
}

4875
yarn.lock

File diff suppressed because it is too large Load Diff