|
|
@@ -0,0 +1,263 @@
|
|
|
+import type {
|
|
|
+ MonographCategory,
|
|
|
+ MonographDTO,
|
|
|
+ MonographSubmitVO,
|
|
|
+ MonographVO,
|
|
|
+} from './monograph.schema';
|
|
|
+
|
|
|
+import type { PageQueryMethodArgs } from '#/request/schema';
|
|
|
+import type { PageVO } from '#/request/schema/record';
|
|
|
+
|
|
|
+import { pageQueryArgsTransform } from '#/request/schema';
|
|
|
+
|
|
|
+import {
|
|
|
+ decodeMonograph,
|
|
|
+ encodeMonograph,
|
|
|
+ encodeMonographQuery,
|
|
|
+} from './monograph.schema';
|
|
|
+
|
|
|
+/** 后端接口就绪后改为 false */
|
|
|
+export const USE_MONOGRAPH_MOCK = true;
|
|
|
+
|
|
|
+type MethodLike<T> = PromiseLike<T> & {
|
|
|
+ send?: (force?: boolean) => PromiseLike<T>;
|
|
|
+};
|
|
|
+
|
|
|
+const MOCK_PDF_URL =
|
|
|
+ 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf';
|
|
|
+
|
|
|
+const SEED_RECORDS: Omit<
|
|
|
+ MonographDTO,
|
|
|
+ 'createTime' | 'id' | 'personalStudioId' | 'updateTime'
|
|
|
+>[] = [
|
|
|
+ {
|
|
|
+ category: 'textbook',
|
|
|
+ title: '中医内科学(第三版)',
|
|
|
+ author: '王教授 主编',
|
|
|
+ publisher: '中国中医药出版社',
|
|
|
+ publishDate: '2025-08',
|
|
|
+ isbn: '978-7-5132-6789-0',
|
|
|
+ description:
|
|
|
+ '全国高等中医药院校规划教材,系统阐述中医内科疾病的诊治理论与临床实践,涵盖常见内科疾病的病因病机、辨证论治及现代研究进展。',
|
|
|
+ viewCount: 1250,
|
|
|
+ commentCount: 23,
|
|
|
+ createBy: '王刚',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ category: 'academic',
|
|
|
+ title: '伤寒论条文解',
|
|
|
+ author: '张仲景 著,李教授 校注',
|
|
|
+ publisher: '人民卫生出版社',
|
|
|
+ publishDate: '2024-06',
|
|
|
+ isbn: '978-7-117-34567-8',
|
|
|
+ description:
|
|
|
+ '以经典条文为主线,结合历代医家注释与现代临床体会,深入解读《伤寒论》核心思想与辨证体系。',
|
|
|
+ viewCount: 890,
|
|
|
+ commentCount: 15,
|
|
|
+ createBy: '张许',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ category: 'popular_science',
|
|
|
+ title: '中医养生智慧',
|
|
|
+ author: '陈医师 著',
|
|
|
+ publisher: '科学出版社',
|
|
|
+ publishDate: '2025-03',
|
|
|
+ isbn: '978-7-03-45678-9',
|
|
|
+ description:
|
|
|
+ '面向大众的中医养生科普读物,介绍四季养生、情志调摄、饮食起居等实用养生方法,语言通俗易懂。',
|
|
|
+ viewCount: 2100,
|
|
|
+ commentCount: 45,
|
|
|
+ createBy: '李虎',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ category: 'reference',
|
|
|
+ title: '中药学大辞典',
|
|
|
+ author: '中国药学会 编',
|
|
|
+ publisher: '上海科学技术出版社',
|
|
|
+ publishDate: '2023-12',
|
|
|
+ isbn: '978-7-5323-7890-1',
|
|
|
+ description:
|
|
|
+ '收录常用中药及民族药条目,详述性味归经、功效主治、用法用量及现代药理研究,是中医药工作者必备工具书。',
|
|
|
+ viewCount: 560,
|
|
|
+ commentCount: 8,
|
|
|
+ createBy: '王刚',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ category: 'academic',
|
|
|
+ title: '针灸学理论与实践',
|
|
|
+ author: '刘教授 主编',
|
|
|
+ publisher: '中国中医药出版社',
|
|
|
+ publishDate: '2024-09',
|
|
|
+ isbn: '978-7-5132-5678-2',
|
|
|
+ description:
|
|
|
+ '系统论述针灸学基础理论、经络腧穴、刺灸方法及临床各科常见病证的针灸治疗方案,附大量临床案例。',
|
|
|
+ viewCount: 720,
|
|
|
+ commentCount: 12,
|
|
|
+ createBy: '张许',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+ {
|
|
|
+ category: 'textbook',
|
|
|
+ title: '方剂学(第二版)',
|
|
|
+ author: '赵主任 主编',
|
|
|
+ publisher: '高等教育出版社',
|
|
|
+ publishDate: '2025-01',
|
|
|
+ isbn: '978-7-04-01234-5',
|
|
|
+ description:
|
|
|
+ '高等院校中医药类专业核心教材,介绍方剂组成原则、各类方剂的功用主治及临床应用要点。',
|
|
|
+ viewCount: 980,
|
|
|
+ commentCount: 18,
|
|
|
+ createBy: '李虎',
|
|
|
+ fileUrl: MOCK_PDF_URL,
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+function createInitialStore(): MonographDTO[] {
|
|
|
+ const records: MonographDTO[] = [];
|
|
|
+ for (let index = 0; index < 28; index += 1) {
|
|
|
+ const seed = SEED_RECORDS[index % SEED_RECORDS.length] ?? SEED_RECORDS[0];
|
|
|
+ if (!seed) continue;
|
|
|
+ const day = String((index % 28) + 1).padStart(2, '0');
|
|
|
+ const month = String((index % 12) + 1).padStart(2, '0');
|
|
|
+ records.push({
|
|
|
+ ...seed,
|
|
|
+ id: String(index + 1),
|
|
|
+ personalStudioId: '327477138296832',
|
|
|
+ createTime: `2026-${month}-${day}T10:00:00`,
|
|
|
+ updateTime: `2026-05-${day}T10:00:00`,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return records;
|
|
|
+}
|
|
|
+
|
|
|
+let nextId = 100;
|
|
|
+let store = createInitialStore();
|
|
|
+
|
|
|
+function delay<T>(runner: () => Promise<T> | T, ms = 120): MethodLike<T> {
|
|
|
+ const run = async () => {
|
|
|
+ await new Promise((resolve) => setTimeout(resolve, ms));
|
|
|
+ return runner();
|
|
|
+ };
|
|
|
+ const promise = run();
|
|
|
+ return Object.assign(promise, { send: run });
|
|
|
+}
|
|
|
+
|
|
|
+function matchKeyword(record: MonographDTO, keyword?: string) {
|
|
|
+ if (!keyword) return true;
|
|
|
+ const text = [
|
|
|
+ record.title,
|
|
|
+ record.author,
|
|
|
+ record.isbn,
|
|
|
+ record.publisher,
|
|
|
+ record.description,
|
|
|
+ record.createBy,
|
|
|
+ ]
|
|
|
+ .filter(Boolean)
|
|
|
+ .join(' ');
|
|
|
+ return text.includes(keyword);
|
|
|
+}
|
|
|
+
|
|
|
+function matchWorkroom(record: MonographDTO, workroomId?: string) {
|
|
|
+ if (!workroomId) return true;
|
|
|
+ return String(record.personalStudioId ?? '') === String(workroomId);
|
|
|
+}
|
|
|
+
|
|
|
+function matchCategory(record: MonographDTO, category?: MonographCategory) {
|
|
|
+ if (!category) return true;
|
|
|
+ return record.category === category;
|
|
|
+}
|
|
|
+
|
|
|
+function toVo(dto: MonographDTO): MonographVO {
|
|
|
+ return decodeMonograph(dto);
|
|
|
+}
|
|
|
+
|
|
|
+export function mockListMonographMethod(...args: PageQueryMethodArgs) {
|
|
|
+ const { params, data } = pageQueryArgsTransform(args, encodeMonographQuery);
|
|
|
+ const pageNum = Number(params.pageNum ?? 1);
|
|
|
+ const pageSize = Number(params.pageSize ?? 10);
|
|
|
+ const keyword = data.mixture;
|
|
|
+ const workroomId = data.personalStudioId?.toString();
|
|
|
+ const category = data.category;
|
|
|
+
|
|
|
+ const filtered = store.filter(
|
|
|
+ (record) =>
|
|
|
+ matchKeyword(record, keyword) &&
|
|
|
+ matchWorkroom(record, workroomId) &&
|
|
|
+ matchCategory(record, category),
|
|
|
+ );
|
|
|
+ const start = (pageNum - 1) * pageSize;
|
|
|
+ const items = filtered
|
|
|
+ .slice(start, start + pageSize)
|
|
|
+ .map((record) => toVo(record));
|
|
|
+
|
|
|
+ const result: PageVO<MonographVO> = {
|
|
|
+ total: filtered.length,
|
|
|
+ items,
|
|
|
+ };
|
|
|
+ return delay(() => result);
|
|
|
+}
|
|
|
+
|
|
|
+export function mockGetMonographMethod(vo: Partial<MonographVO>) {
|
|
|
+ return delay(() => {
|
|
|
+ const record = store.find((item) => String(item.id) === String(vo.id));
|
|
|
+ if (!record) {
|
|
|
+ throw new Error('论著不存在');
|
|
|
+ }
|
|
|
+ return toVo(record);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export function mockEditMonographMethod(vo: MonographSubmitVO) {
|
|
|
+ return delay(() => {
|
|
|
+ const dto = encodeMonograph(vo);
|
|
|
+ const now = new Date().toISOString();
|
|
|
+
|
|
|
+ if (vo.id) {
|
|
|
+ const index = store.findIndex(
|
|
|
+ (item) => String(item.id) === String(vo.id),
|
|
|
+ );
|
|
|
+ if (index === -1) {
|
|
|
+ throw new Error('论著不存在');
|
|
|
+ }
|
|
|
+ store[index] = {
|
|
|
+ ...store[index],
|
|
|
+ ...dto,
|
|
|
+ updateTime: now,
|
|
|
+ };
|
|
|
+ return String(vo.id);
|
|
|
+ }
|
|
|
+
|
|
|
+ const id = String(nextId++);
|
|
|
+ store.unshift({
|
|
|
+ ...dto,
|
|
|
+ id,
|
|
|
+ viewCount: 0,
|
|
|
+ commentCount: 0,
|
|
|
+ createBy: dto.createBy ?? '当前用户',
|
|
|
+ createTime: now,
|
|
|
+ updateTime: now,
|
|
|
+ });
|
|
|
+ return id;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export function mockDeleteMonographMethod(vo: Pick<MonographVO, 'id'>) {
|
|
|
+ return delay(() => {
|
|
|
+ const before = store.length;
|
|
|
+ store = store.filter((item) => String(item.id) !== String(vo.id));
|
|
|
+ if (store.length === before) {
|
|
|
+ throw new Error('论著不存在');
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+/** 仅用于本地调试,重置 mock 数据 */
|
|
|
+export function resetMonographMockStore() {
|
|
|
+ nextId = 100;
|
|
|
+ store = createInitialStore();
|
|
|
+}
|