|
|
@@ -13,7 +13,7 @@
|
|
|
</view>
|
|
|
<template v-else-if="article">
|
|
|
<scroll-view scroll-y class="content-scroll" @scrolltolower="onScrollToBottom">
|
|
|
- <image v-if="article.coverImage" class="detail-cover" :src="article.coverImage" mode="widthFix" />
|
|
|
+ <image v-if="article.coverImage" class="detail-cover" :src="article.coverImage" mode="widthFix" lazy-load />
|
|
|
<text class="detail-title">{{ article.title }}</text>
|
|
|
<view class="detail-meta">
|
|
|
<text class="meta-author">{{ article.author || '浠艾福' }}</text>
|
|
|
@@ -41,16 +41,7 @@
|
|
|
<view class="divider"></view>
|
|
|
<view class="detail-body"><mp-html :content="article.content" :domain="config.API_BASE_URL" :tag-style="contentTagStyle" /></view>
|
|
|
|
|
|
- <!-- 关联商品推荐(文章标签 ↔ 商品标签匹配,登录/匿名均可返回) -->
|
|
|
- <view v-if="relatedProducts.length > 0" class="related-section">
|
|
|
- <view class="related-header">
|
|
|
- <text class="related-title">相关商品</text>
|
|
|
- <text class="related-subtitle">根据文章内容推荐</text>
|
|
|
- </view>
|
|
|
- <dimension-products :products="relatedProducts" @productClick="goRelatedProduct" />
|
|
|
- </view>
|
|
|
-
|
|
|
- <!-- 相关文章(按标签关联,无匹配整块隐藏) -->
|
|
|
+ <!-- 相关文章(按标签关联,无匹配整块隐藏;触底分页加载) -->
|
|
|
<view v-if="relatedArticles.length > 0" class="related-section">
|
|
|
<view class="related-header">
|
|
|
<text class="related-title">相关文章</text>
|
|
|
@@ -64,13 +55,25 @@
|
|
|
hover-class="ra-item-pressed"
|
|
|
@click="goRelatedArticle(item)"
|
|
|
>
|
|
|
- <image class="ra-cover" :src="getImageUrl(item.coverImage) || '/static/default-article.png'" mode="aspectFill" />
|
|
|
+ <image class="ra-cover" :src="getImageUrl(item.coverImage) || '/static/default-article.png'" mode="aspectFill" lazy-load />
|
|
|
<view class="ra-body">
|
|
|
<text class="ra-title">{{ item.title }}</text>
|
|
|
<text class="ra-summary" v-if="item.summary">{{ item.summary }}</text>
|
|
|
</view>
|
|
|
</view>
|
|
|
</view>
|
|
|
+ <view v-if="relatedArticlesLoading" class="related-loading-hint">加载中...</view>
|
|
|
+ </view>
|
|
|
+
|
|
|
+ <!-- 关联商品推荐(文章标签 ↔ 商品标签匹配,登录/匿名均可返回;商城两列大卡片样式,触底分页加载) -->
|
|
|
+ <view v-if="relatedProducts.length > 0" class="related-section">
|
|
|
+ <view class="related-header">
|
|
|
+ <text class="related-title">相关商品</text>
|
|
|
+ <text class="related-subtitle">根据文章内容推荐</text>
|
|
|
+ </view>
|
|
|
+ <dimension-products :products="relatedProducts" layout="mall" @productClick="goRelatedProduct" />
|
|
|
+ <view v-if="relatedProductsLoading" class="related-loading-hint">加载中...</view>
|
|
|
+ <view v-else-if="relatedProductsNoMore" class="related-loading-hint dim">没有更多了</view>
|
|
|
</view>
|
|
|
|
|
|
<!-- 评论区(已屏蔽) -->
|
|
|
@@ -108,7 +111,11 @@
|
|
|
</view>
|
|
|
<text class="q-title">{{ currentQuestion.question }}</text>
|
|
|
<view class="q-options">
|
|
|
- <text v-for="(opt, oi) in currentQuestion.options" :key="oi" class="q-option" :class="{ selected: quizAnswers[currentQuizIndex] === String.fromCharCode(65 + oi) }" @click="selectQuizAnswer(currentQuizIndex, oi)">{{ opt }}</text>
|
|
|
+ <view v-for="(opt, oi) in currentQuestionOptions" :key="oi" class="q-option-row" :class="opt.selected ? 'selected' : ''" @click="selectQuizAnswer(currentQuizIndex, oi)">
|
|
|
+ <text class="q-option-letter">{{ opt.letter }}.</text>
|
|
|
+ <text class="q-option-text">{{ opt.text }}</text>
|
|
|
+ <text class="q-option-check">✓</text>
|
|
|
+ </view>
|
|
|
</view>
|
|
|
<view class="quiz-nav">
|
|
|
<button v-if="currentQuizIndex > 0" class="quiz-prev" @click="goPrevQuestion">上一题</button>
|
|
|
@@ -148,6 +155,9 @@ export default {
|
|
|
articleId: '', article: null, loading: true, error: false, errorMsg: '',
|
|
|
relatedProducts: [],
|
|
|
relatedArticles: [],
|
|
|
+ // 关联区块分页状态
|
|
|
+ relatedProductsPage: 1, relatedProductsLoading: false, relatedProductsNoMore: false,
|
|
|
+ relatedArticlesPage: 1, relatedArticlesLoading: false, relatedArticlesNoMore: false,
|
|
|
readingSeconds: 0, lastReportedSeconds: 0, readingCompleted: false,
|
|
|
isTimerRunning: false, timerHandle: null, syncHandle: null,
|
|
|
currentChildId: null, isLogin: false,
|
|
|
@@ -173,6 +183,20 @@ export default {
|
|
|
currentQuestion: function() {
|
|
|
if (!this.quizQuestions || !this.quizQuestions.length) return null
|
|
|
return this.quizQuestions[this.currentQuizIndex] || null
|
|
|
+ },
|
|
|
+ // 当前题的选项展示数据:统一派生字母、剥离后端自带前缀、标记选中态。
|
|
|
+ // 避免在模板 :class / 插值中调用方法(小程序渲染层不支持)且数组索引访问不响应。
|
|
|
+ currentQuestionOptions: function() {
|
|
|
+ var q = this.currentQuestion
|
|
|
+ if (!q || !q.options) return []
|
|
|
+ var selected = this.quizAnswers[this.currentQuizIndex] || ''
|
|
|
+ return q.options.map(function(opt, oi) {
|
|
|
+ var letter = String.fromCharCode(65 + oi)
|
|
|
+ var s = opt ? opt.toString().trim() : ''
|
|
|
+ // 剥离 "A." / "A)" / "(A)" 等常见前缀,字母由下方单独渲染避免重复
|
|
|
+ var cleaned = s.replace(/^[A-Za-z][\.\)\::]\s*/i, '').trim()
|
|
|
+ return { letter: letter, text: cleaned, selected: selected === letter }
|
|
|
+ })
|
|
|
}
|
|
|
},
|
|
|
onLoad(options) {
|
|
|
@@ -220,33 +244,78 @@ export default {
|
|
|
this.article.content = this.resolveContentUrls(this.article.content)
|
|
|
this.setShareInfo('推荐阅读: ' + (res.data.title || ''), '/pages/article-center/article-detail?id=' + id)
|
|
|
this.startReadingTimer()
|
|
|
- // 关联商品:放在 loadDetail 内只走一次(onShow 不重复请求,避免双发)
|
|
|
- this.loadRelatedProducts(id)
|
|
|
- // 相关文章:同样只走一次,无匹配时为空数组 → 模板整块隐藏
|
|
|
- this.loadRelatedArticles(id)
|
|
|
+ // 关联区块:放在 loadDetail 内只走一次(onShow 不重复请求,避免双发);先重置分页状态再加载第 1 页
|
|
|
+ this.resetRelatedState()
|
|
|
+ this.loadRelatedProducts(id, 1, false)
|
|
|
+ this.loadRelatedArticles(id, 1, false)
|
|
|
} else { this.error = true; this.errorMsg = '文章不存在或无权限查看' }
|
|
|
} catch (e) { this.error = true; this.errorMsg = '加载失败' }
|
|
|
finally { this.loading = false }
|
|
|
},
|
|
|
- // 加载文章关联商品(后端按 标签匹配数 > 用户权重 > 家庭权重 > 销量 排序)
|
|
|
- loadRelatedProducts: function(articleId) {
|
|
|
+ // 重置关联区块分页状态(loadDetail 每次加载前调用,避免切文章后旧状态残留)
|
|
|
+ resetRelatedState: function() {
|
|
|
+ this.relatedProductsPage = 1
|
|
|
+ this.relatedProductsLoading = false
|
|
|
+ this.relatedProductsNoMore = false
|
|
|
+ this.relatedArticlesPage = 1
|
|
|
+ this.relatedArticlesLoading = false
|
|
|
+ this.relatedArticlesNoMore = false
|
|
|
+ },
|
|
|
+ // 加载文章关联商品(后端按 标签匹配数 > 用户权重 > 家庭权重 > 销量 排序),每页 4 个,触底翻页
|
|
|
+ loadRelatedProducts: function(articleId, page, append) {
|
|
|
var self = this
|
|
|
if (!articleId) return
|
|
|
- getArticleRelatedProducts({ articleId: articleId, size: 4 }).then(function(res) {
|
|
|
+ var pg = page || 1
|
|
|
+ if (pg === 1) {
|
|
|
+ this.relatedProducts = []
|
|
|
+ this.relatedProductsNoMore = false
|
|
|
+ }
|
|
|
+ if (this.relatedProductsLoading) return
|
|
|
+ this.relatedProductsLoading = true
|
|
|
+ getArticleRelatedProducts({ articleId: articleId, size: 4, page: pg }).then(function(res) {
|
|
|
+ self.relatedProductsLoading = false
|
|
|
if (res && res.code === 200 && res.data && Array.isArray(res.data)) {
|
|
|
- self.relatedProducts = res.data
|
|
|
+ if (append && pg > 1) {
|
|
|
+ self.relatedProducts = self.relatedProducts.concat(res.data)
|
|
|
+ } else {
|
|
|
+ self.relatedProducts = res.data
|
|
|
+ }
|
|
|
+ if (res.data.length < 4) self.relatedProductsNoMore = true
|
|
|
+ } else {
|
|
|
+ self.relatedProductsNoMore = true
|
|
|
}
|
|
|
- }).catch(function() { self.relatedProducts = [] })
|
|
|
+ }).catch(function() {
|
|
|
+ self.relatedProductsLoading = false
|
|
|
+ self.relatedProductsNoMore = true
|
|
|
+ })
|
|
|
},
|
|
|
- // 加载相关文章(后端按共享标签数降序,无匹配返回空数组 → 前端整块隐藏)
|
|
|
- loadRelatedArticles: function(articleId) {
|
|
|
+ // 加载相关文章(后端按共享标签数降序),每页 3 篇,触底翻页;无匹配返回空数组 → 前端整块隐藏
|
|
|
+ loadRelatedArticles: function(articleId, page, append) {
|
|
|
var self = this
|
|
|
if (!articleId) return
|
|
|
- getRelatedArticles({ articleId: articleId, size: 3 }).then(function(res) {
|
|
|
+ var pg = page || 1
|
|
|
+ if (pg === 1) {
|
|
|
+ this.relatedArticles = []
|
|
|
+ this.relatedArticlesNoMore = false
|
|
|
+ }
|
|
|
+ if (this.relatedArticlesLoading) return
|
|
|
+ this.relatedArticlesLoading = true
|
|
|
+ getRelatedArticles({ articleId: articleId, size: 3, page: pg }).then(function(res) {
|
|
|
+ self.relatedArticlesLoading = false
|
|
|
if (res && res.code === 200 && res.data && Array.isArray(res.data)) {
|
|
|
- self.relatedArticles = res.data
|
|
|
+ if (append && pg > 1) {
|
|
|
+ self.relatedArticles = self.relatedArticles.concat(res.data)
|
|
|
+ } else {
|
|
|
+ self.relatedArticles = res.data
|
|
|
+ }
|
|
|
+ if (res.data.length < 3) self.relatedArticlesNoMore = true
|
|
|
+ } else {
|
|
|
+ self.relatedArticlesNoMore = true
|
|
|
}
|
|
|
- }).catch(function() { self.relatedArticles = [] })
|
|
|
+ }).catch(function() {
|
|
|
+ self.relatedArticlesLoading = false
|
|
|
+ self.relatedArticlesNoMore = true
|
|
|
+ })
|
|
|
},
|
|
|
// 跳转相关文章详情
|
|
|
goRelatedArticle: function(item) {
|
|
|
@@ -294,7 +363,18 @@ export default {
|
|
|
}
|
|
|
return best ? best.code : ''
|
|
|
},
|
|
|
- onScrollToBottom() {},
|
|
|
+ onScrollToBottom: function() {
|
|
|
+ // 触底优先翻页「相关商品」(页面下方区块),商品加载完再翻「相关文章」
|
|
|
+ if (this.relatedProducts.length > 0 && !this.relatedProductsNoMore && !this.relatedProductsLoading) {
|
|
|
+ this.relatedProductsPage++
|
|
|
+ this.loadRelatedProducts(this.articleId, this.relatedProductsPage, true)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ if (this.relatedArticles.length > 0 && !this.relatedArticlesNoMore && !this.relatedArticlesLoading) {
|
|
|
+ this.relatedArticlesPage++
|
|
|
+ this.loadRelatedArticles(this.articleId, this.relatedArticlesPage, true)
|
|
|
+ }
|
|
|
+ },
|
|
|
startNewReadingSession: function() {
|
|
|
// 每次进入文章详情页都从 0 开始新会话,时长不延续上一次
|
|
|
this.readingSeconds = 0
|
|
|
@@ -471,7 +551,9 @@ export default {
|
|
|
this.showResult = false
|
|
|
},
|
|
|
selectQuizAnswer: function(qi, oi) {
|
|
|
- this.quizAnswers[qi] = String.fromCharCode(65 + oi)
|
|
|
+ // Vue 2 中数组索引直接赋值(quizAnswers[qi] = x)不触发响应式更新,
|
|
|
+ // 必须用 $set 才能驱动选中态/圆点高亮刷新
|
|
|
+ this.$set(this.quizAnswers, qi, String.fromCharCode(65 + oi))
|
|
|
},
|
|
|
// 一题一页:上一题 / 下一题
|
|
|
goPrevQuestion: function() {
|
|
|
@@ -485,58 +567,60 @@ export default {
|
|
|
</script>
|
|
|
|
|
|
<style scoped lang="scss">
|
|
|
-.detail-container { min-height: 100vh; background: #fff; }
|
|
|
+.detail-container { min-height: 100vh; background: $app-surface; }
|
|
|
.loading-wrap { display: flex; flex-direction: column; align-items: center; padding-top: 300rpx; }
|
|
|
-.loading-spinner { width: 60rpx; height: 60rpx; border: 4rpx solid #e0e0e0; border-top-color: $uni-info; border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 20rpx; }
|
|
|
+.loading-spinner { width: 60rpx; height: 60rpx; border: 4rpx solid $facade-hairline; border-top-color: $uni-info; border-radius: 50%; animation: spin 0.8s linear infinite; margin-bottom: 20rpx; }
|
|
|
@keyframes spin { 0% { transform: rotate(0deg); } 360% { transform: rotate(360deg); } }
|
|
|
-.loading-text { font-size: 26rpx; color: #999; }
|
|
|
+.loading-text { font-size: 26rpx; color: $facade-text-muted; }
|
|
|
.error-wrap { display: flex; flex-direction: column; align-items: center; padding-top: 300rpx; }
|
|
|
.error-icon { font-size: 100rpx; margin-bottom: 24rpx; }
|
|
|
-.error-text { font-size: 28rpx; color: #999; margin-bottom: 30rpx; }
|
|
|
-.retry-btn { width: 240rpx; height: 72rpx; line-height: 72rpx; background: $brand-primary; color: #fff; font-size: 28rpx; border-radius: 36rpx; text-align: center; border: none; }
|
|
|
+.error-text { font-size: 28rpx; color: $facade-text-muted; margin-bottom: 30rpx; }
|
|
|
+.retry-btn { width: 240rpx; height: 72rpx; line-height: 72rpx; background: $brand-primary; color: $app-surface; font-size: 28rpx; border-radius: 36rpx; text-align: center; border: none; }
|
|
|
.content-scroll { height: calc(100vh - 120rpx); }
|
|
|
.detail-cover { width: 100%; display: block; }
|
|
|
-.detail-title { display: block; font-size: calc(36rpx * var(--font-scale, 1)); font-weight: bold; color: #333; line-height: 1.4; padding: 30rpx 30rpx 0; }
|
|
|
-.detail-meta { display: flex; align-items: center; padding: 16rpx 30rpx 0; font-size: 22rpx; color: #999; flex-wrap: wrap; }
|
|
|
+.detail-title { display: block; font-size: calc(36rpx * var(--font-scale, 1)); font-weight: bold; color: $facade-text-strong; line-height: 1.4; padding: 30rpx 30rpx 0; }
|
|
|
+.detail-meta { display: flex; align-items: center; padding: 16rpx 30rpx 0; font-size: 22rpx; color: $facade-text-muted; flex-wrap: wrap; }
|
|
|
.meta-author { color: $uni-info; }
|
|
|
-.meta-sep { margin: 0 12rpx; color: #ddd; }
|
|
|
+.meta-sep { margin: 0 12rpx; color: $facade-border-soft; }
|
|
|
.reading-time-badge { margin-left: auto; font-size: 20rpx; color: $uni-info; background: rgba(14, 165, 233, 0.08); padding: 4rpx 12rpx; border-radius: 20rpx; white-space: nowrap; }
|
|
|
-.reading-time-badge.completed { color: #10B981; background: rgba(16,185,129,0.1); }
|
|
|
+.reading-time-badge.completed { color: $status-success; background: rgba(16,185,129,0.1); }
|
|
|
.meta-readcount {
|
|
|
font-size: 20rpx;
|
|
|
- color: #bbb;
|
|
|
+ color: $facade-text-ghost-light;
|
|
|
}
|
|
|
.detail-category-row { padding: 16rpx 30rpx 0; }
|
|
|
.detail-category { display: inline-block; font-size: 20rpx; color: $uni-info; background: rgba(14, 165, 233, 0.1); padding: 4rpx 16rpx; border-radius: 8rpx; }
|
|
|
.detail-dimensions { padding: 16rpx 30rpx 0; display: flex; gap: 12rpx; }
|
|
|
.dim-bar-item { flex: 1; }
|
|
|
.dim-bar { height: 8rpx; border-radius: 4rpx; }
|
|
|
-.dim-label { font-size: 18rpx; color: #999; text-align: center; display: block; margin-top: 4rpx; }
|
|
|
+.dim-label { font-size: 18rpx; color: $facade-text-muted; text-align: center; display: block; margin-top: 4rpx; }
|
|
|
.detail-summary { padding: 20rpx 30rpx; }
|
|
|
-.detail-summary-text { font-size: calc(26rpx * var(--font-scale, 1)); color: #888; line-height: 1.7; display: block; border-left: 4rpx solid #F97316; padding-left: 20rpx; }
|
|
|
-.divider { height: 1rpx; background: #eee; margin: 24rpx 30rpx; }
|
|
|
+.detail-summary-text { font-size: calc(26rpx * var(--font-scale, 1)); color: $facade-text-faint; line-height: 1.7; display: block; border-left: 4rpx solid $brand-primary; padding-left: 20rpx; }
|
|
|
+.divider { height: 1rpx; background: $facade-hairline-2; margin: 24rpx 30rpx; }
|
|
|
.detail-body { padding: 0 30rpx; font-size: calc(32rpx * var(--font-scale, 1)); color: #444; line-height: 1.8; }
|
|
|
|
|
|
/* 关联商品推荐 */
|
|
|
.related-section { margin-top: 20rpx; padding: 0 30rpx 8rpx; }
|
|
|
.related-header { display: flex; align-items: baseline; margin-bottom: 16rpx; }
|
|
|
-.related-title { font-size: 30rpx; font-weight: bold; color: #333; }
|
|
|
-.related-subtitle { font-size: 20rpx; color: #999; margin-left: 12rpx; }
|
|
|
+.related-title { font-size: 30rpx; font-weight: bold; color: $facade-text-strong; }
|
|
|
+.related-subtitle { font-size: 20rpx; color: $facade-text-muted; margin-left: 12rpx; }
|
|
|
+.related-loading-hint { text-align: center; font-size: 22rpx; color: $brand-primary; padding: 16rpx 0 8rpx; }
|
|
|
+.related-loading-hint.dim { color: $facade-text-ghost-light; }
|
|
|
|
|
|
/* 相关文章 */
|
|
|
.ra-list { display: flex; flex-direction: column; gap: 16rpx; }
|
|
|
-.ra-item { display: flex; align-items: center; background: #fafafa; border-radius: 12rpx; padding: 16rpx; }
|
|
|
+.ra-item { display: flex; align-items: center; background: $facade-fill-ghost; border-radius: 12rpx; padding: 16rpx; }
|
|
|
.ra-item-pressed { opacity: 0.7; }
|
|
|
-.ra-cover { width: 140rpx; height: 100rpx; border-radius: 8rpx; background: #eee; flex-shrink: 0; }
|
|
|
+.ra-cover { width: 140rpx; height: 100rpx; border-radius: 8rpx; background: $facade-hairline-2; flex-shrink: 0; }
|
|
|
.ra-body { margin-left: 20rpx; flex: 1; min-width: 0; }
|
|
|
-.ra-title { display: block; font-size: 28rpx; font-weight: 600; color: #333; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
-.ra-summary { display: block; margin-top: 8rpx; font-size: 22rpx; color: #999; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
+.ra-title { display: block; font-size: 28rpx; font-weight: 600; color: $facade-text-strong; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
+.ra-summary { display: block; margin-top: 8rpx; font-size: 22rpx; color: $facade-text-muted; line-height: 1.4; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
|
|
|
|
-.detail-footer { position: fixed; bottom: 0; left: 0; right: 0; background: #fff; padding: 20rpx 30rpx; display: flex; align-items: center; gap: 16rpx; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.06); z-index: 10; }
|
|
|
-.share-btn { height: 72rpx; padding: 0 30rpx; background: linear-gradient(135deg, #F97316, #FB923C); border-radius: 36rpx; display: flex; align-items: center; justify-content: center; border: none; }
|
|
|
+.detail-footer { position: fixed; bottom: 0; left: 0; right: 0; background: $app-surface; padding: 20rpx 30rpx; display: flex; align-items: center; gap: 16rpx; box-shadow: 0 -2rpx 10rpx rgba(0,0,0,0.06); z-index: 10; }
|
|
|
+.share-btn { height: 72rpx; padding: 0 30rpx; background: linear-gradient(135deg, $brand-primary, $brand-primary-light); border-radius: 36rpx; display: flex; align-items: center; justify-content: center; border: none; }
|
|
|
.share-btn::after { border: none; }
|
|
|
.share-btn-icon { font-size: 30rpx; margin-right: 8rpx; }
|
|
|
-.share-btn-text { font-size: 26rpx; color: #fff; font-weight: 600; }
|
|
|
+.share-btn-text { font-size: 26rpx; color: $app-surface; font-weight: 600; }
|
|
|
|
|
|
.listen-btn { height: 72rpx; padding: 0 30rpx; background: rgba(14, 165, 233, 0.1); border: 2rpx solid $uni-info; border-radius: 36rpx; display: flex; align-items: center; justify-content: center; }
|
|
|
.listen-btn.playing { background: rgba(14, 165, 233, 0.2); }
|
|
|
@@ -545,28 +629,34 @@ export default {
|
|
|
|
|
|
/* 答题弹窗 */
|
|
|
.quiz-mask, .result-mask { position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 999; display: flex; align-items: center; justify-content: center; }
|
|
|
-.quiz-dialog, .result-dialog { background: #fff; border-radius: 24rpx; width: 650rpx; padding: 32rpx; }
|
|
|
+.quiz-dialog, .result-dialog { background: $app-surface; border-radius: 24rpx; width: 650rpx; padding: 32rpx; }
|
|
|
.quiz-mascot { display: flex; align-items: center; justify-content: center; gap: 12rpx; margin-bottom: 16rpx; }
|
|
|
.mascot-icon { font-size: 60rpx; }
|
|
|
-.mascot-name { font-size: 32rpx; font-weight: 700; color: #F97316; }
|
|
|
+.mascot-name { font-size: 32rpx; font-weight: 700; color: $brand-primary; }
|
|
|
.quiz-step-bar { display: flex; align-items: center; justify-content: center; margin-bottom: 24rpx; }
|
|
|
-.quiz-step-text { font-size: 24rpx; color: #999; margin-right: 12rpx; }
|
|
|
+.quiz-step-text { font-size: 24rpx; color: $facade-text-muted; margin-right: 12rpx; }
|
|
|
.quiz-dots { display: flex; align-items: center; gap: 8rpx; }
|
|
|
-.quiz-dot { width: 12rpx; height: 12rpx; border-radius: 50%; background: #E5E7EB; }
|
|
|
-.quiz-dot.active { background: #F97316; }
|
|
|
+.quiz-dot { width: 12rpx; height: 12rpx; border-radius: 50%; background: $facade-gray-200; }
|
|
|
+.quiz-dot.active { background: $brand-primary; }
|
|
|
.quiz-dot.done { background: #FDBA74; }
|
|
|
-.q-title { font-size: 30rpx; font-weight: 600; color: #333; line-height: 1.5; margin-bottom: 20rpx; }
|
|
|
+.q-title { font-size: 30rpx; font-weight: 600; color: $facade-text-strong; line-height: 1.5; margin-bottom: 20rpx; }
|
|
|
.q-options { display: flex; flex-direction: column; gap: 12rpx; }
|
|
|
-.q-option { padding: 16rpx 20rpx; border: 2rpx solid #E5E7EB; border-radius: 12rpx; font-size: 26rpx; color: #333; }
|
|
|
-.q-option.selected { border-color: #F97316; background: #FFF7ED; color: #92400E; }
|
|
|
+.q-option-row { display: flex; align-items: center; padding: 16rpx 20rpx; border: 2rpx solid $facade-gray-200; border-radius: 12rpx; }
|
|
|
+.q-option-row.selected { border-color: $brand-primary; background: $uni-primary-pale; }
|
|
|
+.q-option-letter { width: 44rpx; font-size: 26rpx; font-weight: 600; color: $facade-text-body; flex-shrink: 0; }
|
|
|
+.q-option-row.selected .q-option-letter { color: $brand-primary; }
|
|
|
+.q-option-text { flex: 1; min-width: 0; font-size: 26rpx; color: $facade-text-strong; }
|
|
|
+.q-option-row.selected .q-option-text { color: $status-warning-strong; }
|
|
|
+.q-option-check { width: 32rpx; height: 32rpx; border-radius: 50%; border: 3rpx solid #D1D5DB; color: transparent; font-size: 20rpx; display: flex; align-items: center; justify-content: center; flex-shrink: 0; }
|
|
|
+.q-option-row.selected .q-option-check { border-color: $brand-primary; background: $brand-primary; color: $app-surface; }
|
|
|
.quiz-nav { display: flex; gap: 16rpx; margin-top: 28rpx; }
|
|
|
-.quiz-prev { flex: 1; padding: 20rpx; background: #fff; color: #F97316; border: 2rpx solid #F97316; font-size: 28rpx; border-radius: 12rpx; }
|
|
|
+.quiz-prev { flex: 1; padding: 20rpx; background: $app-surface; color: $brand-primary; border: 2rpx solid $brand-primary; font-size: 28rpx; border-radius: 12rpx; }
|
|
|
.quiz-prev::after { border: none; }
|
|
|
-.quiz-submit { flex: 1; padding: 20rpx; background: linear-gradient(135deg, #F97316, #FB923C); color: #fff; font-size: 28rpx; border-radius: 12rpx; border: none; }
|
|
|
+.quiz-submit { flex: 1; padding: 20rpx; background: linear-gradient(135deg, $brand-primary, $brand-primary-light); color: $app-surface; font-size: 28rpx; border-radius: 12rpx; border: none; }
|
|
|
.quiz-submit::after { border: none; }
|
|
|
-.result-btn { width: 100%; padding: 20rpx; background: linear-gradient(135deg, #F97316, #FB923C); color: #fff; font-size: 28rpx; border-radius: 12rpx; border: none; margin-top: 20rpx; }
|
|
|
+.result-btn { width: 100%; padding: 20rpx; background: linear-gradient(135deg, $brand-primary, $brand-primary-light); color: $app-surface; font-size: 28rpx; border-radius: 12rpx; border: none; margin-top: 20rpx; }
|
|
|
.result-dialog { text-align: center; }
|
|
|
.result-icon { font-size: 80rpx; }
|
|
|
-.result-text { font-size: 32rpx; font-weight: 700; color: #333; margin: 16rpx 0; }
|
|
|
-.result-energy { font-size: 28rpx; color: #F97316; }
|
|
|
+.result-text { font-size: 32rpx; font-weight: 700; color: $facade-text-strong; margin: 16rpx 0; }
|
|
|
+.result-energy { font-size: 28rpx; color: $brand-primary; }
|
|
|
</style>
|