|
@@ -2,14 +2,11 @@
|
|
|
<view class="container">
|
|
<view class="container">
|
|
|
<view v-if="!isLoggedIn">
|
|
<view v-if="!isLoggedIn">
|
|
|
<PageBanner theme="action" tagline="干预 · 记录 · 成长" quote="知行合一,每天进步一点点" />
|
|
<PageBanner theme="action" tagline="干预 · 记录 · 成长" quote="知行合一,每天进步一点点" />
|
|
|
- <!-- 品牌定位语 -->
|
|
|
|
|
<view class="brand-strap"><text class="brand-strap-text">看见改变正在发生</text></view>
|
|
<view class="brand-strap"><text class="brand-strap-text">看见改变正在发生</text></view>
|
|
|
- <!-- 理念卡 -->
|
|
|
|
|
<view class="concept-card">
|
|
<view class="concept-card">
|
|
|
<text class="concept-quote">记录不是目的,看见改变才是。</text>
|
|
<text class="concept-quote">记录不是目的,看见改变才是。</text>
|
|
|
<text class="concept-desc">每一份饮食、运动、心情的记录,都在为成长提供依据。</text>
|
|
<text class="concept-desc">每一份饮食、运动、心情的记录,都在为成长提供依据。</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 示例案例 -->
|
|
|
|
|
<view class="case-card">
|
|
<view class="case-card">
|
|
|
<view class="case-header">
|
|
<view class="case-header">
|
|
|
<text class="case-label">📖 真实案例(脱敏)</text>
|
|
<text class="case-label">📖 真实案例(脱敏)</text>
|
|
@@ -34,7 +31,6 @@
|
|
|
<text class="case-note">通过饮食记录 + 睡眠打卡,免疫力显著提升</text>
|
|
<text class="case-note">通过饮食记录 + 睡眠打卡,免疫力显著提升</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 功能预览 -->
|
|
|
|
|
<view class="guest-features">
|
|
<view class="guest-features">
|
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
|
<text class="feat-icon">✅</text>
|
|
<text class="feat-icon">✅</text>
|
|
@@ -43,7 +39,7 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
|
<text class="feat-icon">📋</text>
|
|
<text class="feat-icon">📋</text>
|
|
|
- <text class="feat-title">成长记¼</text>
|
|
|
|
|
|
|
+ <text class="feat-title">成长回看</text>
|
|
|
<text class="feat-desc">每周家庭健康问卷</text>
|
|
<text class="feat-desc">每周家庭健康问卷</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
@@ -53,11 +49,10 @@
|
|
|
</view>
|
|
</view>
|
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
<view class="feat-card" @click="handleGuestFeatureTap">
|
|
|
<text class="feat-icon">🎯</text>
|
|
<text class="feat-icon">🎯</text>
|
|
|
- <text class="feat-title">家庭挑ս</text>
|
|
|
|
|
|
|
+ <text class="feat-title">家庭挑战</text>
|
|
|
<text class="feat-desc">全家参与的互动任务</text>
|
|
<text class="feat-desc">全家参与的互动任务</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 五维健康体ϵ -->
|
|
|
|
|
<view class="wuxing-section">
|
|
<view class="wuxing-section">
|
|
|
<view class="wuxing-title">身·心·智·行·富 · 可执行的成长闭环</view>
|
|
<view class="wuxing-title">身·心·智·行·富 · 可执行的成长闭环</view>
|
|
|
<view class="wuxing-desc">五行相生相克,动起来、坚持做,让成长真正发生</view>
|
|
<view class="wuxing-desc">五行相生相克,动起来、坚持做,让成长真正发生</view>
|
|
@@ -111,7 +106,7 @@
|
|
|
<view class="wc-card wc-action" @click="goPage('/pages/action-detail/member-action-detail')">
|
|
<view class="wc-card wc-action" @click="goPage('/pages/action-detail/member-action-detail')">
|
|
|
<text class="wc-icon">🌿</text>
|
|
<text class="wc-icon">🌿</text>
|
|
|
<view class="wc-info">
|
|
<view class="wc-info">
|
|
|
- <text class="wc-name">行 · 人际和г</text>
|
|
|
|
|
|
|
+ <text class="wc-name">行 · 人际和谐</text>
|
|
|
<text class="wc-text">从一次倾听开始,让家庭关系每天升温</text>
|
|
<text class="wc-text">从一次倾听开始,让家庭关系每天升温</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -119,25 +114,28 @@
|
|
|
<text class="wc-icon">🔥</text>
|
|
<text class="wc-icon">🔥</text>
|
|
|
<view class="wc-info">
|
|
<view class="wc-info">
|
|
|
<text class="wc-name">心 · 大爱相随</text>
|
|
<text class="wc-name">心 · 大爱相随</text>
|
|
|
- <text class="wc-text">每天留 10 分钟说说话,把家人的心事接ס</text>
|
|
|
|
|
|
|
+ <text class="wc-text">每天留 10 分钟说说话,把家人的心事接住</text>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 登录引导 -->
|
|
|
|
|
<view class="login-guide-section">
|
|
<view class="login-guide-section">
|
|
|
<LoginGuideCard
|
|
<LoginGuideCard
|
|
|
title="解锁完整成长档案"
|
|
title="解锁完整成长档案"
|
|
|
:items="[
|
|
:items="[
|
|
|
- '查看干预进度与追踪记¼',
|
|
|
|
|
- '完成每日打卡累积连续记¼',
|
|
|
|
|
|
|
+ '查看干预进度与追踪记录',
|
|
|
|
|
+ '完成每日打卡累积连续记录',
|
|
|
'参与家庭挑战获得里程碑奖励'
|
|
'参与家庭挑战获得里程碑奖励'
|
|
|
]" />
|
|
]" />
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
<view v-else>
|
|
<view v-else>
|
|
|
<PageBanner theme="action" tagline="干预 · 记录 · 成长" quote="知行合一,每天进步一点点" />
|
|
<PageBanner theme="action" tagline="干预 · 记录 · 成长" quote="知行合一,每天进步一点点" />
|
|
|
- <!-- 里程碑 -->
|
|
|
|
|
|
|
+ <FamilyMemberStrip @select="onMemberSelect" />
|
|
|
|
|
+ <view class="reminder-bar" v-if="hasIncomplete">
|
|
|
|
|
+ <text class="reminder-text">⚠ 今日还有 {{ incompleteCount }} 项未记录</text>
|
|
|
|
|
+ <text class="reminder-close" @click="dismissReminder">✕</text>
|
|
|
|
|
+ </view>
|
|
|
<view class="section">
|
|
<view class="section">
|
|
|
<view class="milestone-card">
|
|
<view class="milestone-card">
|
|
|
<text class="section-title-row">🏆 里程碑</text>
|
|
<text class="section-title-row">🏆 里程碑</text>
|
|
@@ -150,7 +148,7 @@
|
|
|
<view class="milestone-item">
|
|
<view class="milestone-item">
|
|
|
<text class="milestone-icon">🎯</text>
|
|
<text class="milestone-icon">🎯</text>
|
|
|
<text class="milestone-value">{{ activeChallenges }}</text>
|
|
<text class="milestone-value">{{ activeChallenges }}</text>
|
|
|
- <text class="milestone-label">进行中挑ս</text>
|
|
|
|
|
|
|
+ <text class="milestone-label">进行中挑战</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="milestone-item">
|
|
<view class="milestone-item">
|
|
|
<text class="milestone-icon">📈</text>
|
|
<text class="milestone-icon">📈</text>
|
|
@@ -160,14 +158,13 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <!-- 成长记¼ -->
|
|
|
|
|
<view class="section">
|
|
<view class="section">
|
|
|
<view class="survey-card">
|
|
<view class="survey-card">
|
|
|
- <text class="section-title-row">📋 成长记¼</text>
|
|
|
|
|
|
|
+ <text class="section-title-row">📋 成长回看</text>
|
|
|
<view class="survey-pending" v-if="pendingSurvey">
|
|
<view class="survey-pending" v-if="pendingSurvey">
|
|
|
<text class="survey-alert">⚠ 本周还未完成调研</text>
|
|
<text class="survey-alert">⚠ 本周还未完成调研</text>
|
|
|
<text class="survey-title-text">{{ pendingSurvey.title }}</text>
|
|
<text class="survey-title-text">{{ pendingSurvey.title }}</text>
|
|
|
- <text class="survey-btn" @click="startSurvey">[开始填д]</text>
|
|
|
|
|
|
|
+ <text class="survey-btn" @click="startSurvey">[开始填写]</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="survey-done" v-else-if="allDone"><text class="survey-done-text">✅ 所有调研已完成</text></view>
|
|
<view class="survey-done" v-else-if="allDone"><text class="survey-done-text">✅ 所有调研已完成</text></view>
|
|
|
<view class="survey-history-list" v-if="surveyHistory.length > 0">
|
|
<view class="survey-history-list" v-if="surveyHistory.length > 0">
|
|
@@ -181,22 +178,17 @@
|
|
|
<view class="survey-empty" v-else-if="!pendingSurvey"><text class="survey-empty-text">暂无待完成调研</text></view>
|
|
<view class="survey-empty" v-else-if="!pendingSurvey"><text class="survey-empty-text">暂无待完成调研</text></view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="reminder-bar" v-if="hasIncomplete">
|
|
|
|
|
- <text class="reminder-text">⚠ 今日还有 {{ incompleteCount }} 项未记¼</text>
|
|
|
|
|
- <text class="reminder-close" @click="dismissReminder">✕</text>
|
|
|
|
|
- </view>
|
|
|
|
|
<view class="section">
|
|
<view class="section">
|
|
|
<view class="progress-card">
|
|
<view class="progress-card">
|
|
|
<view class="progress-header">
|
|
<view class="progress-header">
|
|
|
- <text class="progress-title">今日成长</text>
|
|
|
|
|
|
|
+ <text class="progress-title">今日干预进度</text>
|
|
|
<text class="progress-date">{{ todayDate }}</text>
|
|
<text class="progress-date">{{ todayDate }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="progress-grid">
|
|
|
|
|
- <view class="progress-grid-item" v-for="(item, idx) in progressItems" :key="getProgressKey(item)" @click="handleProgressClick(item)">
|
|
|
|
|
- <text class="progress-grid-icon">{{ item.icon }}</text>
|
|
|
|
|
- <text class="progress-grid-label">{{ item.label }}</text>
|
|
|
|
|
- <text class="progress-grid-status" :class="item.done ? 'status-done' : 'status-pending'">{{ item.done ? '✔' : (item.actionText || '去记¼') }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+ <view class="progress-item" v-for="(item, idx) in progressItems" :key="getProgressKey(item)">
|
|
|
|
|
+ <text class="progress-icon">{{ item.icon }}</text>
|
|
|
|
|
+ <text class="progress-label">{{ item.label }}</text>
|
|
|
|
|
+ <text class="progress-status" :class="item.done ? 'status-done' : 'status-pending'">{{ item.done ? '✔ 已完成' : '' }}</text>
|
|
|
|
|
+ <text class="progress-btn" v-if="!item.done" @click="handleProgressClick(item)">{{ item.actionText || '补录' }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="progress-footer">
|
|
<view class="progress-footer">
|
|
|
<text class="footer-text">今日完成 {{ doneCount }}/{{ totalCount }}</text>
|
|
<text class="footer-text">今日完成 {{ doneCount }}/{{ totalCount }}</text>
|
|
@@ -218,7 +210,7 @@
|
|
|
<view class="diet-card">
|
|
<view class="diet-card">
|
|
|
<view class="diet-card-header">
|
|
<view class="diet-card-header">
|
|
|
<text class="diet-card-title">🥬 今日推荐食材</text>
|
|
<text class="diet-card-title">🥬 今日推荐食材</text>
|
|
|
- <text class="diet-card-link" @click="goToDiet">饮食主ҳ ›</text>
|
|
|
|
|
|
|
+ <text class="diet-card-link" @click="goToDiet">饮食主页 ›</text>
|
|
|
</view>
|
|
</view>
|
|
|
<view class="diet-card-content" v-if="ingredients.length > 0">
|
|
<view class="diet-card-content" v-if="ingredients.length > 0">
|
|
|
<view class="diet-item" v-for="(item, index) in ingredients" :key="getIngredientKey(item, index)">
|
|
<view class="diet-item" v-for="(item, index) in ingredients" :key="getIngredientKey(item, index)">
|
|
@@ -232,41 +224,36 @@
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
-
|
|
|
|
|
- <!-- ===== 推荐商Ʒ ===== -->
|
|
|
|
|
<RecommendedFeed
|
|
<RecommendedFeed
|
|
|
:products="recommendedProducts"
|
|
:products="recommendedProducts"
|
|
|
:activities="[]"
|
|
:activities="[]"
|
|
|
:loading="loadingProducts"
|
|
:loading="loadingProducts"
|
|
|
@itemClick="onFeedItemClick"
|
|
@itemClick="onFeedItemClick"
|
|
|
@more="goMoreDiscover" />
|
|
@more="goMoreDiscover" />
|
|
|
-
|
|
|
|
|
- <!-- ===== 推荐阅读 ===== -->
|
|
|
|
|
<ArticleBookshelf
|
|
<ArticleBookshelf
|
|
|
:articles="indexArticles"
|
|
:articles="indexArticles"
|
|
|
:loading="articlesLoading"
|
|
:loading="articlesLoading"
|
|
|
:isLoggedIn="isLoggedIn"
|
|
:isLoggedIn="isLoggedIn"
|
|
|
@articleClick="goArticleDetail"
|
|
@articleClick="goArticleDetail"
|
|
|
@moreArticles="goMoreArticles" />
|
|
@moreArticles="goMoreArticles" />
|
|
|
-
|
|
|
|
|
<view class="section">
|
|
<view class="section">
|
|
|
- <view class="section-title-row">📊 记录概览</view>
|
|
|
|
|
- <view class="record-grid">
|
|
|
|
|
- <view class="record-card" v-for="tab in trackingTabs" :key="tab.key" @click="viewAllRecordsByType(tab.key)">
|
|
|
|
|
- <view class="record-card-header">
|
|
|
|
|
- <text class="record-card-icon">{{ tab.icon }}</text>
|
|
|
|
|
- <text class="record-card-label">{{ tab.label }}</text>
|
|
|
|
|
|
|
+ <view class="tracking-card">
|
|
|
|
|
+ <view class="tracking-tabs">
|
|
|
|
|
+ <view class="tracking-tab" :class="activeTab === tab.key ? 'tab-active' : ''" v-for="tab in trackingTabs" :key="tab.key" @click="switchTab(tab.key)">
|
|
|
|
|
+ <text class="tab-text" :class="activeTab === tab.key ? 'tab-active-text' : ''">{{ tab.label }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="record-card-body" v-if="(trackingData[tab.key] || []).length > 0">
|
|
|
|
|
- <view class="record-card-item" v-for="(rec, rIdx) in (trackingData[tab.key] || []).slice(0, 2)" :key="getRecordKey(rec)">
|
|
|
|
|
- <text class="record-card-date">{{ rec._date || rec._text }}</text>
|
|
|
|
|
- <text class="record-card-content">{{ rec._content }}</text>
|
|
|
|
|
- </view>
|
|
|
|
|
|
|
+ </view>
|
|
|
|
|
+ <view class="tracking-content">
|
|
|
|
|
+ <view class="tracking-empty" v-if="currentRecords.length === 0">
|
|
|
|
|
+ <text class="empty-icon">📊</text>
|
|
|
|
|
+ <text class="empty-text">还没有记录</text>
|
|
|
|
|
+ <text class="empty-hint">开始记录{{ activeTabLabel }}吧</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="record-card-empty" v-else>
|
|
|
|
|
- <text class="empty-text">暂无记¼</text>
|
|
|
|
|
|
|
+ <view class="tracking-record" v-for="(rec, rIdx) in currentRecords" :key="getRecordKey(rec)">
|
|
|
|
|
+ <text class="record-date">{{ rec._date || rec._text }}</text>
|
|
|
|
|
+ <text class="record-content">{{ rec._content }}</text>
|
|
|
</view>
|
|
</view>
|
|
|
- <view class="record-card-footer">查看全部 ›</view>
|
|
|
|
|
|
|
+ <view class="tracking-more" v-if="currentRecords.length > 0" @click="viewAllRecords">查看全部 ›</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
|
</view>
|
|
</view>
|
|
@@ -277,17 +264,17 @@
|
|
|
<script>
|
|
<script>
|
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
import PageBanner from '../../components/PageBanner.vue'
|
|
|
import LoginGuideCard from '../../components/LoginGuideCard.vue'
|
|
import LoginGuideCard from '../../components/LoginGuideCard.vue'
|
|
|
|
|
+import FamilyMemberStrip from '../../components/FamilyMemberStrip.vue'
|
|
|
import DimensionActivities from '../../components/DimensionActivities.vue'
|
|
import DimensionActivities from '../../components/DimensionActivities.vue'
|
|
|
import RecommendedFeed from '../../components/RecommendedFeed.vue'
|
|
import RecommendedFeed from '../../components/RecommendedFeed.vue'
|
|
|
import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
|
|
import ArticleBookshelf from '../../components/ArticleBookshelf.vue'
|
|
|
-import { healthCheckinList, getDietIngredients, getSurveyStatus, getSurveyHistory, getFoodCautionList, getExerciseList, getMindCheckinList, getSleepList, getHealthMealList, productList, getFeaturedArticles } from '../../utils/api.js'
|
|
|
|
|
|
|
+import { healthCheckinList, getDietDailyRecords, getDietIngredients, getSurveyStatus, getSurveyHistory, getFoodCautionList, getExerciseList, getMindCheckinList, getSleepList, productList, getFeaturedArticles, getStreakProgress, getChallengeList } from '../../utils/api.js'
|
|
|
export default {
|
|
export default {
|
|
|
- components: { PageBanner, LoginGuideCard, DimensionActivities, RecommendedFeed, ArticleBookshelf },
|
|
|
|
|
- data() { return { memberId: '', todayDate: '', hasIncomplete: false, incompleteCount: 0, progressItems: [], trackingTabs: [{ key: 'diet', label: '饮ʳ', icon: '🍽️' }, { key: 'exercise', label: '运动', icon: '🏃' }, { key: 'sleep', label: '睡眠', icon: '😴' }, { key: 'emotion', label: '心情', icon: '😊' }], trackingData: { diet: [], exercise: [], sleep: [], emotion: [] }, streakDays: 0, activeChallenges: 0, completeness: 0, cautionCount: 0,
|
|
|
|
|
|
|
+ components: { PageBanner, LoginGuideCard, FamilyMemberStrip, DimensionActivities, RecommendedFeed, ArticleBookshelf },
|
|
|
|
|
+ data() { return { memberId: '', todayDate: '', hasIncomplete: false, incompleteCount: 0, progressItems: [], activeTab: 'diet', trackingTabs: [{ key: 'diet', label: '饮食' }, { key: 'exercise', label: '运动' }, { key: 'sleep', label: '睡眠' }, { key: 'emotion', label: '心情' }, { key: 'survey', label: '调研' }], trackingData: { diet: [], exercise: [], sleep: [], emotion: [], survey: [] }, streakDays: 0, activeChallenges: 0, completeness: 0, cautionCount: 0,
|
|
|
pendingSurvey: null, allDone: false, surveyHistory: [], isLoggedIn: false,
|
|
pendingSurvey: null, allDone: false, surveyHistory: [], isLoggedIn: false,
|
|
|
ingredients: [],
|
|
ingredients: [],
|
|
|
ingredientsLoading: false,
|
|
ingredientsLoading: false,
|
|
|
- // 推荐商品 + 推荐阅读(与首页 parent-index 一致)
|
|
|
|
|
recommendedProducts: [],
|
|
recommendedProducts: [],
|
|
|
loadingProducts: false,
|
|
loadingProducts: false,
|
|
|
indexArticles: [],
|
|
indexArticles: [],
|
|
@@ -301,7 +288,9 @@ export default {
|
|
|
] } },
|
|
] } },
|
|
|
computed: {
|
|
computed: {
|
|
|
doneCount: function() { var c = 0; for (var i = 0; i < this.progressItems.length; i++) if (this.progressItems[i] && this.progressItems[i].done) c++; return c },
|
|
doneCount: function() { var c = 0; for (var i = 0; i < this.progressItems.length; i++) if (this.progressItems[i] && this.progressItems[i].done) c++; return c },
|
|
|
- totalCount: function() { return this.progressItems.length }
|
|
|
|
|
|
|
+ totalCount: function() { return this.progressItems.length },
|
|
|
|
|
+ activeTabLabel: function() { var m = { diet: '饮食', exercise: '运动', sleep: '睡眠', emotion: '心情', survey: '调研' }; return m[this.activeTab] || '' },
|
|
|
|
|
+ currentRecords: function() { return this.trackingData[this.activeTab] || [] }
|
|
|
},
|
|
},
|
|
|
onShow() {
|
|
onShow() {
|
|
|
this.isLoggedIn = !!uni.getStorageSync('token')
|
|
this.isLoggedIn = !!uni.getStorageSync('token')
|
|
@@ -313,16 +302,17 @@ export default {
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
|
|
+ onMemberSelect: function(member) {
|
|
|
|
|
+ this.memberId = member && member.id ? member.id : ''
|
|
|
|
|
+ this.loadAllData()
|
|
|
|
|
+ },
|
|
|
pad: function(n) { return n < 10 ? '0' + n : '' + n },
|
|
pad: function(n) { return n < 10 ? '0' + n : '' + n },
|
|
|
getProgressKey: function(item) { return item && item.label ? item.label : 'p-' + Math.random() },
|
|
getProgressKey: function(item) { return item && item.label ? item.label : 'p-' + Math.random() },
|
|
|
- getRecordKey: function(rec) { return rec && rec._text ? rec._text + rec._content : 'r-' + Math.random() },
|
|
|
|
|
|
|
+ getRecordKey: function(rec) { return rec && (rec._id || rec.id) ? 'r' + (rec._id || rec.id) : (rec && rec._text ? rec._text + rec._content : 'r-' + Math.random()) },
|
|
|
getIngredientKey: function(item, index) { return 'ing-' + (item.id || index) },
|
|
getIngredientKey: function(item, index) { return 'ing-' + (item.id || index) },
|
|
|
getHistoryKey: function(h) { return h && h._date ? h._date + h._content : 'h-' + Math.random() },
|
|
getHistoryKey: function(h) { return h && h._date ? h._date + h._content : 'h-' + Math.random() },
|
|
|
dismissReminder: function() { this.hasIncomplete = false },
|
|
dismissReminder: function() { this.hasIncomplete = false },
|
|
|
- viewAllRecordsByType: function(key) {
|
|
|
|
|
- var m = { diet: '/pages/health/diet-index', exercise: '/pages/health/exercise-index', sleep: '/pages/health/sleep-index', emotion: '/pages/mind-detail/emotion-checkin' }
|
|
|
|
|
- if (m[key]) uni.navigateTo({ url: m[key] })
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ switchTab: function(key) { this.activeTab = key; this.loadTrackingData(key) },
|
|
|
handleProgressClick: function(item) {
|
|
handleProgressClick: function(item) {
|
|
|
if (!item || !item.key) return
|
|
if (!item || !item.key) return
|
|
|
var m = { checkin: '/pages/health/daily-checkin', diet: '/pages/health/diet-index', exercise: '/pages/health/exercise-index', sleep: '/pages/health/sleep-index', emotion: '/pages/mind-detail/emotion-checkin' }
|
|
var m = { checkin: '/pages/health/daily-checkin', diet: '/pages/health/diet-index', exercise: '/pages/health/exercise-index', sleep: '/pages/health/sleep-index', emotion: '/pages/mind-detail/emotion-checkin' }
|
|
@@ -333,6 +323,7 @@ export default {
|
|
|
if (url) uni.navigateTo({ url: url })
|
|
if (url) uni.navigateTo({ url: url })
|
|
|
},
|
|
},
|
|
|
startSurvey: function() { if (this.pendingSurvey && this.pendingSurvey.templateId) uni.navigateTo({ url: '/pages/health/survey-questionnaire?templateId=' + this.pendingSurvey.templateId + '&templateTitle=' + encodeURIComponent(this.pendingSurvey.title) + '&templateDimension=' + (this.pendingSurvey.dimension || '') }) },
|
|
startSurvey: function() { if (this.pendingSurvey && this.pendingSurvey.templateId) uni.navigateTo({ url: '/pages/health/survey-questionnaire?templateId=' + this.pendingSurvey.templateId + '&templateTitle=' + encodeURIComponent(this.pendingSurvey.title) + '&templateDimension=' + (this.pendingSurvey.dimension || '') }) },
|
|
|
|
|
+ viewAllRecords: function() { var m = { diet: '/pages/health/diet-index', exercise: '/pages/health/exercise-index', sleep: '/pages/health/sleep-index', survey: '/pages/health/survey-history?memberId=' + this.memberId, emotion: '/pages/mind-detail/emotion-checkin' }; if (m[this.activeTab]) uni.navigateTo({ url: m[this.activeTab] }) },
|
|
|
viewAllHistory: function() { uni.navigateTo({ url: '/pages/health/survey-history?memberId=' + this.memberId }) },
|
|
viewAllHistory: function() { uni.navigateTo({ url: '/pages/health/survey-history?memberId=' + this.memberId }) },
|
|
|
goActivityDetail: function(act) { uni.navigateTo({ url: '/pages/activity/activity-detail/activity-detail?id=' + act.id }) },
|
|
goActivityDetail: function(act) { uni.navigateTo({ url: '/pages/activity/activity-detail/activity-detail?id=' + act.id }) },
|
|
|
goMoreActivities: function() { uni.navigateTo({ url: '/pages/activity/index' }) },
|
|
goMoreActivities: function() { uni.navigateTo({ url: '/pages/activity/index' }) },
|
|
@@ -340,142 +331,76 @@ export default {
|
|
|
goToCaution: function() { uni.navigateTo({ url: '/pages/growth/caution-detail' }) },
|
|
goToCaution: function() { uni.navigateTo({ url: '/pages/growth/caution-detail' }) },
|
|
|
goToDiet: function() { uni.navigateTo({ url: '/pages/diet/index' }) },
|
|
goToDiet: function() { uni.navigateTo({ url: '/pages/diet/index' }) },
|
|
|
goPage: function(url) { uni.navigateTo({ url: url }) },
|
|
goPage: function(url) { uni.navigateTo({ url: url }) },
|
|
|
- // ===== 推荐商品 + 推荐阅读(与首页 parent-index 一致) =====
|
|
|
|
|
onFeedItemClick: function(item) {
|
|
onFeedItemClick: function(item) {
|
|
|
if (item && item.type === 'product' && item.id) {
|
|
if (item && item.type === 'product' && item.id) {
|
|
|
uni.navigateTo({ url: '/pages/discover-detail/product-detail/product-detail?id=' + item.id })
|
|
uni.navigateTo({ url: '/pages/discover-detail/product-detail/product-detail?id=' + item.id })
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
- goMoreDiscover: function() {
|
|
|
|
|
- uni.navigateTo({ url: '/pages/shop/index/index' })
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ goMoreDiscover: function() { uni.navigateTo({ url: '/pages/shop/index/index' }) },
|
|
|
goArticleDetail: function(articleOrId) {
|
|
goArticleDetail: function(articleOrId) {
|
|
|
var id = typeof articleOrId === 'object' ? articleOrId.id : articleOrId
|
|
var id = typeof articleOrId === 'object' ? articleOrId.id : articleOrId
|
|
|
if (id) uni.navigateTo({ url: '/pages/article-center/article-detail?id=' + id })
|
|
if (id) uni.navigateTo({ url: '/pages/article-center/article-detail?id=' + id })
|
|
|
},
|
|
},
|
|
|
- goMoreArticles: function() {
|
|
|
|
|
- uni.navigateTo({ url: '/pages/article-center/index' })
|
|
|
|
|
- },
|
|
|
|
|
|
|
+ goMoreArticles: function() { uni.navigateTo({ url: '/pages/article-center/index' }) },
|
|
|
|
|
+ loadTrackingData: function(key) { return this.trackingData[key] || [] },
|
|
|
async loadAllData() {
|
|
async loadAllData() {
|
|
|
var self = this
|
|
var self = this
|
|
|
- self.loadProgressItems()
|
|
|
|
|
- self.loadSurveyData()
|
|
|
|
|
- self.loadRecommendedProducts()
|
|
|
|
|
- self.loadFeaturedArticles()
|
|
|
|
|
- self.loadCautionData()
|
|
|
|
|
- self.loadMilestones()
|
|
|
|
|
- self.loadDietIngredients()
|
|
|
|
|
- },
|
|
|
|
|
- loadRecommendedProducts: function() {
|
|
|
|
|
- var self = this
|
|
|
|
|
- self.loadingProducts = true
|
|
|
|
|
- productList({ page: 1, size: 6 }).then(function(res) {
|
|
|
|
|
- self.loadingProducts = false
|
|
|
|
|
- if (res && res.code === 200 && res.data) {
|
|
|
|
|
- var list = res.data.records || []
|
|
|
|
|
- self.recommendedProducts = list.map(function(p) {
|
|
|
|
|
- p.type = 'product'
|
|
|
|
|
- return p
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- }).catch(function() {
|
|
|
|
|
- self.loadingProducts = false
|
|
|
|
|
- self.recommendedProducts = []
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
- loadFeaturedArticles: function() {
|
|
|
|
|
- var self = this
|
|
|
|
|
- self.articlesLoading = true
|
|
|
|
|
- getFeaturedArticles({ size: 5 }).then(function(res) {
|
|
|
|
|
- self.articlesLoading = false
|
|
|
|
|
- if (res && res.code === 200) {
|
|
|
|
|
- var rawList = res.data && (Array.isArray(res.data) ? res.data : (res.data.data || res.data.records || []))
|
|
|
|
|
- var list = Array.isArray(rawList) ? rawList : []
|
|
|
|
|
- self.indexArticles = list.map(function(item, index) {
|
|
|
|
|
- return {
|
|
|
|
|
- id: item.id,
|
|
|
|
|
- category: item.categoryName || item.category || '热门文章',
|
|
|
|
|
- categoryColor: self.gradientColors[index % self.gradientColors.length],
|
|
|
|
|
- title: item.title || '',
|
|
|
|
|
- summary: item.summary || '',
|
|
|
|
|
- views: item.viewCount ? String(item.viewCount) : '0',
|
|
|
|
|
- date: item.publishedAt ? item.publishedAt.slice(0, 10) : '',
|
|
|
|
|
- coverImage: item.coverImage
|
|
|
|
|
- }
|
|
|
|
|
- })
|
|
|
|
|
- }
|
|
|
|
|
- }).catch(function() {
|
|
|
|
|
- self.articlesLoading = false
|
|
|
|
|
- self.indexArticles = []
|
|
|
|
|
- })
|
|
|
|
|
|
|
+ try { await self.loadProgressItems() } catch(e) {}
|
|
|
|
|
+ try { await self.loadSurveyData() } catch(e) {}
|
|
|
|
|
+ try { await self.loadMilestones() } catch(e) {}
|
|
|
|
|
+ try { self.loadRecommendedProducts() } catch(e) {}
|
|
|
|
|
+ try { self.loadFeaturedArticles() } catch(e) {}
|
|
|
|
|
+ try { await self.loadCautionData() } catch(e) {}
|
|
|
|
|
+ try { await self.loadDietIngredients() } catch(e) {}
|
|
|
},
|
|
},
|
|
|
async loadProgressItems() {
|
|
async loadProgressItems() {
|
|
|
var self = this
|
|
var self = this
|
|
|
var items = []
|
|
var items = []
|
|
|
- var dietDone = false
|
|
|
|
|
|
|
+ var checkinDone = false
|
|
|
try {
|
|
try {
|
|
|
- var dRes = await getHealthMealList({ memberId: self.memberId })
|
|
|
|
|
- if (dRes.code === 200 && dRes.data && dRes.data.length > 0) {
|
|
|
|
|
- for (var dm = 0; dm < dRes.data.length; dm++) {
|
|
|
|
|
- var dRec = dRes.data[dm]
|
|
|
|
|
- if (!dRec) continue
|
|
|
|
|
- var dDate = dRec.createdAt
|
|
|
|
|
- if (dDate instanceof Date) dDate = dDate.toISOString().substring(0, 10)
|
|
|
|
|
- else if (typeof dDate === 'string') dDate = dDate.substring(0, 10)
|
|
|
|
|
- else continue
|
|
|
|
|
- if (dDate === self.todayDate) { dietDone = true; break }
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ var ciRes = await healthCheckinList({ yearMonth: self.todayDate.substring(0, 7) })
|
|
|
|
|
+ if (ciRes.code === 200 && ciRes.data) {
|
|
|
|
|
+ for (var ci = 0; ci < ciRes.data.length; ci++) { if (ciRes.data[ci] && ciRes.data[ci].checkinDate && ciRes.data[ci].checkinDate.substring(0, 10) === self.todayDate) { checkinDone = true; break } }
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
- items.push({ key: 'diet', icon: '🍽️', label: '饮食记录', done: dietDone, actionText: '补¼' })
|
|
|
|
|
|
|
+ items.push({ key: 'checkin', icon: '✅', label: '今日打卡', done: checkinDone, actionText: '打卡' })
|
|
|
|
|
+ var dietDone = false
|
|
|
|
|
+ try {
|
|
|
|
|
+ var dRes = await getDietDailyRecords({ date: self.todayDate })
|
|
|
|
|
+ if (dRes.code === 200 && dRes.data && dRes.data.length > 0) dietDone = true
|
|
|
|
|
+ } catch(e) {}
|
|
|
|
|
+ items.push({ key: 'diet', icon: '🍽️', label: '饮食记录', done: dietDone, actionText: '补录' })
|
|
|
var exerciseDone = false
|
|
var exerciseDone = false
|
|
|
try {
|
|
try {
|
|
|
var exRes = await getExerciseList({ memberId: self.memberId })
|
|
var exRes = await getExerciseList({ memberId: self.memberId })
|
|
|
- if (exRes.code === 200 && exRes.data && exRes.data.length > 0) {
|
|
|
|
|
- for (var ex = 0; ex < exRes.data.length; ex++) {
|
|
|
|
|
- var exRec = exRes.data[ex]
|
|
|
|
|
- if (!exRec) continue
|
|
|
|
|
- var exDate = exRec.createdAt
|
|
|
|
|
- if (exDate instanceof Date) exDate = exDate.toISOString().substring(0, 10)
|
|
|
|
|
- else if (typeof exDate === 'string') exDate = exDate.substring(0, 10)
|
|
|
|
|
- else continue
|
|
|
|
|
- if (exDate === self.todayDate) { exerciseDone = true; break }
|
|
|
|
|
|
|
+ if (exRes.code === 200 && exRes.data) {
|
|
|
|
|
+ for (var ei = 0; ei < exRes.data.length; ei++) {
|
|
|
|
|
+ if (exRes.data[ei] && exRes.data[ei].recordDate && exRes.data[ei].recordDate.substring(0, 10) === self.todayDate) { exerciseDone = true; break }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
- items.push({ key: 'exercise', icon: '🏃', label: '运动记录', done: exerciseDone, actionText: '记¼' })
|
|
|
|
|
|
|
+ items.push({ key: 'exercise', icon: '🏃', label: '运动记录', done: exerciseDone, actionText: '记录' })
|
|
|
var sleepDone = false
|
|
var sleepDone = false
|
|
|
try {
|
|
try {
|
|
|
var slRes = await getSleepList({ memberId: self.memberId })
|
|
var slRes = await getSleepList({ memberId: self.memberId })
|
|
|
- if (slRes.code === 200 && slRes.data && slRes.data.length > 0) {
|
|
|
|
|
- for (var sl = 0; sl < slRes.data.length; sl++) {
|
|
|
|
|
- var slRec = slRes.data[sl]
|
|
|
|
|
- if (!slRec) continue
|
|
|
|
|
- var slDate = slRec.createdAt
|
|
|
|
|
- if (slDate instanceof Date) slDate = slDate.toISOString().substring(0, 10)
|
|
|
|
|
- else if (typeof slDate === 'string') slDate = slDate.substring(0, 10)
|
|
|
|
|
- else continue
|
|
|
|
|
- if (slDate === self.todayDate) { sleepDone = true; break }
|
|
|
|
|
|
|
+ if (slRes.code === 200 && slRes.data) {
|
|
|
|
|
+ for (var si = 0; si < slRes.data.length; si++) {
|
|
|
|
|
+ if (slRes.data[si] && slRes.data[si].recordDate && slRes.data[si].recordDate.substring(0, 10) === self.todayDate) { sleepDone = true; break }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
- items.push({ key: 'sleep', icon: '😴', label: '睡眠记录', done: sleepDone, actionText: '记¼' })
|
|
|
|
|
|
|
+ items.push({ key: 'sleep', icon: '😴', label: '睡眠记录', done: sleepDone, actionText: '记录' })
|
|
|
var emotionDone = false
|
|
var emotionDone = false
|
|
|
try {
|
|
try {
|
|
|
var emRes = await getMindCheckinList({ page: 1, size: 20, memberId: self.memberId })
|
|
var emRes = await getMindCheckinList({ page: 1, size: 20, memberId: self.memberId })
|
|
|
- if (emRes.code === 200 && emRes.data && emRes.data.length > 0) {
|
|
|
|
|
|
|
+ if (emRes.code === 200 && emRes.data) {
|
|
|
for (var em = 0; em < emRes.data.length; em++) {
|
|
for (var em = 0; em < emRes.data.length; em++) {
|
|
|
- var emRec = emRes.data[em]
|
|
|
|
|
- if (!emRec) continue
|
|
|
|
|
- var emDate = emRec.checkinDate
|
|
|
|
|
- if (emDate instanceof Date) emDate = emDate.toISOString().substring(0, 10)
|
|
|
|
|
- else if (typeof emDate === 'string') emDate = emDate.substring(0, 10)
|
|
|
|
|
- else continue
|
|
|
|
|
- if (emDate === self.todayDate) { emotionDone = true; break }
|
|
|
|
|
|
|
+ if (emRes.data[em] && emRes.data[em].checkinDate && emRes.data[em].checkinDate.substring(0, 10) === self.todayDate) { emotionDone = true; break }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
- items.push({ key: 'emotion', icon: '😊', label: '心情记录', done: emotionDone, actionText: '记¼' })
|
|
|
|
|
|
|
+ items.push({ key: 'emotion', icon: '😊', label: '心情记录', done: emotionDone, actionText: '记录' })
|
|
|
|
|
+ items.push({ key: 'survey', icon: '📋', label: '本周调研', done: self.allDone, actionText: self.allDone ? '' : '开始' })
|
|
|
self.progressItems = items.filter(function(it) { return it && it.key })
|
|
self.progressItems = items.filter(function(it) { return it && it.key })
|
|
|
self.incompleteCount = 0
|
|
self.incompleteCount = 0
|
|
|
for (var pi = 0; pi < items.length; pi++) if (items[pi] && !items[pi].done) self.incompleteCount++
|
|
for (var pi = 0; pi < items.length; pi++) if (items[pi] && !items[pi].done) self.incompleteCount++
|
|
@@ -488,7 +413,7 @@ export default {
|
|
|
if (statusRes.code === 200 && statusRes.data) {
|
|
if (statusRes.code === 200 && statusRes.data) {
|
|
|
var list = statusRes.data
|
|
var list = statusRes.data
|
|
|
self.pendingSurvey = null; self.allDone = true; var hasAny = false
|
|
self.pendingSurvey = null; self.allDone = true; var hasAny = false
|
|
|
- for (var si = 0; si < list.length; si++) { var s = list[si]; if (!s) continue; hasAny = true; if (s.status === 'pending') { self.pendingSurvey = { templateId: s.templateId, title: s.title || '成长记¼', dimension: s.dimension || '' }; self.allDone = false } }
|
|
|
|
|
|
|
+ for (var si = 0; si < list.length; si++) { var s = list[si]; if (!s) continue; hasAny = true; if (s.status === 'pending') { self.pendingSurvey = { templateId: s.templateId, title: s.title || '成长回看', dimension: s.dimension || '' }; self.allDone = false } }
|
|
|
if (!hasAny) { self.pendingSurvey = null; self.allDone = false }
|
|
if (!hasAny) { self.pendingSurvey = null; self.allDone = false }
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
@@ -500,6 +425,49 @@ export default {
|
|
|
}
|
|
}
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
},
|
|
},
|
|
|
|
|
+ loadRecommendedProducts: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ self.loadingProducts = true
|
|
|
|
|
+ productList({ page: 1, size: 6 }).then(function(res) {
|
|
|
|
|
+ self.loadingProducts = false
|
|
|
|
|
+ if (res && res.code === 200 && res.data) {
|
|
|
|
|
+ var list = res.data.records || []
|
|
|
|
|
+ self.recommendedProducts = list.map(function(p) {
|
|
|
|
|
+ p.type = 'product'
|
|
|
|
|
+ return p
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ self.loadingProducts = false
|
|
|
|
|
+ self.recommendedProducts = []
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
|
|
+ loadFeaturedArticles: function() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ self.articlesLoading = true
|
|
|
|
|
+ getFeaturedArticles({ size: 5 }).then(function(res) {
|
|
|
|
|
+ self.articlesLoading = false
|
|
|
|
|
+ if (res && res.code === 200) {
|
|
|
|
|
+ var rawList = res.data && (Array.isArray(res.data) ? res.data : (res.data.data || res.data.records || []))
|
|
|
|
|
+ var list = Array.isArray(rawList) ? rawList : []
|
|
|
|
|
+ self.indexArticles = list.map(function(item, index) {
|
|
|
|
|
+ return {
|
|
|
|
|
+ id: item.id,
|
|
|
|
|
+ category: item.categoryName || item.category || '热门文章',
|
|
|
|
|
+ categoryColor: self.gradientColors[index % self.gradientColors.length],
|
|
|
|
|
+ title: item.title || '',
|
|
|
|
|
+ summary: item.summary || '',
|
|
|
|
|
+ views: item.viewCount ? String(item.viewCount) : '0',
|
|
|
|
|
+ date: item.publishedAt ? item.publishedAt.slice(0, 10) : '',
|
|
|
|
|
+ coverImage: item.coverImage
|
|
|
|
|
+ }
|
|
|
|
|
+ })
|
|
|
|
|
+ }
|
|
|
|
|
+ }).catch(function() {
|
|
|
|
|
+ self.articlesLoading = false
|
|
|
|
|
+ self.indexArticles = []
|
|
|
|
|
+ })
|
|
|
|
|
+ },
|
|
|
async loadCautionData() {
|
|
async loadCautionData() {
|
|
|
var self = this
|
|
var self = this
|
|
|
try {
|
|
try {
|
|
@@ -507,25 +475,31 @@ export default {
|
|
|
if (res && res.code === 200) self.cautionCount = (res.data || []).length
|
|
if (res && res.code === 200) self.cautionCount = (res.data || []).length
|
|
|
} catch(e) {}
|
|
} catch(e) {}
|
|
|
},
|
|
},
|
|
|
- async loadMilestones() {
|
|
|
|
|
- var self = this
|
|
|
|
|
- try {
|
|
|
|
|
- var ciRes = await healthCheckinList({})
|
|
|
|
|
- if (ciRes.code === 200 && ciRes.data) self.streakDays = Math.min(ciRes.data.length, 30)
|
|
|
|
|
- } catch(e) {}
|
|
|
|
|
- self.activeChallenges = 0
|
|
|
|
|
- self.completeness = self.streakDays > 0 ? Math.min(100, Math.round(self.streakDays * 10)) : 0
|
|
|
|
|
- },
|
|
|
|
|
async loadDietIngredients() {
|
|
async loadDietIngredients() {
|
|
|
var self = this
|
|
var self = this
|
|
|
self.ingredientsLoading = true
|
|
self.ingredientsLoading = true
|
|
|
try {
|
|
try {
|
|
|
var res = await getDietIngredients()
|
|
var res = await getDietIngredients()
|
|
|
self.ingredientsLoading = false
|
|
self.ingredientsLoading = false
|
|
|
- if (res && res.ingredients) {
|
|
|
|
|
- self.ingredients = res.ingredients
|
|
|
|
|
|
|
+ if (res && res.ingredients) self.ingredients = res.ingredients
|
|
|
|
|
+ } catch(e) { self.ingredientsLoading = false }
|
|
|
|
|
+ },
|
|
|
|
|
+ async loadMilestones() {
|
|
|
|
|
+ var self = this
|
|
|
|
|
+ try {
|
|
|
|
|
+ if (self.memberId) {
|
|
|
|
|
+ var streakRes = await getStreakProgress(self.memberId)
|
|
|
|
|
+ if (streakRes.code === 200 && streakRes.data) self.streakDays = streakRes.data.streakDays || 0
|
|
|
}
|
|
}
|
|
|
- } catch(e) { self.ingredientsLoading = false; console.error('loadDietIngredients error:', e) }
|
|
|
|
|
|
|
+ } catch(e) {}
|
|
|
|
|
+ try {
|
|
|
|
|
+ var chRes = await getChallengeList({})
|
|
|
|
|
+ if (chRes.code === 200 && chRes.data) {
|
|
|
|
|
+ var activeList = chRes.data.filter(function(c) { return c && c.status === 'active' })
|
|
|
|
|
+ self.activeChallenges = activeList.length
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch(e) {}
|
|
|
|
|
+ self.completeness = self.streakDays > 0 ? Math.min(100, Math.round(self.streakDays * 10)) : 0
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -533,7 +507,6 @@ export default {
|
|
|
<style scoped>
|
|
<style scoped>
|
|
|
.container{background:#FFF7ED;min-height:100vh;padding-bottom:calc(160rpx + env(safe-area-inset-bottom))}
|
|
.container{background:#FFF7ED;min-height:100vh;padding-bottom:calc(160rpx + env(safe-area-inset-bottom))}
|
|
|
.section{margin:16rpx 24rpx}
|
|
.section{margin:16rpx 24rpx}
|
|
|
-/* 游客̬ */
|
|
|
|
|
.brand-strap{margin:0 24rpx 16rpx;background:linear-gradient(135deg,#F0FFF4,rgba(16,185,129,0.1));border-radius:16rpx;padding:20rpx 24rpx}
|
|
.brand-strap{margin:0 24rpx 16rpx;background:linear-gradient(135deg,#F0FFF4,rgba(16,185,129,0.1));border-radius:16rpx;padding:20rpx 24rpx}
|
|
|
.brand-strap-text{font-size:26rpx;color:#10B981;font-weight:600}
|
|
.brand-strap-text{font-size:26rpx;color:#10B981;font-weight:600}
|
|
|
.concept-card{margin:0 24rpx 16rpx;background:#fff;border-radius:20rpx;padding:28rpx;border-left:6rpx solid #10B981;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
.concept-card{margin:0 24rpx 16rpx;background:#fff;border-radius:20rpx;padding:28rpx;border-left:6rpx solid #10B981;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
@@ -556,7 +529,6 @@ export default {
|
|
|
.feat-title{font-size:26rpx;font-weight:600;color:#333;display:block;margin-bottom:4rpx}
|
|
.feat-title{font-size:26rpx;font-weight:600;color:#333;display:block;margin-bottom:4rpx}
|
|
|
.feat-desc{font-size:22rpx;color:#999;display:block}
|
|
.feat-desc{font-size:22rpx;color:#999;display:block}
|
|
|
.login-guide-section{margin:0 24rpx 24rpx}
|
|
.login-guide-section{margin:0 24rpx 24rpx}
|
|
|
-/* 成长行动卡Ƭ */
|
|
|
|
|
.action-card{display:flex;align-items:center;padding:24rpx 28rpx;background:#fff;border-radius:16rpx;margin:0 24rpx 16rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
.action-card{display:flex;align-items:center;padding:24rpx 28rpx;background:#fff;border-radius:16rpx;margin:0 24rpx 16rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
|
.action-card:active{opacity:0.85}
|
|
.action-card:active{opacity:0.85}
|
|
|
.action-icon{font-size:44rpx;margin-right:20rpx}
|
|
.action-icon{font-size:44rpx;margin-right:20rpx}
|
|
@@ -564,7 +536,6 @@ export default {
|
|
|
.action-title{font-size:28rpx;font-weight:600;color:#333;display:block}
|
|
.action-title{font-size:28rpx;font-weight:600;color:#333;display:block}
|
|
|
.action-desc{font-size:22rpx;color:#888;margin-top:4rpx;display:block}
|
|
.action-desc{font-size:22rpx;color:#888;margin-top:4rpx;display:block}
|
|
|
.action-arrow{font-size:32rpx;color:#ccc}
|
|
.action-arrow{font-size:32rpx;color:#ccc}
|
|
|
-/* 登录后原有样ʽ */
|
|
|
|
|
.reminder-bar{margin:12rpx 24rpx;background:#FFF3E0;border:1rpx solid #FFB74D;border-radius:12rpx;padding:14rpx 20rpx;display:flex;align-items:center;justify-content:space-between}
|
|
.reminder-bar{margin:12rpx 24rpx;background:#FFF3E0;border:1rpx solid #FFB74D;border-radius:12rpx;padding:14rpx 20rpx;display:flex;align-items:center;justify-content:space-between}
|
|
|
.reminder-text{font-size:24rpx;color:#E65100}
|
|
.reminder-text{font-size:24rpx;color:#E65100}
|
|
|
.reminder-close{font-size:28rpx;color:#999}
|
|
.reminder-close{font-size:28rpx;color:#999}
|
|
@@ -572,33 +543,33 @@ export default {
|
|
|
.progress-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}
|
|
.progress-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}
|
|
|
.progress-title{font-size:28rpx;font-weight:bold;color:#333}
|
|
.progress-title{font-size:28rpx;font-weight:bold;color:#333}
|
|
|
.progress-date{font-size:22rpx;color:#999}
|
|
.progress-date{font-size:22rpx;color:#999}
|
|
|
-.progress-grid{display:flex}
|
|
|
|
|
-.progress-grid-item{flex:1;box-sizing:border-box;display:flex;flex-direction:column;align-items:center;justify-content:center;background:#FFF7ED;border-radius:16rpx;padding:20rpx 8rpx;border:1rpx solid rgba(249,115,22,0.12)}
|
|
|
|
|
-.progress-grid-item:active{opacity:0.85;background:#FFEDD5}
|
|
|
|
|
-.progress-grid-icon{font-size:40rpx;margin-bottom:8rpx}
|
|
|
|
|
-.progress-grid-label{font-size:24rpx;color:#333;margin-bottom:8rpx;text-align:center}
|
|
|
|
|
-.progress-grid-status{font-size:20rpx;flex-shrink:0}
|
|
|
|
|
|
|
+.progress-item{display:flex;align-items:center;padding:12rpx 0;border-bottom:1rpx solid #f5f5f5}
|
|
|
|
|
+.progress-item:last-of-type{border-bottom:none}
|
|
|
|
|
+.progress-icon{font-size:28rpx;margin-right:12rpx;flex-shrink:0}
|
|
|
|
|
+.progress-label{font-size:26rpx;color:#333;flex:1}
|
|
|
|
|
+.progress-status{font-size:22rpx;margin-right:8rpx;flex-shrink:0}
|
|
|
.status-done{color:#10B981}
|
|
.status-done{color:#10B981}
|
|
|
-.status-pending{color:#F97316}
|
|
|
|
|
|
|
+.status-pending{color:#ccc}
|
|
|
|
|
+.progress-btn{font-size:22rpx;color:#F97316;padding:4rpx 16rpx;border:1rpx solid #F97316;border-radius:20rpx;flex-shrink:0}
|
|
|
.progress-footer{display:flex;justify-content:space-between;align-items:center;margin-top:16rpx;padding-top:16rpx;border-top:1rpx solid #f5f5f5}
|
|
.progress-footer{display:flex;justify-content:space-between;align-items:center;margin-top:16rpx;padding-top:16rpx;border-top:1rpx solid #f5f5f5}
|
|
|
.footer-text{font-size:24rpx;color:#666;font-weight:bold}
|
|
.footer-text{font-size:24rpx;color:#666;font-weight:bold}
|
|
|
.footer-streak{font-size:24rpx;color:#F97316;font-weight:bold}
|
|
.footer-streak{font-size:24rpx;color:#F97316;font-weight:bold}
|
|
|
-/* 记录概览:平铺卡Ƭ */
|
|
|
|
|
-.record-grid{display:flex;flex-wrap:wrap;justify-content:space-between}
|
|
|
|
|
-.record-card{width:calc(50% - 8rpx);box-sizing:border-box;background:#fff;border-radius:20rpx;padding:20rpx;margin-bottom:16rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
|
|
|
-.record-card:active{opacity:0.85}
|
|
|
|
|
-.record-card-header{display:flex;align-items:center;margin-bottom:12rpx}
|
|
|
|
|
-.record-card-icon{font-size:32rpx;margin-right:8rpx}
|
|
|
|
|
-.record-card-label{font-size:26rpx;font-weight:bold;color:#333}
|
|
|
|
|
-.record-card-body{display:flex;flex-direction:column}
|
|
|
|
|
-.record-card-item{display:flex;flex-direction:column;padding:10rpx 0;border-bottom:1rpx solid #f7f7f7}
|
|
|
|
|
-.record-card-item:last-child{border-bottom:none}
|
|
|
|
|
-.record-card-date{font-size:20rpx;color:#999;margin-bottom:2rpx}
|
|
|
|
|
-.record-card-content{font-size:24rpx;color:#666;overflow:hidden;display:-webkit-box;-webkit-line-clamp:1;-webkit-box-orient:vertical}
|
|
|
|
|
-.record-card-empty{display:flex;align-items:center;justify-content:center;padding:24rpx 0}
|
|
|
|
|
-.record-card-empty .empty-text{font-size:22rpx;color:#bbb}
|
|
|
|
|
-.record-card-footer{font-size:22rpx;color:#F97316;text-align:right;padding-top:10rpx}
|
|
|
|
|
-/* 今日推荐食材 */
|
|
|
|
|
|
|
+.tracking-card{background:#fff;border-radius:20rpx;padding:24rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
|
|
|
+.tracking-tabs{display:flex;margin-bottom:16rpx}
|
|
|
|
|
+.tracking-tab{flex:1;text-align:center;padding:10rpx 0;border-radius:20rpx;margin-right:8rpx;background:#FFF7ED}
|
|
|
|
|
+.tracking-tab:last-child{margin-right:0}
|
|
|
|
|
+.tab-active{background:#F97316}
|
|
|
|
|
+.tab-text{font-size:24rpx;color:#666}
|
|
|
|
|
+.tab-active-text{color:#fff;font-weight:bold}
|
|
|
|
|
+.tracking-content{min-height:200rpx}
|
|
|
|
|
+.tracking-empty{display:flex;flex-direction:column;align-items:center;padding:60rpx 0}
|
|
|
|
|
+.empty-icon{font-size:60rpx;margin-bottom:12rpx}
|
|
|
|
|
+.empty-text{font-size:26rpx;color:#999}
|
|
|
|
|
+.empty-hint{font-size:22rpx;color:#ccc;margin-top:8rpx}
|
|
|
|
|
+.tracking-record{display:flex;align-items:center;padding:10rpx 0;border-bottom:1rpx solid #f5f5f5}
|
|
|
|
|
+.record-date{font-size:22rpx;color:#999;width:120rpx;flex-shrink:0}
|
|
|
|
|
+.record-content{font-size:24rpx;color:#333;flex:1}
|
|
|
|
|
+.tracking-more{text-align:right;font-size:24rpx;color:#F97316;padding:12rpx 0 0 0}
|
|
|
.diet-card{background:#fff;border-radius:20rpx;padding:24rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
.diet-card{background:#fff;border-radius:20rpx;padding:24rpx;box-shadow:0 2rpx 12rpx rgba(0,0,0,0.06)}
|
|
|
.diet-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}
|
|
.diet-card-header{display:flex;justify-content:space-between;align-items:center;margin-bottom:16rpx}
|
|
|
.diet-card-title{font-size:28rpx;font-weight:bold;color:#333}
|
|
.diet-card-title{font-size:28rpx;font-weight:bold;color:#333}
|
|
@@ -634,11 +605,9 @@ export default {
|
|
|
.survey-empty{padding:12rpx 0}
|
|
.survey-empty{padding:12rpx 0}
|
|
|
.survey-empty-text{font-size:24rpx;color:#999}
|
|
.survey-empty-text{font-size:24rpx;color:#999}
|
|
|
|
|
|
|
|
-/* ===== 五维闭环体系样ʽ ===== */
|
|
|
|
|
.wuxing-section { margin: 0 24rpx 16rpx; background: #fff; border-radius: 20rpx; padding: 24rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
|
|
.wuxing-section { margin: 0 24rpx 16rpx; background: #fff; border-radius: 20rpx; padding: 24rpx; box-shadow: 0 2rpx 12rpx rgba(0,0,0,0.06); }
|
|
|
.wuxing-title { font-size: 30rpx; font-weight: bold; color: #333; text-align: center; margin-bottom: 6rpx; }
|
|
.wuxing-title { font-size: 30rpx; font-weight: bold; color: #333; text-align: center; margin-bottom: 6rpx; }
|
|
|
.wuxing-desc { font-size: 22rpx; color: #999; text-align: center; margin-bottom: 20rpx; }
|
|
.wuxing-desc { font-size: 22rpx; color: #999; text-align: center; margin-bottom: 20rpx; }
|
|
|
-.wuxing-diagram { position: relative; height: 320rpx; margin: 0 auto 20rpx; }
|
|
|
|
|
.wuxing-relations { margin-top: 8rpx; }
|
|
.wuxing-relations { margin-top: 8rpx; }
|
|
|
.rel-group { margin-bottom: 16rpx; }
|
|
.rel-group { margin-bottom: 16rpx; }
|
|
|
.rel-title { font-size: 24rpx; font-weight: bold; color: #333; margin-bottom: 8rpx; display: block; }
|
|
.rel-title { font-size: 24rpx; font-weight: bold; color: #333; margin-bottom: 8rpx; display: block; }
|
|
@@ -665,4 +634,4 @@ export default {
|
|
|
.wc-action .wc-name { color: #10B981; }
|
|
.wc-action .wc-name { color: #10B981; }
|
|
|
.wc-mind { border-color: rgba(255,107,157,0.3); background: rgba(255,107,157,0.04); border-left: 8rpx solid #FF6B9D; }
|
|
.wc-mind { border-color: rgba(255,107,157,0.3); background: rgba(255,107,157,0.04); border-left: 8rpx solid #FF6B9D; }
|
|
|
.wc-mind .wc-name { color: #FF6B9D; }
|
|
.wc-mind .wc-name { color: #FF6B9D; }
|
|
|
-</style>
|
|
|
|
|
|
|
+</style>
|