Files
ctms/frontend/src/store/study.ts
T
2026-02-04 16:17:51 +08:00

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,
};
});