diff --git a/app/citizen-frontend/src/pages/self-assessment.vue b/app/citizen-frontend/src/pages/self-assessment.vue index 68cf0a2..b1876f8 100644 --- a/app/citizen-frontend/src/pages/self-assessment.vue +++ b/app/citizen-frontend/src/pages/self-assessment.vue @@ -491,7 +491,7 @@ variant="flat" @click="handleAppointment" > - {{ APPOINTMENT_ENABLED ? "立即預約" : "預約功能尚未開放" }} + {{ APPOINTMENT_ENABLED ? "立即預約" : "註冊會員" }} @@ -506,7 +506,7 @@ to="/" variant="outlined" > - 回首頁健康儀表板 + 回首頁 diff --git a/app/citizen-frontend/src/stores/app.ts b/app/citizen-frontend/src/stores/app.ts index 5382525..a56fd3a 100644 --- a/app/citizen-frontend/src/stores/app.ts +++ b/app/citizen-frontend/src/stores/app.ts @@ -35,6 +35,7 @@ import { saveGuestSelfAssessmentDraft, type GuestSelfAssessmentDraft, } from "@/utils/guest-self-assessment"; +import { getApiErrorMessage, getApiErrorStatus } from "@/utils/api-error"; import { calculateProvisionalRiskLevel } from "@/utils/self-assessment"; /** 開發環境可用 VITE_USE_MOCK=true 模擬流程;正式串接時設為 false。 */ @@ -313,6 +314,8 @@ export const useAppStore = defineStore("app", () => { const userID = ref(""); const userProfile = ref(createEmptyUserProfile()); const selfAssessment = ref(createEmptySelfAssessment()); + const selfAssessmentLoading = ref(false); + const selfAssessmentError = ref(""); const appointments = ref(createDefaultAppointments()); const measurements = ref>( createDefaultMeasurements(), @@ -373,6 +376,12 @@ export const useAppStore = defineStore("app", () => { const profile = await apiGetProfile(); isLoggedIn.value = true; userProfile.value = applyProfileToStore(profile); + + try { + await loadLatestSelfAssessment(); + } catch { + // 最近自評載入失敗不應使已驗證的登入 Session 失效。 + } } return isLoggedIn.value; @@ -405,6 +414,13 @@ export const useAppStore = defineStore("app", () => { : await apiLogin({ phone, password }); setAuthenticated(response); + + try { + await loadLatestSelfAssessment(); + } catch { + // 最近自評載入失敗不應使已驗證的登入 Session 失效。 + } + return response; } @@ -443,6 +459,8 @@ export const useAppStore = defineStore("app", () => { userID.value = ""; userProfile.value = createEmptyUserProfile(); selfAssessment.value = createEmptySelfAssessment(); + selfAssessmentLoading.value = false; + selfAssessmentError.value = ""; } /** 呼叫後端登出,無論請求結果都清除前端登入狀態。 */ @@ -510,9 +528,32 @@ export const useAppStore = defineStore("app", () => { return null; } - const assessment = await apiGetLatestSelfAssessment(); - setSelfAssessment(assessment); - return assessment; + selfAssessmentLoading.value = true; + selfAssessmentError.value = ""; + + try { + const assessment = await apiGetLatestSelfAssessment(); + setSelfAssessment(assessment); + return assessment; + } catch (error) { + const status = getApiErrorStatus(error); + + if (status === 404) { + selfAssessment.value = createEmptySelfAssessment(); + return null; + } + + if (status !== 401) { + selfAssessmentError.value = getApiErrorMessage( + error, + "無法載入最近一次自評,請稍後再試。", + ); + } + + throw error; + } finally { + selfAssessmentLoading.value = false; + } } /** @@ -631,6 +672,8 @@ export const useAppStore = defineStore("app", () => { userID, userProfile, selfAssessment, + selfAssessmentLoading, + selfAssessmentError, appointments, measurements, completedStationsCount,