|
|
@@ -0,0 +1,235 @@
|
|
|
+import type {
|
|
|
+ ReadingNoteDTO,
|
|
|
+ ReadingNoteSubmitVO,
|
|
|
+ ReadingNoteVO,
|
|
|
+} from './reading-note.schema';
|
|
|
+
|
|
|
+import type { PageQueryMethodArgs } from '#/request/schema';
|
|
|
+import type { PageVO } from '#/request/schema/record';
|
|
|
+
|
|
|
+import { pageQueryArgsTransform } from '#/request/schema';
|
|
|
+
|
|
|
+import {
|
|
|
+ decodeReadingNote,
|
|
|
+ encodeReadingNote,
|
|
|
+ encodeReadingNoteQuery,
|
|
|
+} from './reading-note.schema';
|
|
|
+
|
|
|
+/** 后端接口就绪后改为 false */
|
|
|
+export const USE_READING_NOTE_MOCK = true;
|
|
|
+
|
|
|
+type MethodLike<T> = PromiseLike<T> & {
|
|
|
+ send?: (force?: boolean) => PromiseLike<T>;
|
|
|
+};
|
|
|
+
|
|
|
+const SEED_RECORDS: Omit<
|
|
|
+ ReadingNoteDTO,
|
|
|
+ 'createTime' | 'id' | 'personalStudioId' | 'updateTime'
|
|
|
+>[] = [
|
|
|
+ {
|
|
|
+ insightTitle: '《黄帝内经》阴阳五行理论学习心得',
|
|
|
+ bookName: '《黄帝内经》',
|
|
|
+ authorName: '王医师',
|
|
|
+ noteDate: '2026-05-20',
|
|
|
+ noteContent:
|
|
|
+ '《黄帝内经》作为中医理论的奠基之作,其阴阳五行学说贯穿整个中医理论体系。通过深入学习,我对阴阳互根、五行生克有了更深刻的理解,这对临床辨证论治具有重要指导意义。',
|
|
|
+ agreeCount: 23,
|
|
|
+ createBy: '王医师',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ insightTitle: '《伤寒论》六经辨证临床应用体会',
|
|
|
+ bookName: '《伤寒论》',
|
|
|
+ authorName: '李主任',
|
|
|
+ noteDate: '2026-05-18',
|
|
|
+ noteContent:
|
|
|
+ '六经辨证是《伤寒论》的核心内容。在临床实践中,太阳病与少阳病的鉴别尤为关键。结合具体病例,我总结了若干辨证要点,供同仁参考。',
|
|
|
+ agreeCount: 18,
|
|
|
+ createBy: '李主任',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ insightTitle: '《金匮要略》杂病诊治思路梳理',
|
|
|
+ bookName: '《金匮要略》',
|
|
|
+ authorName: '张教授',
|
|
|
+ noteDate: '2026-05-15',
|
|
|
+ noteContent:
|
|
|
+ '《金匮要略》对杂病的论述系统而深入。本书心得重点梳理了虚劳、痰饮、水气等常见杂病的辨治思路,并结合现代临床进行了延伸思考。',
|
|
|
+ agreeCount: 31,
|
|
|
+ createBy: '张教授',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ insightTitle: '《温病条辨》卫气营血辨证学习笔记',
|
|
|
+ bookName: '《温病条辨》',
|
|
|
+ authorName: '赵医师',
|
|
|
+ noteDate: '2026-05-12',
|
|
|
+ noteContent:
|
|
|
+ '温病学说是中医外感热病学的重要组成部分。吴鞠通的卫气营血辨证体系层次分明,对急性热病的诊治具有重要价值。',
|
|
|
+ agreeCount: 15,
|
|
|
+ createBy: '赵医师',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ insightTitle: '《神农本草经》药物性味归经研读',
|
|
|
+ bookName: '《神农本草经》',
|
|
|
+ authorName: '陈教授',
|
|
|
+ noteDate: '2026-05-10',
|
|
|
+ noteContent:
|
|
|
+ '《神农本草经》是我国现存最早的本草学专著。通过系统研读,我对药物四气五味、升降浮沉及归经理论有了更系统的认识。',
|
|
|
+ agreeCount: 27,
|
|
|
+ createBy: '陈教授',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ insightTitle: '《针灸大成》腧穴配伍心得',
|
|
|
+ bookName: '《针灸大成》',
|
|
|
+ authorName: '刘医师',
|
|
|
+ noteDate: '2026-05-08',
|
|
|
+ noteContent:
|
|
|
+ '《针灸大成》汇集历代针灸精华。本书心得重点记录了常用腧穴配伍规律及临床运用体会,对提高针灸疗效颇有帮助。',
|
|
|
+ agreeCount: 12,
|
|
|
+ createBy: '刘医师',
|
|
|
+ },
|
|
|
+];
|
|
|
+
|
|
|
+function createInitialStore(): ReadingNoteDTO[] {
|
|
|
+ const records: ReadingNoteDTO[] = [];
|
|
|
+ for (let index = 0; index < 36; 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',
|
|
|
+ agreeCount: (seed.agreeCount ?? 0) + (index % 5),
|
|
|
+ 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: ReadingNoteDTO, keyword?: string) {
|
|
|
+ if (!keyword) return true;
|
|
|
+ const text = [
|
|
|
+ record.insightTitle,
|
|
|
+ record.bookName,
|
|
|
+ record.authorName,
|
|
|
+ record.createBy,
|
|
|
+ ]
|
|
|
+ .filter(Boolean)
|
|
|
+ .join(' ');
|
|
|
+ return text.includes(keyword);
|
|
|
+}
|
|
|
+
|
|
|
+function matchWorkroom(record: ReadingNoteDTO, workroomId?: string) {
|
|
|
+ if (!workroomId) return true;
|
|
|
+ return String(record.personalStudioId ?? '') === String(workroomId);
|
|
|
+}
|
|
|
+
|
|
|
+function sortRecords(records: ReadingNoteDTO[]) {
|
|
|
+ return records.toSorted((a, b) => {
|
|
|
+ const timeA = a.noteDate ? Date.parse(a.noteDate) : 0;
|
|
|
+ const timeB = b.noteDate ? Date.parse(b.noteDate) : 0;
|
|
|
+ return timeB - timeA;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function toVo(dto: ReadingNoteDTO): ReadingNoteVO {
|
|
|
+ return decodeReadingNote(dto);
|
|
|
+}
|
|
|
+
|
|
|
+export function mockListReadingNoteMethod(...args: PageQueryMethodArgs) {
|
|
|
+ const { params, data } = pageQueryArgsTransform(args, encodeReadingNoteQuery);
|
|
|
+ const pageNum = Number(params.pageNum ?? 1);
|
|
|
+ const pageSize = Number(params.pageSize ?? 20);
|
|
|
+ const keyword = data.mixture;
|
|
|
+ const workroomId = data.personalStudioId?.toString();
|
|
|
+
|
|
|
+ const filtered = sortRecords(
|
|
|
+ store.filter(
|
|
|
+ (record) =>
|
|
|
+ matchKeyword(record, keyword) && matchWorkroom(record, workroomId),
|
|
|
+ ),
|
|
|
+ );
|
|
|
+ const start = (pageNum - 1) * pageSize;
|
|
|
+ const items = filtered
|
|
|
+ .slice(start, start + pageSize)
|
|
|
+ .map((record) => toVo(record));
|
|
|
+
|
|
|
+ const result: PageVO<ReadingNoteVO> = {
|
|
|
+ total: filtered.length,
|
|
|
+ items,
|
|
|
+ };
|
|
|
+ return delay(() => result);
|
|
|
+}
|
|
|
+
|
|
|
+export function mockGetReadingNoteMethod(vo: Partial<ReadingNoteVO>) {
|
|
|
+ return delay(() => {
|
|
|
+ const record = store.find((item) => String(item.id) === String(vo.id));
|
|
|
+ if (!record) {
|
|
|
+ throw new Error('读书心得不存在');
|
|
|
+ }
|
|
|
+ return toVo(record);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export function mockEditReadingNoteMethod(vo: ReadingNoteSubmitVO) {
|
|
|
+ return delay(() => {
|
|
|
+ const dto = encodeReadingNote(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,
|
|
|
+ agreeCount: 0,
|
|
|
+ createBy: dto.authorName ?? '当前用户',
|
|
|
+ createTime: now,
|
|
|
+ updateTime: now,
|
|
|
+ });
|
|
|
+ return id;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+export function mockDeleteReadingNoteMethod(vo: Pick<ReadingNoteVO, '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 resetReadingNoteMockStore() {
|
|
|
+ nextId = 100;
|
|
|
+ store = createInitialStore();
|
|
|
+}
|