统一业务页面权限与抽屉编辑

1、将 FAQ 分类和问题维护改为抽屉交互,并按分类、问题、回复的细粒度权限控制入口。

2、将注意事项、可行性和伦理记录接入详情页抽屉编辑,创建时支持先保存主记录再上传附件。

3、将参与者基础信息编辑改为抽屉,详情页按可读权限显示病史、访视、AE 和 PD 标签页。

4、补充业务页面权限一致性测试,覆盖停用中心、无权限入口和面包屑上下文。
This commit is contained in:
Cheng Zhou
2026-06-04 11:10:20 +08:00
parent 6a2e43f829
commit 6e8494abd5
39 changed files with 2334 additions and 337 deletions
+57
View File
@@ -0,0 +1,57 @@
import { beforeEach, describe, expect, it, vi } from "vitest";
const apiPost = vi.fn();
const apiPatch = vi.fn();
const apiDelete = vi.fn();
vi.mock("./axios", () => ({
apiPost,
apiPatch,
apiDelete,
}));
describe("faqs category api", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("passes study_id as a query parameter for category write permission checks", async () => {
const { createFaqCategory, updateFaqCategory, deleteFaqCategory } = await import("./faqs");
const payload = { study_id: "study-1", name: "用药咨询" };
createFaqCategory(payload);
updateFaqCategory("category-1", payload);
deleteFaqCategory("category-1", "study-1");
expect(apiPost).toHaveBeenCalledWith("/api/v1/faqs/categories/", payload, { params: { study_id: "study-1" } });
expect(apiPatch).toHaveBeenCalledWith("/api/v1/faqs/categories/category-1", payload, {
params: { study_id: "study-1" },
});
expect(apiDelete).toHaveBeenCalledWith("/api/v1/faqs/categories/category-1", {
params: { study_id: "study-1" },
});
});
});
describe("faqs item api", () => {
beforeEach(() => {
vi.clearAllMocks();
});
it("passes study_id as a query parameter for item write permission checks", async () => {
const { createFaqItem, updateFaqItem, deleteFaqItem } = await import("./faqs");
const payload = { study_id: "study-1", category_id: "category-1", question: "是否需要空腹用药?" };
createFaqItem(payload);
updateFaqItem("item-1", payload);
deleteFaqItem("item-1", "study-1");
expect(apiPost).toHaveBeenCalledWith("/api/v1/faqs/items/", payload, { params: { study_id: "study-1" } });
expect(apiPatch).toHaveBeenCalledWith("/api/v1/faqs/items/item-1", payload, {
params: { study_id: "study-1" },
});
expect(apiDelete).toHaveBeenCalledWith("/api/v1/faqs/items/item-1", {
params: { study_id: "study-1" },
});
});
});