Преглед изворни кода

feat(@six/wisdom-legacy): 成果管理 - 新药证书页面接口对接

Co-authored-by: Cursor <cursoragent@cursor.com>
cmj пре 2 дана
родитељ
комит
ce789e56d7

+ 5 - 5
apps/wisdom-legacy/src/api/outcome/new-drug-certificate.api.ts

@@ -50,7 +50,7 @@ export function listNewDrugCertificateMethod(...args: PageQueryMethodArgs) {
     encodeNewDrugCertificateQuery,
   );
   return httpClient.Post(
-    `/wis-pc/outcome/newDrugCertificateManage/page`,
+    `/wis-pc/outcome/ngceManage/page`,
     { ...params, ...data },
     {
       params,
@@ -67,7 +67,7 @@ export function createNewDrugCertificateMethod(vo: NewDrugCertificateSubmitVO) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/newDrugCertificateManage/add`,
+    `/wis-pc/outcome/ngceManage/add`,
     encodeNewDrugCertificate(vo),
     {
       name: 'outcome-new-drug-certificate:edit',
@@ -83,7 +83,7 @@ export function updateNewDrugCertificateMethod(vo: NewDrugCertificateSubmitVO) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/newDrugCertificateManage/update`,
+    `/wis-pc/outcome/ngceManage/update`,
     encodeNewDrugCertificate(vo),
     {
       name: 'outcome-new-drug-certificate:edit',
@@ -106,7 +106,7 @@ export function getNewDrugCertificateMethod(vo: Partial<NewDrugCertificateVO>) {
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/newDrugCertificateManage/detail/${vo.id}`,
+    `/wis-pc/outcome/ngceManage/detail/${vo.id}`,
     {},
     {
       hitSource: /^outcome-new-drug-certificate:edit/,
@@ -124,7 +124,7 @@ export function deleteNewDrugCertificateMethod(
   }
 
   return httpClient.Post(
-    `/wis-pc/outcome/newDrugCertificateManage/delete/${vo.id}`,
+    `/wis-pc/outcome/ngceManage/delete/${vo.id}`,
     {},
     {
       name: 'outcome-new-drug-certificate:delete',

+ 33 - 36
apps/wisdom-legacy/src/api/outcome/new-drug-certificate.mock.ts

@@ -12,12 +12,13 @@ import { pageQueryArgsTransform } from '#/request/schema';
 
 import {
   decodeNewDrugCertificate,
+  decodeNewDrugType,
   encodeNewDrugCertificate,
   encodeNewDrugCertificateQuery,
 } from './new-drug-certificate.schema';
 
 /** 后端接口就绪后改为 false */
-export const USE_NEW_DRUG_CERTIFICATE_MOCK = true;
+export const USE_NEW_DRUG_CERTIFICATE_MOCK = false;
 
 type MethodLike<T> = PromiseLike<T> & {
   send?: (force?: boolean) => PromiseLike<T>;
@@ -31,59 +32,53 @@ const SEED_RECORDS: Omit<
   'createTime' | 'id' | 'personalStudioId' | 'updateTime'
 >[] = [
   {
-    approvalNumber: '国药准字Z20050002',
+    approvalCode: '国药准字Z20050002',
     name: '复方丹参滴丸',
-    drugType: 'tcm',
-    applicant: '天津天士力制药股份有限公司',
-    approvalDate: '2005-01-10',
-    longTerm: true,
+    type: '0',
+    applyCompany: '天津天士力制药股份有限公司',
+    approvalTime: '2005-01-10T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    approvalNumber: '国药准字Z20040033',
+    approvalCode: '国药准字Z20040033',
     name: '血必净注射液',
-    drugType: 'tcm_injection',
-    applicant: '天津红日药业股份有限公司',
-    approvalDate: '2004-06-18',
-    longTerm: true,
+    type: '1',
+    applyCompany: '天津红日药业股份有限公司',
+    approvalTime: '2004-06-18T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    approvalNumber: '国药准字Z20030139',
+    approvalCode: '国药准字Z20030139',
     name: '参麦注射液',
-    drugType: 'tcm_injection',
-    applicant: '正大青春宝药业有限公司',
-    approvalDate: '2003-09-25',
-    validUntil: '2028-09-25',
-    longTerm: false,
+    type: '1',
+    applyCompany: '正大青春宝药业有限公司',
+    approvalTime: '2003-09-25T00:00:00',
+    expirationTime: '2028-09-25T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    approvalNumber: '国药准字H20123456',
+    approvalCode: '国药准字H20123456',
     name: '阿莫西林胶囊',
-    drugType: 'chemical',
-    applicant: '华北制药股份有限公司',
-    approvalDate: '2012-05-20',
-    validUntil: '2027-05-20',
-    longTerm: false,
+    type: '2',
+    applyCompany: '华北制药股份有限公司',
+    approvalTime: '2012-05-20T00:00:00',
+    expirationTime: '2027-05-20T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    approvalNumber: '国药准字S20210001',
+    approvalCode: '国药准字S20210001',
     name: '重组人胰岛素注射液',
-    drugType: 'biological',
-    applicant: '通化东宝药业股份有限公司',
-    approvalDate: '2021-03-15',
-    longTerm: true,
+    type: '3',
+    applyCompany: '通化东宝药业股份有限公司',
+    approvalTime: '2021-03-15T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
   {
-    approvalNumber: '国药准字Z20190088',
+    approvalCode: '国药准字Z20190088',
     name: '连花清瘟胶囊',
-    drugType: 'tcm',
-    applicant: '石家庄以岭药业股份有限公司',
-    approvalDate: '2019-11-08',
-    longTerm: true,
+    type: '0',
+    applyCompany: '石家庄以岭药业股份有限公司',
+    approvalTime: '2019-11-08T00:00:00',
     fileUrl: MOCK_PDF_URL,
   },
 ];
@@ -118,7 +113,7 @@ function delay<T>(runner: () => Promise<T> | T, ms = 120): MethodLike<T> {
 
 function matchKeyword(record: NewDrugCertificateDTO, keyword?: string) {
   if (!keyword) return true;
-  const text = [record.name, record.approvalNumber, record.applicant]
+  const text = [record.name, record.approvalCode, record.applyCompany]
     .filter(Boolean)
     .join(' ');
   return text.includes(keyword);
@@ -131,7 +126,7 @@ function matchWorkroom(record: NewDrugCertificateDTO, workroomId?: string) {
 
 function matchDrugType(record: NewDrugCertificateDTO, drugType?: NewDrugType) {
   if (!drugType) return true;
-  return record.drugType === drugType;
+  return decodeNewDrugType(record.type) === drugType;
 }
 
 function toVo(dto: NewDrugCertificateDTO): NewDrugCertificateVO {
@@ -147,7 +142,9 @@ export function mockListNewDrugCertificateMethod(...args: PageQueryMethodArgs) {
   const pageSize = Number(params.pageSize ?? 10);
   const keyword = data.mixture;
   const workroomId = data.personalStudioId?.toString();
-  const drugType = data.drugType;
+  const drugType = data.type
+    ? decodeNewDrugType(data.type as string)
+    : undefined;
 
   const filtered = store.filter(
     (record) =>

+ 87 - 22
apps/wisdom-legacy/src/api/outcome/new-drug-certificate.schema.ts

@@ -18,6 +18,25 @@ export type NewDrugType =
   | 'tcm'
   | 'tcm_injection';
 
+/** 后端 `type` 字段,对应字典:智慧传承系统-新药类型 */
+export type NewDrugTypeDTO = '0' | '1' | '2' | '3' | '4';
+
+const NEW_DRUG_TYPE_TO_DTO: Record<NewDrugType, NewDrugTypeDTO> = {
+  tcm: '0',
+  tcm_injection: '1',
+  chemical: '2',
+  biological: '3',
+  other: '4',
+};
+
+const NEW_DRUG_TYPE_FROM_DTO: Record<NewDrugTypeDTO, NewDrugType> = {
+  '0': 'tcm',
+  '1': 'tcm_injection',
+  '2': 'chemical',
+  '3': 'biological',
+  '4': 'other',
+};
+
 export const NEW_DRUG_TYPE_OPTIONS = [
   { label: '中药', value: 'tcm', color: 'success' },
   { label: '中药注射剂', value: 'tcm_injection', color: 'success' },
@@ -34,32 +53,71 @@ export function getNewDrugTypeLabel(type?: NewDrugType) {
   return NEW_DRUG_TYPE_OPTIONS.find((item) => item.value === type)?.label ?? '';
 }
 
+export function decodeNewDrugType(type?: number | string): NewDrugType {
+  const normalized = type?.toString();
+  if (
+    normalized === '0' ||
+    normalized === '1' ||
+    normalized === '2' ||
+    normalized === '3' ||
+    normalized === '4'
+  ) {
+    return NEW_DRUG_TYPE_FROM_DTO[normalized];
+  }
+  return 'tcm';
+}
+
+function encodeNewDrugType(type: NewDrugType): NewDrugTypeDTO {
+  return NEW_DRUG_TYPE_TO_DTO[type];
+}
+
 export function formatValidUntil(validUntil?: string, longTerm?: boolean) {
   if (longTerm) return '长期有效';
   return validUntil || '-';
 }
 
+function formatDateTime(date: string) {
+  if (!date) return date;
+  if (/^\d{4}-\d{2}-\d{2}$/.test(date)) {
+    return `${date}T00:00:00`;
+  }
+  return date;
+}
+
+function formatDateOnly(dateTime?: string) {
+  if (!dateTime) return '';
+  return dateTime.slice(0, 10);
+}
+
 // ---------------------------------------------------------------------------
 // DTO
 // ---------------------------------------------------------------------------
 
+/** 新药证书 DTO,对应 `OutcomeNewdrugCertificateDetail` */
 export interface NewDrugCertificateDTO extends AuditRecordDTO {
   id?: number | string;
+  status?: string;
+  remark?: string;
   personalStudioId?: number | string;
-  approvalNumber?: string;
-  name?: string;
-  drugType?: NewDrugType;
-  applicant?: string;
-  approvalDate?: string;
-  validUntil?: string;
-  longTerm?: boolean;
   fileUrl?: string;
+  downloadCount?: number;
+  browseCount?: number;
+  commentCount?: number;
+  praiseCount?: number;
+  approvalCode?: string;
+  name?: string;
+  /** 新药类型,详见字典:智慧传承系统-新药类型 */
+  type?: NewDrugTypeDTO | string;
+  applyCompany?: string;
+  approvalTime?: string;
+  expirationTime?: string;
 }
 
 export interface NewDrugCertificateQueryDTO {
   mixture?: string;
   personalStudioId?: number | string;
-  drugType?: NewDrugType;
+  type?: NewDrugTypeDTO | string;
+  status?: string;
   pageNum?: number;
   pageSize?: number;
 }
@@ -113,17 +171,20 @@ export const NewDrugCertificateVOSchema = z.object({
 export function decodeNewDrugCertificate(
   dto: NewDrugCertificateDTO,
 ): NewDrugCertificateVO {
+  const expirationTime = dto.expirationTime;
+  const longTerm = !expirationTime;
+
   return {
     ...decodeAuditRecord(dto),
     id: dto.id?.toString(),
     workroomId: dto.personalStudioId?.toString() ?? '',
-    approvalNumber: dto.approvalNumber ?? '',
+    approvalNumber: dto.approvalCode ?? '',
     name: dto.name ?? '',
-    drugType: dto.drugType ?? 'tcm',
-    applicant: dto.applicant ?? '',
-    approvalDate: dto.approvalDate ?? '',
-    validUntil: dto.validUntil,
-    longTerm: dto.longTerm ?? false,
+    drugType: decodeNewDrugType(dto.type),
+    applicant: dto.applyCompany ?? '',
+    approvalDate: formatDateOnly(dto.approvalTime),
+    validUntil: longTerm ? undefined : formatDateOnly(expirationTime),
+    longTerm,
     pdfUrl: dto.fileUrl,
   };
 }
@@ -134,24 +195,28 @@ export function encodeNewDrugCertificateQuery(
   return {
     mixture: query.keyword || undefined,
     personalStudioId: query.workroomId,
-    drugType: query.drugType || undefined,
+    type: query.drugType ? encodeNewDrugType(query.drugType) : undefined,
   };
 }
 
 export function encodeNewDrugCertificate(
   vo: NewDrugCertificateSubmitVO,
 ): NewDrugCertificateDTO {
+  let expirationTime: string | undefined;
+  if (!vo.longTerm && vo.validUntil) {
+    expirationTime = formatDateTime(vo.validUntil);
+  }
+
   return {
     id: vo.id,
     personalStudioId: vo.workroomId,
-    approvalNumber: vo.approvalNumber,
+    fileUrl: vo.pdfUrl ?? '',
+    approvalCode: vo.approvalNumber,
     name: vo.name,
-    drugType: vo.drugType,
-    applicant: vo.applicant,
-    approvalDate: vo.approvalDate,
-    validUntil: vo.longTerm ? undefined : vo.validUntil,
-    longTerm: vo.longTerm,
-    fileUrl: vo.pdfUrl,
+    type: encodeNewDrugType(vo.drugType),
+    applyCompany: vo.applicant,
+    approvalTime: formatDateTime(vo.approvalDate),
+    expirationTime,
   };
 }
 

+ 11 - 2
apps/wisdom-legacy/src/views/outcome/NewDrugCertificateList.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,
@@ -140,11 +141,19 @@ async function handleDelete(row: NewDrugCertificateVO) {
   }
 }
 
-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;

+ 1 - 0
apps/wisdom-legacy/src/views/outcome/new-drug-certificate.data.ts

@@ -49,6 +49,7 @@ export const newDrugCertificateForm = defineEditShell<NewDrugCertificateVO>({
       label: '新药类型',
       defaultValue: 'tcm',
       componentProps: {
+        class: 'w-full',
         options: [...NEW_DRUG_TYPE_OPTIONS],
         placeholder: '请选择新药类型',
         getPopupContainer,