index.vue 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528
  1. <template>
  2. <view class="container">
  3. <view v-if="!isLoggedIn">
  4. <PageBanner theme="body" tagline="科学管理全家健康" quote="身体健康是幸福的基础" />
  5. <!-- 品牌定位语 -->
  6. <view class="brand-strap"><text class="brand-strap-text">科学管理全家健康数据</text></view>
  7. <!-- 痛点卡 -->
  8. <view class="pain-card">
  9. <text class="pain-quote">指标正常 ≠ 健康</text>
  10. <text class="pain-desc">孩子反复生病,你扛了多少次了?</text>
  11. </view>
  12. <!-- 功能预览 -->
  13. <view class="guest-features">
  14. <view class="feat-card" @click="goPage('/pages/health/report-upload')">
  15. <text class="feat-icon">📋</text>
  16. <text class="feat-title">上传健康报告</text>
  17. <text class="feat-desc">体检/肠道/舌诊 · AI解读</text>
  18. </view>
  19. <view class="feat-card" @click="goPage('/pages/body/detail')">
  20. <text class="feat-icon">🧠</text>
  21. <text class="feat-title">认知能力测评</text>
  22. <text class="feat-desc">记忆力·注意力·逻辑推理</text>
  23. </view>
  24. <view class="feat-card" @click="goPage('/pages/mind/index')">
  25. <text class="feat-icon">💖</text>
  26. <text class="feat-title">心理健康测评</text>
  27. <text class="feat-desc">情绪稳定·抗压能力</text>
  28. </view>
  29. <view class="feat-card" @click="goPlanSummary">
  30. <text class="feat-icon">📝</text>
  31. <text class="feat-title">智能健康方案</text>
  32. <text class="feat-desc">选维度·选成员·定目标</text>
  33. </view>
  34. </view>
  35. <!-- 自测入口 -->
  36. <view class="self-test-card" @click="goSelfTest">
  37. <view class="self-test-head">
  38. <text class="self-test-icon">⚡</text>
  39. <view class="self-test-info">
  40. <text class="self-test-title">15题五维健康自检</text>
  41. <text class="self-test-sub">约20秒,了解家人健康概况</text>
  42. </view>
  43. <text class="self-test-arrow">›</text>
  44. </view>
  45. </view>
  46. <!-- 数据预览(示例) -->
  47. <view class="demo-section">
  48. <view class="demo-section-head">
  49. <text class="demo-section-title">登录后 · 看懂这些数据</text>
  50. <text class="demo-section-sub">示例数据 · 上传报告 / 完成测评后展示真实结果</text>
  51. </view>
  52. <view class="demo-chart-title-row">
  53. <text class="demo-chart-name">🟠 身体七维</text>
  54. <text class="demo-chart-tag">示例</text>
  55. </view>
  56. <RadarChart :dimensions="demoBodyDims" :scores="demoBodyScores" fillColor="#FF8C42" childName="示例" width="560" height="460" />
  57. <view class="demo-chart-title-row">
  58. <text class="demo-chart-name">🧠 认知雷达</text>
  59. <text class="demo-chart-tag">示例</text>
  60. </view>
  61. <RadarChart :dimensions="demoCogDims" :scores="demoCogScores" fillColor="#6366F1" childName="示例" width="560" height="460" />
  62. </view>
  63. <!-- 五维健康体系 -->
  64. <view class="wuxing-section">
  65. <view class="wuxing-title">身·心·智·行·富 · 看得见的健康闭环</view>
  66. <view class="wuxing-desc">五行相生相克,从报告和测评里,真正读懂家人的身体</view>
  67. <view class="wuxing-relations">
  68. <view class="rel-group">
  69. <text class="rel-title">相生 → 系统前进</text>
  70. <view class="rel-chain">
  71. <text class="rel-item">🌏 身</text>
  72. <text class="rel-arrow">→</text>
  73. <text class="rel-item">⚡ 智</text>
  74. <text class="rel-arrow">→</text>
  75. <text class="rel-item">💧 富</text>
  76. <text class="rel-arrow">→</text>
  77. <text class="rel-item">🌿 行</text>
  78. <text class="rel-arrow">→</text>
  79. <text class="rel-item">🔥 心</text>
  80. <text class="rel-arrow">→</text>
  81. <text class="rel-item">🌏 身</text>
  82. </view>
  83. <text class="rel-hint">健康孕育智慧,智慧创造价值,价值滋养关系,关系反哺心灵,心灵守护健康</text>
  84. </view>
  85. <view class="rel-group">
  86. <text class="rel-title">相克 → 系统平衡</text>
  87. <view class="rel-chain">
  88. <text class="rel-item">🌏 身</text>
  89. <text class="rel-op">克</text>
  90. <text class="rel-item">💧 富</text>
  91. <text class="rel-dot">·</text>
  92. <text class="rel-item">⚡ 智</text>
  93. <text class="rel-op">克</text>
  94. <text class="rel-item">🌿 行</text>
  95. <text class="rel-dot">·</text>
  96. <text class="rel-item">💧 富</text>
  97. <text class="rel-op">克</text>
  98. <text class="rel-item">🔥 心</text>
  99. <text class="rel-dot">·</text>
  100. <text class="rel-item">🌿 行</text>
  101. <text class="rel-op">克</text>
  102. <text class="rel-item">🌏 身</text>
  103. <text class="rel-dot">·</text>
  104. <text class="rel-item">🔥 心</text>
  105. <text class="rel-op">克</text>
  106. <text class="rel-item">⚡ 智</text>
  107. </view>
  108. <text class="rel-hint">莫以健康换金钱,真诚胜过算计,财富服务家庭,关爱有度、大爱留白</text>
  109. </view>
  110. </view>
  111. <view class="wuxing-cards">
  112. <view class="wc-card wc-body" @click="goPage('/pages/body-detail/index')">
  113. <text class="wc-icon">🌏</text>
  114. <view class="wc-info">
  115. <text class="wc-name">身 · 主动健康</text>
  116. <text class="wc-text">读懂每一份报告,看见全家体质的变化</text>
  117. </view>
  118. </view>
  119. <view class="wc-card wc-wisdom" @click="goPage('/pages/wisdom-detail/index')">
  120. <text class="wc-icon">⚡</text>
  121. <view class="wc-info">
  122. <text class="wc-name">智 · 赋能未来</text>
  123. <text class="wc-text">一次测评,看见孩子真实的专注与潜能</text>
  124. </view>
  125. </view>
  126. <view class="wc-card wc-wealth" @click="goPage('/pages/wealth/index')">
  127. <text class="wc-icon">💧</text>
  128. <view class="wc-info">
  129. <text class="wc-name">富 · 利他创富</text>
  130. <text class="wc-text">看懂健康与财富的关系,明白身体是最大的本钱</text>
  131. </view>
  132. </view>
  133. <view class="wc-card wc-action" @click="goPage('/pages/action-detail/member-action-detail')">
  134. <text class="wc-icon">🌿</text>
  135. <view class="wc-info">
  136. <text class="wc-name">行 · 人际和谐</text>
  137. <text class="wc-text">看懂关系里的情绪,看见家人真实的需求</text>
  138. </view>
  139. </view>
  140. <view class="wc-card wc-mind" @click="goPage('/pages/mind-detail/index')">
  141. <text class="wc-icon">🔥</text>
  142. <view class="wc-info">
  143. <text class="wc-name">心 · 大爱相随</text>
  144. <text class="wc-text">读懂情绪的信号,听懂家人没说出口的话</text>
  145. </view>
  146. </view>
  147. </view>
  148. </view>
  149. <!-- 登录引导 -->
  150. <view class="login-guide-section">
  151. <LoginGuideCard
  152. title="解锁全家健康数据"
  153. :items="[
  154. '查看七维雷达图与健康报告AI解读',
  155. '完成测评获取个性化健康方案',
  156. '每日打卡追踪身体/情绪/认知趋势'
  157. ]" />
  158. </view>
  159. </view>
  160. <view v-else>
  161. <PageBanner theme="body" tagline="看见·主动健康闭环" quote="采集→看见→行动" />
  162. <view class="tab-bar">
  163. <view v-for="tab in tabs" :key="tab.code" class="tab-item" :class="{ active: currentTab === tab.code }" @click="switchTab(tab.code)">
  164. <text class="tab-icon">{{ tab.icon }}</text>
  165. <text class="tab-label">{{ tab.label }}</text>
  166. <view v-if="currentTab === tab.code" class="tab-underline" :style="{ background: tab.color }"></view>
  167. </view>
  168. </view>
  169. <view class="section section-chart">
  170. <RadarChart :dimensions="currentDimensions" :scores="currentScores" :fillColor="currentColor" :childName="selectedMemberName" width="640" height="520" />
  171. <view class="chart-empty" v-if="chartIsEmpty">
  172. <text class="empty-text">{{ currentTabLabel }}数据待采集</text>
  173. <text class="empty-sub">上传报告或完成测评后显示</text>
  174. </view>
  175. </view>
  176. <FamilyMemberStrip @select="onMemberSelect" />
  177. <view class="section section-dc-header">
  178. <view class="dc-title-row">
  179. <text class="dc-icon">🔍</text>
  180. <text class="dc-title">看见 · 健康数据中心</text>
  181. </view>
  182. </view>
  183. <view class="section section-data-collect">
  184. <view class="data-card" @click="goPage('/pages/health/report-upload')">
  185. <view class="data-card-icon" style="background:rgba(249,115,22,0.12)"><text>📋</text></view>
  186. <view class="data-card-info">
  187. <text class="data-card-title">上传健康报告</text>
  188. <text class="data-card-desc">体检/肠道/舌诊报告 · AI智能解读</text>
  189. </view>
  190. <text class="data-card-arrow">›</text>
  191. </view>
  192. <view class="data-card data-card-assessment">
  193. <view class="data-card-head">
  194. <text class="data-card-title">在线测评</text>
  195. <text class="data-card-subtitle">多维度自测评估</text>
  196. </view>
  197. <view v-for="quiz in quizzes" :key="quiz.code" class="quiz-item">
  198. <view class="quiz-info">
  199. <text class="quiz-icon">{{ quiz.icon }}</text>
  200. <text class="quiz-label">{{ quiz.label }}</text>
  201. </view>
  202. <view v-if="quiz.score" class="quiz-score">
  203. <text class="score-value">{{ quiz.score }}</text>
  204. <text class="score-unit">分</text>
  205. </view>
  206. <button v-else class="quiz-btn" @click.stop="goQuiz(quiz.code)">开始</button>
  207. </view>
  208. </view>
  209. </view>
  210. <view class="section section-data-view">
  211. <view class="section-header">
  212. <text class="section-title">最近记录</text>
  213. <text class="section-more" @click="goPage('/pages/health/report-list')">查看全部 ›</text>
  214. </view>
  215. <view v-if="reports.length > 0">
  216. <view class="report-card" v-for="(report, idx) in reports.slice(0, 3)" :key="idx" @click="goReportDetail(report)">
  217. <text class="report-icon">📄</text>
  218. <view class="report-info">
  219. <text class="report-name">{{ report.title || '健康报告' }}</text>
  220. <text class="report-status">{{ report.status === 'resolved' ? '已解析' : '待确认' }}</text>
  221. </view>
  222. <text class="report-arrow">›</text>
  223. </view>
  224. </view>
  225. <view v-else class="empty-hint">
  226. <text class="empty-text">暂无报告和测评结果</text>
  227. <text class="empty-sub">上传报告或完成测评开启健康之旅</text>
  228. </view>
  229. </view>
  230. <view class="section section-plan">
  231. <view class="plan-card">
  232. <view class="plan-head">
  233. <text class="plan-title">📋 健康方案</text>
  234. <button class="plan-btn" @click="goPlanSummary">{{ lastPlan ? '查看方案' : '生成新方案' }}</button>
  235. </view>
  236. <text v-if="lastPlan" class="plan-goal">{{ lastPlan }}</text>
  237. <text v-else class="plan-hint">选维度 + 选成员 + 设定目标 → 智能生成</text>
  238. </view>
  239. </view>
  240. <ArticleBookshelf :articles="healthArticles" :isLoggedIn="true" @articleClick="goArticleDetail" @moreArticles="goMoreArticles" />
  241. </view>
  242. </view>
  243. </template>
  244. <script>
  245. import PageBanner from '../../components/PageBanner.vue'
  246. import LoginGuideCard from '../../components/LoginGuideCard.vue'
  247. import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
  248. import RadarChart from '../../components/RadarChart.vue'
  249. import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
  250. export default {
  251. components: { PageBanner, LoginGuideCard, FamilyMemberStrip, RadarChart, ArticleBookshelf },
  252. data() {
  253. return {
  254. isLoggedIn: false,
  255. currentTab: 'body',
  256. selectedMemberName: '',
  257. selectedMemberId: '',
  258. reports: [],
  259. lastPlan: '',
  260. healthArticles: [],
  261. tabs: [
  262. { code: 'body', label: '健康', icon: '🟠', color: '#FF8C42' },
  263. { code: 'cognitive', label: '认知', icon: '🧠', color: '#6366F1' },
  264. { code: 'mental', label: '心理', icon: '💖', color: '#FF6B9D' },
  265. { code: 'relationship', label: '社会性', icon: '🤝', color: '#10B981' }
  266. ],
  267. quizzes: [
  268. { code: 'cognitive', label: '认知能力测评', icon: '🧠', score: null },
  269. { code: 'mental', label: '心理健康测评', icon: '💖', score: null },
  270. { code: 'relationship', label: '关系质量测评', icon: '🤝', score: null }
  271. ],
  272. demoBodyDims: [
  273. { label: '生长发育', key: 'growth' },
  274. { label: '睡眠质量', key: 'sleep' },
  275. { label: '视力健康', key: 'vision' },
  276. { label: '免疫力', key: 'immunity' },
  277. { label: '营养均衡', key: 'nutrition' },
  278. { label: '肠胃健康', key: 'gut' },
  279. { label: '运动活力', key: 'exercise' }
  280. ],
  281. demoBodyScores: [72, 68, 75, 80, 70, 78, 82],
  282. demoCogDims: [
  283. { label: '记忆力', key: 'memory' },
  284. { label: '注意力', key: 'attention' },
  285. { label: '逻辑推理', key: 'logic' },
  286. { label: '空间想象', key: 'spatial' },
  287. { label: '语言表达', key: 'language' }
  288. ],
  289. demoCogScores: [78, 72, 85, 68, 80]
  290. }
  291. },
  292. computed: {
  293. currentTabLabel: function() {
  294. var tab = this.tabs.filter(function(t) { return t.code === this.currentTab }.bind(this))[0]
  295. return tab ? tab.label : ''
  296. },
  297. currentColor: function() {
  298. var tab = this.tabs.filter(function(t) { return t.code === this.currentTab }.bind(this))[0]
  299. return tab ? tab.color : '#FF8C42'
  300. },
  301. currentDimensions: function() {
  302. if (this.currentTab === 'cognitive') {
  303. return [{ label:'记忆力',key:'memory'},{ label:'注意力',key:'attention'},{ label:'逻辑推理',key:'logic'},{ label:'空间想象',key:'spatial'},{ label:'语言表达',key:'language' }]
  304. }
  305. if (this.currentTab === 'mental') {
  306. return [{ label:'情绪稳定',key:'emotion'},{ label:'抗压能力',key:'stress'},{ label:'自我认知',key:'self'},{ label:'社交意愿',key:'social'},{ label:'幸福感',key:'happiness' }]
  307. }
  308. if (this.currentTab === 'relationship') {
  309. return [{ label:'亲子关系',key:'parent'},{ label:'夫妻关系',key:'spouse'},{ label:'亲友关系',key:'friend'},{ label:'同事关系',key:'colleague'},{ label:'社区参与',key:'community' }]
  310. }
  311. return [{ label:'生长发育',key:'growth'},{ label:'睡眠质量',key:'sleep'},{ label:'视力健康',key:'vision'},{ label:'免疫力',key:'immunity'},{ label:'营养均衡',key:'nutrition'},{ label:'肠胃健康',key:'gut'},{ label:'运动活力',key:'exercise' }]
  312. },
  313. currentScores: function() {
  314. if (this.chartIsEmpty) {
  315. var dims = this.currentDimensions, scores = []
  316. for (var i = 0; i < dims.length; i++) scores.push(0)
  317. return scores
  318. }
  319. if (this.currentTab === 'body') return [72, 68, 75, 80, 70, 78, 82]
  320. var dims = this.currentDimensions, scores = []
  321. for (var i = 0; i < dims.length; i++) scores.push(0)
  322. return scores
  323. },
  324. chartIsEmpty: function() {
  325. if (this.currentTab === 'body') return this.reports.length === 0
  326. var quiz = this.quizzes.filter(function(q) { return q.code === this.currentTab }.bind(this))[0]
  327. return !(quiz && quiz.score)
  328. }
  329. },
  330. onShow() {
  331. this.isLoggedIn = !!uni.getStorageSync('token')
  332. if (this.isLoggedIn) {
  333. var stored = uni.getStorageSync('currentChildId') || ''
  334. if (stored) {
  335. this.selectedMemberId = stored
  336. this.selectedMemberName = uni.getStorageSync('currentChildName') || '成员'
  337. }
  338. this.loadHealthData()
  339. this.loadPlanList()
  340. }
  341. },
  342. methods: {
  343. onMemberSelect: function(member) {
  344. this.selectedMemberId = member && member.id ? member.id : ''
  345. this.selectedMemberName = member && member.name ? member.name : '成员'
  346. },
  347. switchTab: function(code) { this.currentTab = code },
  348. goPage: function(url) { uni.navigateTo({ url: url }) },
  349. goQuiz: function(code) {
  350. var url = '/pages/body-detail/dimension-questionnaire?dim=' + code
  351. if (this.selectedMemberId) url += '&memberId=' + this.selectedMemberId
  352. uni.navigateTo({ url: url })
  353. },
  354. goReportDetail: function(report) {
  355. uni.navigateTo({ url: '/pages/health/report-list' + (report && report.id ? '?reportId=' + report.id : '') })
  356. },
  357. goSelfTest: function() { uni.navigateTo({ url: '/pages/health/survey-questionnaire?dim=all' }) },
  358. goPlanSummary: function() {
  359. var url = '/pages/health/health-plan-summary'
  360. if (this.selectedMemberId) url += '?memberId=' + this.selectedMemberId
  361. uni.navigateTo({ url: url })
  362. },
  363. loadHealthData: function() {
  364. var self = this
  365. try {
  366. var api = require('../../utils/api.js')
  367. api.getReportList().then(function(res) {
  368. if (res.code === 200 && res.data) {
  369. var list = Array.isArray(res.data) ? res.data : (res.data.list || [])
  370. self.reports = list
  371. }
  372. }).catch(function() {})
  373. api.getFeaturedArticles({ size: 3, dimensionCode: 'body' }).then(function(res) {
  374. if (res.code === 200 && res.data) {
  375. var list = Array.isArray(res.data) ? res.data : (res.data.records || [])
  376. self.healthArticles = list.slice(0, 3) || []
  377. }
  378. }).catch(function() {})
  379. } catch (e) { console.error('加载健康数据失败', e) }
  380. },
  381. loadPlanList: function() {
  382. var self = this
  383. var api = require('../../utils/api.js')
  384. api.getHealthPlanList({}).then(function(res) {
  385. if (res && res.code === 200 && res.data) {
  386. var list = res.data.list || res.data
  387. if (Array.isArray(list) && list.length > 0) self.lastPlan = list[0].goal || ''
  388. }
  389. }).catch(function() {})
  390. },
  391. goArticleDetail: function(article) {
  392. var id = article && article.id || article
  393. uni.navigateTo({ url: '/pages/article-center/article-detail?id=' + id })
  394. },
  395. goMoreArticles: function() {
  396. uni.navigateTo({ url: '/pages/article-center/index?dimension=body' })
  397. }
  398. }
  399. }
  400. </script>
  401. <style scoped>
  402. .container { background: #F8F8F8; min-height: 100vh; padding-bottom: calc(160rpx + env(safe-area-inset-bottom)); }
  403. .section { margin: 16rpx 24rpx; }
  404. .tab-bar { display: flex; background: #fff; margin: 0 24rpx 16rpx; border-radius: 16rpx; padding: 8rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  405. .tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; padding: 12rpx 0; position: relative; border-radius: 12rpx; }
  406. .tab-item.active { background: #FFF7ED; }
  407. .tab-icon { font-size: 32rpx; margin-bottom: 4rpx; }
  408. .tab-label { font-size: 26rpx; color: #666; font-weight: 500; }
  409. .tab-item.active .tab-label { color: #333; font-weight: bold; }
  410. .tab-underline { width: 40rpx; height: 4rpx; border-radius: 2rpx; margin-top: 6rpx; }
  411. .section-chart { position: relative; margin: 0 24rpx 16rpx; }
  412. .chart-empty { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; z-index: 3; background: rgba(255,255,255,0.85); border-radius: 12rpx; padding: 20rpx 30rpx; }
  413. .chart-empty .empty-text { font-size: 28rpx; color: #333; font-weight: 500; display: block; }
  414. .chart-empty .empty-sub { font-size: 22rpx; color: #999; display: block; margin-top: 4rpx; }
  415. .section-dc-header { margin: 20rpx 24rpx 8rpx; }
  416. .dc-title-row { display: flex; align-items: center; }
  417. .dc-icon { font-size: 32rpx; margin-right: 8rpx; }
  418. .dc-title { font-size: 32rpx; font-weight: bold; color: #333; }
  419. .section-data-collect { margin: 8rpx 24rpx; }
  420. .data-card { display: flex; align-items: center; background: #fff; border-radius: 20rpx; padding: 24rpx; margin-bottom: 12rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  421. .data-card-icon { width: 88rpx; height: 88rpx; border-radius: 20rpx; display: flex; align-items: center; justify-content: center; margin-right: 20rpx; font-size: 40rpx; }
  422. .data-card-info { flex: 1; }
  423. .data-card-title { font-size: 28rpx; font-weight: bold; color: #333; display: block; margin-bottom: 6rpx; }
  424. .data-card-desc { font-size: 22rpx; color: #999; }
  425. .data-card-arrow { font-size: 36rpx; color: #ccc; }
  426. .data-card-assessment { flex-direction: column; align-items: stretch; padding: 24rpx; }
  427. .data-card-head { display: flex; align-items: center; margin-bottom: 16rpx; }
  428. .data-card-subtitle { font-size: 22rpx; color: #999; margin-left: 12rpx; }
  429. .quiz-item { display: flex; align-items: center; padding: 16rpx 0; border-top: 1rpx solid #f0f0f0; }
  430. .quiz-item:first-of-type { border-top: none; }
  431. .quiz-info { display: flex; align-items: center; flex: 1; }
  432. .quiz-icon { font-size: 36rpx; margin-right: 16rpx; }
  433. .quiz-label { font-size: 28rpx; color: #333; }
  434. .quiz-score { display: flex; align-items: baseline; margin-right: 16rpx; }
  435. .score-value { font-size: 36rpx; font-weight: bold; color: #F97316; }
  436. .score-unit { font-size: 22rpx; color: #999; margin-left: 4rpx; }
  437. .quiz-btn { background: #F97316; color: #fff; font-size: 24rpx; border: none; border-radius: 20rpx; padding: 10rpx 30rpx; height: 56rpx; line-height: 36rpx; margin: 0; }
  438. .section-data-view { margin: 16rpx 24rpx; }
  439. .section-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 12rpx; }
  440. .section-title { font-size: 28rpx; font-weight: bold; color: #333; }
  441. .section-more { font-size: 24rpx; color: #F97316; }
  442. .report-card { display: flex; align-items: center; background: #fff; border-radius: 16rpx; padding: 16rpx 20rpx; margin-bottom: 10rpx; }
  443. .report-icon { font-size: 32rpx; margin-right: 16rpx; }
  444. .report-info { flex: 1; }
  445. .report-name { font-size: 24rpx; color: #333; display: block; margin-bottom: 4rpx; }
  446. .report-status { font-size: 20rpx; color: #999; }
  447. .report-arrow { font-size: 28rpx; color: #ccc; }
  448. .empty-hint { text-align: center; padding: 30rpx 0; background: #fff; border-radius: 16rpx; }
  449. .empty-hint .empty-text { font-size: 26rpx; color: #999; display: block; }
  450. .empty-hint .empty-sub { font-size: 22rpx; color: #ccc; display: block; margin-top: 6rpx; }
  451. .section-plan { margin: 8rpx 24rpx 16rpx; }
  452. .plan-card { background: #fff; border-radius: 20rpx; padding: 24rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  453. .plan-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12rpx; }
  454. .plan-title { font-size: 28rpx; font-weight: bold; color: #333; }
  455. .plan-btn { background: linear-gradient(135deg, #F97316, #FB923C); color: #fff; font-size: 24rpx; border: none; border-radius: 20rpx; padding: 10rpx 28rpx; height: 56rpx; line-height: 36rpx; margin: 0; }
  456. .plan-goal { font-size: 24rpx; color: #666; line-height: 1.5; display: block; }
  457. .plan-hint { font-size: 22rpx; color: #999; display: block; }
  458. /* ===== 游客态样式 ===== */
  459. .brand-strap { margin: 0 24rpx 16rpx; background: linear-gradient(135deg, #FFF7ED, rgba(249,115,22,0.08)); border-radius: 16rpx; padding: 20rpx 24rpx; }
  460. .brand-strap-text { font-size: 26rpx; color: #F97316; font-weight: 600; }
  461. .pain-card { margin: 0 24rpx 16rpx; background: #fff; border-radius: 20rpx; padding: 28rpx; border-left: 6rpx solid #F97316; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  462. .pain-quote { font-size: 32rpx; font-weight: bold; color: #333; display: block; margin-bottom: 8rpx; }
  463. .pain-desc { font-size: 26rpx; color: #888; display: block; }
  464. .guest-features { display: flex; flex-wrap: wrap; justify-content: space-between; margin: 0 24rpx 16rpx; }
  465. .feat-card { width: 48.5%; box-sizing: border-box; background: #fff; border-radius: 20rpx; padding: 24rpx 20rpx; margin-bottom: 16rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  466. .feat-icon { font-size: 44rpx; display: block; margin-bottom: 10rpx; }
  467. .feat-title { font-size: 26rpx; font-weight: 600; color: #333; display: block; margin-bottom: 4rpx; }
  468. .feat-desc { font-size: 22rpx; color: #999; display: block; }
  469. .self-test-card { margin: 0 24rpx 16rpx; background: linear-gradient(135deg, #667eea, #764ba2); border-radius: 20rpx; padding: 24rpx 28rpx; }
  470. .self-test-head { display: flex; align-items: center; }
  471. .self-test-icon { font-size: 40rpx; margin-right: 16rpx; }
  472. .self-test-info { flex: 1; }
  473. .self-test-title { font-size: 28rpx; font-weight: bold; color: #fff; display: block; }
  474. .self-test-sub { font-size: 22rpx; color: rgba(255,255,255,0.8); display: block; margin-top: 4rpx; }
  475. .self-test-arrow { font-size: 36rpx; color: rgba(255,255,255,0.7); }
  476. .demo-section { margin: 0 24rpx 16rpx; }
  477. .demo-section-head { margin-bottom: 8rpx; }
  478. .demo-section-title { font-size: 30rpx; font-weight: bold; color: #333; display: block; }
  479. .demo-section-sub { font-size: 22rpx; color: #999; display: block; margin-top: 4rpx; }
  480. .demo-chart-title-row { display: flex; align-items: center; justify-content: space-between; margin: 8rpx 8rpx 0; padding: 0 8rpx; }
  481. .demo-chart-name { font-size: 26rpx; font-weight: 600; color: #333; }
  482. .demo-chart-tag { font-size: 20rpx; color: #F97316; background: rgba(249,115,22,0.1); border-radius: 8rpx; padding: 4rpx 12rpx; }
  483. .login-guide-section { margin: 0 24rpx 24rpx; }
  484. /* ===== 五维闭环体系样式 ===== */
  485. .wuxing-section { margin: 0 24rpx 16rpx; background: #fff; border-radius: 20rpx; padding: 24rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
  486. .wuxing-title { font-size: 30rpx; font-weight: bold; color: #333; text-align: center; margin-bottom: 6rpx; }
  487. .wuxing-desc { font-size: 22rpx; color: #999; text-align: center; margin-bottom: 20rpx; }
  488. .wuxing-diagram { position: relative; height: 320rpx; margin: 0 auto 20rpx; }
  489. .wuxing-relations { margin-top: 8rpx; }
  490. .rel-group { margin-bottom: 16rpx; }
  491. .rel-title { font-size: 24rpx; font-weight: bold; color: #333; margin-bottom: 8rpx; display: block; }
  492. .rel-chain { display: flex; flex-wrap: wrap; align-items: center; gap: 4rpx; margin-bottom: 6rpx; }
  493. .rel-item { font-size: 22rpx; padding: 4rpx 10rpx; border-radius: 8rpx; background: #f7f7f7; color: #555; }
  494. .rel-arrow { font-size: 20rpx; color: #F97316; font-weight: bold; }
  495. .rel-dot { font-size: 20rpx; color: #ccc; }
  496. .rel-hint { font-size: 20rpx; color: #999; line-height: 1.5; display: block; }
  497. .wuxing-cards { display: flex; flex-direction: column; gap: 10rpx; margin-top: 16rpx; }
  498. .wc-card { display: flex; align-items: center; padding: 16rpx 20rpx; border-radius: 16rpx; border: 2rpx solid #f0f0f0; }
  499. .wc-card:active { opacity: 0.85; }
  500. .wc-icon { font-size: 36rpx; margin-right: 16rpx; flex-shrink: 0; }
  501. .wc-info { flex: 1; min-width: 0; display: flex; flex-direction: column; }
  502. .wc-name { font-size: 24rpx; font-weight: 600; display: block; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  503. .wc-text { font-size: 20rpx; color: #999; display: block; margin-top: 4rpx; white-space: normal; }
  504. .wc-body { border-color: rgba(255,140,66,0.3); background: rgba(255,140,66,0.04); border-left: 8rpx solid #FF8C42; }
  505. .wc-body .wc-name { color: #FF8C42; }
  506. .wc-wisdom { border-color: rgba(99,102,241,0.3); background: rgba(99,102,241,0.04); border-left: 8rpx solid #6366F1; }
  507. .wc-wisdom .wc-name { color: #6366F1; }
  508. .wc-wealth { border-color: rgba(245,158,11,0.3); background: rgba(245,158,11,0.04); border-left: 8rpx solid #F59E0B; }
  509. .wc-wealth .wc-name { color: #F59E0B; }
  510. .wc-action { border-color: rgba(16,185,129,0.3); background: rgba(16,185,129,0.04); border-left: 8rpx solid #10B981; }
  511. .wc-action .wc-name { color: #10B981; }
  512. .wc-mind { border-color: rgba(255,107,157,0.3); background: rgba(255,107,157,0.04); border-left: 8rpx solid #FF6B9D; }
  513. .wc-mind .wc-name { color: #FF6B9D; }
  514. </style>