Explorar o código

feat(@six/smart-pharmacy): 智慧药事系统第二版-患者评价接口对接

cmj hai 3 semanas
pai
achega
2d349f8776

+ 102 - 823
apps/smart-pharmacy/src/api/method/patient-evaluation.ts

@@ -1,6 +1,20 @@
-import type { TransformList, TransformRecord } from '#/api';
-
-/** 患者评价(接口就绪后替换为真实请求) */
+import type {
+  TransformBlob,
+  TransformData,
+  TransformList,
+  TransformRecord,
+} from '#/api';
+
+import { downloadFileFromBlob } from '@vben/utils';
+
+import { http } from '#/api';
+import {
+  fromEfficacyEvaluation,
+  fromSatisfactionEvaluation,
+  toEvaluationQuery,
+} from '#/api/model/evaluation';
+
+/** 患者评价 */
 export namespace PatientEvaluationModel {
   export type SatisfactionScore = 1 | 2 | 3 | 4 | 5;
 
@@ -83,437 +97,6 @@ export function getSatisfactionScoreLabel(
   return SATISFACTION_SCORE_LABELS[score] ?? '';
 }
 
-const MOCK_DETAIL_TEXT = [
-  '内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容',
-  '内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容',
-  '内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容',
-  '内容内容内容内容内容内容内容内容内容内容内容内容内容内容内容',
-].join('\n');
-
-function withDetailFields(
-  item: PatientEvaluationModel.SatisfactionEvaluation,
-): PatientEvaluationModel.SatisfactionEvaluation {
-  return {
-    ...item,
-    prescriptionId: item.prescriptionId ?? item.id,
-    logisticsNumber: item.logisticsNumber ?? '',
-    patientName: item.patientName ?? '',
-    gender: item.gender ?? '',
-    age: item.age ?? '',
-    patientPhone: item.patientPhone ?? '',
-    decoctionDispensing: item.decoctionDispensing ?? '',
-    evaluationDetail:
-      item.evaluationDetail ?? item.remark ?? MOCK_DETAIL_TEXT,
-    improvementSuggestion: item.improvementSuggestion ?? MOCK_DETAIL_TEXT,
-  };
-}
-
-const MOCK_SATISFACTION_EVALUATIONS: PatientEvaluationModel.SatisfactionEvaluation[] =
-  [
-    {
-      id: '1',
-      prescriptionDate: '2027-3-20',
-      prescriptionNumber: '944895756806594342',
-      prescriptionId: '1',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '重药(浙江)控股',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      logisticsNumber: 'SF73648596038958987',
-      patientName: '唐理理',
-      gender: '女',
-      age: 48,
-      patientPhone: '13828394123',
-      decoctionDispensing: '代煎',
-      satisfactionScore: 5,
-      evaluationTime: '2024-01-06 10:30:00',
-      evaluationDetail: MOCK_DETAIL_TEXT,
-      improvementSuggestion: MOCK_DETAIL_TEXT,
-    },
-    {
-      id: '2',
-      prescriptionDate: '2024-01-08',
-      prescriptionNumber: 'CF20240108002',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 1,
-      evaluationTime: '2024-01-09 14:20:00',
-      remark: '等待时间过长',
-    },
-    {
-      id: '3',
-      prescriptionDate: '2024-01-10',
-      prescriptionNumber: 'CF20240110003',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '',
-      satisfactionScore: 3,
-      evaluationTime: '2024-01-11 09:15:00',
-    },
-    {
-      id: '4',
-      prescriptionDate: '2024-01-12',
-      prescriptionNumber: 'CF20240112004',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 5,
-      evaluationTime: '2024-01-13 16:45:00',
-    },
-    {
-      id: '5',
-      prescriptionDate: '2024-01-15',
-      prescriptionNumber: 'CF20240115005',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '西溪院区',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '圆通速递',
-      satisfactionScore: 4,
-      evaluationTime: '2024-01-16 11:00:00',
-    },
-    {
-      id: '6',
-      prescriptionDate: '2024-01-18',
-      prescriptionNumber: 'CF20240118006',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 2,
-      evaluationTime: '2024-01-19 08:30:00',
-      remark: '包装有破损',
-    },
-    {
-      id: '7',
-      prescriptionDate: '2024-01-20',
-      prescriptionNumber: 'CF20240120007',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 5,
-      evaluationTime: '2024-01-21 13:20:00',
-    },
-    {
-      id: '8',
-      prescriptionDate: '2024-01-22',
-      prescriptionNumber: 'CF20240122008',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '西溪院区',
-      decoctionEnterprise: '',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 3,
-      evaluationTime: '2024-01-23 15:10:00',
-    },
-    {
-      id: '9',
-      prescriptionDate: '2024-01-25',
-      prescriptionNumber: 'CF20240125009',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '圆通速递',
-      satisfactionScore: 1,
-      evaluationTime: '2024-01-26 10:00:00',
-    },
-    {
-      id: '10',
-      prescriptionDate: '2024-01-28',
-      prescriptionNumber: 'CF20240128010',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 4,
-      evaluationTime: '2024-01-29 17:30:00',
-    },
-    {
-      id: '11',
-      prescriptionDate: '2024-02-01',
-      prescriptionNumber: 'CF20240201011',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 5,
-      evaluationTime: '2024-02-02 09:45:00',
-    },
-    {
-      id: '12',
-      prescriptionDate: '2024-02-03',
-      prescriptionNumber: 'CF20240203012',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '',
-      satisfactionScore: 3,
-      evaluationTime: '2024-02-04 14:00:00',
-    },
-    {
-      id: '13',
-      prescriptionDate: '2024-02-05',
-      prescriptionNumber: 'CF20240205013',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 5,
-      evaluationTime: '2024-02-06 11:30:00',
-    },
-    {
-      id: '14',
-      prescriptionDate: '2024-02-08',
-      prescriptionNumber: 'CF20240208014',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '西溪院区',
-      decoctionEnterprise: '',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '圆通速递',
-      satisfactionScore: 2,
-      evaluationTime: '2024-02-09 16:20:00',
-    },
-    {
-      id: '15',
-      prescriptionDate: '2024-02-10',
-      prescriptionNumber: 'CF20240210015',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 4,
-      evaluationTime: '2024-02-11 08:50:00',
-    },
-    {
-      id: '16',
-      prescriptionDate: '2024-02-12',
-      prescriptionNumber: 'CF20240212016',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 1,
-      evaluationTime: '2024-02-13 12:10:00',
-    },
-    {
-      id: '17',
-      prescriptionDate: '2024-02-15',
-      prescriptionNumber: 'CF20240215017',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '西溪院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 5,
-      evaluationTime: '2024-02-16 15:40:00',
-    },
-    {
-      id: '18',
-      prescriptionDate: '2024-02-18',
-      prescriptionNumber: 'CF20240218018',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '圆通速递',
-      satisfactionScore: 3,
-      evaluationTime: '2024-02-19 10:25:00',
-    },
-    {
-      id: '19',
-      prescriptionDate: '2024-02-20',
-      prescriptionNumber: 'CF20240220019',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '',
-      satisfactionScore: 4,
-      evaluationTime: '2024-02-21 13:55:00',
-    },
-    {
-      id: '20',
-      prescriptionDate: '2024-02-22',
-      prescriptionNumber: 'CF20240222020',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '西溪院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 5,
-      evaluationTime: '2024-02-23 09:00:00',
-    },
-    {
-      id: '21',
-      prescriptionDate: '2024-02-25',
-      prescriptionNumber: 'CF20240225021',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 2,
-      evaluationTime: '2024-02-26 14:30:00',
-    },
-    {
-      id: '22',
-      prescriptionDate: '2024-02-28',
-      prescriptionNumber: 'CF20240228022',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 3,
-      evaluationTime: '2024-03-01 11:15:00',
-    },
-    {
-      id: '23',
-      prescriptionDate: '2024-03-02',
-      prescriptionNumber: 'CF20240302023',
-      medicalInstitution: '西溪社区卫生服务中心',
-      campus: '',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '西溪煎药中心',
-      logisticsCompany: '圆通速递',
-      satisfactionScore: 5,
-      evaluationTime: '2024-03-03 16:00:00',
-    },
-    {
-      id: '24',
-      prescriptionDate: '2024-03-05',
-      prescriptionNumber: 'CF20240305024',
-      medicalInstitution: '文新社区卫生服务中心',
-      campus: '文新院区',
-      decoctionEnterprise: '杭州中药煎配中心',
-      decoctionCenter: '文新煎药中心',
-      logisticsCompany: '顺丰速运',
-      satisfactionScore: 1,
-      evaluationTime: '2024-03-06 08:40:00',
-    },
-    {
-      id: '25',
-      prescriptionDate: '2024-03-08',
-      prescriptionNumber: 'CF20240308025',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '蒋村院区',
-      decoctionEnterprise: '浙江煎药企业',
-      decoctionCenter: '西湖煎药中心',
-      logisticsCompany: '京东物流',
-      satisfactionScore: 4,
-      evaluationTime: '2024-03-09 12:50:00',
-    },
-  ];
-
-function filterSatisfactionEvaluations(
-  items: PatientEvaluationModel.SatisfactionEvaluation[],
-  query?: PatientEvaluationModel.SatisfactionListQuery,
-) {
-  const range = query?.dateRange;
-  if (!range?.length || range.length < 2 || !range[0] || !range[1]) {
-    return items;
-  }
-  const [start, end] = range;
-  return items.filter(
-    (item) => item.prescriptionDate >= start && item.prescriptionDate <= end,
-  );
-}
-
-/** 满意度评价列表(当前为本地 mock,后期对接后端分页接口) */
-export function listSatisfactionEvaluationsMethod(
-  page = 1,
-  size = 10,
-  query?: PatientEvaluationModel.SatisfactionListQuery,
-): Promise<TransformList<PatientEvaluationModel.SatisfactionEvaluation>> {
-  const filtered = filterSatisfactionEvaluations(
-    MOCK_SATISFACTION_EVALUATIONS,
-    query,
-  );
-  const start = (page - 1) * size;
-  const items = filtered.slice(start, start + size);
-  return Promise.resolve({
-    items,
-    total: filtered.length,
-    data: { page, size, total: filtered.length },
-  });
-}
-
-/** 满意度评价详情(当前为本地 mock,后期对接后端接口) */
-export function getSatisfactionEvaluationMethod(id: string) {
-  const item = MOCK_SATISFACTION_EVALUATIONS.find((row) => row.id === id);
-  if (!item) {
-    return Promise.reject(new Error('评价记录不存在'));
-  }
-  return Promise.resolve(withDetailFields(item));
-}
-
-/** 导出满意度评价(当前为本地 mock,后期对接后端导出接口) */
-export function exportSatisfactionEvaluationsMethod(
-  query?: PatientEvaluationModel.SatisfactionListQuery,
-) {
-  const filtered = filterSatisfactionEvaluations(
-    MOCK_SATISFACTION_EVALUATIONS,
-    query,
-  );
-  const headers = [
-    '处方日期',
-    '处方号',
-    '医疗机构',
-    '院区',
-    '煎药企业',
-    '煎药中心',
-    '物流公司',
-    '满意度评分',
-    '评价时间',
-    '评价备注',
-  ];
-  const rows = filtered.map((item) => [
-    item.prescriptionDate,
-    item.prescriptionNumber,
-    item.medicalInstitution ?? '',
-    item.campus ?? '',
-    item.decoctionEnterprise ?? '',
-    item.decoctionCenter ?? '',
-    item.logisticsCompany ?? '',
-    getSatisfactionScoreLabel(item.satisfactionScore),
-    item.evaluationTime,
-    item.remark ?? '',
-  ]);
-  const csvContent = [headers, ...rows]
-    .map((row) =>
-      row.map((cell) => `"${String(cell).replaceAll('"', '""')}"`).join(','),
-    )
-    .join('\n');
-  const blob = new Blob([`\uFEFF${csvContent}`], {
-    type: 'text/csv;charset=utf-8;',
-  });
-  const url = URL.createObjectURL(blob);
-  const link = document.createElement('a');
-  link.href = url;
-  link.download = `满意度评价_${new Date().toISOString().slice(0, 10)}.csv`;
-  link.click();
-  URL.revokeObjectURL(url);
-  return Promise.resolve(true);
-}
-
 export const EFFICACY_RESULT_LABELS: Record<
   PatientEvaluationModel.EfficacyResult,
   string
@@ -530,416 +113,112 @@ export function getEfficacyResultLabel(
   return EFFICACY_RESULT_LABELS[result] ?? '';
 }
 
-function withEfficacyDetailFields(
-  item: PatientEvaluationModel.EfficacyEvaluation,
-): PatientEvaluationModel.EfficacyEvaluation {
-  return {
-    ...item,
-    prescriptionId: item.prescriptionId ?? item.id,
-    logisticsNumber: item.logisticsNumber ?? '',
-    patientName: item.patientName ?? '',
-    gender: item.gender ?? '',
-    age: item.age ?? '',
-    patientPhone: item.patientPhone ?? '',
-    decoctionDispensing: item.decoctionDispensing ?? '',
-    evaluationDetail:
-      item.evaluationDetail ?? item.remark ?? MOCK_DETAIL_TEXT,
-  };
+const EVALUATION_BASE = '/manager/tcmp-pc/evaluation';
+
+function downloadEvaluationExport(data: TransformBlob, defaultFileName: string) {
+  downloadFileFromBlob({
+    fileName: defaultFileName,
+    source: data.source,
+  });
+  return data;
 }
 
-const MOCK_EFFICACY_EVALUATIONS: PatientEvaluationModel.EfficacyEvaluation[] =
-  [
-    {
-      id: 'e1',
-      prescriptionDate: '2023-09-23',
-      prescriptionNumber: '2023092323945',
-      prescriptionId: '1',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      logisticsNumber: 'SF73648596038958987',
-      patientName: '张三',
-      gender: '男',
-      age: 52,
-      patientPhone: '13828394123',
-      decoctionDispensing: '代煎',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-09-30 14:23:33',
-      evaluationDetail: MOCK_DETAIL_TEXT,
-    },
-    {
-      id: 'e2',
-      prescriptionDate: '2023-09-24',
-      prescriptionNumber: '2023092423946',
-      medicalInstitution: '同仁堂',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-01 09:15:20',
-    },
-    {
-      id: 'e3',
-      prescriptionDate: '2023-09-25',
-      prescriptionNumber: '2023092523947',
-      medicalInstitution: '浙江省中医院',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-02 16:40:11',
-    },
-    {
-      id: 'e4',
-      prescriptionDate: '2023-09-26',
-      prescriptionNumber: '2023092623948',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-03 11:22:45',
-    },
-    {
-      id: 'e5',
-      prescriptionDate: '2023-09-27',
-      prescriptionNumber: '2023092723949',
-      medicalInstitution: '同仁堂',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-04 08:30:00',
-    },
-    {
-      id: 'e6',
-      prescriptionDate: '2023-09-28',
-      prescriptionNumber: '2023092823950',
-      medicalInstitution: '浙江省中医院',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-05 13:55:18',
-    },
-    {
-      id: 'e7',
-      prescriptionDate: '2023-09-29',
-      prescriptionNumber: '2023092923951',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-06 10:10:33',
-    },
-    {
-      id: 'e8',
-      prescriptionDate: '2023-09-30',
-      prescriptionNumber: '2023093023952',
-      medicalInstitution: '同仁堂',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-07 15:20:44',
-    },
-    {
-      id: 'e9',
-      prescriptionDate: '2023-10-01',
-      prescriptionNumber: '2023100123953',
-      medicalInstitution: '浙江省中医院',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-08 09:45:22',
-    },
-    {
-      id: 'e10',
-      prescriptionDate: '2023-10-02',
-      prescriptionNumber: '2023100223954',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-09 14:33:10',
-    },
-    {
-      id: 'e11',
-      prescriptionDate: '2023-10-03',
-      prescriptionNumber: '2023100323955',
-      medicalInstitution: '同仁堂',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-10 11:18:55',
-    },
-    {
-      id: 'e12',
-      prescriptionDate: '2023-10-04',
-      prescriptionNumber: '2023100423956',
-      medicalInstitution: '浙江省中医院',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-11 16:02:30',
-    },
-    {
-      id: 'e13',
-      prescriptionDate: '2023-10-05',
-      prescriptionNumber: '2023100523957',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-12 08:55:41',
-    },
-    {
-      id: 'e14',
-      prescriptionDate: '2023-10-06',
-      prescriptionNumber: '2023100623958',
-      medicalInstitution: '同仁堂',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-13 13:40:19',
-    },
-    {
-      id: 'e15',
-      prescriptionDate: '2023-10-07',
-      prescriptionNumber: '2023100723959',
-      medicalInstitution: '浙江省中医院',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-14 10:25:08',
-    },
-    {
-      id: 'e16',
-      prescriptionDate: '2023-10-08',
-      prescriptionNumber: '2023100823960',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-15 15:12:37',
-    },
-    {
-      id: 'e17',
-      prescriptionDate: '2023-10-09',
-      prescriptionNumber: '2023100923961',
-      medicalInstitution: '同仁堂',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-16 09:08:52',
-    },
-    {
-      id: 'e18',
-      prescriptionDate: '2023-10-10',
-      prescriptionNumber: '2023101023962',
-      medicalInstitution: '浙江省中医院',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-17 14:50:26',
-    },
-    {
-      id: 'e19',
-      prescriptionDate: '2023-10-11',
-      prescriptionNumber: '2023101123963',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-18 11:35:14',
-    },
-    {
-      id: 'e20',
-      prescriptionDate: '2023-10-12',
-      prescriptionNumber: '2023101223964',
-      medicalInstitution: '同仁堂',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-19 16:28:03',
-    },
-    {
-      id: 'e21',
-      prescriptionDate: '2023-10-13',
-      prescriptionNumber: '2023101323965',
-      medicalInstitution: '浙江省中医院',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-20 08:42:17',
-    },
-    {
-      id: 'e22',
-      prescriptionDate: '2023-10-14',
-      prescriptionNumber: '2023101423966',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'unchanged',
-      evaluationTime: '2023-10-21 13:15:49',
-    },
-    {
-      id: 'e23',
-      prescriptionDate: '2023-10-15',
-      prescriptionNumber: '2023101523967',
-      medicalInstitution: '同仁堂',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-22 10:03:28',
-    },
-    {
-      id: 'e24',
-      prescriptionDate: '2023-10-16',
-      prescriptionNumber: '2023101623968',
-      medicalInstitution: '浙江省中医院',
-      campus: '萧山馆',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'improved',
-      evaluationTime: '2023-10-23 15:47:56',
+/** 满意度评价列表 */
+export function listSatisfactionEvaluationsMethod(
+  page = 1,
+  size = 10,
+  query?: PatientEvaluationModel.SatisfactionListQuery,
+) {
+  return http.get<
+    TransformList<PatientEvaluationModel.SatisfactionEvaluation>,
+    TransformList
+  >(`${EVALUATION_BASE}/getSatisfactionList`, {
+    params: toEvaluationQuery(page, size, query),
+    cacheFor: 0,
+    transform({ items, ...data }) {
+      return {
+        ...data,
+        items: (items ?? []).map((item) =>
+          fromSatisfactionEvaluation(item as TransformData),
+        ),
+      };
     },
+  });
+}
+
+/** 满意度评价详情 */
+export function getSatisfactionEvaluationMethod(id: string) {
+  return http.get<PatientEvaluationModel.SatisfactionEvaluation, TransformData>(
+    `${EVALUATION_BASE}/detailById`,
     {
-      id: 'e25',
-      prescriptionDate: '2023-10-17',
-      prescriptionNumber: '2023101723969',
-      medicalInstitution: '蒋村社区卫生服务中心',
-      campus: '湖滨院区',
-      decoctionEnterprise: '重药煎药中心',
-      decoctionCenter: '重药煎药中心华东区',
-      logisticsCompany: '顺丰速运',
-      efficacyResult: 'cured',
-      evaluationTime: '2023-10-24 09:22:11',
+      params: { id },
+      cacheFor: 0,
+      transform(data) {
+        return fromSatisfactionEvaluation(data);
+      },
     },
-  ];
+  );
+}
 
-function filterEfficacyEvaluations(
-  items: PatientEvaluationModel.EfficacyEvaluation[],
-  query?: PatientEvaluationModel.EfficacyListQuery,
+/** 导出满意度评价 */
+export function exportSatisfactionEvaluationsMethod(
+  query?: PatientEvaluationModel.SatisfactionListQuery,
 ) {
-  const range = query?.dateRange;
-  if (!range?.length || range.length < 2 || !range[0] || !range[1]) {
-    return items;
-  }
-  const [start, end] = range;
-  return items.filter(
-    (item) => item.prescriptionDate >= start && item.prescriptionDate <= end,
-  );
+  return http.get(`${EVALUATION_BASE}/exportSatisfaction`, {
+    params: toEvaluationQuery(undefined, undefined, query),
+    cacheFor: 0,
+    transform(data: TransformBlob) {
+      return downloadEvaluationExport(data, '满意度评价.xlsx');
+    },
+  });
 }
 
-/** 处方疗效评价列表(当前为本地 mock,后期对接后端分页接口) */
+/** 处方疗效评价列表 */
 export function listEfficacyEvaluationsMethod(
   page = 1,
   size = 10,
   query?: PatientEvaluationModel.EfficacyListQuery,
-): Promise<TransformList<PatientEvaluationModel.EfficacyEvaluation>> {
-  const filtered = filterEfficacyEvaluations(MOCK_EFFICACY_EVALUATIONS, query);
-  const start = (page - 1) * size;
-  const items = filtered.slice(start, start + size);
-  return Promise.resolve({
-    items,
-    total: filtered.length,
-    data: { page, size, total: filtered.length },
+) {
+  return http.get<
+    TransformList<PatientEvaluationModel.EfficacyEvaluation>,
+    TransformList
+  >(`${EVALUATION_BASE}/getEfficacyList`, {
+    params: toEvaluationQuery(page, size, query),
+    cacheFor: 0,
+    transform({ items, ...data }) {
+      return {
+        ...data,
+        items: (items ?? []).map((item) =>
+          fromEfficacyEvaluation(item as TransformData),
+        ),
+      };
+    },
   });
 }
 
-/** 处方疗效评价详情(当前为本地 mock,后期对接后端接口) */
+/** 处方疗效评价详情 */
 export function getEfficacyEvaluationMethod(id: string) {
-  const item = MOCK_EFFICACY_EVALUATIONS.find((row) => row.id === id);
-  if (!item) {
-    return Promise.reject(new Error('评价记录不存在'));
-  }
-  return Promise.resolve(withEfficacyDetailFields(item));
+  return http.get<PatientEvaluationModel.EfficacyEvaluation, TransformData>(
+    `${EVALUATION_BASE}/detailById`,
+    {
+      params: { id },
+      cacheFor: 0,
+      transform(data) {
+        return fromEfficacyEvaluation(data);
+      },
+    },
+  );
 }
 
-/** 导出处方疗效评价(当前为本地 mock,后期对接后端导出接口) */
+/** 导出处方疗效评价 */
 export function exportEfficacyEvaluationsMethod(
   query?: PatientEvaluationModel.EfficacyListQuery,
 ) {
-  const filtered = filterEfficacyEvaluations(MOCK_EFFICACY_EVALUATIONS, query);
-  const headers = [
-    '处方日期',
-    '处方号',
-    '医疗机构',
-    '院区',
-    '煎药企业',
-    '煎药中心',
-    '物流公司',
-    '疗效评价',
-    '评价时间',
-    '评价备注',
-  ];
-  const rows = filtered.map((item) => [
-    item.prescriptionDate,
-    item.prescriptionNumber,
-    item.medicalInstitution ?? '',
-    item.campus ?? '',
-    item.decoctionEnterprise ?? '',
-    item.decoctionCenter ?? '',
-    item.logisticsCompany ?? '',
-    getEfficacyResultLabel(item.efficacyResult),
-    item.evaluationTime,
-    item.remark ?? '',
-  ]);
-  const csvContent = [headers, ...rows]
-    .map((row) =>
-      row.map((cell) => `"${String(cell).replaceAll('"', '""')}"`).join(','),
-    )
-    .join('\n');
-  const blob = new Blob([`\uFEFF${csvContent}`], {
-    type: 'text/csv;charset=utf-8;',
+  return http.get(`${EVALUATION_BASE}/exportEfficacy`, {
+    params: toEvaluationQuery(undefined, undefined, query),
+    cacheFor: 0,
+    transform(data: TransformBlob) {
+      return downloadEvaluationExport(data, '处方疗效评价.xlsx');
+    },
   });
-  const url = URL.createObjectURL(blob);
-  const link = document.createElement('a');
-  link.href = url;
-  link.download = `处方疗效评价_${new Date().toISOString().slice(0, 10)}.csv`;
-  link.click();
-  URL.revokeObjectURL(url);
-  return Promise.resolve(true);
 }

+ 136 - 0
apps/smart-pharmacy/src/api/model/evaluation.ts

@@ -0,0 +1,136 @@
+import type { TransformData } from '#/api';
+
+import type { PatientEvaluationModel } from '#/api/method/patient-evaluation';
+
+import { fromRow } from '#/api/model';
+
+const SEX_LABELS: Record<number, string> = {
+  0: '未知',
+  1: '男',
+  2: '女',
+};
+
+const IS_BEHALF_LABELS: Record<number, string> = {
+  1: '代煎',
+  2: '自煎代配',
+};
+
+const EFFICACY_VALUE_MAP: Record<string, PatientEvaluationModel.EfficacyResult> =
+  {
+    '1': 'cured',
+    '2': 'improved',
+    '3': 'unchanged',
+    cured: 'cured',
+    improved: 'improved',
+    unchanged: 'unchanged',
+    痊愈: 'cured',
+    好转: 'improved',
+    无变化: 'unchanged',
+  };
+
+function formatQueryDateTime(date?: string, endOfDay = false): string {
+  if (!date) return '';
+  if (date.includes(' ')) return date;
+  return endOfDay ? `${date} 23:59:59` : `${date} 00:00:00`;
+}
+
+function mapBaseFields(data?: TransformData) {
+  const id = data?.id === undefined || data?.id === null ? '' : String(data.id);
+  const sex = Number(data?.sex);
+  const isBehalf = Number(data?.isBehalf);
+
+  return {
+    ...fromRow({ ...data, id }),
+    id,
+    prescriptionId:
+      data?.prescriptionId === undefined || data?.prescriptionId === null
+        ? undefined
+        : String(data.prescriptionId),
+    prescriptionDate: String(data?.dealDate ?? ''),
+    prescriptionNumber: String(data?.recipeCode ?? ''),
+    medicalInstitution: String(data?.hospitalName ?? ''),
+    campus: String(data?.yardName ?? ''),
+    decoctionEnterprise: String(data?.medCenterName ?? ''),
+    decoctionCenter: String(data?.decoctionCenterName ?? ''),
+    logisticsCompany: String(data?.logisticsCompany ?? ''),
+    logisticsNumber: String(data?.trackingNumber ?? ''),
+    patientName: String(data?.recipientName ?? ''),
+    gender: SEX_LABELS[sex] ?? '',
+    age: data?.age ?? '',
+    patientPhone: String(data?.recipientTel ?? ''),
+    decoctionDispensing: IS_BEHALF_LABELS[isBehalf] ?? '',
+    evaluationTime: String(data?.createTime ?? ''),
+  };
+}
+
+function resolveSatisfactionScore(
+  value?: unknown,
+): PatientEvaluationModel.SatisfactionScore {
+  const score = Number(value);
+  if ([1, 2, 3, 4, 5].includes(score)) {
+    return score as PatientEvaluationModel.SatisfactionScore;
+  }
+  return 3;
+}
+
+function resolveEfficacyResult(
+  data?: TransformData,
+): PatientEvaluationModel.EfficacyResult {
+  const raw =
+    data?.efficacy ??
+    data?.efficacyResult ??
+    data?.curativeEffect ??
+    data?.efficacyEvaluationResult;
+  if (raw === undefined || raw === null || raw === '') {
+    return 'unchanged';
+  }
+  return EFFICACY_VALUE_MAP[String(raw).trim()] ?? 'unchanged';
+}
+
+export function fromSatisfactionEvaluation(
+  data?: TransformData,
+): PatientEvaluationModel.SatisfactionEvaluation {
+  return {
+    ...mapBaseFields(data),
+    satisfactionScore: resolveSatisfactionScore(data?.satisfaction),
+    evaluationDetail: String(data?.satisfactionEvaluation ?? ''),
+    improvementSuggestion: String(data?.satisfactionSuggestion ?? ''),
+  };
+}
+
+export function fromEfficacyEvaluation(
+  data?: TransformData,
+): PatientEvaluationModel.EfficacyEvaluation {
+  return {
+    ...mapBaseFields(data),
+    efficacyResult: resolveEfficacyResult(data),
+    evaluationDetail: String(
+      data?.efficacyEvaluation ??
+        data?.efficacyEvaluationDetail ??
+        data?.satisfactionEvaluation ??
+        '',
+    ),
+  };
+}
+
+/** 列表/导出查询条件 -> EvaluationDTO */
+export function toEvaluationQuery(
+  page?: number,
+  size?: number,
+  query?:
+    | PatientEvaluationModel.EfficacyListQuery
+    | PatientEvaluationModel.SatisfactionListQuery,
+): TransformData {
+  const dto: TransformData = {};
+
+  if (page !== undefined) dto.pageNum = page;
+  if (size !== undefined) dto.pageSize = size;
+
+  const range = query?.dateRange;
+  if (range?.length && range.length >= 2 && range[0] && range[1]) {
+    dto.startTime = formatQueryDateTime(range[0], false);
+    dto.endTime = formatQueryDateTime(range[1], true);
+  }
+
+  return dto;
+}

+ 1 - 0
apps/smart-pharmacy/src/api/model/index.ts

@@ -4,6 +4,7 @@ export * from './department';
 export * from './dict';
 export * from './doctor';
 export * from './enterprise';
+export * from './evaluation';
 export * from './organization';
 export * from './prescription';
 export * from './prescription-detail';

+ 23 - 6
apps/smart-pharmacy/src/views/patient-evaluation/efficacy/list.vue

@@ -14,6 +14,10 @@ import {
   exportEfficacyEvaluationsMethod,
   listEfficacyEvaluationsMethod,
 } from '#/api';
+import {
+  getLogisticsCompanyLabelMap,
+  resolveLogisticsCompanyLabel,
+} from '#/api/model/process-node-dict';
 
 import {
   useEfficacySearchFormSchema,
@@ -42,12 +46,25 @@ const [Grid, gridApi] = useVbenVxeGrid({
     },
     proxyConfig: {
       ajax: {
-        query({ page }, formValues) {
-          return listEfficacyEvaluationsMethod(
-            page.currentPage,
-            page.pageSize,
-            formValues,
-          );
+        async query({ page }, formValues) {
+          const [result, logisticsCompanyMap] = await Promise.all([
+            listEfficacyEvaluationsMethod(
+              page.currentPage,
+              page.pageSize,
+              formValues,
+            ),
+            getLogisticsCompanyLabelMap(),
+          ]);
+          return {
+            ...result,
+            items: result.items.map((item) => ({
+              ...item,
+              logisticsCompany: resolveLogisticsCompanyLabel(
+                item.logisticsCompany,
+                logisticsCompanyMap,
+              ),
+            })),
+          };
         },
       },
     },

+ 15 - 1
apps/smart-pharmacy/src/views/patient-evaluation/efficacy/modules/detail.vue

@@ -10,6 +10,10 @@ import { Spin } from 'ant-design-vue';
 
 import { getEfficacyEvaluationMethod } from '#/api';
 import { getEfficacyResultLabel } from '#/api/method/patient-evaluation';
+import {
+  getLogisticsCompanyLabelMap,
+  resolveLogisticsCompanyLabel,
+} from '#/api/model/process-node-dict';
 import { maskPhone } from '#/utils/mask-phone';
 
 const router = useRouter();
@@ -36,7 +40,17 @@ const [Modal, modalApi] = useVbenModal({
     if (!data?.id) return;
     loading.value = true;
     try {
-      detail.value = await getEfficacyEvaluationMethod(data.id);
+      const [result, logisticsCompanyMap] = await Promise.all([
+        getEfficacyEvaluationMethod(data.id),
+        getLogisticsCompanyLabelMap(),
+      ]);
+      detail.value = {
+        ...result,
+        logisticsCompany: resolveLogisticsCompanyLabel(
+          result.logisticsCompany,
+          logisticsCompanyMap,
+        ),
+      };
     } finally {
       loading.value = false;
     }

+ 23 - 6
apps/smart-pharmacy/src/views/patient-evaluation/satisfaction/list.vue

@@ -14,6 +14,10 @@ import {
   exportSatisfactionEvaluationsMethod,
   listSatisfactionEvaluationsMethod,
 } from '#/api';
+import {
+  getLogisticsCompanyLabelMap,
+  resolveLogisticsCompanyLabel,
+} from '#/api/model/process-node-dict';
 
 import {
   useSatisfactionSearchFormSchema,
@@ -42,12 +46,25 @@ const [Grid, gridApi] = useVbenVxeGrid({
     },
     proxyConfig: {
       ajax: {
-        query({ page }, formValues) {
-          return listSatisfactionEvaluationsMethod(
-            page.currentPage,
-            page.pageSize,
-            formValues,
-          );
+        async query({ page }, formValues) {
+          const [result, logisticsCompanyMap] = await Promise.all([
+            listSatisfactionEvaluationsMethod(
+              page.currentPage,
+              page.pageSize,
+              formValues,
+            ),
+            getLogisticsCompanyLabelMap(),
+          ]);
+          return {
+            ...result,
+            items: result.items.map((item) => ({
+              ...item,
+              logisticsCompany: resolveLogisticsCompanyLabel(
+                item.logisticsCompany,
+                logisticsCompanyMap,
+              ),
+            })),
+          };
         },
       },
     },

+ 15 - 1
apps/smart-pharmacy/src/views/patient-evaluation/satisfaction/modules/detail.vue

@@ -10,6 +10,10 @@ import { Spin } from 'ant-design-vue';
 
 import { getSatisfactionEvaluationMethod } from '#/api';
 import { getSatisfactionScoreLabel } from '#/api/method/patient-evaluation';
+import {
+  getLogisticsCompanyLabelMap,
+  resolveLogisticsCompanyLabel,
+} from '#/api/model/process-node-dict';
 import { maskPhone } from '#/utils/mask-phone';
 
 const router = useRouter();
@@ -36,7 +40,17 @@ const [Modal, modalApi] = useVbenModal({
     if (!data?.id) return;
     loading.value = true;
     try {
-      detail.value = await getSatisfactionEvaluationMethod(data.id);
+      const [result, logisticsCompanyMap] = await Promise.all([
+        getSatisfactionEvaluationMethod(data.id),
+        getLogisticsCompanyLabelMap(),
+      ]);
+      detail.value = {
+        ...result,
+        logisticsCompany: resolveLogisticsCompanyLabel(
+          result.logisticsCompany,
+          logisticsCompanyMap,
+        ),
+      };
     } finally {
       loading.value = false;
     }

+ 59 - 22
packages/request/src/index.ts

@@ -9,6 +9,48 @@ import { createAlovaClient } from './alova';
 
 const { requestBaseURL } = useAppConfig(import.meta.env, import.meta.env.PROD);
 
+const BINARY_DOWNLOAD_CONTENT_TYPES = new Set([
+  'application/octet-stream',
+  'application/vnd.ms-excel',
+  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
+]);
+
+function decodeContentDispositionFileName(value: string): string {
+  try {
+    return decodeURIComponent(value.trim());
+  } catch {
+    return value.trim();
+  }
+}
+
+function parseContentDispositionFileName(
+  disposition?: string | null,
+  fallbackUrl?: string,
+): string {
+  if (disposition) {
+    const utf8Match = disposition.match(/filename\*=UTF-8''([^;]+)/i);
+    if (utf8Match?.[1]) {
+      return decodeContentDispositionFileName(utf8Match[1]);
+    }
+
+    const fileNameMatch = disposition.match(/filename=["']?([^"';]+)["']?/i);
+    if (fileNameMatch?.[1]) {
+      return decodeContentDispositionFileName(fileNameMatch[1]);
+    }
+  }
+
+  const urlFileName = fallbackUrl?.match(/[^/?#]+(?=$|[?#])/i)?.[0];
+  return urlFileName ? decodeContentDispositionFileName(urlFileName) : 'download';
+}
+
+function isBinaryDownloadContentType(contentType?: string): boolean {
+  if (!contentType) return false;
+  return (
+    BINARY_DOWNLOAD_CONTENT_TYPES.has(contentType) ||
+    contentType.startsWith('application/vnd.openxmlformats-officedocument.')
+  );
+}
+
 export default function createRequestClient(options?: SimpleAlovaOptions) {
   const store = options?.tokenStore ?? useAccessStore();
   const transform = options?.transform ?? ((body) => body);
@@ -25,29 +67,24 @@ export default function createRequestClient(options?: SimpleAlovaOptions) {
 
       /* prettier-ignore */
       const [contentType] = response.headers.get('content-type')?.split(';') ?? [];
-      switch (contentType) {
-        case 'application/json': {
-          const body = transform(await response.json(), method);
-          if (method.meta?.notParseResponseBody) return body;
-          if (body.code === 0) return body.data;
-          throw body;
-        }
-        case 'application/octet-stream': {
-          /* prettier-ignore */
-          const disposition = response.headers.get('content-disposition') ?? method.url;
-          /* prettier-ignore */
-          const fileName = disposition.match(/fileName=["']?([^"';]+)["']?/i)?.[1];
-          return fileName
-            ? {
-                fileName: decodeURIComponent(fileName),
-                source: await response.blob(),
-              }
-            : response;
-        }
-        default: {
-          return response;
-        }
+      if (contentType === 'application/json') {
+        const body = transform(await response.json(), method);
+        if (method.meta?.notParseResponseBody) return body;
+        if (body.code === 0) return body.data;
+        throw body;
       }
+
+      if (isBinaryDownloadContentType(contentType)) {
+        return {
+          fileName: parseContentDispositionFileName(
+            response.headers.get('content-disposition'),
+            method.url,
+          ),
+          source: await response.blob(),
+        };
+      }
+
+      return response;
     },
   };