feat: feature switch

This commit is contained in:
skytek_xinliang
2026-09-14 09:35:56 +08:00
parent a6042b993a
commit bcaaf8797c
7 changed files with 41 additions and 13 deletions
@@ -132,7 +132,7 @@
/> />
<v-list-item <v-list-item
v-if="store.isLoggedIn" v-if="APPOINTMENT_ENABLED && store.isLoggedIn"
color="primary" color="primary"
prepend-icon="mdi-calendar-check" prepend-icon="mdi-calendar-check"
title="普測活動預約" title="普測活動預約"
@@ -140,7 +140,7 @@
/> />
<v-list-item <v-list-item
v-if="store.isLoggedIn" v-if="CHECKIN_ENABLED && store.isLoggedIn"
color="primary" color="primary"
prepend-icon="mdi-qrcode-scan" prepend-icon="mdi-qrcode-scan"
title="現場報到與量測" title="現場報到與量測"
@@ -219,14 +219,22 @@
<span class="bottom-nav-text">自評</span> <span class="bottom-nav-text">自評</span>
</v-btn> </v-btn>
<v-btn v-if="store.isLoggedIn" to="/checkin" value="checkin"> <v-btn
v-if="CHECKIN_ENABLED && store.isLoggedIn"
to="/checkin"
value="checkin"
>
<v-icon :color="getBottomNavIconColor('checkin')" <v-icon :color="getBottomNavIconColor('checkin')"
>mdi-qrcode-scan</v-icon >mdi-qrcode-scan</v-icon
> >
<span class="bottom-nav-text">量測</span> <span class="bottom-nav-text">量測</span>
</v-btn> </v-btn>
<v-btn v-if="store.isLoggedIn" to="/appointment" value="appointment"> <v-btn
v-if="APPOINTMENT_ENABLED && store.isLoggedIn"
to="/appointment"
value="appointment"
>
<v-icon :color="getBottomNavIconColor('appointment')" <v-icon :color="getBottomNavIconColor('appointment')"
>mdi-calendar-check</v-icon >mdi-calendar-check</v-icon
> >
@@ -250,7 +258,7 @@
</p> </p>
<ul class="pl-4 mb-3"> <ul class="pl-4 mb-3">
<li>提供個人化的運動方針與健康改善建議。</li> <li>提供個人化的運動與健康改善建議。</li>
<li>於普測活動現場合對您的身分。</li> <li>於普測活動現場合對您的身分。</li>
<li>在去識別化的安全機制下,作為高齡健康促進的政策分析參考。</li> <li>在去識別化的安全機制下,作為高齡健康促進的政策分析參考。</li>
</ul> </ul>
@@ -279,6 +287,7 @@
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router"; import { useRoute, useRouter } from "vue-router";
import { useDisplayUserName } from "@/composables/useDisplayUserName"; import { useDisplayUserName } from "@/composables/useDisplayUserName";
import { APPOINTMENT_ENABLED, CHECKIN_ENABLED } from "@/config/features";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
import { useCourseStore } from "@/stores/course"; import { useCourseStore } from "@/stores/course";
@@ -0,0 +1,3 @@
export const APPOINTMENT_ENABLED = false;
export const CHECKIN_ENABLED = false;
export const RADAR_ENABLED = false;
@@ -5,7 +5,7 @@
<v-card-title class="text-primary">預約</v-card-title> <v-card-title class="text-primary">預約</v-card-title>
<v-card-subtitle class="text-grey-darken-3"> <v-card-subtitle class="text-grey-darken-3">
報名免費體能普測,取得個人運動方針 報名免費體能普測,取得個人運動建議
</v-card-subtitle> </v-card-subtitle>
</v-card> </v-card>
+1 -1
View File
@@ -161,7 +161,7 @@
<v-expansion-panel> <v-expansion-panel>
<v-expansion-panel-title class="font-weight-bold"> <v-expansion-panel-title class="font-weight-bold">
精準運動方針建議 精準運動建議
</v-expansion-panel-title> </v-expansion-panel-title>
<v-expansion-panel-text> <v-expansion-panel-text>
+10 -5
View File
@@ -60,7 +60,7 @@
</v-card-subtitle> </v-card-subtitle>
<!-- 四項核心能力數值簡覽 --> <!-- 四項核心能力數值簡覽 -->
<!-- <v-row class="mt-4" no-gutters> <v-row v-if="RADAR_ENABLED" class="mt-4" no-gutters>
<v-col class="text-center border pa-2" cols="3"> <v-col class="text-center border pa-2" cols="3">
<div class="">肌力</div> <div class="">肌力</div>
@@ -92,7 +92,7 @@
{{ store.radarData.cardio }} {{ store.radarData.cardio }}
</div> </div>
</v-col> </v-col>
</v-row> --> </v-row>
<!-- 課程建議入口 --> <!-- 課程建議入口 -->
@@ -113,7 +113,11 @@
</v-card> </v-card>
<!-- 中間:功能指標與五維雷達圖 --> <!-- 中間:功能指標與五維雷達圖 -->
<!-- <v-card class="border-xl border-primary rounded-xl mt-4" variant="flat"> <v-card
v-if="RADAR_ENABLED"
class="border-xl border-primary rounded-xl mt-4"
variant="flat"
>
<v-card-title> 個人五維健康力指標 </v-card-title> <v-card-title> 個人五維健康力指標 </v-card-title>
<v-card-subtitle> <v-card-subtitle>
@@ -121,7 +125,7 @@
</v-card-subtitle> </v-card-subtitle>
<HealthRadarChart :radar-data="store.radarData" /> <HealthRadarChart :radar-data="store.radarData" />
</v-card> --> </v-card>
<ModuleRouterCard <ModuleRouterCard
description="了解公益普測計畫、研究依據與平台流程。" description="了解公益普測計畫、研究依據與平台流程。"
@@ -215,7 +219,7 @@
</div> </div>
<div class="text-title-small text-grey"> <div class="text-title-small text-grey">
普測預約、現場報到、量測紀錄與運動方針。 普測預約、現場報到、量測紀錄與運動建議
</div> </div>
</div> </div>
</div> </div>
@@ -284,6 +288,7 @@ import HealthRadarChart from "@/components/HealthRadarChart.vue";
import Layout from "@/components/layout/DefaultLayout.vue"; import Layout from "@/components/layout/DefaultLayout.vue";
import ModuleRouterCard from "@/components/ModuleRouterCard.vue"; import ModuleRouterCard from "@/components/ModuleRouterCard.vue";
import { useDisplayUserName } from "@/composables/useDisplayUserName"; import { useDisplayUserName } from "@/composables/useDisplayUserName";
import { RADAR_ENABLED } from "@/config/features";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
import { useCourseStore } from "@/stores/course"; import { useCourseStore } from "@/stores/course";
@@ -421,7 +421,7 @@
class="text-body-medium text-grey-darken-3 mb-2" class="text-body-medium text-grey-darken-3 mb-2"
> >
您的身體功能與日常活動習慣良好。建議您每週繼續保持 3 您的身體功能與日常活動習慣良好。建議您每週繼續保持 3
次以上的運動,並可以預約普測活動以獲得精準的五維健康指標與運動方針。 次以上的運動,並可以預約普測活動以獲得精準的五維健康指標與運動建議。
</p> </p>
<p <p
+11
View File
@@ -9,6 +9,7 @@ import Login from "@/pages/login.vue";
import Profile from "@/pages/profile.vue"; import Profile from "@/pages/profile.vue";
import Register from "@/pages/register.vue"; import Register from "@/pages/register.vue";
import SelfAssessment from "@/pages/self-assessment.vue"; import SelfAssessment from "@/pages/self-assessment.vue";
import { APPOINTMENT_ENABLED, CHECKIN_ENABLED } from "@/config/features";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
import { useCourseStore } from "@/stores/course"; import { useCourseStore } from "@/stores/course";
import { getApiErrorStatus } from "@/utils/api-error"; import { getApiErrorStatus } from "@/utils/api-error";
@@ -83,8 +84,18 @@ const router = createRouter({
], ],
}); });
const APPOINTMENT_PATH = /^\/appointment(?:\/|$)/;
const CHECKIN_PATH = /^\/checkin(?:\/|$)/;
// 簡單的導航守衛:只有標記需要登入的頁面會導向登入頁 // 簡單的導航守衛:只有標記需要登入的頁面會導向登入頁
router.beforeEach(async (to) => { router.beforeEach(async (to) => {
if (
(!APPOINTMENT_ENABLED && APPOINTMENT_PATH.test(to.path)) ||
(!CHECKIN_ENABLED && CHECKIN_PATH.test(to.path))
) {
return { name: "home" };
}
const store = useAppStore(); const store = useAppStore();
await store.initializeAuthentication(); await store.initializeAuthentication();