Prechádzať zdrojové kódy

feat(@six/smart-pharmacy): 智慧药事系统第一版医疗机构管理接口对接

cmj 1 mesiac pred
rodič
commit
febfb50987

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

@@ -10,6 +10,7 @@ import '@six/request/alova';
 export * from './method/access';
 export * from './method/business';
 export * from './method/common';
+export * from './method/dict';
 export * from './method/system';
 
 export const http = createRequestClient({

+ 40 - 0
apps/smart-pharmacy/src/api/method/dict.ts

@@ -0,0 +1,40 @@
+import type { TransformData } from '#/api';
+
+import { http } from '#/api';
+import { fromDict, type DictItem } from '#/api/model/dict';
+
+export namespace DictModel {
+  export type Item = DictItem;
+}
+
+function normalizeDictList(data: unknown): TransformData[] {
+  if (Array.isArray(data)) return data;
+  if (data && typeof data === 'object') {
+    const record = data as TransformData;
+    if (Array.isArray(record.rows)) return record.rows;
+    if (Array.isArray(record.list)) return record.list;
+    if (Array.isArray(record.items)) return record.items;
+  }
+  return [];
+}
+
+/** 按字典编码获取字典项列表 */
+export function listDictByCodeMethod(dictCode: string) {
+  return http.get<DictItem[], TransformData>(
+    `/manager/tcmp-pc/dict/list`,
+    {
+      params: { dictCode },
+      cacheFor: 60_000,
+      transform(data) {
+        return normalizeDictList(data)
+          .map((item) => fromDict(item))
+          .sort((a, b) => (a.dictSort ?? 0) - (b.dictSort ?? 0));
+      },
+    },
+  );
+}
+
+/** 机构类型字典(dept_type) */
+export function listDeptTypeDictMethod() {
+  return listDictByCodeMethod('dept_type');
+}

+ 17 - 17
apps/smart-pharmacy/src/api/method/system.ts

@@ -81,6 +81,8 @@ export namespace SystemModel {
     createUser?: string;
     parentInstitutionId?: string;
     parentinstitutionSelsourceName?: string;
+    /** 机构类型:1院区 2管理部门 3医疗机构 */
+    deptType?: number;
     type?: string;
     creditCode?: string;
     medicineCenter?: string;
@@ -124,19 +126,23 @@ export namespace SystemModel {
     children?: Menu[];
   }
 }
-// 获取机构列表
+// 获取机构(部门)列表
 export function listOrganizationsMethod(
   page = 1,
   size = 20,
-  query?: TransformData,
+  query?: Partial<SystemModel.Organization>,
 ) {
-  return http.post<TransformList<SystemModel.Organization>, TransformList>(
-    `/basis/medicalinstitutionsMgr/listPain`,
-    toOrganization(query),
+  return http.get<TransformList<SystemModel.Organization>, TransformList>(
+    `/manager/tcmp-pc/dept/list`,
     {
-      params: { page, limit: size },
+      params: { pageNum: page, pageSize: size, ...toOrganization(query) },
+      cacheFor: 0,
       transform({ items, ...data }) {
-        return { ...data, items: items.map((item) => fromOrganization(item)) };
+        const rows = items ?? [];
+        return {
+          ...data,
+          items: rows.map((item) => fromOrganization(item)),
+        };
       },
     },
   );
@@ -208,16 +214,10 @@ export function listSourcePlatformMethod() {
     },
   );
 }
-// 获取全部机构
-export function listOrganizationsMethodAll() {
-  return http.Post<SystemModel.Organization[], TransformData[]>(
-    `/basis/medicalinstitutionsMgr/list`,
-    {
-      transform(data) {
-        return data.map((item) => fromOrganization(item));
-      },
-    },
-  );
+// 获取全部机构(用于上级机构下拉)
+export async function listOrganizationsMethodAll() {
+  const { items } = await listOrganizationsMethod(1, 9999);
+  return items;
 }
 function fromDeptTreeSelect(nodes?: TransformData[]): TransformData[] {
   return (nodes ?? []).map((node) => ({

+ 28 - 0
apps/smart-pharmacy/src/api/model/dict.ts

@@ -0,0 +1,28 @@
+import type { TransformData } from '#/api';
+
+export interface DictItem {
+  id?: string;
+  dictCode?: string;
+  dictName: string;
+  dictValue: number | string;
+  dictSort?: number;
+  remark?: string;
+}
+
+export function fromDict(data?: TransformData): DictItem {
+  const rawValue = data?.dictValue;
+  let dictValue: DictItem['dictValue'] = '';
+  if (rawValue !== undefined && rawValue !== null && rawValue !== '') {
+    const num = Number(rawValue);
+    dictValue = Number.isFinite(num) ? num : String(rawValue);
+  }
+  return {
+    id:
+      data?.id === undefined || data?.id === null ? undefined : String(data.id),
+    dictCode: data?.dictCode,
+    dictName: data?.dictName ?? data?.remark ?? '',
+    dictValue,
+    dictSort: data?.dictSort,
+    remark: data?.remark,
+  };
+}

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

@@ -1,6 +1,7 @@
 import type { TransformData, TransformRecord } from '#/api';
 
 export * from './department';
+export * from './dict';
 export * from './doctor';
 export * from './enterprise';
 export * from './organization';

+ 49 - 21
apps/smart-pharmacy/src/api/model/organization.ts

@@ -2,22 +2,53 @@ import type { SystemModel, TransformData } from '#/api';
 
 import { fromRow } from '#/api/model';
 
+const DEPT_TYPE_LABEL: Record<number, string> = {
+  1: '院区',
+  2: '管理部门',
+  3: '医疗机构',
+};
+
+export function getDeptTypeLabel(type?: number | string): string {
+  if (type === undefined || type === null || type === '') return '-';
+  const key = Number(type);
+  return DEPT_TYPE_LABEL[key] ?? String(type);
+}
+
 export function fromOrganization(
   data?: TransformData,
 ): SystemModel.Organization {
+  const id =
+    data?.deptId === undefined || data?.deptId === null
+      ? data?.pid === undefined || data?.pid === null
+        ? data?.id === undefined || data?.id === null
+          ? ''
+          : String(data.id)
+        : String(data.pid)
+      : String(data.deptId);
+  const deptType = data?.deptType;
+  const typeLabel = getDeptTypeLabel(deptType);
   return {
-    ...fromRow(data),
-    id: data?.pid,
-    name: data?.name,
-    code: data?.code,
-    type: data?.type,
-    parentInstitutionId: data?.parentInstitutionId,
-    parentinstitutionSelsourceName: data?.parentinstitutionSelsourceName,
-    creditCode: data?.creditCode,
-    medicineCenter: data?.medicineCenter,
+    ...fromRow({
+      ...data,
+      id,
+      createUser: data?.createBy ?? data?.createUser,
+      createTime: data?.createTime,
+    }),
+    id,
+    name: data?.deptName ?? data?.name,
+    code: data?.deptCode ?? data?.code,
+    deptType,
+    type: typeLabel !== '-' ? typeLabel : data?.type,
+    parentInstitutionId:
+      data?.parentId === undefined || data?.parentId === null
+        ? data?.parentInstitutionId
+        : String(data.parentId),
+    parentinstitutionSelsourceName:
+      data?.parentName ?? data?.parentinstitutionSelsourceName,
+    creditCode: data?.socialCode ?? data?.creditCode,
+    medicineCenter: data?.medicineCenterName ?? data?.medicineCenter,
     remark: data?.remark,
-    createTime: data?.createTime,
-    createUser: data?.createUser,
+    createUser: data?.createBy ?? data?.createUser,
   };
 }
 
@@ -25,16 +56,13 @@ export function toOrganization(
   data?: Partial<SystemModel.Organization>,
 ): TransformData {
   return {
-    pid: data?.id,
-    name: data?.name,
-    code: data?.code,
-    type: data?.type,
-    parentInstitutionId: data?.parentInstitutionId,
-    parentinstitutionSelsourceName: data?.parentinstitutionSelsourceName,
-    creditCode: data?.creditCode,
-    medicineCenter: data?.medicineCenter,
+    deptId: data?.id || void 0,
+    deptName: data?.name,
+    deptCode: data?.code,
+    deptType: data?.deptType,
+    parentId: data?.parentInstitutionId,
+    socialCode: data?.creditCode,
+    medicineCenterName: data?.medicineCenter,
     remark: data?.remark,
-    createTime: data?.createTime,
-    createUser: data?.createUser,
   };
 }

+ 36 - 67
apps/smart-pharmacy/src/views/system/organization/data.ts

@@ -4,6 +4,7 @@ import type { VbenFormSchema } from '#/adapter/form';
 import type { OnActionClickFn } from '#/adapter/vxe-table';
 import type { SystemModel } from '#/api/method/system';
 
+import { listDeptTypeDictMethod } from '#/api';
 import { listOrganizationsMethodAll } from '#/api/method/system';
 import { $t } from '#/locales';
 
@@ -15,20 +16,15 @@ export function useUserSearchFormSchema(): VbenFormSchema[] {
       label: $t('system.organization.name'),
     },
     {
-      component: 'Select',
-      fieldName: 'status',
+      component: 'ApiSelect',
+      fieldName: 'deptType',
       label: $t('system.organization.type'),
       componentProps: {
-        options: [
-          {
-            label: '院区',
-            value: 1,
-          },
-          {
-            label: '管理部门',
-            value: 0,
-          },
-        ],
+        allowClear: true,
+        api: listDeptTypeDictMethod,
+        class: 'w-full',
+        labelField: 'dictName',
+        valueField: 'dictValue',
       },
     },
   ];
@@ -86,14 +82,15 @@ export function useUserTableColumns<T = SystemModel.Organization>(
     },
     {
       align: 'center',
-      // cellRender: {
-      //   attrs: {
-      //     nameField: 'name',
-      //     nameTitle: $t('system.user._'),
-      //     onClick: onActionClick,
-      //   },
-      //   name: 'CellOperation',
-      // },
+      cellRender: {
+        attrs: {
+          nameField: 'name',
+          nameTitle: $t('system.organization._'),
+          onClick: onActionClick,
+          options: ['edit'],
+        },
+        name: 'CellOperation',
+      },
       field: 'operation',
       fixed: 'right',
       title: $t('table.column.operation'),
@@ -122,63 +119,36 @@ export function useUserFormSchema(
       rules: 'required',
     },
     {
-      component: 'Input',
+      component: 'Select',
       componentProps: {
-        placeholder: $t('system.organization.type'),
+        allowClear: true,
+        class: 'w-full',
+        options: [
+          { label: '院区', value: 1 },
+          { label: '管理部门', value: 2 },
+          { label: '医疗机构', value: 3 },
+        ],
       },
-      fieldName: 'type',
+      fieldName: 'deptType',
       label: $t('system.organization.type'),
       rules: 'required',
     },
-    // {
-    //   component: 'ApiSelect',
-    //   componentProps: {
-    //     allowClear: true,
-    //     api: listOrganizationsMethodAll,
-    //     class: 'w-full',
-    //     labelField: 'name',
-    //     valueField: 'pid',
-    //     childrenField: 'children',
-    //     afterFetch: (res: SystemModel.Organization[]) => {
-    //       if (!current) return res;
-    //       return Array.isArray(res)
-    //         ? res.filter(
-    //             (item) => item.pid !== current.id && item.name !== current.name,
-    //           )
-    //         : res;
-    //     },
-    //   },
-    //   fieldName: 'parentInstitutionId',
-    //   label: $t('system.organization.superior'),
-    // },
     {
-      component: 'Select',
-
+      component: 'ApiSelect',
       componentProps: {
         allowClear: true,
-
+        api: listOrganizationsMethodAll,
         class: 'w-full',
-
-        options: [
-          {
-            label: '测试1上级机构',
-            value: '1',
-          },
-
-          {
-            label: '测试2上级机构',
-            value: '2',
-          },
-
-          {
-            label: '测试3上级机构',
-            value: '3',
-          },
-        ],
+        labelField: 'name',
+        valueField: 'id',
+        afterFetch: (res: SystemModel.Organization[]) => {
+          if (!current) return res;
+          return Array.isArray(res)
+            ? res.filter((item) => item.id !== current.id)
+            : res;
+        },
       },
-
       fieldName: 'parentInstitutionId',
-
       label: $t('system.organization.superior'),
     },
     {
@@ -207,7 +177,6 @@ export function useUserFormSchema(
       },
       fieldName: 'remark',
       label: $t('system.organization.remark'),
-      rules: 'required',
     },
   ];
 }

+ 16 - 112
apps/smart-pharmacy/src/views/system/organization/list.vue

@@ -8,6 +8,7 @@ import type { SystemModel } from '#/api';
 import { Page, useVbenModal } from '@vben/common-ui';
 
 import { useVbenVxeGrid } from '#/adapter/vxe-table';
+import { listOrganizationsMethod } from '#/api';
 
 import { useUserSearchFormSchema, useUserTableColumns } from './data';
 import Form from './modules/form.vue';
@@ -26,139 +27,42 @@ const [Grid, gridApi] = useVbenVxeGrid({
     columns: useUserTableColumns(onActionClick),
     height: 'auto',
     keepSource: true,
-    // proxyConfig: {
-    //   ajax: {
-    //     query({ page }, formValues) {
-    //       return listOrganizationsMethod(
-    //         page.currentPage,
-    //         page.pageSize,
-    //         formValues,
-    //       );
-    //     },
-    //   },
-    // },
-    // rowConfig: {
-    //   keyField: 'id',
-    // },
-
     proxyConfig: {
       ajax: {
-        query() {
-          return Promise.resolve({
-            Data: {
-              TotalRecordCount: 3,
-
-              Items: [
-                {
-                  pid: '1',
-                  name: '六只五常院区',
-                  code: 'lz0003',
-                  parentinstitutionSelsourceName: '杭州六只医院',
-                  createUser: '张三',
-                  createTime: '2025-10-26 11:23:21',
-                  type: '院区',
-                  creditCode: '123456789',
-                  medicineCenter: '煎药中心1',
-                  remark: '备注1',
-                },
-                {
-                  pid: '2',
-                  name: '杭州卫健委',
-                  code: 'hz9876',
-                  parentinstitutionSelsourceName: '',
-                  createUser: '张三',
-                  createTime: '2025-10-26 11:23:21',
-                  type: '管理部门',
-                  creditCode: '987654321',
-                  medicineCenter: '煎药中心2',
-                  remark: '备注2',
-                },
-                {
-                  pid: '3',
-                  name: '同仁堂',
-                  code: 'trt0001',
-                  parentinstitutionSelsourceName: '杭州卫健委',
-                  createUser: '张三',
-                  createTime: '2025-10-26 11:23:21',
-                  type: '医疗机构',
-                  creditCode: '555555555',
-                  medicineCenter: '煎药中心3',
-                  remark: '无',
-                },
-              ],
-            },
-
-            ResultCode: 0,
-          });
+        query({ page }, formValues) {
+          return listOrganizationsMethod(
+            page.currentPage,
+            page.pageSize,
+            formValues,
+          );
         },
       },
-
-      response: {
-        result: 'Data.Items',
-        total: 'Data.TotalRecordCount',
-      },
     },
-
     rowConfig: {
-      keyField: 'pid',
+      keyField: 'id',
     },
-  } as VxeTableGridOptions<SystemModel.User>,
+  } as VxeTableGridOptions<SystemModel.Organization>,
 });
-// 表格的操作 删除和修改功能
-function onActionClick(e: OnActionClickParams<SystemModel.User>) {
-  switch (e.code) {
-    case 'delete': {
-      onDeleteHandle(e.row);
-      break;
-    }
-    case 'edit': {
-      onEditHandle(e.row);
-      break;
-    }
+
+function onActionClick(e: OnActionClickParams<SystemModel.Organization>) {
+  if (e.code === 'edit') {
+    onEditHandle(e.row);
   }
 }
-// 刷新
+
 function onRefresh() {
   gridApi.query();
 }
 
-// 修改
-function onEditHandle(row?: SystemModel.User) {
-  // console.log('row', row);
+function onEditHandle(row?: SystemModel.Organization) {
   formModalApi.setData(row ?? {}).open();
 }
-
-// 删除
-async function onDeleteHandle(row: SystemModel.Organization) {
-  console.log('delete', row);
-  // const hideLoading = message.loading({
-  //   content: $t('ui.actionMessage.deleting', [row.name]),
-  //   duration: 0,
-  //   key: 'action_process_msg',
-  // });
-  // try {
-  //   await deleteOrganizationMethod(row);
-  //   message.success({
-  //     content: $t('ui.actionMessage.deleteSuccess', [row.name]),
-  //     key: 'action_process_msg',
-  //   });
-  //   // 删除之后重新刷新页面
-  //   onRefresh();
-  // } finally {
-  //   hideLoading();
-  // }
-}
 </script>
 <template>
   <Page auto-content-height>
     <FormModal @success="onRefresh" />
     <Grid>
-      <template #toolbar-tools>
-        <!-- <Button type="primary" @click="onEditHandle()">
-          <Plus class="size-5" />
-          {{ $t('ui.actionTitle.create', [$t('system.organization._')]) }}
-        </Button> -->
-      </template>
+      <template #toolbar-tools></template>
     </Grid>
   </Page>
 </template>

+ 7 - 5
apps/smart-pharmacy/src/views/system/organization/modules/form.vue

@@ -20,8 +20,8 @@ const emit = defineEmits(['success']);
 //   },
 // );
 const edit = {
-  send() {
-    console.log('修改,确定');
+  send(_data?: Partial<SystemModel.Organization>) {
+    console.warn('机构新增/编辑接口尚未对接', _data);
     return Promise.resolve();
   },
 };
@@ -63,13 +63,15 @@ const [Modal, modalApi] = useVbenModal({
       const data = modalApi.getData<SystemModel.Organization>();
       if (data) {
         if (data.id) {
-          // 编辑态:重建 schema,传入当前机构信息(id 与 name)以便过滤自身
           formApi.setState(() => ({
-            schema: useUserFormSchema({ id: data.id, name: data.name as any }),
+            schema: useUserFormSchema({ id: data.id, name: data.name }),
           }));
         }
         formData.value = data;
-        formApi.setValues(formData.value);
+        formApi.setValues({
+          ...data,
+          deptType: data.deptType,
+        });
       }
     }
   },