Files
2026-03-25 15:53:37 +08:00

1167 lines
30 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!-- +----------------------------------------------------------------------
| 麦沃德科技赋能开发者助力商协会发展
+----------------------------------------------------------------------
| Copyright (c) 20172024 www.wdsxh.cn All rights reserved.
+----------------------------------------------------------------------
| 沃德商协会系统并不是自由软件不加密并不代表开源未经许可不可自由转售和商用
+----------------------------------------------------------------------
| Author: MY WORLD Team <bd@maiwd.cn> www.maiwd.cn
+----------------------------------------------------------------------
| 活动详情 开发者: 麦沃德科技-半夏
+---------------------------------------------------------------------- -->
<template>
<page-meta :page-style="'overflow:' + (pageShow ? 'hidden' : 'visible')"></page-meta>
<view class="container" :style="{'--theme-color': themeColor}">
<!-- 标题栏 -->
<title-bar :showBack="true" title="活动详情"></title-bar>
<!-- 内容区 -->
<view class="container-main" v-if="loadEnd">
<!-- 驳回原因 -->
<view class="main-reason" v-if="activityInfo.pay_state == 5">驳回原因{{activityInfo.reject || ""}}</view>
<!-- 轮播图 -->
<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-box">
<view class="box-title">{{activityInfo.name}}</view>
<view class="box-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="box-label" v-if="activityInfo.points_status == 1">参加活动可得{{activityInfo.points || 0}}积分
</view>
<view class="box-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="box-column flex align-items-start" v-if="activityInfo.organizing_method == 2">
<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>
<view class="footer-btn flex-item flex">
<!-- 报名中 -->
<block v-if="activityInfo.activity_state == 1">
<!-- 待付款 -->
<block v-if="activityInfo.pay_state == 1">
<view class="btn1" style="background: #FF626E;" @click="toCancel(activityInfo.apply_id)">
取消参加</view>
<view class="btn" @click="toPayment">去支付</view>
</block>
<!-- 已付款 -->
<block v-else-if="activityInfo.pay_state == 2">
<!-- 取消参加/申请退款 -->
<block>
<!-- 免费 -->
<view class="btn1" style="background: #FF626E;"
@click="handleCancel(activityInfo.apply_id)"
v-if="parseFloat(activityInfo.fees) == 0">取消参加</view>
<!-- 付费 -->
<view class="btn" style="background: #FF626E;"
@click="handleRefund(activityInfo.apply_id)"
v-else-if="activityInfo.refund == 1">申请退款</view>
</block>
<!-- 线上地址/参会凭证 -->
<block>
<view class="btn" style="background: #FFB656;"
@click="showWebsite(activityInfo.url)"
v-if="activityInfo.organizing_method == 1">线上地址</view>
<view v-else-if="activityInfo.organizing_method == 2"
class="btn footer-btn flex-item flex flex-center"
:class="{disabled: buttonConfig.disabled}" @click="handleButtonClick"
:style="{backgroundColor: buttonConfig.bgColor}">
<text>{{buttonConfig.text}}</text>
</view>
</block>
</block>
<!-- 退款中 -->
<block v-else-if="activityInfo.pay_state == 3">
<view class="btn" style="background: #bbbbbb;">退款中</view>
</block>
<!-- 已退款 -->
<block v-else-if="activityInfo.pay_state == 4">
<view class="btn" style="background: #bbbbbb;">已退款</view>
</block>
<!-- 已驳回 -->
<block v-else-if="activityInfo.pay_state == 5">
<view class="btn" style="background: #FF626E;"
@click="handleRefund(activityInfo.apply_id)">申请退款</view>
</block>
</block>
<!-- 进行中 -->
<block v-else-if="activityInfo.activity_state == 2 && activityInfo.pay_state == 2">
<view class="btn" style="background: #FFB656;" @click="showWebsite(activityInfo.url)"
v-if="activityInfo.organizing_method == 1">线上地址</view>
<view v-else-if="activityInfo.organizing_method == 2"
class="btn footer-btn flex-item flex flex-center"
:class="{disabled: buttonConfig.disabled}" @click="handleButtonClick"
:style="{backgroundColor: buttonConfig.bgColor}">
<text>{{buttonConfig.text}}</text>
</view>
</block>
<!-- 已结束 opacity:0.6-->
<block v-else-if="activityInfo.activity_state == 3">
<view class="btn" style="background: #8d929c;" @click="handleButtonClick">活动已结束</view>
<view class="btn" @click="showCertificate" v-if="activityInfo.pay_state == 2">参会证书</view>
</block>
</view>
</view>
<view class="safe-padding"></view>
</view>
</view>
<!-- 参会凭证 -->
<activity-poster ref="activityPoster" @onChange="pageChange"></activity-poster>
<!-- 参会证书 -->
<activity-certificate ref="activityCertificate" @onChange="pageChange"></activity-certificate>
</view>
</template>
<script>
import {
mapState
} from "vuex"
import carousel from "@/pages/component/carousel/carousel.vue"
import activityPoster from "@/pages/component/activity/poster.vue"
import activityCertificate from "@/pages/component/activity/certificate.vue"
import svgData from "@/common/svg.js"
// #ifdef H5
import wx from 'weixin-js-sdk';
// #endif
export default {
components: {
carousel,
activityPoster,
activityCertificate,
},
data() {
return {
// 加载完成
loadEnd: false,
// 页面是否阻止滚动
pageShow: false,
// 活动id
activityId: null,
// 报名id
applyId: null,
// 活动详情
activityInfo: {},
// 活动剩余时间计时器
activityInterval: null,
// 活动倒计时
countdown: {
day: 0,
hours: 0,
minutes: 0,
seconds: 0,
},
// 延时器
delayer: null,
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)
},
// 按钮配置
buttonConfig() {
// 默认配置
const config = {
text: '已报名',
disabled: false,
needPhone: false
}
// 根据活动状态返回不同配置
switch (this.activityStatus) {
case 1: // 报名阶段
// 已报名
return {
text: '已报名',
disabled: false,
needPhone: false
}
case 2: // 未开始
return {
text: '活动未开始',
disabled: true,
needPhone: false,
bgColor: '#8d929c' // 绿色,表示已完成
}
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) {
uni.showLoading({
title: "加载中"
})
if (!uni.getStorageSync("token")) {
this.$util.verifyLogin(2)
return
}
if (option.scene) {
let scene = this.$util.parseURLParams(decodeURIComponent(option.scene))
this.activityId = scene.activity_id
this.applyId = scene.id
} else {
this.activityId = option.activity_id
this.applyId = option.id
}
this.getActivity(() => {
this.loadEnd = true
uni.hideLoading()
})
// #ifdef H5
this.initConfig()
// #endif
},
onUnload() {
clearInterval(this.activityInterval)
if (this.delayer) clearTimeout(this.delayer)
},
methods: {
// 改变页面滚动状态
pageChange(state) {
this.pageShow = state
},
// #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: ['wx-open-launch-weapp', 'scanQRCode', "getLocation"],
openTagList: ['wx-open-launch-weapp'],
})
} else {
uni.hideLoading()
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('通过config接口注入权限验证配置 ', error)
})
},
// #endif
// 获取活动详情
getActivity(fn) {
this.$util.request("activity.orderDetails", {
id: this.activityId,
apply_id: this.applyId,
}).then(res => {
if (fn) fn()
if (res.code == 1) {
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 {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
console.error('获取活动详情 ', error)
})
},
// 显示提示
showToast(msg) {
uni.showToast({
title: msg,
icon: 'none'
})
},
// 统一处理按钮点击
handleButtonClick() {
// 如果按钮是禁用状态,不处理点击
if (this.buttonConfig.disabled) {
// 禁用状态的按钮也有对应的提示
this.handleAction()
return
}
// 已登录且按钮可用,根据状态执行对应操作
this.handleAction()
},
// handleResult(){
// this.showToast('本次活动已结束,无法进行签到或报名!')
// return;
// },
// 根据状态处理不同逻辑
handleAction() {
switch (this.activityStatus) {
case 1: // 报名阶段
this.showToast('您已报名!')
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('签到失败,请重试')
})
},
// 获取活动剩余时间
getCountdown() {
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) {
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: {
address: this.activityInfo.address,
latitude: this.activityInfo.latitude,
longitude: this.activityInfo.longitude
}
})
},
// 联系
onContact() {
this.$util.toPage({
mode: 6,
phone: this.activityInfo.mobile,
})
},
// 去支付
toPayment() {
this.$util.toPage({
mode: 1,
path: "/pagesActivity/index/order?id=" + this.activityId
})
},
// 未支付取消参加
toCancel(applyId) {
uni.showModal({
content: "确认取消参加此活动?",
confirmColor: "#FF626E",
confirmText: "确认取消",
cancelColor: "#999999",
cancelText: "我再想想",
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("activity.applyDel", {
id: applyId
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.showToast({
title: "取消成功",
icon: "success",
mask: true,
duration: 1500
})
this.delayer = setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('取消参加 ', error)
})
}
}
})
},
// 取消参加
handleCancel(applyId) {
uni.showModal({
content: "确认取消参加此活动?",
confirmColor: "#FF626E",
confirmText: "确认取消",
cancelColor: "#999999",
cancelText: "我再想想",
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("activity.applyCancel", {
id: applyId
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.showToast({
title: "取消成功",
icon: "success",
mask: true,
duration: 1500
})
this.delayer = setTimeout(() => {
uni.navigateBack()
}, 1500)
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('取消参加 ', error)
})
}
}
})
},
// 申请退款
handleRefund(applyId) {
uni.showModal({
content: "确认申请退款此活动?",
confirmColor: "#FF626E",
confirmText: "确认退款",
cancelColor: "#999999",
cancelText: "取消退款",
success: (res) => {
if (res.confirm) {
uni.showLoading({
title: "加载中",
mask: true
})
this.$util.request("activity.applyRefund", {
activity_id: this.activityId,
apply_id: applyId
}).then(res => {
uni.hideLoading()
if (res.code == 1) {
uni.redirectTo({
url: "/pagesActivity/order/success"
})
} else {
uni.showToast({
title: res.msg,
icon: 'none'
})
}
}).catch(error => {
uni.hideLoading()
console.error('申请退款 ', error)
})
}
}
})
},
// 线上地址
showWebsite() {
if (this.activityInfo.url) {
uni.showModal({
content: this.activityInfo.url,
confirmColor: this.themeColor,
confirmText: "复制链接",
cancelColor: "#999999",
cancelText: "关闭页面",
success: (res) => {
if (res.confirm) {
this.$util.toPage({
mode: 8,
content: this.activityInfo.url,
})
}
}
})
} else {
uni.showToast({
icon: "none",
title: "暂无线上地址,请稍后再试"
})
}
},
// 获取位置权限
getAuthSetting(fn) {
// #ifdef MP-WEIXIN
uni.getSetting({
success: (setting) => {
if (setting.authSetting && setting.authSetting.hasOwnProperty("scope.userLocation")) {
if (setting.authSetting["scope.userLocation"]) {
if (fn) fn()
} else {
uni.hideLoading()
uni.showModal({
title: '提示',
content: '请重新授权获取您的地理位置,否则部分功能将无法使用',
confirmColor: this.themeColor,
confirmText: "授权",
success: (res) => {
if (res.confirm) {
uni.openSetting({
success: (result) => {
if (result.authSetting[
"scope.userLocation"]) {
if (fn) fn()
} else {
uni.showToast({
title: '请确定已打开定位权限',
icon: "none",
duration: 2000,
});
}
},
fail: () => {
uni.showToast({
title: '位置获取失败',
icon: 'none',
duration: 2000,
})
}
})
} else {
uni.showToast({
title: '请授权获取您的地理位置,否则部分功能将无法使用',
icon: 'none',
duration: 2000,
})
}
},
fail: () => {
if (fn) fn()
}
})
}
} else {
if (fn) fn()
}
},
fail: () => {
uni.showToast({
title: '位置获取失败',
icon: 'none',
duration: 2000,
})
}
})
// #endif
// #ifdef H5
if (fn) fn()
// #endif
},
// 获取当前地址
getLocation(fn) {
// #ifdef MP-WEIXIN
uni.getLocation({
type: 'wgs84',
geocode: true,
success: (res) => {
fn({
latitude: res.latitude,
longitude: res.longitude,
})
},
fail: () => {
fn()
}
});
// #endif
// #ifdef H5
wx.ready(() => {
wx.getLocation({
type: 'wgs84',
success: (res) => {
fn({
latitude: res.latitude,
longitude: res.longitude,
})
},
fail: (err) => {
fn()
},
cancel: () => {
fn()
}
});
})
// #endif
},
// 截取地址栏参数
getUrlParam(url) {
const query = url.split("?")[1] || "";
const params = {};
query.split("&").forEach((pair) => {
const [key, value] = pair.split("=");
if (key) {
params[key] = decodeURIComponent(value || "");
}
});
return params;
},
// 参会证书
showCertificate() {
this.$refs.activityCertificate.getPoster(this.activityId, this.applyId)
},
}
}
</script>
<style lang="scss">
.container {
.container-main {
padding: 32rpx 32rpx 144rpx;
.main-reason {
color: #FF626E;
font-size: 28rpx;
line-height: 40rpx;
padding: 32rpx;
border-radius: 16rpx;
background: #FFF3F3;
margin-bottom: 32rpx;
}
.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-box {
padding: 32rpx;
.box-title {
color: #5A5B6E;
font-size: 32rpx;
font-weight: 600;
line-height: 44rpx;
}
.box-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;
}
}
}
.box-label {
margin-top: 24rpx;
color: #FF8112;
font-size: 24rpx;
line-height: 36rpx;
padding: 14rpx 24rpx;
border-radius: 16rpx;
background: #FFF9EF;
}
.box-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;
&::after {
content: "";
display: block;
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 {
.btn1 {
color: #ffffff;
font-size: 32rpx;
line-height: 44rpx;
padding: 22rpx 24rpx;
border-radius: 16rpx;
background: var(--theme-color);
text-align: center;
width: 50%;
margin-left: 16rpx;
&:first-child {
margin-left: 0;
}
}
.btn {
color: #ffffff;
font-size: 32rpx;
line-height: 44rpx;
padding: 22rpx 24rpx;
border-radius: 16rpx;
background: var(--theme-color);
text-align: center;
width: 100%;
margin-left: 16rpx;
&:first-child {
margin-left: 0;
}
}
}
}
}
}
</style>