项目里程碑初步优化

This commit is contained in:
Cheng Zhou
2026-02-27 09:06:06 +08:00
parent 8f3f717e48
commit fd7e3fc948
47 changed files with 2029 additions and 783 deletions
+7 -2
View File
@@ -22,7 +22,10 @@ export const useAuthStore = defineStore("auth", () => {
// 避免锁屏态下 fetchMe 被请求拦截
useSessionStore().unlock();
localStorage.setItem(LAST_LOGIN_EMAIL_KEY, email);
await fetchMeAction();
const me = await fetchMeAction();
const studyStore = useStudyStore();
const userKey = me?.email || email;
await studyStore.restoreStudyForUser(userKey, { preferActive: me?.role === "ADMIN" });
forceLogin.value = false;
} finally {
loading.value = false;
@@ -39,11 +42,13 @@ export const useAuthStore = defineStore("auth", () => {
};
const logout = () => {
const studyStore = useStudyStore();
const userKey = user.value?.email || localStorage.getItem(LAST_LOGIN_EMAIL_KEY) || "";
studyStore.rememberCurrentStudyForUser(userKey);
token.value = null;
user.value = null;
forceLogin.value = false;
clearToken();
const studyStore = useStudyStore();
studyStore.clearCurrentStudy();
};
+72
View File
@@ -6,12 +6,37 @@ import type { Study } from "../types/api";
const STUDY_KEY = "ctms_current_study";
const STUDY_ROLE_KEY = "ctms_current_study_role";
const SITE_KEY = "ctms_current_site";
const LAST_STUDY_BY_USER_KEY = "ctms_last_study_by_user";
export const useStudyStore = defineStore("study", () => {
const currentStudy = ref<Study | null>(null);
const currentStudyRole = ref<string | null>(null);
const currentSite = ref<any | null>(null);
const viewContext = ref<{ siteName?: string } | null>(null);
const normalizeUserKey = (value: string) => value.trim().toLowerCase();
const readLastStudyMap = (): Record<string, Study> => {
try {
const raw = localStorage.getItem(LAST_STUDY_BY_USER_KEY);
if (!raw) return {};
const parsed = JSON.parse(raw);
return parsed && typeof parsed === "object" ? parsed : {};
} catch {
return {};
}
};
const writeLastStudyMap = (value: Record<string, Study>) => {
localStorage.setItem(LAST_STUDY_BY_USER_KEY, JSON.stringify(value));
};
const rememberStudyForUser = (userKey: string, study: Study) => {
const normalized = normalizeUserKey(userKey || "");
if (!normalized || !study?.id) return;
const map = readLastStudyMap();
map[normalized] = study;
writeLastStudyMap(map);
};
const setCurrentStudy = (study: Study) => {
currentStudy.value = study;
@@ -24,6 +49,10 @@ export const useStudyStore = defineStore("study", () => {
if (role) {
localStorage.setItem(STUDY_ROLE_KEY, role);
}
const loginEmail = localStorage.getItem("ctms_last_login_email") || "";
if (loginEmail) {
rememberStudyForUser(loginEmail, study);
}
};
const loadCurrentStudy = () => {
@@ -89,6 +118,47 @@ export const useStudyStore = defineStore("study", () => {
localStorage.removeItem(SITE_KEY);
};
const rememberCurrentStudyForUser = (userKey: string) => {
if (!currentStudy.value) return;
rememberStudyForUser(userKey, currentStudy.value);
};
const restoreStudyForUser = async (userKey: string, opts?: { preferActive?: boolean }) => {
const normalized = normalizeUserKey(userKey || "");
if (!normalized) return null;
try {
const { data } = await fetchStudies();
const items = ((data as any).items || []) as Study[];
if (!items.length) {
clearCurrentStudy();
return null;
}
const saved = readLastStudyMap()[normalized];
if (saved?.id) {
const matched = items.find((item) => item.id === saved.id);
if (matched) {
setCurrentStudy(matched);
return matched;
}
}
const fallback = opts?.preferActive
? items.find((study) => study.status === "ACTIVE" && !study.is_locked) || items[0]
: items[0];
if (fallback) {
setCurrentStudy(fallback);
return fallback;
}
clearCurrentStudy();
return null;
} catch {
clearCurrentStudy();
return null;
}
};
const setCurrentStudyRole = (role: string | null) => {
currentStudyRole.value = role;
if (role) {
@@ -120,9 +190,11 @@ export const useStudyStore = defineStore("study", () => {
setCurrentStudyRole,
setCurrentSite,
setViewContext,
rememberCurrentStudyForUser,
loadCurrentStudy,
ensureDefaultStudy,
ensureDefaultActiveStudy,
restoreStudyForUser,
clearCurrentStudy,
};
});