|
|
@@ -18,8 +18,54 @@ export type ResearchReportCategory =
|
|
|
| 'observational'
|
|
|
| 'translational';
|
|
|
|
|
|
+/** 后端 `progress` 字段:0-进行中 1-已暂停 2-已完成 */
|
|
|
+export type ResearchReportProgressDTO = '0' | '1' | '2';
|
|
|
+
|
|
|
+/** 后端 `type` 字段,对应字典:智慧传承系统-研究类型 */
|
|
|
+export type ResearchReportTypeDTO = '0' | '1' | '2' | '3' | '4';
|
|
|
+
|
|
|
export type ResearchReportStatus = 'completed' | 'in_progress' | 'paused';
|
|
|
|
|
|
+const RESEARCH_PROGRESS_TO_DTO: Record<
|
|
|
+ ResearchReportStatus,
|
|
|
+ ResearchReportProgressDTO
|
|
|
+> = {
|
|
|
+ in_progress: '0',
|
|
|
+ paused: '1',
|
|
|
+ completed: '2',
|
|
|
+};
|
|
|
+
|
|
|
+const RESEARCH_PROGRESS_FROM_DTO: Record<
|
|
|
+ ResearchReportProgressDTO,
|
|
|
+ ResearchReportStatus
|
|
|
+> = {
|
|
|
+ '0': 'in_progress',
|
|
|
+ '1': 'paused',
|
|
|
+ '2': 'completed',
|
|
|
+};
|
|
|
+
|
|
|
+const RESEARCH_TYPE_TO_DTO: Record<
|
|
|
+ ResearchReportCategory,
|
|
|
+ ResearchReportTypeDTO
|
|
|
+> = {
|
|
|
+ clinical: '0',
|
|
|
+ basic: '1',
|
|
|
+ epidemiological: '2',
|
|
|
+ observational: '3',
|
|
|
+ translational: '4',
|
|
|
+};
|
|
|
+
|
|
|
+const RESEARCH_TYPE_FROM_DTO: Record<
|
|
|
+ ResearchReportTypeDTO,
|
|
|
+ ResearchReportCategory
|
|
|
+> = {
|
|
|
+ '0': 'clinical',
|
|
|
+ '1': 'basic',
|
|
|
+ '2': 'epidemiological',
|
|
|
+ '3': 'observational',
|
|
|
+ '4': 'translational',
|
|
|
+};
|
|
|
+
|
|
|
export const RESEARCH_REPORT_CATEGORY_OPTIONS = [
|
|
|
{ label: '临床研究', value: 'clinical' },
|
|
|
{ label: '基础研究', value: 'basic' },
|
|
|
@@ -82,35 +128,105 @@ export function formatResearchPeriod(
|
|
|
return startDate ?? endDate ?? '';
|
|
|
}
|
|
|
|
|
|
+export function decodeResearchReportType(
|
|
|
+ type?: number | string,
|
|
|
+): ResearchReportCategory {
|
|
|
+ const normalized = type?.toString();
|
|
|
+ if (
|
|
|
+ normalized === '0' ||
|
|
|
+ normalized === '1' ||
|
|
|
+ normalized === '2' ||
|
|
|
+ normalized === '3' ||
|
|
|
+ normalized === '4'
|
|
|
+ ) {
|
|
|
+ return RESEARCH_TYPE_FROM_DTO[normalized];
|
|
|
+ }
|
|
|
+ return 'clinical';
|
|
|
+}
|
|
|
+
|
|
|
+export function decodeResearchReportProgress(
|
|
|
+ progress?: number | string,
|
|
|
+): ResearchReportStatus {
|
|
|
+ const normalized = progress?.toString();
|
|
|
+ if (normalized === '0' || normalized === '1' || normalized === '2') {
|
|
|
+ return RESEARCH_PROGRESS_FROM_DTO[normalized];
|
|
|
+ }
|
|
|
+ return 'in_progress';
|
|
|
+}
|
|
|
+
|
|
|
+/** 按研究类型过滤分页结果(后端未按 type 过滤时的兜底) */
|
|
|
+export function filterResearchReportPageByCategory<
|
|
|
+ T extends { items: ResearchReportVO[]; total: number },
|
|
|
+>(page: T, category?: ResearchReportCategory): T {
|
|
|
+ if (!category) return page;
|
|
|
+ const items = page.items.filter((item) => item.category === category);
|
|
|
+ return { ...page, items };
|
|
|
+}
|
|
|
+
|
|
|
+function encodeResearchReportType(
|
|
|
+ category: ResearchReportCategory,
|
|
|
+): ResearchReportTypeDTO {
|
|
|
+ return RESEARCH_TYPE_TO_DTO[category];
|
|
|
+}
|
|
|
+
|
|
|
+function encodeResearchReportProgress(
|
|
|
+ status: ResearchReportStatus,
|
|
|
+): ResearchReportProgressDTO {
|
|
|
+ return RESEARCH_PROGRESS_TO_DTO[status];
|
|
|
+}
|
|
|
+
|
|
|
+function formatDateTime(date: string) {
|
|
|
+ if (!date) return date;
|
|
|
+ if (/^\d{4}-\d{2}$/.test(date)) {
|
|
|
+ return `${date}-01T00:00:00`;
|
|
|
+ }
|
|
|
+ return date;
|
|
|
+}
|
|
|
+
|
|
|
+function formatMonthDate(dateTime?: string) {
|
|
|
+ if (!dateTime) return '';
|
|
|
+ return dateTime.slice(0, 7);
|
|
|
+}
|
|
|
+
|
|
|
// ---------------------------------------------------------------------------
|
|
|
// DTO
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
|
|
+/** 研究报告 DTO,对应 `OutcomeStudyReportDetail` */
|
|
|
export interface ResearchReportDTO extends AuditRecordDTO {
|
|
|
id?: number | string;
|
|
|
+ status?: string;
|
|
|
+ remark?: string;
|
|
|
personalStudioId?: number | string;
|
|
|
- status?: ResearchReportStatus;
|
|
|
- category?: ResearchReportCategory;
|
|
|
+ fileUrl?: string;
|
|
|
+ downloadCount?: number;
|
|
|
+ browseCount?: number;
|
|
|
+ commentCount?: number;
|
|
|
+ praiseCount?: number;
|
|
|
title?: string;
|
|
|
- leader?: string;
|
|
|
- startDate?: string;
|
|
|
- endDate?: string;
|
|
|
+ /** 负责人姓名 */
|
|
|
+ curatorName?: string;
|
|
|
+ /** 研究类型,详见字典:智慧传承系统-研究类型 */
|
|
|
+ type?: ResearchReportTypeDTO | string;
|
|
|
+ /** 进度 0-进行中 1-已暂停 2-已完成 */
|
|
|
+ progress?: ResearchReportProgressDTO | string;
|
|
|
+ beginTime?: string;
|
|
|
+ endTime?: string;
|
|
|
fundingSource?: string;
|
|
|
- projectNumber?: string;
|
|
|
- keywords?: string;
|
|
|
- abstract?: string;
|
|
|
- objectives?: string;
|
|
|
- methods?: string;
|
|
|
- expectedResults?: string;
|
|
|
- fileUrl?: string;
|
|
|
- viewCount?: number;
|
|
|
+ projectCode?: string;
|
|
|
+ keyword?: string;
|
|
|
+ resume?: string;
|
|
|
+ target?: string;
|
|
|
+ method?: string;
|
|
|
+ result?: string;
|
|
|
}
|
|
|
|
|
|
export interface ResearchReportQueryDTO {
|
|
|
mixture?: string;
|
|
|
personalStudioId?: number | string;
|
|
|
- category?: ResearchReportCategory;
|
|
|
- status?: ResearchReportStatus;
|
|
|
+ type?: ResearchReportTypeDTO | string;
|
|
|
+ status?: string;
|
|
|
+ progress?: ResearchReportProgressDTO | string;
|
|
|
pageNum?: number;
|
|
|
pageSize?: number;
|
|
|
}
|
|
|
@@ -184,21 +300,21 @@ export function decodeResearchReport(dto: ResearchReportDTO): ResearchReportVO {
|
|
|
...decodeAuditRecord(dto),
|
|
|
id: dto.id?.toString(),
|
|
|
workroomId: dto.personalStudioId?.toString() ?? '',
|
|
|
- status: dto.status ?? 'in_progress',
|
|
|
- category: dto.category ?? 'clinical',
|
|
|
+ status: decodeResearchReportProgress(dto.progress),
|
|
|
+ category: decodeResearchReportType(dto.type),
|
|
|
title: dto.title ?? '',
|
|
|
- leader: dto.leader ?? '',
|
|
|
- startDate: dto.startDate ?? '',
|
|
|
- endDate: dto.endDate,
|
|
|
+ leader: dto.curatorName ?? '',
|
|
|
+ startDate: formatMonthDate(dto.beginTime),
|
|
|
+ endDate: dto.endTime ? formatMonthDate(dto.endTime) : undefined,
|
|
|
fundingSource: dto.fundingSource,
|
|
|
- projectNumber: dto.projectNumber,
|
|
|
- keywords: dto.keywords,
|
|
|
- abstract: dto.abstract ?? '',
|
|
|
- objectives: dto.objectives,
|
|
|
- methods: dto.methods,
|
|
|
- expectedResults: dto.expectedResults,
|
|
|
+ projectNumber: dto.projectCode,
|
|
|
+ keywords: dto.keyword,
|
|
|
+ abstract: dto.resume ?? '',
|
|
|
+ objectives: dto.target,
|
|
|
+ methods: dto.method,
|
|
|
+ expectedResults: dto.result,
|
|
|
pdfUrl: dto.fileUrl,
|
|
|
- viewCount: dto.viewCount ?? 0,
|
|
|
+ viewCount: dto.browseCount ?? 0,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -208,8 +324,10 @@ export function encodeResearchReportQuery(
|
|
|
return {
|
|
|
mixture: query.keyword,
|
|
|
personalStudioId: query.workroomId,
|
|
|
- category: query.category,
|
|
|
- status: query.status,
|
|
|
+ type: query.category ? encodeResearchReportType(query.category) : undefined,
|
|
|
+ progress: query.status
|
|
|
+ ? encodeResearchReportProgress(query.status)
|
|
|
+ : undefined,
|
|
|
};
|
|
|
}
|
|
|
|
|
|
@@ -219,20 +337,20 @@ export function encodeResearchReport(
|
|
|
return {
|
|
|
id: vo.id,
|
|
|
personalStudioId: vo.workroomId,
|
|
|
- status: vo.status,
|
|
|
- category: vo.category,
|
|
|
+ fileUrl: vo.pdfUrl ?? '',
|
|
|
title: vo.title,
|
|
|
- leader: vo.leader,
|
|
|
- startDate: vo.startDate,
|
|
|
- endDate: vo.endDate,
|
|
|
+ curatorName: vo.leader,
|
|
|
+ type: encodeResearchReportType(vo.category),
|
|
|
+ progress: encodeResearchReportProgress(vo.status),
|
|
|
+ beginTime: formatDateTime(vo.startDate),
|
|
|
+ endTime: vo.endDate ? formatDateTime(vo.endDate) : undefined,
|
|
|
fundingSource: vo.fundingSource,
|
|
|
- projectNumber: vo.projectNumber,
|
|
|
- keywords: vo.keywords,
|
|
|
- abstract: vo.abstract,
|
|
|
- objectives: vo.objectives,
|
|
|
- methods: vo.methods,
|
|
|
- expectedResults: vo.expectedResults,
|
|
|
- fileUrl: vo.pdfUrl,
|
|
|
+ projectCode: vo.projectNumber,
|
|
|
+ keyword: vo.keywords,
|
|
|
+ resume: vo.abstract,
|
|
|
+ target: vo.objectives,
|
|
|
+ method: vo.methods,
|
|
|
+ result: vo.expectedResults,
|
|
|
};
|
|
|
}
|
|
|
|