paper.schema.ts 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. import type {
  2. AuditRecordDTO,
  3. AuditRecordVO,
  4. } from '#/request/schema/audit-record';
  5. import { z } from '#/adapter/form';
  6. import { decodeList } from '#/request/schema';
  7. import { decodeAuditRecord } from '#/request/schema/audit-record';
  8. // ---------------------------------------------------------------------------
  9. // 枚举
  10. // ---------------------------------------------------------------------------
  11. export type PaperCategory = 'conference' | 'degree' | 'journal';
  12. /** 后端 `type` 字段:0-期刊论文 1-学位论文 2-会议论文 */
  13. export type PaperTypeDTO = '0' | '1' | '2';
  14. const PAPER_TYPE_TO_DTO: Record<PaperCategory, PaperTypeDTO> = {
  15. journal: '0',
  16. degree: '1',
  17. conference: '2',
  18. };
  19. const PAPER_TYPE_FROM_DTO: Record<PaperTypeDTO, PaperCategory> = {
  20. '0': 'journal',
  21. '1': 'degree',
  22. '2': 'conference',
  23. };
  24. export const PAPER_CATEGORY_OPTIONS = [
  25. { label: '期刊论文', value: 'journal' },
  26. { label: '学位论文', value: 'degree' },
  27. { label: '会议论文', value: 'conference' },
  28. ] as const satisfies ReadonlyArray<{
  29. label: string;
  30. value: PaperCategory;
  31. }>;
  32. export function getPaperCategoryLabel(category?: PaperCategory) {
  33. return (
  34. PAPER_CATEGORY_OPTIONS.find((item) => item.value === category)?.label ?? ''
  35. );
  36. }
  37. export function decodePaperType(type?: number | string): PaperCategory {
  38. const normalized = type?.toString();
  39. if (normalized === '0' || normalized === '1' || normalized === '2') {
  40. return PAPER_TYPE_FROM_DTO[normalized];
  41. }
  42. return 'journal';
  43. }
  44. /** 按 Tab 分类过滤分页结果(后端未按 type 过滤时的兜底) */
  45. export function filterPaperPageByCategory<
  46. T extends { items: PaperVO[]; total: number },
  47. >(page: T, category?: PaperCategory): T {
  48. if (!category) return page;
  49. const items = page.items.filter((item) => item.category === category);
  50. return { ...page, items };
  51. }
  52. function encodePaperType(category: PaperCategory): PaperTypeDTO {
  53. return PAPER_TYPE_TO_DTO[category];
  54. }
  55. // ---------------------------------------------------------------------------
  56. // DTO
  57. // ---------------------------------------------------------------------------
  58. /** 论文 DTO,对应 `OutcomePaperDetail` */
  59. export interface PaperDTO extends AuditRecordDTO {
  60. id?: number | string;
  61. status?: string;
  62. remark?: string;
  63. personalStudioId?: number | string;
  64. fileUrl?: string;
  65. downloadCount?: number;
  66. browseCount?: number;
  67. commentCount?: number;
  68. praiseCount?: number;
  69. /** 分类 0-期刊论文 1-学位论文 2-会议论文 */
  70. type?: PaperTypeDTO | string;
  71. title?: string;
  72. author?: string;
  73. journalName?: string;
  74. publishYear?: string;
  75. phase?: string;
  76. keyword?: string;
  77. }
  78. export interface PaperQueryDTO {
  79. mixture?: string;
  80. personalStudioId?: number | string;
  81. type?: PaperTypeDTO | string;
  82. status?: string;
  83. pageNum?: number;
  84. pageSize?: number;
  85. }
  86. // ---------------------------------------------------------------------------
  87. // VO
  88. // ---------------------------------------------------------------------------
  89. export interface PaperVO extends AuditRecordVO {
  90. id?: string;
  91. workroomId: string;
  92. category: PaperCategory;
  93. title: string;
  94. authors: string;
  95. journalName: string;
  96. publishYear: string;
  97. volumeInfo?: string;
  98. keywords?: string;
  99. pdfUrl?: string;
  100. downloadCount?: number;
  101. commentCount?: number;
  102. }
  103. export type PaperSubmitVO = PaperVO;
  104. export interface PaperQueryVO {
  105. keyword?: string;
  106. workroomId?: string;
  107. category?: PaperCategory;
  108. }
  109. // ---------------------------------------------------------------------------
  110. // Schema
  111. // ---------------------------------------------------------------------------
  112. export const PaperVOSchema = z.object({
  113. id: z.string().optional(),
  114. workroomId: z.string().min(1, '工作室不能为空'),
  115. category: z.enum(['journal', 'degree', 'conference'], {
  116. message: '请选择论文分类',
  117. }),
  118. title: z.string().min(1, '请输入论文标题'),
  119. authors: z.string().min(1, '请输入作者'),
  120. journalName: z.string().min(1, '请输入期刊名称'),
  121. publishYear: z.string().min(1, '请输入发表年份'),
  122. volumeInfo: z.string().optional(),
  123. keywords: z.string().optional(),
  124. });
  125. // ---------------------------------------------------------------------------
  126. // 编解码
  127. // ---------------------------------------------------------------------------
  128. export function decodePaper(dto: PaperDTO): PaperVO {
  129. return {
  130. ...decodeAuditRecord(dto),
  131. id: dto.id?.toString(),
  132. workroomId: dto.personalStudioId?.toString() ?? '',
  133. category: decodePaperType(dto.type),
  134. title: dto.title ?? '',
  135. authors: dto.author ?? '',
  136. journalName: dto.journalName ?? '',
  137. publishYear: dto.publishYear ?? '',
  138. volumeInfo: dto.phase,
  139. keywords: dto.keyword,
  140. pdfUrl: dto.fileUrl,
  141. downloadCount: dto.downloadCount ?? 0,
  142. commentCount: dto.commentCount ?? 0,
  143. };
  144. }
  145. export function encodePaperQuery(query: Partial<PaperQueryVO>): PaperQueryDTO {
  146. return {
  147. mixture: query.keyword,
  148. personalStudioId: query.workroomId,
  149. type: query.category ? encodePaperType(query.category) : undefined,
  150. };
  151. }
  152. export function encodePaper(vo: PaperSubmitVO): PaperDTO {
  153. return {
  154. id: vo.id,
  155. personalStudioId: vo.workroomId,
  156. fileUrl: vo.pdfUrl,
  157. type: encodePaperType(vo.category),
  158. title: vo.title,
  159. author: vo.authors,
  160. journalName: vo.journalName,
  161. publishYear: vo.publishYear,
  162. phase: vo.volumeInfo,
  163. keyword: vo.keywords,
  164. };
  165. }
  166. export function decodePaperList(dto: PaperDTO[]) {
  167. return decodeList(dto, decodePaper);
  168. }