129 lines
3.4 KiB
TypeScript
129 lines
3.4 KiB
TypeScript
import { defineStore } from "pinia";
|
|
import { ref } from "vue";
|
|
import { fetchStudies } from "../api/studies";
|
|
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";
|
|
|
|
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 setCurrentStudy = (study: Study) => {
|
|
currentStudy.value = study;
|
|
currentSite.value = null; // 切换项目时清空中心
|
|
localStorage.removeItem(SITE_KEY);
|
|
currentStudy.value = study;
|
|
const role = (study as any).role_in_study || (study as any).role || null;
|
|
currentStudyRole.value = role;
|
|
localStorage.setItem(STUDY_KEY, JSON.stringify(study));
|
|
if (role) {
|
|
localStorage.setItem(STUDY_ROLE_KEY, role);
|
|
}
|
|
};
|
|
|
|
const loadCurrentStudy = () => {
|
|
const raw = localStorage.getItem(STUDY_KEY);
|
|
if (raw) {
|
|
try {
|
|
currentStudy.value = JSON.parse(raw) as Study;
|
|
} catch {
|
|
currentStudy.value = null;
|
|
}
|
|
}
|
|
const savedRole = localStorage.getItem(STUDY_ROLE_KEY);
|
|
currentStudyRole.value = savedRole || null;
|
|
|
|
const savedSite = localStorage.getItem(SITE_KEY);
|
|
if (savedSite) {
|
|
try {
|
|
currentSite.value = JSON.parse(savedSite);
|
|
} catch {
|
|
currentSite.value = null;
|
|
}
|
|
}
|
|
};
|
|
|
|
const ensureDefaultStudy = async () => {
|
|
if (currentStudy.value) return currentStudy.value;
|
|
try {
|
|
const { data } = await fetchStudies();
|
|
const items = (data as any).items || [];
|
|
if (items.length) {
|
|
setCurrentStudy(items[0] as Study);
|
|
return items[0] as Study;
|
|
}
|
|
} catch {
|
|
return null;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const ensureDefaultActiveStudy = async () => {
|
|
if (currentStudy.value) return currentStudy.value;
|
|
try {
|
|
const { data } = await fetchStudies();
|
|
const items = (data as any).items || [];
|
|
const active = items.find((study: Study) => study.status === "ACTIVE" && !study.is_locked);
|
|
if (active) {
|
|
setCurrentStudy(active as Study);
|
|
return active as Study;
|
|
}
|
|
} catch {
|
|
return null;
|
|
}
|
|
return null;
|
|
};
|
|
|
|
const clearCurrentStudy = () => {
|
|
currentStudy.value = null;
|
|
currentStudyRole.value = null;
|
|
currentSite.value = null;
|
|
viewContext.value = null;
|
|
localStorage.removeItem(STUDY_KEY);
|
|
localStorage.removeItem(STUDY_ROLE_KEY);
|
|
localStorage.removeItem(SITE_KEY);
|
|
};
|
|
|
|
const setCurrentStudyRole = (role: string | null) => {
|
|
currentStudyRole.value = role;
|
|
if (role) {
|
|
localStorage.setItem(STUDY_ROLE_KEY, role);
|
|
} else {
|
|
localStorage.removeItem(STUDY_ROLE_KEY);
|
|
}
|
|
};
|
|
|
|
const setCurrentSite = (site: any | null) => {
|
|
currentSite.value = site;
|
|
if (site) {
|
|
localStorage.setItem(SITE_KEY, JSON.stringify(site));
|
|
} else {
|
|
localStorage.removeItem(SITE_KEY);
|
|
}
|
|
};
|
|
|
|
const setViewContext = (ctx: { siteName?: string } | null) => {
|
|
viewContext.value = ctx;
|
|
};
|
|
|
|
return {
|
|
currentStudy,
|
|
currentStudyRole,
|
|
currentSite,
|
|
viewContext,
|
|
setCurrentStudy,
|
|
setCurrentStudyRole,
|
|
setCurrentSite,
|
|
setViewContext,
|
|
loadCurrentStudy,
|
|
ensureDefaultStudy,
|
|
ensureDefaultActiveStudy,
|
|
clearCurrentStudy,
|
|
};
|
|
});
|