Преглед на файлове

fix(@six/wisdom-legacy): 成果管理 - 论著页面接口对接

cmj преди 2 дни
родител
ревизия
4d2b8b1d45

+ 20 - 7
apps/wisdom-legacy/src/api/outcome/monograph.api.ts

@@ -1,6 +1,11 @@
-import type { MonographSubmitVO, MonographVO } from './monograph.schema';
+import type {
+  MonographDTO,
+  MonographSubmitVO,
+  MonographVO,
+} from './monograph.schema';
 
 import type { PageQueryMethodArgs } from '#/request/schema';
+import type { PageDTO } from '#/request/schema/record';
 
 import { getEnvelopeData, httpClient } from '#/request';
 import {
@@ -18,8 +23,10 @@ import {
 } from './monograph.mock';
 import {
   decodeMonograph,
+  decodeMonographType,
   encodeMonograph,
   encodeMonographQuery,
+  filterMonographPageByCategory,
 } from './monograph.schema';
 
 export { USE_MONOGRAPH_MOCK } from './monograph.mock';
@@ -42,13 +49,19 @@ export function listMonographMethod(...args: PageQueryMethodArgs) {
   }
 
   const { params, data } = pageQueryArgsTransform(args, encodeMonographQuery);
+  const filterCategory = data.type ? decodeMonographType(data.type) : undefined;
+
   return httpClient.Post(
-    `/wis-pc/outcome/monographManage/page`,
+    `/wis-pc/outcome/treatiseManage/page`,
     { ...params, ...data },
     {
       params,
       hitSource: /^outcome-monograph:(edit|delete)/,
-      transform: paginateTransform(decodeMonograph),
+      transform: (page: PageDTO<MonographDTO>) =>
+        filterMonographPageByCategory(
+          paginateTransform(decodeMonograph)(page),
+          filterCategory,
+        ),
     },
   );
 }
@@ -60,7 +73,7 @@ export function createMonographMethod(vo: MonographSubmitVO) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/monographManage/add`,
+    `/wis-pc/outcome/treatiseManage/add`,
     encodeMonograph(vo),
     {
       name: 'outcome-monograph:edit',
@@ -76,7 +89,7 @@ export function updateMonographMethod(vo: MonographSubmitVO) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/monographManage/update`,
+    `/wis-pc/outcome/treatiseManage/update`,
     encodeMonograph(vo),
     {
       name: 'outcome-monograph:edit',
@@ -97,7 +110,7 @@ export function getMonographMethod(vo: Partial<MonographVO>) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/monographManage/detail/${vo.id}`,
+    `/wis-pc/outcome/treatiseManage/detail/${vo.id}`,
     {},
     {
       hitSource: /^outcome-monograph:edit/,
@@ -113,7 +126,7 @@ export function deleteMonographMethod(vo: Pick<MonographVO, 'id'>) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/monographManage/delete/${vo.id}`,
+    `/wis-pc/outcome/treatiseManage/delete/${vo.id}`,
     {},
     {
       name: 'outcome-monograph:delete',

+ 37 - 36
apps/wisdom-legacy/src/api/outcome/monograph.mock.ts

@@ -12,12 +12,13 @@ import { pageQueryArgsTransform } from '#/request/schema';
 
 import {
   decodeMonograph,
+  decodeMonographType,
   encodeMonograph,
   encodeMonographQuery,
 } from './monograph.schema';
 
 /** 后端接口就绪后改为 false */
-export const USE_MONOGRAPH_MOCK = true;
+export const USE_MONOGRAPH_MOCK = false;
 
 type MethodLike<T> = PromiseLike<T> & {
   send?: (force?: boolean) => PromiseLike<T>;
@@ -31,85 +32,85 @@ const SEED_RECORDS: Omit<
   'createTime' | 'id' | 'personalStudioId' | 'updateTime'
 >[] = [
   {
-    category: 'textbook',
+    type: '0',
     title: '中医内科学(第三版)',
     author: '王教授 主编',
-    publisher: '中国中医药出版社',
-    publishDate: '2025-08',
+    publishHouse: '中国中医药出版社',
+    publishTime: '2025-08-01T00:00:00',
     isbn: '978-7-5132-6789-0',
-    description:
+    profile:
       '全国高等中医药院校规划教材,系统阐述中医内科疾病的诊治理论与临床实践,涵盖常见内科疾病的病因病机、辨证论治及现代研究进展。',
-    viewCount: 1250,
+    browseCount: 1250,
     commentCount: 23,
     createBy: '王刚',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    category: 'academic',
+    type: '1',
     title: '伤寒论条文解',
     author: '张仲景 著,李教授 校注',
-    publisher: '人民卫生出版社',
-    publishDate: '2024-06',
+    publishHouse: '人民卫生出版社',
+    publishTime: '2024-06-01T00:00:00',
     isbn: '978-7-117-34567-8',
-    description:
+    profile:
       '以经典条文为主线,结合历代医家注释与现代临床体会,深入解读《伤寒论》核心思想与辨证体系。',
-    viewCount: 890,
+    browseCount: 890,
     commentCount: 15,
     createBy: '张许',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    category: 'popular_science',
+    type: '2',
     title: '中医养生智慧',
     author: '陈医师 著',
-    publisher: '科学出版社',
-    publishDate: '2025-03',
+    publishHouse: '科学出版社',
+    publishTime: '2025-03-01T00:00:00',
     isbn: '978-7-03-45678-9',
-    description:
+    profile:
       '面向大众的中医养生科普读物,介绍四季养生、情志调摄、饮食起居等实用养生方法,语言通俗易懂。',
-    viewCount: 2100,
+    browseCount: 2100,
     commentCount: 45,
     createBy: '李虎',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    category: 'reference',
+    type: '3',
     title: '中药学大辞典',
     author: '中国药学会 编',
-    publisher: '上海科学技术出版社',
-    publishDate: '2023-12',
+    publishHouse: '上海科学技术出版社',
+    publishTime: '2023-12-01T00:00:00',
     isbn: '978-7-5323-7890-1',
-    description:
+    profile:
       '收录常用中药及民族药条目,详述性味归经、功效主治、用法用量及现代药理研究,是中医药工作者必备工具书。',
-    viewCount: 560,
+    browseCount: 560,
     commentCount: 8,
     createBy: '王刚',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    category: 'academic',
+    type: '1',
     title: '针灸学理论与实践',
     author: '刘教授 主编',
-    publisher: '中国中医药出版社',
-    publishDate: '2024-09',
+    publishHouse: '中国中医药出版社',
+    publishTime: '2024-09-01T00:00:00',
     isbn: '978-7-5132-5678-2',
-    description:
+    profile:
       '系统论述针灸学基础理论、经络腧穴、刺灸方法及临床各科常见病证的针灸治疗方案,附大量临床案例。',
-    viewCount: 720,
+    browseCount: 720,
     commentCount: 12,
     createBy: '张许',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    category: 'textbook',
+    type: '0',
     title: '方剂学(第二版)',
     author: '赵主任 主编',
-    publisher: '高等教育出版社',
-    publishDate: '2025-01',
+    publishHouse: '高等教育出版社',
+    publishTime: '2025-01-01T00:00:00',
     isbn: '978-7-04-01234-5',
-    description:
+    profile:
       '高等院校中医药类专业核心教材,介绍方剂组成原则、各类方剂的功用主治及临床应用要点。',
-    viewCount: 980,
+    browseCount: 980,
     commentCount: 18,
     createBy: '李虎',
     fileUrl: MOCK_PDF_URL,
@@ -152,8 +153,8 @@ function matchKeyword(record: MonographDTO, keyword?: string) {
     record.title,
     record.author,
     record.isbn,
-    record.publisher,
-    record.description,
+    record.publishHouse,
+    record.profile,
     record.createBy,
   ]
     .filter(Boolean)
@@ -168,7 +169,7 @@ function matchWorkroom(record: MonographDTO, workroomId?: string) {
 
 function matchCategory(record: MonographDTO, category?: MonographCategory) {
   if (!category) return true;
-  return record.category === category;
+  return decodeMonograph(record).category === category;
 }
 
 function toVo(dto: MonographDTO): MonographVO {
@@ -181,7 +182,7 @@ export function mockListMonographMethod(...args: PageQueryMethodArgs) {
   const pageSize = Number(params.pageSize ?? 10);
   const keyword = data.mixture;
   const workroomId = data.personalStudioId?.toString();
-  const category = data.category;
+  const category = data.type ? decodeMonographType(data.type) : undefined;
 
   const filtered = store.filter(
     (record) =>
@@ -235,7 +236,7 @@ export function mockEditMonographMethod(vo: MonographSubmitVO) {
     store.unshift({
       ...dto,
       id,
-      viewCount: 0,
+      browseCount: 0,
       commentCount: 0,
       createBy: dto.createBy ?? '当前用户',
       createTime: now,

+ 82 - 19
apps/wisdom-legacy/src/api/outcome/monograph.schema.ts

@@ -17,6 +17,23 @@ export type MonographCategory =
   | 'reference'
   | 'textbook';
 
+/** 后端 `type` 字段,对应字典:智慧传承系统-论著类别 */
+export type MonographTypeDTO = '0' | '1' | '2' | '3';
+
+const MONOGRAPH_TYPE_TO_DTO: Record<MonographCategory, MonographTypeDTO> = {
+  textbook: '0',
+  academic: '1',
+  popular_science: '2',
+  reference: '3',
+};
+
+const MONOGRAPH_TYPE_FROM_DTO: Record<MonographTypeDTO, MonographCategory> = {
+  '0': 'textbook',
+  '1': 'academic',
+  '2': 'popular_science',
+  '3': 'reference',
+};
+
 export const MONOGRAPH_CATEGORY_OPTIONS = [
   { label: '教材', value: 'textbook' },
   { label: '学术专著', value: 'academic' },
@@ -34,29 +51,75 @@ export function getMonographCategoryLabel(category?: MonographCategory) {
   );
 }
 
+export function decodeMonographType(type?: number | string): MonographCategory {
+  const normalized = type?.toString();
+  if (
+    normalized === '0' ||
+    normalized === '1' ||
+    normalized === '2' ||
+    normalized === '3'
+  ) {
+    return MONOGRAPH_TYPE_FROM_DTO[normalized];
+  }
+  return 'textbook';
+}
+
+/** 按类别过滤分页结果(后端未按 type 过滤时的兜底) */
+export function filterMonographPageByCategory<
+  T extends { items: MonographVO[]; total: number },
+>(page: T, category?: MonographCategory): T {
+  if (!category) return page;
+  const items = page.items.filter((item) => item.category === category);
+  return { ...page, items };
+}
+
+function encodeMonographType(category: MonographCategory): MonographTypeDTO {
+  return MONOGRAPH_TYPE_TO_DTO[category];
+}
+
+function formatPublishTime(publishDate: string) {
+  if (!publishDate) return publishDate;
+  if (/^\d{4}-\d{2}$/.test(publishDate)) {
+    return `${publishDate}-01T00:00:00`;
+  }
+  return publishDate;
+}
+
+function formatPublishDate(publishTime?: string) {
+  if (!publishTime) return '';
+  return publishTime.slice(0, 7);
+}
+
 // ---------------------------------------------------------------------------
 // DTO
 // ---------------------------------------------------------------------------
 
+/** 论著 DTO,对应 `OutcomeTreatiseDetail` */
 export interface MonographDTO extends AuditRecordDTO {
   id?: number | string;
+  status?: string;
+  remark?: string;
   personalStudioId?: number | string;
-  category?: MonographCategory;
+  fileUrl?: string;
+  downloadCount?: number;
+  browseCount?: number;
+  commentCount?: number;
+  praiseCount?: number;
+  /** 论著类别,详见字典:智慧传承系统-论著类别 */
+  type?: MonographTypeDTO | string;
   title?: string;
   author?: string;
-  publisher?: string;
-  publishDate?: string;
+  publishHouse?: string;
+  publishTime?: string;
   isbn?: string;
-  description?: string;
-  fileUrl?: string;
-  viewCount?: number;
-  commentCount?: number;
+  profile?: string;
 }
 
 export interface MonographQueryDTO {
   mixture?: string;
   personalStudioId?: number | string;
-  category?: MonographCategory;
+  type?: MonographTypeDTO | string;
+  status?: string;
   pageNum?: number;
   pageSize?: number;
 }
@@ -115,15 +178,15 @@ export function decodeMonograph(dto: MonographDTO): MonographVO {
     ...decodeAuditRecord(dto),
     id: dto.id?.toString(),
     workroomId: dto.personalStudioId?.toString() ?? '',
-    category: dto.category ?? 'textbook',
+    category: decodeMonographType(dto.type),
     title: dto.title ?? '',
     author: dto.author ?? '',
-    publisher: dto.publisher ?? '',
-    publishDate: dto.publishDate ?? '',
+    publisher: dto.publishHouse ?? '',
+    publishDate: formatPublishDate(dto.publishTime),
     isbn: dto.isbn ?? '',
-    description: dto.description,
+    description: dto.profile,
     pdfUrl: dto.fileUrl,
-    viewCount: dto.viewCount ?? 0,
+    viewCount: dto.browseCount ?? 0,
     commentCount: dto.commentCount ?? 0,
   };
 }
@@ -134,7 +197,7 @@ export function encodeMonographQuery(
   return {
     mixture: query.keyword,
     personalStudioId: query.workroomId,
-    category: query.category,
+    type: query.category ? encodeMonographType(query.category) : undefined,
   };
 }
 
@@ -142,14 +205,14 @@ export function encodeMonograph(vo: MonographSubmitVO): MonographDTO {
   return {
     id: vo.id,
     personalStudioId: vo.workroomId,
-    category: vo.category,
+    fileUrl: vo.pdfUrl,
+    type: encodeMonographType(vo.category),
     title: vo.title,
     author: vo.author,
-    publisher: vo.publisher,
-    publishDate: vo.publishDate,
+    publishHouse: vo.publisher,
+    publishTime: formatPublishTime(vo.publishDate),
     isbn: vo.isbn,
-    description: vo.description,
-    fileUrl: vo.pdfUrl,
+    profile: vo.description,
   };
 }
 

+ 11 - 2
apps/wisdom-legacy/src/views/outcome/MonographList.vue

@@ -6,6 +6,7 @@ import { computed, ref, shallowRef, triggerRef, watch } from 'vue';
 import { Page } from '@vben/common-ui';
 import { Plus } from '@vben/icons';
 
+import { watchDebounced } from '@vueuse/core';
 import {
   Button,
   Empty,
@@ -139,11 +140,19 @@ async function handleDelete(row: MonographVO) {
   }
 }
 
-function onSearch() {
-  searchKeyword.value = keyword.value.trim();
+function applySearch(value: string) {
+  const next = value.trim();
+  if (next === searchKeyword.value) return;
+  searchKeyword.value = next;
   pageNum.value = 1;
 }
 
+watchDebounced(keyword, applySearch, { debounce: 300 });
+
+function onSearch() {
+  applySearch(keyword.value);
+}
+
 function onPageChange(page: number, size: number) {
   pageNum.value = page;
   pageSize.value = size;

+ 3 - 0
apps/wisdom-legacy/src/views/outcome/monograph.data.ts

@@ -72,6 +72,7 @@ export const monographForm = defineEditShell<MonographVO>({
       component: 'Input',
       fieldName: 'isbn',
       label: 'ISBN',
+      formItemClass: 'col-span-2',
       componentProps: {
         placeholder: '例如:978-7-5132-6789-0',
       },
@@ -81,7 +82,9 @@ export const monographForm = defineEditShell<MonographVO>({
       component: 'Select',
       fieldName: 'category',
       label: '类别',
+      formItemClass: 'col-span-2',
       componentProps: {
+        class: 'w-full',
         options: [...MONOGRAPH_CATEGORY_OPTIONS],
         placeholder: '请选择类别',
         getPopupContainer,