1104 lines
29 KiB
Vue
1104 lines
29 KiB
Vue
<template>
|
||
<view class="container" :style="{'--theme-color': themeColor}">
|
||
<!-- 标题栏 -->
|
||
<title-bar :showBack="true" title="活动详情"></title-bar>
|
||
<!-- 内容区 -->
|
||
<view class="container-main">
|
||
<block v-if="loadEnd && !showLogin">
|
||
<!-- 轮播图 -->
|
||
<carousel :show-data="activityInfo.image_list" height="320rpx" radius="10rpx" bottom="24rpx"
|
||
right="24rpx"></carousel>
|
||
<!-- 活动信息 -->
|
||
<view class="main-info">
|
||
<view class="info-header flex align-items-center" v-if="activityInfo.activity_state == 1">
|
||
<image class="header-bg" src="/static/activity/time_bg.png" mode="aspectFill"></image>
|
||
<image class="header-icon" src="/static/activity/time.png" mode="aspectFit"></image>
|
||
<view class="header-box flex-item flex align-items-center">
|
||
<view class="text flex-item">距离报名结束还有</view>
|
||
<view class="cell">{{countdown.day}}</view>
|
||
<view class="text">天</view>
|
||
<view class="cell">{{countdown.hours}}</view>
|
||
<view class="text">时</view>
|
||
<view class="cell">{{countdown.minutes}}</view>
|
||
<view class="text">分</view>
|
||
<view class="cell">{{countdown.seconds}}</view>
|
||
<view class="text">秒</view>
|
||
</view>
|
||
</view>
|
||
<view class="info-main">
|
||
<view class="main-title">{{activityInfo.name}}</view>
|
||
<view class="main-row flex align-items-center">
|
||
<view class="price" v-if="parseFloat(activityInfo.fees || 0) > 0">
|
||
<text>¥</text>{{activityInfo.fees}}
|
||
</view>
|
||
<view class="price" v-else>免费</view>
|
||
<view class="label">
|
||
<text class="type-1" v-if="activityInfo.activity_state == 1">报名中</text>
|
||
<text class="type-2" v-else-if="activityInfo.activity_state == 2">进行中</text>
|
||
<text class="type-3" v-else-if="activityInfo.activity_state == 3">已结束</text>
|
||
</view>
|
||
<view class="label">
|
||
<text v-if="activityInfo.organizing_method == 1">线上活动</text>
|
||
<text v-else-if="activityInfo.organizing_method == 2">线下活动</text>
|
||
</view>
|
||
</view>
|
||
<view class="main-label" v-if="activityInfo.points_status == 1">
|
||
参加活动可得{{activityInfo.points || 0}}积分</view>
|
||
<view class="main-column flex align-items-center">
|
||
<view class="column-icon" :style="{'background-image': 'url('+ iconTime +')'}"
|
||
v-if="iconTime"></view>
|
||
<view class="column-text flex-item">{{activityInfo.time_frame}}</view>
|
||
</view>
|
||
<view class="main-column flex align-items-start"
|
||
v-if="activityInfo.organizing_method == 2 && activityInfo.address">
|
||
<view class="column-icon" :style="{'background-image': 'url('+ iconLocation +')'}"
|
||
v-if="iconLocation"></view>
|
||
<view class="column-text flex-item">{{activityInfo.address}}</view>
|
||
<view class="column-navigation flex align-items-center" @click="toNavigation()">
|
||
<view class="icon" :style="{'background-image': 'url('+ iconNavigation +')'}"
|
||
v-if="iconNavigation"></view>
|
||
<text class="text">导航</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 已报名 -->
|
||
<view class="main-record flex justify-content-between align-items-center"
|
||
v-if="activityInfo.apply_count">
|
||
<view class="record-bubble">已报名:{{activityInfo.apply_count}}人</view>
|
||
<view class="record-list flex">
|
||
<view class="list-item" v-for="(item, index) in activityInfo.apply_list" :key="index">
|
||
<image :src="item.member_avatar" mode="aspectFill"></image>
|
||
</view>
|
||
<view class="list-item" v-if="parseInt(activityInfo.apply_count || 0) > 9">
|
||
<view class="item-more flex justify-content-around align-items-center">
|
||
<view class="point"></view>
|
||
<view class="point"></view>
|
||
<view class="point"></view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- 活动介绍 -->
|
||
<view class="main-content">
|
||
<mp-html :content="activityInfo.content"></mp-html>
|
||
</view>
|
||
|
||
<!-- 底部按钮 -->
|
||
<view class="main-footer">
|
||
<view class="flex justify-content-between align-items-center">
|
||
<view class="footer-menu flex">
|
||
<!-- #ifdef MP-WEIXIN -->
|
||
<button type="default" open-type="share" class="menu-btn">
|
||
<image class="icon" src="/static/share.png" mode="aspectFit"></image>
|
||
<view class="text">分享</view>
|
||
</button>
|
||
<!-- #endif -->
|
||
<view class="menu-btn" @click="onContact">
|
||
<image class="icon" src="/static/phone.png" mode="aspectFit"></image>
|
||
<view class="text">联系</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 根据计算属性显示按钮 -->
|
||
<block v-if="buttonConfig.needPhone">
|
||
<button class="footer-btn flex-item clear flex flex-center"
|
||
:class="{disabled: buttonConfig.disabled}" open-type="getPhoneNumber"
|
||
:style="{backgroundColor: buttonConfig.bgColor}" @getphonenumber="bindPhoneNumber">
|
||
<text>{{buttonConfig.text}}</text>
|
||
</button>
|
||
</block>
|
||
<block v-else>
|
||
<view class="footer-btn flex-item flex flex-center"
|
||
:class="{disabled: buttonConfig.disabled}" @click="handleButtonClick"
|
||
:style="{backgroundColor: buttonConfig.bgColor}">
|
||
<text>{{buttonConfig.text}}</text>
|
||
</view>
|
||
</block>
|
||
</view>
|
||
<view class="safe-padding"></view>
|
||
</view>
|
||
</block>
|
||
<view class="main-login" v-else-if="showLogin">
|
||
<image class="login-image" :src="loginImg" mode="aspectFit"></image>
|
||
<view class="login-tips">小程序需要登录注册才能使用相关功能,请登录后查看该页面</view>
|
||
<view class="login-btn" @click="toLogin()">前往登录</view>
|
||
</view>
|
||
</view>
|
||
|
||
<!-- 调试信息 - 上线后可删除 -->
|
||
<!-- <view
|
||
style="position:fixed; bottom:200rpx; left:0; right:0; background:#f0f0f0; padding:10rpx; font-size:24rpx; text-align:center; z-index:1000;">
|
||
状态:{{activityStatus}} | 报名:{{activityInfo.apply_status}} | 签到:{{isUserSigned}} | 按钮:{{buttonConfig.text}}
|
||
</view> -->
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import {
|
||
mapState
|
||
} from "vuex"
|
||
import carousel from "@/pages/component/carousel/carousel.vue"
|
||
import svgData from "@/common/svg.js"
|
||
// #ifdef H5
|
||
import wx from 'weixin-js-sdk';
|
||
// #endif
|
||
|
||
export default {
|
||
components: {
|
||
carousel,
|
||
},
|
||
data() {
|
||
return {
|
||
// 加载完成
|
||
loadEnd: false,
|
||
// 活动id
|
||
activityId: null,
|
||
// 活动详情
|
||
activityInfo: {},
|
||
// 活动剩余时间计时器
|
||
activityInterval: null,
|
||
// 活动倒计时
|
||
countdown: {
|
||
day: 0,
|
||
hours: 0,
|
||
minutes: 0,
|
||
seconds: 0,
|
||
},
|
||
// 是否显示登录提示
|
||
showLogin: false,
|
||
// 活动状态:
|
||
// 1.报名阶段(当前时间 < 报名截止时间)
|
||
// 2.未开始(报名截止时间 ≤ 当前时间 < 活动开始时间)
|
||
// 3.待签到(活动开始时间 ≤ 当前时间 ≤ 活动结束时间且 用户已报名 且 未签到)
|
||
// 4.已签到 (活动开始时间 ≤ 当前时间 ≤ 活动结束时间 且 用户已签到)
|
||
// 5.活动结束 (当前时间 > 活动结束时间)
|
||
activityStatus: 0,
|
||
|
||
}
|
||
},
|
||
computed: {
|
||
...mapState({
|
||
themeColor: state => state.app.themeColor,
|
||
iconTime: state => {
|
||
return svgData.svgToUrl("time", state.app.themeColor)
|
||
},
|
||
iconLocation: state => {
|
||
return svgData.svgToUrl("location", state.app.themeColor)
|
||
},
|
||
iconNavigation: state => {
|
||
return svgData.svgToUrl("navigation", state.app.themeColor)
|
||
},
|
||
loginImg: state => state.app.loginImg,
|
||
token: state => state.user.token,
|
||
userMobile: state => state.user.mobile,
|
||
}),
|
||
|
||
// 按钮配置
|
||
buttonConfig() {
|
||
// 默认配置
|
||
const config = {
|
||
text: '报名参加',
|
||
disabled: false,
|
||
needPhone: false
|
||
}
|
||
|
||
// 根据活动状态返回不同配置
|
||
switch (this.activityStatus) {
|
||
case 1: // 报名阶段
|
||
// 退款中
|
||
if (this.activityInfo.refund == 1 && this.activityInfo.pay_state == 3) {
|
||
return {
|
||
text: '退款中',
|
||
disabled: true,
|
||
needPhone: false
|
||
}
|
||
}
|
||
// 已报名
|
||
if (this.activityInfo.apply_status == 1) {
|
||
return {
|
||
text: '已报名',
|
||
disabled: this.activityInfo.activity_state != 1,
|
||
needPhone: false
|
||
}
|
||
}
|
||
// 无剩余名额
|
||
if (this.activityInfo.apply_limit_number === 0) {
|
||
return {
|
||
text: '无法报名(剩余0个名额)',
|
||
disabled: true,
|
||
needPhone: false
|
||
}
|
||
}
|
||
// 立即报名(带剩余名额)
|
||
let text = '报名参加'
|
||
if (this.activityInfo.apply_limit_number > 0) {
|
||
text = `报名参加(剩余${this.activityInfo.apply_limit_number}个名额)`
|
||
}
|
||
return {
|
||
text: text,
|
||
disabled: false,
|
||
needPhone: !this.token || !this.userMobile
|
||
}
|
||
|
||
case 2: // 未开始
|
||
return {
|
||
text: '活动未开始',
|
||
disabled: true,
|
||
needPhone: false
|
||
}
|
||
|
||
case 3: // 待签到
|
||
return {
|
||
text: '扫码签到',
|
||
disabled: false,
|
||
needPhone: false
|
||
}
|
||
|
||
case 4: // 已签到
|
||
return {
|
||
text: '已签到',
|
||
disabled: true,
|
||
needPhone: false,
|
||
bgColor: '#52c41a' // 绿色,表示已完成
|
||
}
|
||
|
||
case 5: // 活动结束
|
||
return {
|
||
text: '活动已结束',
|
||
disabled: true,
|
||
needPhone: false
|
||
}
|
||
|
||
default:
|
||
return config
|
||
}
|
||
}
|
||
},
|
||
onLoad(option) {
|
||
|
||
let scene = this.$util.parseURLParams(decodeURIComponent(option.scene))
|
||
this.activityId = option.id || (!(Object.prototype.toString.call(scene) === '[object Object]') ? scene : false) || scene.id
|
||
|
||
uni.showLoading({
|
||
title: "加载中"
|
||
})
|
||
|
||
|
||
this.getActivity(() => {
|
||
this.loadEnd = true
|
||
uni.hideLoading()
|
||
// #ifdef H5
|
||
this.initConfig()
|
||
// #endif
|
||
})
|
||
|
||
if(scene.id) {
|
||
console.log(scene,'=scene=')
|
||
this.verifyAndSign(scene.id)
|
||
}
|
||
|
||
},
|
||
onShow() {
|
||
if (this.loadEnd) this.getActivity()
|
||
},
|
||
onShareAppMessage() {
|
||
return {
|
||
title: this.activityInfo.name,
|
||
path: '/pagesActivity/index/details?id=' + this.activityId,
|
||
imageUrl: this.activityInfo.image_list[0],
|
||
}
|
||
},
|
||
onShareTimeline() {
|
||
return {
|
||
title: this.activityInfo.name,
|
||
path: '/pagesActivity/index/details?id=' + this.activityId,
|
||
imageUrl: this.activityInfo.image_list[0],
|
||
}
|
||
},
|
||
onUnload() {
|
||
clearInterval(this.activityInterval)
|
||
},
|
||
methods: {
|
||
|
||
|
||
|
||
// 获取活动详情
|
||
getActivity(fn) {
|
||
this.$util.request("activity.details", {
|
||
id: this.activityId
|
||
}).then(res => {
|
||
if (res.code == 1) {
|
||
if (res.data.activity_auth == 2) {
|
||
this.getMemberState(1, () => {
|
||
if (fn) fn()
|
||
this.activityInfo = res.data
|
||
this.activityInfo.time_frame = this.getTimeFrame(res.data.start_time, res
|
||
.data.end_time)
|
||
if (this.activityInfo.images) this.activityInfo.image_list = this
|
||
.activityInfo.images.split(",")
|
||
else this.activityInfo.image_list = []
|
||
this.getCountdown()
|
||
// 获取签到状态并计算活动状态
|
||
//1和2的状态可以直接用后台返回
|
||
if(this.activityInfo.actitity_state_trans==1 || this.activityInfo.actitity_state_trans==2) {
|
||
this.activityStatus =this.activityInfo.actitity_state_trans
|
||
}
|
||
if(this.activityInfo.actitity_state_trans == 3 && !this.activityInfo.check_in_status) {
|
||
this.activityStatus=3
|
||
}
|
||
|
||
//3和4的状态需要结合check_in_status参数一起判断3+unchecked_in(未签到)否则已签到
|
||
if(this.activityInfo.actitity_state_trans == 3 && this.activityInfo.check_in_status=='unchecked_in') {
|
||
this.activityStatus=3
|
||
}
|
||
if(this.activityInfo.actitity_state_trans == 3 && this.activityInfo.check_in_status=="checked_in") {
|
||
this.activityStatus=4
|
||
}
|
||
//后台返回的4就是活动结束对应的是前端的5
|
||
if(this.activityInfo.actitity_state_trans==4) {
|
||
this.activityStatus=5
|
||
}
|
||
})
|
||
} else {
|
||
if (fn) fn()
|
||
this.activityInfo = res.data
|
||
this.activityInfo.time_frame = this.getTimeFrame(res.data.start_time, res.data
|
||
.end_time)
|
||
if (this.activityInfo.images) this.activityInfo.image_list = this.activityInfo.images
|
||
.split(",")
|
||
else this.activityInfo.image_list = []
|
||
this.getCountdown()
|
||
// 获取签到状态并计算活动状态
|
||
//1和2的状态可以直接用后台返回
|
||
if(this.activityInfo.actitity_state_trans==1 || this.activityInfo.actitity_state_trans==2) {
|
||
this.activityStatus =this.activityInfo.actitity_state_trans
|
||
}
|
||
if(this.activityInfo.actitity_state_trans == 3 && !this.activityInfo.check_in_status) {
|
||
this.activityStatus=3
|
||
}
|
||
//3和4的状态需要结合check_in_status参数一起判断3+unchecked_in(未签到)否则已签到
|
||
if(this.activityInfo.actitity_state_trans == 3 && this.activityInfo.check_in_status=='unchecked_in') {
|
||
this.activityStatus=3
|
||
}
|
||
if(this.activityInfo.actitity_state_trans == 3 && this.activityInfo.check_in_status=="checked_in") {
|
||
this.activityStatus=4
|
||
}
|
||
//后台返回的4就是活动结束对应的是前端的5
|
||
if(this.activityInfo.actitity_state_trans==4) {
|
||
this.activityStatus=5
|
||
}
|
||
|
||
}
|
||
} else {
|
||
if (fn) fn()
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
if (error == 401) {
|
||
this.showLogin = true
|
||
} else {
|
||
console.error('获取活动详情 ', error)
|
||
}
|
||
})
|
||
},
|
||
|
||
|
||
|
||
// 统一处理按钮点击
|
||
handleButtonClick() {
|
||
// 先验证是否登录(用 token)
|
||
if (!uni.getStorageSync("token")) {
|
||
// 显示登录提示页
|
||
this.showLogin = true
|
||
return
|
||
}
|
||
|
||
// 如果按钮是禁用状态,不处理点击
|
||
if (this.buttonConfig.disabled) {
|
||
// 禁用状态的按钮也有对应的提示
|
||
this.handleAction()
|
||
return
|
||
}
|
||
|
||
// 已登录且按钮可用,根据状态执行对应操作
|
||
this.handleAction()
|
||
},
|
||
|
||
// 根据状态处理不同逻辑
|
||
handleAction() {
|
||
switch (this.activityStatus) {
|
||
case 1: // 报名阶段
|
||
this.handleApply()
|
||
break
|
||
case 2: // 未开始
|
||
this.showToast('活动尚未开始,请在活动开始后前来签到!')
|
||
break
|
||
case 3: // 待签到
|
||
this.handleSignIn()
|
||
break
|
||
case 4: // 已签到
|
||
this.showToast('您已签到成功!')
|
||
break
|
||
case 5: // 活动结束
|
||
this.showToast('本次活动已结束,无法进行签到或报名!')
|
||
break
|
||
// default:
|
||
// this.showToast('活动状态异常')
|
||
}
|
||
},
|
||
|
||
// 处理签到
|
||
handleSignIn() {
|
||
// 检查是否已报名
|
||
if (this.activityStatus == 3 && !this.activityInfo.check_in_status) {
|
||
this.showToast('您尚未报名 !')
|
||
return
|
||
}
|
||
|
||
// 调起扫码功能
|
||
this.scanQRCode()
|
||
},
|
||
|
||
// 扫码签到
|
||
scanQRCode() {
|
||
// 调起摄像头扫码
|
||
uni.scanCode({
|
||
scanType: ['barCode', 'qrCode','wxCode'],
|
||
success: (res) => {
|
||
// 验证并签到
|
||
let path = this.$util.parseURLParams(decodeURIComponent(res.path))
|
||
|
||
if(!path.scene && !path.op) {
|
||
uni.showToast({
|
||
title: '请扫描签到码 !',
|
||
icon: 'none',
|
||
duration: 3000 // 设置显示时间为3000毫秒(3秒)
|
||
})
|
||
return
|
||
|
||
}
|
||
|
||
|
||
let id = path.scene.split('=')[1]
|
||
if(id!==this.activityId) {//name
|
||
uni.showToast({
|
||
title:`二维码不匹配:当前扫码入口属于【活动-${this.activityInfo.name}】`,
|
||
icon: 'none',
|
||
duration: 3000 // 设置显示时间为3000毫秒(3秒)
|
||
});
|
||
return
|
||
}
|
||
// 验证并签到
|
||
this.verifyAndSign(id)
|
||
},
|
||
fail: (err) => {
|
||
|
||
if (err.errMsg !== 'scanCode:fail cancel') {
|
||
// 非取消操作才提示错误
|
||
this.showToast('扫码失败,请重试')
|
||
}
|
||
}
|
||
})
|
||
},
|
||
|
||
// 验证并签到
|
||
verifyAndSign(id) {
|
||
uni.showLoading({
|
||
title: '签到中'
|
||
})
|
||
// 调用签到接口
|
||
this.$util.request('activity.code', {
|
||
id:id, // 扫描到的二维码内容
|
||
}).then(res => {
|
||
uni.hideLoading()
|
||
if (res.code == 1) {
|
||
// 签到成功
|
||
this.showToast('签到成功')
|
||
this.getActivity()
|
||
} else {
|
||
this.showToast(res.msg || '签到失败')
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('签到失败', error)
|
||
this.showToast('签到失败,请重试')
|
||
})
|
||
},
|
||
|
||
// 显示提示
|
||
showToast(msg) {
|
||
uni.showToast({
|
||
title: msg,
|
||
icon: 'none'
|
||
})
|
||
},
|
||
|
||
// 格式化时间(用于调试)
|
||
formatTime(timestamp) {
|
||
if (!timestamp) return '无效时间'
|
||
let date = new Date(timestamp * 1000)
|
||
return `${date.getFullYear()}-${date.getMonth()+1}-${date.getDate()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`
|
||
},
|
||
|
||
// 获取会员状态
|
||
getMemberState(type, fn) {
|
||
this.$util.request("member.state").then(res => {
|
||
if (res.code == 1) {
|
||
if (res.data.state.state == 6) {
|
||
fn()
|
||
} else if (res.data.state.state == -1) {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
title: "系统提示",
|
||
content: type == 2 ? "该活动需成为会员后可报名" : "此页面需成为会员后可查看!",
|
||
confirmColor: this.themeColor,
|
||
confirmText: "去加入",
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.$util.toPage({
|
||
mode: 1,
|
||
path: "/pages/member/apply/index"
|
||
})
|
||
}
|
||
}
|
||
})
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showModal({
|
||
title: "系统提示",
|
||
content: type == 2 ? "该活动需成为会员后可报名" : "此页面需成为会员后可查看!",
|
||
confirmColor: this.themeColor,
|
||
confirmText: "前往查看",
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
uni.switchTab({
|
||
url: "/pages/mine/index"
|
||
})
|
||
}
|
||
}
|
||
})
|
||
}
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('获取会员状态 ', error)
|
||
})
|
||
},
|
||
|
||
// 获取活动剩余时间
|
||
getCountdown() {
|
||
let nowTime = new Date().getTime()
|
||
this.countdown = this.$util.getTimeDifference(nowTime, this.activityInfo.apply_time * 1000)
|
||
if (this.countdown.day == 0 && this.countdown.hours == 0 && this.countdown.minutes == 0 && this.countdown
|
||
.seconds == 0) {
|
||
this.activityInfo.activity_state = 2
|
||
clearInterval(this.activityInterval)
|
||
} else {
|
||
this.activityInterval = setInterval(() => {
|
||
let nowTime = new Date().getTime()
|
||
this.countdown = this.$util.getTimeDifference(nowTime, this.activityInfo.apply_time * 1000)
|
||
if (this.countdown.day == 0 && this.countdown.hours == 0 && this.countdown.minutes == 0 &&
|
||
this.countdown.seconds == 0) {
|
||
this.activityInfo.activity_state = 2
|
||
clearInterval(this.activityInterval)
|
||
}
|
||
}, 1000);
|
||
}
|
||
},
|
||
|
||
// 获取时间范围
|
||
getTimeFrame(start, end) {
|
||
let startTime = this.$util.formatDate(start, "object")
|
||
let endTime = this.$util.formatDate(end, "object")
|
||
let startResult =
|
||
`${startTime.year}-${startTime.month}-${startTime.day} ${startTime.hours}:${startTime.minutes}`
|
||
let endResult = `${endTime.year}-${endTime.month}-${endTime.day} ${endTime.hours}:${endTime.minutes}`
|
||
return startResult + "—" + endResult
|
||
},
|
||
|
||
// 跳转地图导航
|
||
toNavigation() {
|
||
this.$util.toPage({
|
||
mode: 7,
|
||
address: {
|
||
latitude: this.activityInfo.latitude,
|
||
longitude: this.activityInfo.longitude,
|
||
address: this.activityInfo.address,
|
||
},
|
||
})
|
||
},
|
||
|
||
// #ifdef H5
|
||
// 微信公众号初始化方法
|
||
initConfig() {
|
||
this.$util.request("main.WeChatConfig", {
|
||
url: location.href.split('#')[0]
|
||
}).then(res => {
|
||
if (res.code == 1) {
|
||
wx.config({
|
||
debug: false,
|
||
appId: res.data.appId,
|
||
timestamp: Number(res.data.timestamp),
|
||
nonceStr: res.data.nonceStr,
|
||
signature: res.data.signature,
|
||
jsApiList: ["updateAppMessageShareData", "updateTimelineShareData",
|
||
"wx-open-launch-weapp"
|
||
],
|
||
openTagList: ["updateAppMessageShareData", "updateTimelineShareData",
|
||
'wx-open-launch-weapp'
|
||
],
|
||
})
|
||
wx.ready(() => {
|
||
wx.updateAppMessageShareData({
|
||
title: this.activityInfo.name,
|
||
desc: "",
|
||
link: window.location.href,
|
||
imgUrl: this.activityInfo.image_list[0],
|
||
});
|
||
wx.updateTimelineShareData({
|
||
title: this.activityInfo.name,
|
||
link: window.location.href,
|
||
imgUrl: this.activityInfo.image_list[0],
|
||
});
|
||
});
|
||
} else {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('通过config接口注入权限验证配置 ', error)
|
||
})
|
||
},
|
||
// #endif
|
||
|
||
// 联系
|
||
onContact() {
|
||
this.$util.toPage({
|
||
mode: 6,
|
||
phone: this.activityInfo.mobile,
|
||
})
|
||
},
|
||
|
||
// 报名参加
|
||
handleApply() {
|
||
if (this.activityInfo.non_member_registration_status == 2) {
|
||
uni.showLoading({
|
||
title: "加载中",
|
||
mask: true,
|
||
})
|
||
this.getMemberState(2, () => {
|
||
uni.hideLoading()
|
||
this.toApplication()
|
||
})
|
||
} else {
|
||
this.toApplication()
|
||
}
|
||
},
|
||
|
||
// 跳转报名页面
|
||
toApplication() {
|
||
if (this.activityInfo.apply_status == 1) {
|
||
uni.showModal({
|
||
content: "您已报名此活动,是否前往查看?",
|
||
confirmColor: this.themeColor,
|
||
confirmText: "前往查看",
|
||
success: (res) => {
|
||
if (res.confirm) {
|
||
this.$util.toPage({
|
||
mode: 2,
|
||
path: `/pagesActivity/order/details?id=${this.activityInfo.apply_id}&activity_id=${this.activityId}`
|
||
})
|
||
}
|
||
}
|
||
})
|
||
} else {
|
||
if (this.activityInfo.apply_field_state == 1 && this.activityInfo.apply_info_fill_state != 1) {
|
||
this.$util.toPage({
|
||
mode: 1,
|
||
path: "/pagesActivity/index/apply?id=" + this.activityId
|
||
})
|
||
} else {
|
||
this.$util.toPage({
|
||
mode: 1,
|
||
path: "/pagesActivity/index/order?id=" + this.activityId
|
||
})
|
||
}
|
||
}
|
||
},
|
||
|
||
// 绑定手机号
|
||
bindPhoneNumber(e) {
|
||
if (e.detail.errMsg == "getPhoneNumber:ok") {
|
||
uni.showLoading({
|
||
mask: true,
|
||
title: "加载中",
|
||
})
|
||
uni.login({
|
||
provider: 'weixin',
|
||
success: loginRes => {
|
||
let data = e.detail
|
||
data.code = loginRes.code
|
||
this.$util.request("login.bindMobile", data).then(res => {
|
||
uni.hideLoading()
|
||
if (res.code == 1) {
|
||
this.$store.commit('user/updateMobile', res.data.phoneNumber)
|
||
this.handleApply()
|
||
} else {
|
||
uni.showToast({
|
||
title: res.msg,
|
||
icon: 'none'
|
||
})
|
||
}
|
||
}).catch(error => {
|
||
uni.hideLoading()
|
||
console.error('获取用户手机号码 ', error)
|
||
})
|
||
},
|
||
fail: () => {
|
||
uni.hideLoading()
|
||
uni.showToast({
|
||
icon: "none",
|
||
title: "授权手机号失败,请重试"
|
||
})
|
||
}
|
||
});
|
||
} else {
|
||
uni.showToast({
|
||
title: '获取手机号失败,请重新获取',
|
||
icon: 'none'
|
||
})
|
||
}
|
||
},
|
||
|
||
// 前往登录
|
||
toLogin() {
|
||
//跳到登录页面
|
||
uni.redirectTo({
|
||
url: `/pages/login/index`,
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss">
|
||
.container {
|
||
.container-main {
|
||
padding: 32rpx 32rpx 144rpx;
|
||
|
||
.main-info {
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
overflow: hidden;
|
||
margin-top: 32rpx;
|
||
|
||
.info-header {
|
||
background: linear-gradient(134.71deg, var(--theme-color) -1.001%, #ffffff 300%);
|
||
padding: 24rpx 32rpx;
|
||
position: relative;
|
||
|
||
.header-bg {
|
||
position: absolute;
|
||
top: 0;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
}
|
||
|
||
.header-icon {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
position: relative;
|
||
z-index: 1;
|
||
}
|
||
|
||
.header-box {
|
||
position: relative;
|
||
z-index: 1;
|
||
|
||
.text {
|
||
color: #ffffff;
|
||
font-size: 24rpx;
|
||
line-height: 34rpx;
|
||
margin-left: 8rpx;
|
||
}
|
||
|
||
.cell {
|
||
color: #ffffff;
|
||
font-size: 24rpx;
|
||
height: 48rpx;
|
||
line-height: 48rpx;
|
||
padding: 0 8rpx;
|
||
min-width: 48rpx;
|
||
border-radius: 4rpx;
|
||
backdrop-filter: blur(20rpx);
|
||
background: rgba(255, 255, 255, 0.4);
|
||
margin-left: 8rpx;
|
||
text-align: center;
|
||
}
|
||
}
|
||
}
|
||
|
||
.info-main {
|
||
padding: 32rpx;
|
||
|
||
.main-title {
|
||
color: #5A5B6E;
|
||
font-size: 32rpx;
|
||
font-weight: 600;
|
||
line-height: 44rpx;
|
||
}
|
||
|
||
.main-row {
|
||
margin-top: 24rpx;
|
||
|
||
.price {
|
||
color: var(--theme-color);
|
||
font-size: 40rpx;
|
||
font-weight: 600;
|
||
line-height: 50rpx;
|
||
|
||
text {
|
||
font-size: 22rpx
|
||
}
|
||
}
|
||
|
||
.label {
|
||
margin-left: 16rpx;
|
||
|
||
text {
|
||
display: block;
|
||
color: var(--theme-color);
|
||
font-size: 24rpx;
|
||
line-height: 34rpx;
|
||
padding: 6rpx 14rpx;
|
||
border: 2rpx solid var(--theme-color);
|
||
border-radius: 4rpx;
|
||
}
|
||
|
||
.type-1 {
|
||
color: #FFA820;
|
||
border-color: #FFA820;
|
||
}
|
||
|
||
.type-2 {
|
||
color: #00AE84;
|
||
border-color: #00AE84;
|
||
}
|
||
|
||
.type-3 {
|
||
color: #E60012;
|
||
border-color: #E60012;
|
||
}
|
||
}
|
||
}
|
||
|
||
.main-label {
|
||
margin-top: 24rpx;
|
||
color: #FF8112;
|
||
font-size: 24rpx;
|
||
line-height: 36rpx;
|
||
padding: 14rpx 24rpx;
|
||
border-radius: 16rpx;
|
||
background: #FFF9EF;
|
||
}
|
||
|
||
.main-column {
|
||
margin-top: 24rpx;
|
||
|
||
.column-icon {
|
||
width: 32rpx;
|
||
height: 40rpx;
|
||
background-size: 32rpx 40rpx;
|
||
}
|
||
|
||
.column-text {
|
||
margin-left: 10rpx;
|
||
color: #666666;
|
||
font-size: 28rpx;
|
||
line-height: 40rpx;
|
||
}
|
||
|
||
.column-navigation {
|
||
margin-left: 16rpx;
|
||
|
||
.icon {
|
||
width: 32rpx;
|
||
height: 32rpx;
|
||
background-size: 32rpx;
|
||
}
|
||
|
||
.text {
|
||
margin-left: 8rpx;
|
||
color: var(--theme-color);
|
||
font-size: 28rpx;
|
||
line-height: 40rpx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.main-record {
|
||
padding: 12rpx 32rpx;
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
margin-top: 32rpx;
|
||
|
||
.record-bubble {
|
||
color: #ffffff;
|
||
font-size: 20rpx;
|
||
line-height: 28rpx;
|
||
padding: 8rpx 16rpx;
|
||
background: var(--theme-color);
|
||
border-radius: 8rpx;
|
||
display: flex;
|
||
align-items: center;
|
||
position: relative;
|
||
|
||
&::after {
|
||
content: "";
|
||
display: block;
|
||
position: absolute;
|
||
top: 50%;
|
||
right: -10rpx;
|
||
transform: translateY(-50%);
|
||
width: 0;
|
||
height: 0;
|
||
border-top: 12rpx solid transparent;
|
||
border-bottom: 12rpx solid transparent;
|
||
border-left: 12rpx solid var(--theme-color);
|
||
}
|
||
}
|
||
|
||
.record-list {
|
||
padding: 16rpx;
|
||
width: 452rpx;
|
||
border-radius: 8rpx;
|
||
|
||
.list-item {
|
||
width: 48rpx;
|
||
height: 48rpx;
|
||
border-radius: 50%;
|
||
overflow: hidden;
|
||
margin-left: -7rpx;
|
||
border: 2rpx solid #ffffff;
|
||
|
||
.item-more {
|
||
width: 100%;
|
||
height: 100%;
|
||
background: var(--theme-color);
|
||
padding: 0 6rpx;
|
||
|
||
.point {
|
||
width: 6rpx;
|
||
height: 6rpx;
|
||
background: #ffffff;
|
||
border-radius: 50%;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
.main-content {
|
||
padding: 32rpx;
|
||
border-radius: 16rpx;
|
||
background: #ffffff;
|
||
color: #5A5B6E;
|
||
font-size: 28rpx;
|
||
line-height: 48rpx;
|
||
margin-top: 32rpx;
|
||
}
|
||
|
||
.main-footer {
|
||
position: fixed;
|
||
left: 0;
|
||
right: 0;
|
||
bottom: 0;
|
||
z-index: 99;
|
||
padding: 12rpx 32rpx 12rpx 48rpx;
|
||
background: #ffffff;
|
||
border-top: 1rpx solid #F6F7FB;
|
||
|
||
.footer-menu {
|
||
.menu-btn {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
margin-right: 32rpx;
|
||
background: transparent;
|
||
padding: 0;
|
||
|
||
.icon {
|
||
width: 52rpx;
|
||
height: 52rpx;
|
||
}
|
||
|
||
.text {
|
||
color: #5A5B6E;
|
||
font-size: 20rpx;
|
||
line-height: 28rpx;
|
||
}
|
||
}
|
||
}
|
||
|
||
.footer-btn {
|
||
color: #ffffff;
|
||
font-size: 32rpx;
|
||
line-height: 44rpx;
|
||
padding: 22rpx 24rpx;
|
||
border-radius: 16rpx;
|
||
background: var(--theme-color);
|
||
text-align: center;
|
||
|
||
&.disabled {
|
||
background: #8D929C;
|
||
}
|
||
}
|
||
}
|
||
|
||
.main-login {
|
||
padding: 64rpx 28rpx 0;
|
||
|
||
.login-image {
|
||
width: 100%;
|
||
height: 500rpx;
|
||
}
|
||
|
||
.login-tips {
|
||
color: #585858;
|
||
font-size: 36rpx;
|
||
line-height: 50rpx;
|
||
margin-top: 48rpx;
|
||
text-align: center;
|
||
}
|
||
|
||
.login-btn {
|
||
margin-top: 56rpx;
|
||
height: 88rpx;
|
||
line-height: 88rpx;
|
||
font-size: 28rpx;
|
||
border-radius: 16rpx;
|
||
text-align: center;
|
||
background: var(--theme-color);
|
||
color: #ffffff;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
</style> |