项目里程碑初步优化
This commit is contained in:
@@ -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();
|
||||
};
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user