立项配置页初步优化

This commit is contained in:
Cheng Zhou
2026-02-24 16:53:22 +08:00
parent 0693f09b1d
commit 8f3f717e48
124 changed files with 12519 additions and 2954 deletions
+18 -4
View File
@@ -16,6 +16,7 @@ const instance: AxiosInstance = axios.create({
export type ApiRequestConfig = AxiosRequestConfig & {
ignoreIdle?: boolean;
allowWhileLocked?: boolean;
suppressErrorMessage?: boolean;
_retry?: boolean;
};
@@ -52,7 +53,10 @@ instance.interceptors.response.use(
(response: AxiosResponse) => response,
async (error: AxiosError<ApiError>) => {
if (error instanceof LockedError) {
ElMessage.warning(TEXT.common.messages.sessionLocked || "请解锁后继续操作");
const lockedConfig = error.config as ApiRequestConfig | undefined;
if (!lockedConfig?.suppressErrorMessage) {
ElMessage.warning(TEXT.common.messages.sessionLocked || "请解锁后继续操作");
}
return Promise.reject(error);
}
const status = error.response?.status;
@@ -93,10 +97,18 @@ instance.interceptors.response.use(
}
} else if (status === 403 && (data as any)?.detail === "账号已停用") {
forceLogout();
} else if (data?.message || (data as any)?.detail) {
ElMessage.error((data as any)?.message || (data as any)?.detail);
} else {
ElMessage.error(TEXT.common.messages.requestFailed);
const suppressErrorMessage = (error.config as ApiRequestConfig | undefined)?.suppressErrorMessage;
if (!suppressErrorMessage) {
if (data?.message || (data as any)?.detail) {
const detail = (data as any)?.detail;
const detailMessage =
typeof detail === "string" ? detail : typeof detail?.message === "string" ? detail.message : undefined;
ElMessage.error((data as any)?.message || detailMessage || TEXT.common.messages.requestFailed);
} else {
ElMessage.error(TEXT.common.messages.requestFailed);
}
}
}
return Promise.reject(error);
}
@@ -107,6 +119,8 @@ export const apiPost = <T = unknown>(url: string, data?: unknown, config?: ApiRe
instance.post<T>(url, data, config);
export const apiPatch = <T = unknown>(url: string, data?: unknown, config?: ApiRequestConfig) =>
instance.patch<T>(url, data, config);
export const apiPut = <T = unknown>(url: string, data?: unknown, config?: ApiRequestConfig) =>
instance.put<T>(url, data, config);
export const apiDelete = <T = unknown>(url: string, config?: ApiRequestConfig) =>
instance.delete<T>(url, config);
+31 -1
View File
@@ -1,5 +1,12 @@
import { apiGet, apiPatch, apiPost, apiDelete } from "./axios";
import { apiGet, apiPatch, apiPost, apiDelete, apiPut } from "./axios";
import type { ApiListResponse, Study } from "../types/api";
import type {
StudySetupConfigPublishPayload,
StudySetupConfigResponse,
StudySetupConfigRollbackPayload,
StudySetupConfigUpsertPayload,
StudySetupConfigVersionItem,
} from "../types/setupConfig";
// Backend expects trailing slash to avoid 307 redirect
export const fetchStudies = () => apiGet<ApiListResponse<Study>>("/api/v1/studies/");
@@ -18,3 +25,26 @@ export const deleteStudy = (studyId: string) =>
export const lockStudy = (studyId: string) =>
apiPatch<Study>(`/api/v1/studies/${studyId}/lock`, {});
export const fetchStudySetupConfig = (studyId: string) =>
apiGet<StudySetupConfigResponse>(`/api/v1/studies/${studyId}/setup-config`, { suppressErrorMessage: true });
export const saveStudySetupConfig = (studyId: string, payload: StudySetupConfigUpsertPayload) =>
apiPut<StudySetupConfigResponse>(`/api/v1/studies/${studyId}/setup-config`, payload, { suppressErrorMessage: true });
export const publishStudySetupConfig = (studyId: string, payload: StudySetupConfigPublishPayload) =>
apiPost<StudySetupConfigResponse>(`/api/v1/studies/${studyId}/setup-config/publish`, payload, { suppressErrorMessage: true });
export const fetchStudySetupConfigVersions = (studyId: string) =>
apiGet<StudySetupConfigVersionItem[]>(`/api/v1/studies/${studyId}/setup-config/versions`, { suppressErrorMessage: true });
export const deleteStudySetupConfigVersion = (studyId: string, targetVersion: number) =>
apiDelete(`/api/v1/studies/${studyId}/setup-config/versions/${targetVersion}`, { suppressErrorMessage: true });
export const rollbackStudySetupConfig = (studyId: string, payload: StudySetupConfigRollbackPayload) =>
apiPost<StudySetupConfigResponse>(`/api/v1/studies/${studyId}/setup-config/rollback`, payload, { suppressErrorMessage: true });
export const exportStudySetupConfigExcel = (studyId: string) =>
apiGet<Blob>(`/api/v1/studies/${studyId}/setup-config/export-excel`, { responseType: "blob", suppressErrorMessage: true });
export const importStudySetupConfigExcel = (studyId: string, payload: FormData) =>
apiPost<StudySetupConfigResponse>(`/api/v1/studies/${studyId}/setup-config/import-excel`, payload, { suppressErrorMessage: true });