self-check-result.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759
  1. <template>
  2. <view class="scr-page">
  3. <!-- Loading -->
  4. <view class="scr-loading" v-if="loading">
  5. <text class="scr-loading-text">加载中...</text>
  6. </view>
  7. <template v-else>
  8. <!-- 总分横幅 -->
  9. <view class="scr-hero">
  10. <view class="scr-hero-badge">
  11. <text class="scr-hero-title">五维幸福总分</text>
  12. <view class="scr-hero-score-row">
  13. <text class="scr-hero-score">{{ result.totalScore }}</text>
  14. <text class="scr-hero-total">/45</text>
  15. </view>
  16. <view class="scr-hero-level" :class="'level-' + overallLevel">
  17. <text>{{ overallLevelName }}</text>
  18. </view>
  19. </view>
  20. <text class="scr-hero-date" v-if="result.createdAt">自检时间:{{ formatDate(result.createdAt) }}</text>
  21. </view>
  22. <!-- 雷达图 -->
  23. <view class="scr-card">
  24. <view class="scr-card-title">
  25. <text class="scr-card-title-text">五维能量雷达</text>
  26. <text class="scr-card-sub">身·智·富·行·心</text>
  27. </view>
  28. <view class="scr-canvas-wrap">
  29. <canvas
  30. type="2d"
  31. id="selfCheckRadar"
  32. class="scr-canvas"
  33. @ready="onCanvasReady"
  34. ></canvas>
  35. </view>
  36. </view>
  37. <!-- 维度得分 -->
  38. <view class="scr-card">
  39. <view class="scr-card-title">
  40. <text class="scr-card-title-text">维度得分</text>
  41. <text class="scr-card-sub">满分9分/维</text>
  42. </view>
  43. <view class="scr-dim-list">
  44. <view class="scr-dim-item" v-for="dim in result.dimensions" :key="dim.dimension">
  45. <view class="scr-dim-head">
  46. <view class="scr-dim-label">
  47. <view class="scr-dim-dot" :style="{ background: dim.color }"></view>
  48. <text class="scr-dim-name">{{ dim.name }}</text>
  49. <text class="scr-dim-element">{{ dim.element }}</text>
  50. </view>
  51. <view class="scr-dim-score-wrap">
  52. <text class="scr-dim-score" :style="{ color: dim.color }">{{ dim.score }}</text>
  53. <text class="scr-dim-score-max">/9</text>
  54. </view>
  55. </view>
  56. <view class="scr-dim-bar">
  57. <view class="scr-dim-bar-fill" :style="{ width: (dim.score / 9 * 100) + '%', background: dim.color }"></view>
  58. </view>
  59. <view class="scr-dim-foot">
  60. <text class="scr-dim-level" :class="'lvl-' + dim.level">{{ dim.levelName }}</text>
  61. <text class="scr-dim-summary">{{ dim.summary }}</text>
  62. </view>
  63. </view>
  64. </view>
  65. </view>
  66. <!-- 五行相生寻源建议(P0-2) -->
  67. <view class="scr-card" v-if="result.advices && result.advices.length > 0">
  68. <view class="scr-card-title">
  69. <text class="scr-card-title-text">五行相生 · 寻源建议</text>
  70. <text class="scr-card-sub">低分维度 {{ result.advices.length }} 项</text>
  71. </view>
  72. <view class="scr-advice-intro">低于6分的维度,先别硬补——从"生"它的上游借力,同时避开"克"它的压制源:</view>
  73. <view class="scr-advice-item" v-for="adv in result.advices" :key="adv.dimension">
  74. <!-- 低分维度 -->
  75. <view class="scr-advice-dim-row">
  76. <view class="scr-advice-dim-badge" :style="{ background: adv.color }">
  77. <text class="scr-advice-dim-name">{{ adv.dimensionName }}</text>
  78. <text class="scr-advice-dim-elem">{{ adv.element }}</text>
  79. </view>
  80. <text class="scr-advice-dim-score">{{ adv.score }}分</text>
  81. </view>
  82. <!-- 相生寻源 -->
  83. <view class="scr-advice-flow">
  84. <view class="scr-flow-node">
  85. <view class="scr-flow-dot" :style="{ background: adv.upstreamColor }"></view>
  86. <text class="scr-flow-label">上游 · {{ adv.upstreamName }}({{ adv.upstreamElement }})</text>
  87. </view>
  88. <text class="scr-flow-arrow">⟶</text>
  89. <text class="scr-flow-action">{{ adv.upstreamReason }}</text>
  90. </view>
  91. <!-- 相克寻源 -->
  92. <view class="scr-advice-flow">
  93. <view class="scr-flow-node">
  94. <view class="scr-flow-dot" :style="{ background: adv.restrainerColor }"></view>
  95. <text class="scr-flow-label">压制 · {{ adv.restrainerName }}({{ adv.restrainerElement }})</text>
  96. </view>
  97. <text class="scr-flow-arrow">⛔</text>
  98. <text class="scr-flow-action">{{ adv.restrainerReason }}</text>
  99. </view>
  100. <!-- 行动建议 -->
  101. <view class="scr-advice-action">
  102. <text class="scr-advice-action-label">本周行动</text>
  103. <text class="scr-advice-action-text">{{ adv.action }}</text>
  104. </view>
  105. <!-- 一键加入今日微行动(微行动×五维联动) -->
  106. <view class="scr-micro-row" v-if="joinedDims[adv.dimension]">
  107. <text class="scr-micro-done">✅ 今日微行动已完成,能量已入账</text>
  108. </view>
  109. <view class="scr-micro-row" v-else>
  110. <button class="scr-micro-btn" :loading="joiningDim === adv.dimension" :disabled="joiningDim !== ''" @click="joinMicroAction(adv)">
  111. ⚡ 加入今日微行动
  112. </button>
  113. </view>
  114. </view>
  115. </view>
  116. <!-- 全部健康提示 -->
  117. <view class="scr-card" v-else>
  118. <view class="scr-all-healthy">
  119. <text class="scr-all-healthy-icon">🌿</text>
  120. <text class="scr-all-healthy-text">五维状态均健康,请继续保持这份平衡!</text>
  121. </view>
  122. </view>
  123. <!-- 历史与重测 -->
  124. <view class="scr-footer">
  125. <button class="scr-btn scr-btn-primary" @click="goHistory">历史记录</button>
  126. <button class="scr-btn scr-btn-outline" @click="retake">重新自检</button>
  127. </view>
  128. </template>
  129. </view>
  130. </template>
  131. <script>
  132. import { getSelfCheckLatest, getSelfCheckHistory } from '@/utils/api'
  133. import { microActionToday, microActionComplete } from '@/utils/api'
  134. import { parseDate } from '@/utils/format.js'
  135. export default {
  136. data() {
  137. return {
  138. loading: true,
  139. result: null,
  140. selfCheckId: '',
  141. canvasContext: null,
  142. canvasWidth: 340,
  143. canvasHeight: 340,
  144. // 雷达图轴序(对应 tianpan 木火土金水,顺时针)
  145. axes: ['木', '火', '土', '金', '水'],
  146. elementKeys: ['action', 'mind', 'body', 'wisdom', 'wealth'],
  147. elementColors: ['#10B981', '#FF6B9D', '#FF8C42', '#6366F1', '#F59E0B'],
  148. levelMap: {
  149. healthy: '健康',
  150. attention: '留意',
  151. tense: '紧绷'
  152. },
  153. // 今日微行动联动状态
  154. joiningDim: '',
  155. joinedDims: {}
  156. }
  157. },
  158. computed: {
  159. overallLevel: function() {
  160. var total = this.result ? (this.result.totalScore || 0) : 0
  161. if (total >= 35) return 'healthy'
  162. if (total >= 20) return 'attention'
  163. return 'tense'
  164. },
  165. overallLevelName: function() {
  166. return this.levelMap[this.overallLevel] || '留意'
  167. }
  168. },
  169. onLoad: function(options) {
  170. this.selfCheckId = options && options.id ? options.id : ''
  171. this.loadResult()
  172. },
  173. methods: {
  174. loadResult: function() {
  175. var self = this
  176. // 优先使用刚提交时缓存的结果,避免多一次请求
  177. var cached = uni.getStorageSync('lastSelfCheckResult')
  178. if (cached && cached.id) {
  179. this.result = cached
  180. this.loading = false
  181. this.drawRadar()
  182. return
  183. }
  184. getSelfCheckLatest().then(function(res) {
  185. self.loading = false
  186. if (res.code === 200 && res.data) {
  187. self.result = res.data
  188. self.drawRadar()
  189. } else {
  190. uni.showToast({ title: (res && res.message) || '暂无自检记录', icon: 'none' })
  191. }
  192. }).catch(function() {
  193. self.loading = false
  194. uni.showToast({ title: '加载失败', icon: 'none' })
  195. })
  196. },
  197. onCanvasReady: function(res) {
  198. if (!res || !res[0] || !res[0].node) {
  199. return
  200. }
  201. var ctx = res[0].node.getContext('2d')
  202. var dpr = uni.getWindowInfo().pixelRatio
  203. this.canvasContext = ctx
  204. this.canvasContext.scale(dpr, dpr)
  205. this.drawRadar()
  206. },
  207. drawRadar: function() {
  208. if (!this.canvasContext || !this.result) {
  209. return
  210. }
  211. var ctx = this.canvasContext
  212. var w = this.canvasWidth
  213. var h = this.canvasHeight
  214. var cx = w / 2
  215. var cy = h / 2
  216. var r = w * 0.34
  217. var angleStep = (Math.PI * 2) / 5
  218. // 清空画布
  219. ctx.clearRect(0, 0, w, h)
  220. ctx.fillStyle = '#FFF8F0'
  221. ctx.fillRect(0, 0, w, h)
  222. // 维度分数映射
  223. var scores = {}
  224. var dims = this.result.dimensions || []
  225. for (var i = 0; i < dims.length; i++) {
  226. scores[dims[i].dimension] = dims[i].score || 0
  227. }
  228. // 背景五边形(三层网格)
  229. for (var layer = 1; layer <= 3; layer++) {
  230. ctx.beginPath()
  231. for (var g = 0; g < 5; g++) {
  232. var gAngle = g * angleStep - Math.PI / 2
  233. var gx = cx + r * (layer / 3) * Math.cos(gAngle)
  234. var gy = cy + r * (layer / 3) * Math.sin(gAngle)
  235. if (g === 0) {
  236. ctx.moveTo(gx, gy)
  237. } else {
  238. ctx.lineTo(gx, gy)
  239. }
  240. }
  241. ctx.closePath()
  242. ctx.strokeStyle = 'rgba(249, 114, 22, 0.15)'
  243. ctx.lineWidth = 1
  244. ctx.stroke()
  245. }
  246. // 轴线 + 标签
  247. for (var j = 0; j < 5; j++) {
  248. var a2 = j * angleStep - Math.PI / 2
  249. var lx = cx + r * Math.cos(a2)
  250. var ly = cy + r * Math.sin(a2)
  251. ctx.beginPath()
  252. ctx.moveTo(cx, cy)
  253. ctx.lineTo(lx, ly)
  254. ctx.strokeStyle = this.elementColors[j] + '44'
  255. ctx.lineWidth = 1
  256. ctx.stroke()
  257. var labelX = cx + (r + 18) * Math.cos(a2)
  258. var labelY = cy + (r + 18) * Math.sin(a2)
  259. ctx.fillStyle = this.elementColors[j]
  260. ctx.font = 'bold 13px sans-serif'
  261. ctx.textAlign = 'center'
  262. ctx.textBaseline = 'middle'
  263. ctx.fillText(this.axes[j], labelX, labelY)
  264. }
  265. // 数据驱动多边形
  266. ctx.beginPath()
  267. for (var m = 0; m < 5; m++) {
  268. var ang = m * angleStep - Math.PI / 2
  269. var key = this.elementKeys[m]
  270. var ratio = (scores[key] || 0) / 9
  271. var dataR = r * ratio
  272. var dx = cx + dataR * Math.cos(ang)
  273. var dy = cy + dataR * Math.sin(ang)
  274. if (m === 0) {
  275. ctx.moveTo(dx, dy)
  276. } else {
  277. ctx.lineTo(dx, dy)
  278. }
  279. }
  280. ctx.closePath()
  281. ctx.fillStyle = 'rgba(249, 114, 22, 0.2)'
  282. ctx.fill()
  283. ctx.strokeStyle = '#F97316'
  284. ctx.lineWidth = 2
  285. ctx.stroke()
  286. // 数据节点圆点 + 分数标签
  287. for (var n = 0; n < 5; n++) {
  288. var ang2 = n * angleStep - Math.PI / 2
  289. var key2 = this.elementKeys[n]
  290. var ratio2 = (scores[key2] || 0) / 9
  291. var dataR2 = r * ratio2
  292. var px = cx + dataR2 * Math.cos(ang2)
  293. var py = cy + dataR2 * Math.sin(ang2)
  294. ctx.beginPath()
  295. ctx.arc(px, py, 4, 0, Math.PI * 2)
  296. ctx.fillStyle = this.elementColors[n]
  297. ctx.fill()
  298. var pctLabelR = dataR2 + (ratio2 > 0.35 ? -16 : 18)
  299. var pLabelX = cx + pctLabelR * Math.cos(ang2)
  300. var pLabelY = cy + pctLabelR * Math.sin(ang2)
  301. ctx.fillStyle = this.elementColors[n]
  302. ctx.font = 'bold 11px sans-serif'
  303. ctx.textAlign = 'center'
  304. ctx.textBaseline = 'middle'
  305. ctx.fillText(String(scores[key2] || 0), pLabelX, pLabelY)
  306. }
  307. },
  308. formatDate: function(dateStr) {
  309. if (!dateStr) {
  310. return ''
  311. }
  312. var d = parseDate(dateStr)
  313. if (!d) return ''
  314. var pad = function(n) { return n < 10 ? '0' + n : '' + n }
  315. return d.getFullYear() + '-' + pad(d.getMonth() + 1) + '-' + pad(d.getDate()) + ' ' + pad(d.getHours()) + ':' + pad(d.getMinutes())
  316. },
  317. goHistory: function() {
  318. getSelfCheckHistory().then(function(res) {
  319. if (res.code === 200 && res.data && res.data.length > 0) {
  320. uni.showToast({ title: '已生成 ' + res.data.length + ' 条记录', icon: 'none' })
  321. } else {
  322. uni.showToast({ title: '暂无历史记录', icon: 'none' })
  323. }
  324. }).catch(function() {
  325. uni.showToast({ title: '暂无历史记录', icon: 'none' })
  326. })
  327. },
  328. joinMicroAction: function(adv) {
  329. var self = this
  330. if (!adv || !adv.dimension || this.joiningDim) return
  331. var memberId = this.result && this.result.familyMemberId
  332. if (!memberId) {
  333. uni.showToast({ title: '未找到家庭成员信息', icon: 'none' })
  334. return
  335. }
  336. this.joiningDim = adv.dimension
  337. microActionToday({ memberId: memberId, dimensionCode: adv.dimension }).then(function(res) {
  338. if (res.code !== 200) {
  339. self.joiningDim = ''
  340. uni.showToast({ title: (res && res.message) || '获取微行动失败', icon: 'none' })
  341. return
  342. }
  343. var data = res.data || {}
  344. if (data.completed) {
  345. self.joiningDim = ''
  346. self.$set(self.joinedDims, adv.dimension, true)
  347. uni.showToast({ title: '今日微行动已完成', icon: 'none' })
  348. return
  349. }
  350. var action = data.action
  351. if (!action || !action.id) {
  352. self.joiningDim = ''
  353. uni.showToast({ title: '今日暂无该维度微行动', icon: 'none' })
  354. return
  355. }
  356. microActionComplete({ memberId: memberId, actionId: action.id }).then(function(res2) {
  357. self.joiningDim = ''
  358. if (res2.code === 200) {
  359. self.$set(self.joinedDims, adv.dimension, true)
  360. uni.showToast({ title: '已加入今日微行动,能量+1', icon: 'success' })
  361. } else {
  362. uni.showToast({ title: (res2 && res2.message) || '加入失败', icon: 'none' })
  363. }
  364. }).catch(function() {
  365. self.joiningDim = ''
  366. uni.showToast({ title: '加入失败', icon: 'none' })
  367. })
  368. }).catch(function() {
  369. self.joiningDim = ''
  370. uni.showToast({ title: '获取微行动失败', icon: 'none' })
  371. })
  372. },
  373. retake: function() {
  374. uni.redirectTo({ url: '/pages/family/self-check' })
  375. }
  376. }
  377. }
  378. </script>
  379. <style scoped>
  380. .scr-page {
  381. min-height: 100vh;
  382. background: #F5FAFE;
  383. padding: 24rpx 30rpx 120rpx;
  384. box-sizing: border-box;
  385. }
  386. .scr-loading {
  387. display: flex;
  388. justify-content: center;
  389. align-items: center;
  390. height: 60vh;
  391. }
  392. .scr-loading-text {
  393. font-size: 28rpx;
  394. color: #999;
  395. }
  396. /* 总分横幅 */
  397. .scr-hero {
  398. background: linear-gradient(135deg, #F97316, #FF8C42);
  399. border-radius: 24rpx;
  400. padding: 40rpx 30rpx;
  401. margin-bottom: 24rpx;
  402. box-shadow: 0 6rpx 20rpx rgba(249, 114, 22, 0.25);
  403. }
  404. .scr-hero-badge {
  405. display: flex;
  406. flex-direction: column;
  407. align-items: center;
  408. }
  409. .scr-hero-title {
  410. font-size: 26rpx;
  411. color: rgba(255, 255, 255, 0.9);
  412. }
  413. .scr-hero-score-row {
  414. display: flex;
  415. align-items: baseline;
  416. margin-top: 10rpx;
  417. }
  418. .scr-hero-score {
  419. font-size: 88rpx;
  420. font-weight: 700;
  421. color: #fff;
  422. }
  423. .scr-hero-total {
  424. font-size: 30rpx;
  425. color: rgba(255, 255, 255, 0.7);
  426. margin-left: 6rpx;
  427. }
  428. .scr-hero-level {
  429. margin-top: 14rpx;
  430. padding: 8rpx 28rpx;
  431. border-radius: 24rpx;
  432. font-size: 26rpx;
  433. font-weight: 600;
  434. background: rgba(255, 255, 255, 0.92);
  435. }
  436. .scr-hero-level.level-healthy { color: #2E7D32; }
  437. .scr-hero-level.level-attention { color: #E65100; }
  438. .scr-hero-level.level-tense { color: #C62828; }
  439. .scr-hero-date {
  440. display: block;
  441. text-align: center;
  442. font-size: 22rpx;
  443. color: rgba(255, 255, 255, 0.8);
  444. margin-top: 16rpx;
  445. }
  446. /* 通用卡片 */
  447. .scr-card {
  448. background: #fff;
  449. border-radius: 24rpx;
  450. padding: 30rpx 26rpx;
  451. margin-bottom: 24rpx;
  452. box-shadow: 0 2rpx 12rpx rgba(0, 0, 0, 0.05);
  453. }
  454. .scr-card-title {
  455. display: flex;
  456. align-items: baseline;
  457. justify-content: space-between;
  458. margin-bottom: 24rpx;
  459. }
  460. .scr-card-title-text {
  461. font-size: 32rpx;
  462. font-weight: 600;
  463. color: #333;
  464. }
  465. .scr-card-sub {
  466. font-size: 22rpx;
  467. color: #999;
  468. }
  469. /* 雷达图 */
  470. .scr-canvas-wrap {
  471. display: flex;
  472. justify-content: center;
  473. }
  474. .scr-canvas {
  475. width: 340px;
  476. height: 340px;
  477. }
  478. /* 维度得分 */
  479. .scr-dim-list {
  480. display: flex;
  481. flex-direction: column;
  482. }
  483. .scr-dim-item {
  484. margin-bottom: 28rpx;
  485. }
  486. .scr-dim-item:last-child {
  487. margin-bottom: 0;
  488. }
  489. .scr-dim-head {
  490. display: flex;
  491. align-items: center;
  492. justify-content: space-between;
  493. }
  494. .scr-dim-label {
  495. display: flex;
  496. align-items: center;
  497. }
  498. .scr-dim-dot {
  499. width: 28rpx;
  500. height: 28rpx;
  501. border-radius: 50%;
  502. margin-right: 12rpx;
  503. }
  504. .scr-dim-name {
  505. font-size: 30rpx;
  506. font-weight: 600;
  507. color: #333;
  508. }
  509. .scr-dim-element {
  510. font-size: 22rpx;
  511. color: #999;
  512. margin-left: 10rpx;
  513. }
  514. .scr-dim-score-wrap {
  515. display: flex;
  516. align-items: baseline;
  517. }
  518. .scr-dim-score {
  519. font-size: 40rpx;
  520. font-weight: 700;
  521. }
  522. .scr-dim-score-max {
  523. font-size: 22rpx;
  524. color: #BBB;
  525. }
  526. .scr-dim-bar {
  527. height: 12rpx;
  528. background: #F0F0F0;
  529. border-radius: 6rpx;
  530. margin-top: 14rpx;
  531. overflow: hidden;
  532. }
  533. .scr-dim-bar-fill {
  534. height: 100%;
  535. border-radius: 6rpx;
  536. transition: width 0.5s ease;
  537. }
  538. .scr-dim-foot {
  539. display: flex;
  540. align-items: center;
  541. margin-top: 12rpx;
  542. }
  543. .scr-dim-level {
  544. font-size: 22rpx;
  545. padding: 4rpx 16rpx;
  546. border-radius: 16rpx;
  547. margin-right: 14rpx;
  548. flex-shrink: 0;
  549. }
  550. .scr-dim-level.lvl-healthy { background: #E8F5E9; color: #2E7D32; }
  551. .scr-dim-level.lvl-attention { background: #FFF8E1; color: #F57F17; }
  552. .scr-dim-level.lvl-tense { background: #FFEBEE; color: #C62828; }
  553. .scr-dim-summary {
  554. flex: 1;
  555. font-size: 24rpx;
  556. color: #888;
  557. line-height: 1.4;
  558. }
  559. /* 寻源建议 */
  560. .scr-advice-intro {
  561. font-size: 24rpx;
  562. color: #666;
  563. line-height: 1.6;
  564. background: #FFF7ED;
  565. border-radius: 12rpx;
  566. padding: 16rpx 20rpx;
  567. margin-bottom: 24rpx;
  568. }
  569. .scr-advice-item {
  570. border: 2rpx solid #F0E6DC;
  571. border-radius: 16rpx;
  572. padding: 24rpx;
  573. margin-bottom: 20rpx;
  574. }
  575. .scr-advice-item:last-child {
  576. margin-bottom: 0;
  577. }
  578. .scr-advice-dim-row {
  579. display: flex;
  580. align-items: center;
  581. justify-content: space-between;
  582. margin-bottom: 18rpx;
  583. }
  584. .scr-advice-dim-badge {
  585. display: flex;
  586. align-items: center;
  587. padding: 8rpx 20rpx;
  588. border-radius: 20rpx;
  589. }
  590. .scr-advice-dim-name {
  591. font-size: 28rpx;
  592. font-weight: 700;
  593. color: #fff;
  594. margin-right: 8rpx;
  595. }
  596. .scr-advice-dim-elem {
  597. font-size: 22rpx;
  598. color: rgba(255, 255, 255, 0.9);
  599. }
  600. .scr-advice-dim-score {
  601. font-size: 26rpx;
  602. font-weight: 600;
  603. color: #C62828;
  604. }
  605. .scr-advice-flow {
  606. display: flex;
  607. align-items: flex-start;
  608. margin-bottom: 12rpx;
  609. }
  610. .scr-flow-node {
  611. display: flex;
  612. align-items: center;
  613. flex-shrink: 0;
  614. width: 200rpx;
  615. }
  616. .scr-flow-dot {
  617. width: 20rpx;
  618. height: 20rpx;
  619. border-radius: 50%;
  620. margin-right: 8rpx;
  621. flex-shrink: 0;
  622. }
  623. .scr-flow-label {
  624. font-size: 24rpx;
  625. font-weight: 600;
  626. color: #333;
  627. }
  628. .scr-flow-arrow {
  629. flex-shrink: 0;
  630. font-size: 24rpx;
  631. color: #F97316;
  632. margin: 0 10rpx;
  633. }
  634. .scr-flow-action {
  635. flex: 1;
  636. font-size: 24rpx;
  637. color: #666;
  638. line-height: 1.5;
  639. }
  640. .scr-advice-action {
  641. display: flex;
  642. align-items: flex-start;
  643. background: #F5FAFE;
  644. border-radius: 12rpx;
  645. padding: 16rpx 20rpx;
  646. margin-top: 10rpx;
  647. }
  648. .scr-advice-action-label {
  649. flex-shrink: 0;
  650. font-size: 22rpx;
  651. font-weight: 600;
  652. color: #F97316;
  653. margin-right: 12rpx;
  654. padding: 2rpx 0;
  655. }
  656. .scr-advice-action-text {
  657. flex: 1;
  658. font-size: 24rpx;
  659. color: #333;
  660. line-height: 1.5;
  661. }
  662. /* 一键加入今日微行动 */
  663. .scr-micro-row {
  664. display: flex;
  665. margin-top: 14rpx;
  666. }
  667. .scr-micro-btn {
  668. flex: 1;
  669. height: 72rpx;
  670. line-height: 72rpx;
  671. font-size: 26rpx;
  672. font-weight: 600;
  673. color: #fff;
  674. background: linear-gradient(135deg, #10B981, #34D399);
  675. border-radius: 36rpx;
  676. border: none;
  677. }
  678. .scr-micro-btn::after {
  679. border: none;
  680. }
  681. .scr-micro-done {
  682. flex: 1;
  683. text-align: center;
  684. font-size: 24rpx;
  685. color: #10B981;
  686. background: #E8F8F1;
  687. border-radius: 12rpx;
  688. padding: 16rpx 0;
  689. }
  690. /* 全部健康 */
  691. .scr-all-healthy {
  692. display: flex;
  693. flex-direction: column;
  694. align-items: center;
  695. padding: 30rpx 0;
  696. }
  697. .scr-all-healthy-icon {
  698. font-size: 72rpx;
  699. margin-bottom: 16rpx;
  700. }
  701. .scr-all-healthy-text {
  702. font-size: 28rpx;
  703. color: #666;
  704. }
  705. /* 底部按钮 */
  706. .scr-footer {
  707. display: flex;
  708. gap: 20rpx;
  709. margin-top: 20rpx;
  710. }
  711. .scr-btn {
  712. flex: 1;
  713. height: 88rpx;
  714. line-height: 88rpx;
  715. font-size: 30rpx;
  716. border-radius: 44rpx;
  717. text-align: center;
  718. border: none;
  719. }
  720. .scr-btn-primary {
  721. background: linear-gradient(135deg, #F97316, #FF8C42);
  722. color: #fff;
  723. font-weight: 600;
  724. }
  725. .scr-btn-outline {
  726. background: #fff;
  727. color: #F97316;
  728. border: 2rpx solid #F97316;
  729. }
  730. </style>