feat: 添加模式选择功能与页面更新
- 在 onboarding 页面中新增使用模式选择功能,用户可选择“戒烟打卡”或“记录抽烟”模式 - 更新个人资料页面以显示当前模式并允许用户切换模式 - 在 pages.json 中注册新的模式选择页面 - 优化首页和其他相关页面以适应新模式功能
This commit is contained in:
+499
-435
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,219 @@
|
||||
<template>
|
||||
<view class="page">
|
||||
<view class="nav-placeholder" :style="{ height: navBarHeight + 'px' }"></view>
|
||||
|
||||
<view class="content">
|
||||
<view class="hero">
|
||||
<text class="eyebrow">首次进入先选模式</text>
|
||||
<text class="title">你现在想怎么用这个小程序?</text>
|
||||
<text class="subtitle">先选“戒烟打卡”或“记录抽烟”,后续可以在个人中心随时切换。</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="mode-card"
|
||||
:class="{ 'mode-card-active': currentMode === 'quit' }"
|
||||
@tap="selectMode('quit')"
|
||||
>
|
||||
<view class="mode-icon mode-icon-quit">🔥</view>
|
||||
<view class="mode-main">
|
||||
<text class="mode-title">戒烟打卡</text>
|
||||
<text class="mode-desc">按天记录“今天没抽”,用连续天数驱动坚持。</text>
|
||||
</view>
|
||||
<text class="mode-arrow">›</text>
|
||||
</view>
|
||||
|
||||
<view
|
||||
class="mode-card"
|
||||
:class="{ 'mode-card-active': currentMode === 'record' }"
|
||||
@tap="selectMode('record')"
|
||||
>
|
||||
<view class="mode-icon mode-icon-record">🚬</view>
|
||||
<view class="mode-main">
|
||||
<text class="mode-title">记录抽烟</text>
|
||||
<text class="mode-desc">继续按支数记录,观察自己的频率和变化趋势。</text>
|
||||
</view>
|
||||
<text class="mode-arrow">›</text>
|
||||
</view>
|
||||
|
||||
<text class="footer-tip">当前选择:{{ currentModeText }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useProfileStore } from '@/stores/profile'
|
||||
|
||||
const userStore = useUserStore()
|
||||
const profileStore = useProfileStore()
|
||||
const { waitForLogin } = useLogin()
|
||||
|
||||
const navBarHeight = ref(0)
|
||||
const submitting = ref(false)
|
||||
|
||||
const currentMode = computed(() => userStore.mode)
|
||||
const currentModeText = computed(() => {
|
||||
if (userStore.mode === 'quit') return '戒烟打卡'
|
||||
if (userStore.mode === 'record') return '记录抽烟'
|
||||
return '未选择'
|
||||
})
|
||||
|
||||
function setupNavBar() {
|
||||
const sys = uni.getSystemInfoSync()
|
||||
const statusBarH = sys.statusBarHeight || 0
|
||||
try {
|
||||
const menuBtn = uni.getMenuButtonBoundingClientRect()
|
||||
navBarHeight.value = menuBtn.bottom + (menuBtn.top - statusBarH)
|
||||
} catch (e) {
|
||||
navBarHeight.value = statusBarH + 44
|
||||
}
|
||||
}
|
||||
|
||||
async function selectMode(mode) {
|
||||
if (submitting.value) return
|
||||
submitting.value = true
|
||||
userStore.setMode(mode)
|
||||
|
||||
try {
|
||||
const profileData = await profileStore.saveProfile({ mode })
|
||||
const profile = profileData.profile
|
||||
const isCompleted = profileData.is_completed ||
|
||||
(profile && profile.onboarding_completed_at) ||
|
||||
(profile && profile.baseline_cigs_per_day > 0)
|
||||
|
||||
if (!profileData.exists || !isCompleted) {
|
||||
uni.redirectTo({ url: '/pages/onboarding/index' })
|
||||
return
|
||||
}
|
||||
|
||||
uni.switchTab({ url: '/pages/index/index' })
|
||||
} catch (e) {
|
||||
console.error('selectMode error:', e)
|
||||
uni.switchTab({ url: '/pages/index/index' })
|
||||
} finally {
|
||||
submitting.value = false
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
setupNavBar()
|
||||
await waitForLogin()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.page {
|
||||
min-height: 100vh;
|
||||
background:
|
||||
radial-gradient(circle at top left, rgba(16, 185, 129, 0.18), transparent 34%),
|
||||
linear-gradient(180deg, #ecfdf5 0%, #f7fee7 42%, #ffffff 100%);
|
||||
}
|
||||
|
||||
.nav-placeholder {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding: 40rpx 32rpx 56rpx;
|
||||
}
|
||||
|
||||
.hero {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.eyebrow {
|
||||
display: inline-flex;
|
||||
padding: 8rpx 18rpx;
|
||||
border-radius: 999rpx;
|
||||
background: rgba(16, 185, 129, 0.12);
|
||||
color: #047857;
|
||||
font-size: 22rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.title {
|
||||
display: block;
|
||||
font-size: 48rpx;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
line-height: 1.28;
|
||||
}
|
||||
|
||||
.subtitle {
|
||||
display: block;
|
||||
margin-top: 16rpx;
|
||||
font-size: 28rpx;
|
||||
line-height: 1.6;
|
||||
color: #4b5563;
|
||||
}
|
||||
|
||||
.mode-card {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
padding: 30rpx 28rpx;
|
||||
margin-bottom: 24rpx;
|
||||
border-radius: 28rpx;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
border: 2rpx solid rgba(255, 255, 255, 0.6);
|
||||
box-shadow: 0 16rpx 44rpx rgba(15, 23, 42, 0.08);
|
||||
}
|
||||
|
||||
.mode-card-active {
|
||||
border-color: rgba(16, 185, 129, 0.35);
|
||||
box-shadow: 0 20rpx 52rpx rgba(16, 185, 129, 0.14);
|
||||
}
|
||||
|
||||
.mode-icon {
|
||||
width: 92rpx;
|
||||
height: 92rpx;
|
||||
border-radius: 24rpx;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 42rpx;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.mode-icon-quit {
|
||||
background: linear-gradient(135deg, #d1fae5 0%, #86efac 100%);
|
||||
}
|
||||
|
||||
.mode-icon-record {
|
||||
background: linear-gradient(135deg, #fee2e2 0%, #fecaca 100%);
|
||||
}
|
||||
|
||||
.mode-main {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.mode-title {
|
||||
display: block;
|
||||
font-size: 34rpx;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.mode-desc {
|
||||
display: block;
|
||||
margin-top: 10rpx;
|
||||
font-size: 25rpx;
|
||||
line-height: 1.5;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.mode-arrow {
|
||||
font-size: 42rpx;
|
||||
color: #9ca3af;
|
||||
}
|
||||
|
||||
.footer-tip {
|
||||
display: block;
|
||||
margin-top: 20rpx;
|
||||
font-size: 24rpx;
|
||||
color: #6b7280;
|
||||
text-align: center;
|
||||
}
|
||||
</style>
|
||||
+122
-4
@@ -10,9 +10,25 @@
|
||||
</view>
|
||||
|
||||
<view class="content">
|
||||
<view class="mode-section">
|
||||
<text class="mode-section-label">使用模式</text>
|
||||
<view class="mode-switch">
|
||||
<view
|
||||
v-for="item in modeOptions"
|
||||
:key="item.value"
|
||||
class="mode-switch-item"
|
||||
:class="{ 'mode-switch-item-active': currentMode === item.value }"
|
||||
@tap="selectMode(item.value)"
|
||||
>
|
||||
<text class="mode-switch-title">{{ item.label }}</text>
|
||||
<text class="mode-switch-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
|
||||
<view v-if="step === 1" class="step">
|
||||
<text class="step-title">你每天抽多少支烟?</text>
|
||||
<text class="step-desc">这将帮助我们为你制定个性化的戒烟计划</text>
|
||||
<text class="step-desc">{{ baselineDesc }}</text>
|
||||
<view class="input-group">
|
||||
<view class="input-row">
|
||||
<view class="input-btn" @tap="decreaseCigs">-</view>
|
||||
@@ -40,8 +56,8 @@
|
||||
</view>
|
||||
|
||||
<view v-if="step === 3" class="step">
|
||||
<text class="step-title">你为什么想戒烟?</text>
|
||||
<text class="step-desc">选择对你最重要的原因(可多选)</text>
|
||||
<text class="step-title">{{ motivationTitle }}</text>
|
||||
<text class="step-desc">{{ motivationDesc }}</text>
|
||||
<view class="options options-wrap">
|
||||
<view
|
||||
v-for="option in quitMotivationOptions"
|
||||
@@ -96,7 +112,7 @@
|
||||
<view class="footer">
|
||||
<view v-if="step > 1" class="btn-secondary" @tap="prevStep">上一步</view>
|
||||
<view class="btn-primary" :class="{ 'btn-full': step === 1 }" @tap="nextStep">
|
||||
{{ step === 5 ? '开始戒烟之旅 🚀' : '下一步' }}
|
||||
{{ step === 5 ? finishButtonText + ' 🚀' : '下一步' }}
|
||||
</view>
|
||||
</view>
|
||||
</view>
|
||||
@@ -106,16 +122,24 @@
|
||||
import { ref, computed, onMounted } from 'vue'
|
||||
import { onShareAppMessage } from '@dcloudio/uni-app'
|
||||
import { useProfileStore } from '@/stores/profile'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
|
||||
const profileStore = useProfileStore()
|
||||
const userStore = useUserStore()
|
||||
const { waitForLogin } = useLogin()
|
||||
|
||||
const navBarHeight = ref(0)
|
||||
const step = ref(1)
|
||||
const totalSteps = 5
|
||||
const modeSaving = ref(false)
|
||||
const modeOptions = [
|
||||
{ value: 'quit', label: '戒烟打卡', desc: '按天记录今天没抽' },
|
||||
{ value: 'record', label: '记录抽烟', desc: '按支数记录变化' }
|
||||
]
|
||||
|
||||
const formData = ref({
|
||||
mode: 'record',
|
||||
baseline_cigs_per_day: 10,
|
||||
smoking_years: 5,
|
||||
quit_motivations: [],
|
||||
@@ -128,6 +152,12 @@ const formData = ref({
|
||||
const priceYuan = ref('25')
|
||||
|
||||
const progressWidth = computed(() => `${(step.value / totalSteps) * 100}%`)
|
||||
const currentMode = computed(() => formData.value.mode || userStore.mode || 'record')
|
||||
const isRecordMode = computed(() => currentMode.value === 'record')
|
||||
const baselineDesc = computed(() => isRecordMode.value ? '这会成为你后续记录和统计的基线' : '这将帮助我们为你制定更合适的戒烟节奏')
|
||||
const motivationTitle = computed(() => isRecordMode.value ? '你为什么想先开始记录抽烟?' : '你为什么想戒烟?')
|
||||
const motivationDesc = computed(() => isRecordMode.value ? '选择最符合你当前状态的原因(可多选)' : '选择对你最重要的原因(可多选)')
|
||||
const finishButtonText = computed(() => isRecordMode.value ? '开始记录之旅' : '开始戒烟之旅')
|
||||
|
||||
const smokingYearsOptions = [
|
||||
{ label: '少于1年', value: 1 },
|
||||
@@ -165,6 +195,20 @@ function toggleMotivation(option) {
|
||||
}
|
||||
}
|
||||
|
||||
async function selectMode(mode) {
|
||||
formData.value.mode = mode
|
||||
userStore.setMode(mode)
|
||||
if (!profileStore.exists || modeSaving.value) return
|
||||
modeSaving.value = true
|
||||
try {
|
||||
await profileStore.saveProfile({ mode })
|
||||
} catch (e) {
|
||||
console.error('saveModeInOnboarding error:', e)
|
||||
} finally {
|
||||
modeSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function onWakeTimeChange(e) {
|
||||
formData.value.wake_up_time = e.detail.value
|
||||
}
|
||||
@@ -191,6 +235,10 @@ async function nextStep() {
|
||||
uni.showLoading({ title: '保存中...' })
|
||||
await profileStore.saveProfile(formData.value)
|
||||
uni.hideLoading()
|
||||
if (!formData.value.mode) {
|
||||
uni.redirectTo({ url: '/pages/mode-select/index' })
|
||||
return
|
||||
}
|
||||
uni.switchTab({ url: '/pages/index/index' })
|
||||
} catch (e) {
|
||||
uni.hideLoading()
|
||||
@@ -208,6 +256,30 @@ onMounted(async () => {
|
||||
navBarHeight.value = statusBarH + 44
|
||||
}
|
||||
await waitForLogin()
|
||||
try {
|
||||
const profileData = await profileStore.fetchProfile()
|
||||
if (profileData?.profile) {
|
||||
const profile = profileData.profile
|
||||
formData.value = {
|
||||
...formData.value,
|
||||
mode: profile.mode || userStore.mode || formData.value.mode,
|
||||
baseline_cigs_per_day: profile.baseline_cigs_per_day || formData.value.baseline_cigs_per_day,
|
||||
smoking_years: profile.smoking_years || formData.value.smoking_years,
|
||||
quit_motivations: Array.isArray(profile.quit_motivations) ? profile.quit_motivations : formData.value.quit_motivations,
|
||||
smoke_motivations: Array.isArray(profile.smoke_motivations) ? profile.smoke_motivations : formData.value.smoke_motivations,
|
||||
wake_up_time: profile.wake_up_time || formData.value.wake_up_time,
|
||||
sleep_time: profile.sleep_time || formData.value.sleep_time,
|
||||
pack_price_cent: profile.pack_price_cent || formData.value.pack_price_cent
|
||||
}
|
||||
if (profile.pack_price_cent) {
|
||||
priceYuan.value = String((profile.pack_price_cent / 100).toFixed(2)).replace(/\.00$/, '')
|
||||
}
|
||||
} else if (userStore.mode) {
|
||||
formData.value.mode = userStore.mode
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('loadProfileForOnboarding error:', e)
|
||||
}
|
||||
})
|
||||
|
||||
onShareAppMessage(() => {
|
||||
@@ -270,6 +342,52 @@ onShareAppMessage(() => {
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.mode-section {
|
||||
margin-bottom: 40rpx;
|
||||
}
|
||||
|
||||
.mode-section-label {
|
||||
display: block;
|
||||
margin-bottom: 16rpx;
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #047857;
|
||||
}
|
||||
|
||||
.mode-switch {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.mode-switch-item {
|
||||
padding: 24rpx;
|
||||
border-radius: 20rpx;
|
||||
background: rgba(255, 255, 255, 0.82);
|
||||
border: 2rpx solid #d1fae5;
|
||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
||||
}
|
||||
|
||||
.mode-switch-item-active {
|
||||
background: #ecfdf5;
|
||||
border-color: #10b981;
|
||||
}
|
||||
|
||||
.mode-switch-title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.mode-switch-desc {
|
||||
display: block;
|
||||
margin-top: 10rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
color: #6b7280;
|
||||
}
|
||||
|
||||
.step {
|
||||
animation: fadeIn 0.3s ease;
|
||||
}
|
||||
|
||||
+115
-24
@@ -6,25 +6,30 @@
|
||||
</view>
|
||||
|
||||
<view class="section">
|
||||
<view class="mode-card">
|
||||
<view class="mode-card-header">
|
||||
<view class="menu-icon menu-icon-green">🧭</view>
|
||||
<view class="menu-content">
|
||||
<text class="menu-label">打卡模式</text>
|
||||
<text class="menu-desc">直接切换成“戒烟打卡”或“记录抽烟”</text>
|
||||
</view>
|
||||
</view>
|
||||
<view class="mode-switch">
|
||||
<view
|
||||
v-for="item in modeOptions"
|
||||
:key="item.value"
|
||||
class="mode-switch-item"
|
||||
:class="{ 'mode-switch-item-active': userStore.mode === item.value }"
|
||||
@tap="changeMode(item.value)"
|
||||
>
|
||||
<text class="mode-switch-title">{{ item.label }}</text>
|
||||
<text class="mode-switch-desc">{{ item.desc }}</text>
|
||||
</view>
|
||||
</view>
|
||||
<text class="mode-hint">当前:{{ modeText }}</text>
|
||||
</view>
|
||||
|
||||
<view class="menu-list">
|
||||
<view class="menu-item" @tap="goAISuggest">
|
||||
<view class="menu-icon menu-icon-green">🤖</view>
|
||||
<view class="menu-content">
|
||||
<text class="menu-label">AI 建议</text>
|
||||
<text class="menu-desc">查看今日 AI 控烟节奏与建议节点</text>
|
||||
</view>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
|
||||
<view class="menu-item" @tap="goAISummary">
|
||||
<view class="menu-icon menu-icon-green">📝</view>
|
||||
<view class="menu-content">
|
||||
<text class="menu-label">AI 总结</text>
|
||||
<text class="menu-desc">按日期生成抽烟总结和明日建议</text>
|
||||
</view>
|
||||
<text class="menu-arrow">›</text>
|
||||
</view>
|
||||
|
||||
<view class="menu-item">
|
||||
<view class="menu-icon menu-icon-green">🔗</view>
|
||||
<view class="menu-content">
|
||||
@@ -79,18 +84,30 @@
|
||||
import { computed, ref } from 'vue'
|
||||
import { onShareAppMessage, onShow } from '@dcloudio/uni-app'
|
||||
import * as api from '@/api'
|
||||
import { useProfileStore } from '@/stores/profile'
|
||||
import { useUserStore } from '@/stores/user'
|
||||
import { useLogin } from '@/hooks/useLogin'
|
||||
|
||||
const profileStore = useProfileStore()
|
||||
const userStore = useUserStore()
|
||||
const { waitForLogin } = useLogin()
|
||||
|
||||
const shareToken = ref('')
|
||||
const shareExpireAt = ref('')
|
||||
const shareLoading = ref(false)
|
||||
const modeSaving = ref(false)
|
||||
const modeOptions = [
|
||||
{ value: 'quit', label: '戒烟打卡', desc: '按天记录今天没抽' },
|
||||
{ value: 'record', label: '记录抽烟', desc: '按支数记录变化' }
|
||||
]
|
||||
|
||||
const userName = computed(() => userStore.user?.nickname || '戒烟用户')
|
||||
const userAvatar = computed(() => userStore.user?.avatar_url || 'https://linghu-wmr.oss-cn-beijing.aliyuncs.com/smt/avatar.png')
|
||||
const modeText = computed(() => {
|
||||
if (userStore.mode === 'quit') return '戒烟打卡'
|
||||
if (userStore.mode === 'record') return '记录抽烟'
|
||||
return '未选择'
|
||||
})
|
||||
|
||||
const shareDesc = computed(() => {
|
||||
if (!shareToken.value) {
|
||||
@@ -152,12 +169,23 @@ function previewSharePage() {
|
||||
})
|
||||
}
|
||||
|
||||
function goAISuggest() {
|
||||
uni.navigateTo({ url: '/pages/ai/index' })
|
||||
}
|
||||
|
||||
function goAISummary() {
|
||||
uni.navigateTo({ url: '/pages/ai_summary/index' })
|
||||
async function changeMode(nextMode) {
|
||||
if (!nextMode || nextMode === userStore.mode || modeSaving.value) return
|
||||
modeSaving.value = true
|
||||
try {
|
||||
uni.showLoading({ title: '切换中...' })
|
||||
await profileStore.saveProfile({ mode: nextMode })
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '模式已切换', icon: 'success' })
|
||||
setTimeout(() => {
|
||||
uni.switchTab({ url: '/pages/index/index' })
|
||||
}, 250)
|
||||
} catch (e) {
|
||||
uni.hideLoading()
|
||||
uni.showToast({ title: '切换失败', icon: 'none' })
|
||||
} finally {
|
||||
modeSaving.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function goOnboarding() {
|
||||
@@ -199,6 +227,7 @@ onShareAppMessage(() => {
|
||||
|
||||
onShow(async () => {
|
||||
await waitForLogin()
|
||||
await profileStore.fetchProfile()
|
||||
await prepareShareToken(false)
|
||||
})
|
||||
</script>
|
||||
@@ -238,6 +267,22 @@ onShow(async () => {
|
||||
margin-bottom: 24rpx;
|
||||
}
|
||||
|
||||
.mode-card {
|
||||
background-color: #FFFFFF;
|
||||
border-radius: 24rpx;
|
||||
padding: 28rpx 24rpx;
|
||||
border: 2rpx solid #ECFDF3;
|
||||
box-shadow: 0 8rpx 20rpx rgba(16, 185, 129, 0.08);
|
||||
margin-bottom: 16rpx;
|
||||
}
|
||||
|
||||
.mode-card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 24rpx;
|
||||
margin-bottom: 20rpx;
|
||||
}
|
||||
|
||||
.menu-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -313,6 +358,52 @@ onShow(async () => {
|
||||
color: #9CA3AF;
|
||||
}
|
||||
|
||||
.menu-value {
|
||||
font-size: 24rpx;
|
||||
font-weight: 600;
|
||||
color: #10B981;
|
||||
}
|
||||
|
||||
.mode-switch {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
gap: 16rpx;
|
||||
}
|
||||
|
||||
.mode-switch-item {
|
||||
padding: 22rpx 20rpx;
|
||||
border-radius: 18rpx;
|
||||
background: #F9FAFB;
|
||||
border: 2rpx solid #E5E7EB;
|
||||
}
|
||||
|
||||
.mode-switch-item-active {
|
||||
background: #ECFDF5;
|
||||
border-color: #10B981;
|
||||
}
|
||||
|
||||
.mode-switch-title {
|
||||
display: block;
|
||||
font-size: 28rpx;
|
||||
font-weight: 700;
|
||||
color: #111827;
|
||||
}
|
||||
|
||||
.mode-switch-desc {
|
||||
display: block;
|
||||
margin-top: 8rpx;
|
||||
font-size: 22rpx;
|
||||
line-height: 1.5;
|
||||
color: #6B7280;
|
||||
}
|
||||
|
||||
.mode-hint {
|
||||
display: block;
|
||||
margin-top: 16rpx;
|
||||
font-size: 22rpx;
|
||||
color: #10B981;
|
||||
}
|
||||
|
||||
.share-btn {
|
||||
margin: 0;
|
||||
padding: 10rpx 20rpx;
|
||||
|
||||
Reference in New Issue
Block a user