Просмотр исходного кода

Merge branch 'master' of http://192.168.100.32:3000/fanfan/xt-front

Tong 2 лет назад
Родитель
Сommit
7c50a79e0a

+ 6 - 0
src/api/biz/README.md

@@ -6,3 +6,9 @@
     - vascularAccessApi 血管通路
     - accessReturnApi 血透通路转归
     - accessComplicationApi 血管通路并发症
+    - diagnosisHistoryApi 诊断记录
+    - patientReturnApi 转归
+    - patrolWardApi 查房
+    - vitalsHistoryApi 历史体征数据
+  - bed 预约排床
+    - scheduledMemoApi 排床备忘录

+ 63 - 0
src/api/biz/bed/scheduledMemoApi.ts

@@ -0,0 +1,63 @@
+import { defHttp } from '/@/utils/http/axios';
+import { setParams } from '/@/utils/index';
+
+enum Api {
+  bedScheduledMemoQueryPage = '/bed/scheduledMemo/query/page',
+  bedScheduledMemoDetail = '/bed/scheduledMemo/detail',
+  bedScheduledMemoAdd = '/bed/scheduledMemo/add',
+  bedScheduledMemoEdit = '/bed/scheduledMemo/edit',
+  bedScheduledMemoRemove = '/bed/scheduledMemo/removeByIds',
+}
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 根据条件查询排床备忘录列表,权限 - scheduled:scheduledMemo:query
+ * @method: POST
+ */
+
+export const bedScheduledMemoQueryPage = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledMemoQueryPage, params: setParams(params) });
+};
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 根据id查询排床备忘录详细信息,权限 - scheduled:scheduledMemo:query
+ * @method: GET
+ * @param:  id 主键id
+ */
+export const bedScheduledMemoDetail = (id: string) => {
+  return defHttp.get({ url: Api.bedScheduledMemoDetail + '/' + id });
+};
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 添加排床备忘录,权限 - scheduled:scheduledMemo:add
+ * @method: POST
+ */
+export const bedScheduledMemoAdd = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledMemoAdd, params: params });
+};
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 通过主键id编辑排床备忘录,权限 - scheduled:scheduledMemo:edit
+ * @method: POST
+ */
+export const bedScheduledMemoEdit = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledMemoEdit, params: params });
+};
+
+/**
+ * @description: 删除,权限 - scheduled:scheduledMemo:remove
+ * @method: POST
+ */
+export const bedScheduledMemoRemove = (params: Array<string | number>) => {
+  return defHttp.post({ url: Api.bedScheduledMemoRemove, params: params });
+};

+ 73 - 0
src/api/biz/bed/scheduledPersonApi.ts

@@ -0,0 +1,73 @@
+import { defHttp } from '/@/utils/http/axios';
+import { setParams } from '/@/utils/index';
+
+enum Api {
+  bedScheduledPersonQueryPage = '/bed/scheduledPerson/query/page',
+  bedScheduledPersonDetail = '/bed/scheduledPerson/detail',
+  bedScheduledPersonAdd = '/bed/scheduledPerson/add',
+  bedScheduledPersonEdit = '/bed/scheduledPerson/edit',
+  bedScheduledPersonRemove = '/bed/scheduledPerson/removeByIds',
+  bedScheduledPersonStats = '/bed/scheduledPerson/stats',
+}
+
+/**
+ * @author fan
+ * @description 病人类型数量统计
+ * @returns
+ */
+export const bedScheduledPersonStats = () => {
+  return defHttp.post({ url: Api.bedScheduledPersonStats });
+};
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 根据条件查询排列表,权限 - scheduled:scheduledPerson:query
+ * @method: POST
+ */
+
+export const bedScheduledPersonQueryPage = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledPersonQueryPage, params: setParams(params) });
+};
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 根据id查询排详细信息,权限 - scheduled:scheduledPerson:query
+ * @method: GET
+ * @param:  id 主键id
+ */
+export const bedScheduledPersonDetail = (id: string) => {
+  return defHttp.get({ url: Api.bedScheduledPersonDetail + '/' + id });
+};
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 添加排,权限 - scheduled:scheduledPerson:add
+ * @method: POST
+ */
+export const bedScheduledPersonAdd = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledPersonAdd, params: params });
+};
+
+/**
+ *
+ * @author fan
+ * @date  2023/07/17 16:06
+ * @description: 通过主键id编辑排,权限 - scheduled:scheduledPerson:edit
+ * @method: POST
+ */
+export const bedScheduledPersonEdit = (params?: object) => {
+  return defHttp.post({ url: Api.bedScheduledPersonEdit, params: params });
+};
+
+/**
+ * @description: 删除,权限 - scheduled:scheduledPerson:remove
+ * @method: POST
+ */
+export const bedScheduledPersonRemove = (params: Array<string | number>) => {
+  return defHttp.post({ url: Api.bedScheduledPersonRemove, params: params });
+};

+ 2 - 0
src/components/Form/src/componentMap.ts

@@ -22,6 +22,7 @@ import {
 } from 'ant-design-vue';
 
 import ApiRadioGroup from './components/ApiRadioGroup.vue';
+import ApiCheckboxGroup from './components/ApiCheckboxGroup.vue';
 import ApiInputDict from './components/ApiInputDict.vue';
 import ApiComplex from './components/ApiComplex.vue';
 import RadioButtonGroup from './components/RadioButtonGroup.vue';
@@ -57,6 +58,7 @@ componentMap.set('ApiTree', ApiTree);
 componentMap.set('TreeSelect', TreeSelect);
 componentMap.set('ApiTreeSelect', ApiTreeSelect);
 componentMap.set('ApiRadioGroup', ApiRadioGroup);
+componentMap.set('ApiCheckboxGroup', ApiCheckboxGroup);
 componentMap.set('Switch', Switch);
 componentMap.set('RadioButtonGroup', RadioButtonGroup);
 componentMap.set('RadioDescGroup', RadioDescGroup);

+ 118 - 0
src/components/Form/src/components/ApiCheckboxGroup.vue

@@ -0,0 +1,118 @@
+<!--
+ * @Description:It is troublesome to implement Checkbox button group in the form. So it is extracted independently as a separate component
+-->
+<template>
+  <CheckboxGroup v-bind="attrs" v-model:value="state" @change="handleChange">
+    <template v-for="item in getOptions" :key="`${item.value}`">
+      <Checkbox :value="item.value" :disabled="item.disabled">
+        {{ item.label }}
+      </Checkbox>
+    </template>
+  </CheckboxGroup>
+</template>
+<script lang="ts">
+  import { defineComponent, PropType, ref, watchEffect, computed, unref, watch } from 'vue';
+  import { Checkbox, CheckboxGroup } from 'ant-design-vue';
+  import { isFunction } from '/@/utils/is';
+  import { useRuleFormItem } from '/@/hooks/component/useFormItem';
+  import { useAttrs } from '/@/hooks/core/useAttrs';
+  import { propTypes } from '/@/utils/propTypes';
+  import { get, omit } from 'lodash-es';
+  type OptionsItem = { label: string; value: string | number | boolean; disabled?: boolean };
+
+  export default defineComponent({
+    name: 'ApiCheckboxGroup',
+    components: {
+      CheckboxGroup,
+      Checkbox,
+    },
+    props: {
+      api: {
+        type: Function as PropType<(arg?: Recordable | string) => Promise<OptionsItem[]>>,
+        default: null,
+      },
+      params: {
+        type: [Object, String] as PropType<Recordable | string>,
+        default: () => ({}),
+      },
+      value: [Array, Object, String, Number],
+      numberToString: propTypes.bool,
+      resultField: propTypes.string.def(''),
+      labelField: propTypes.string.def('label'),
+      valueField: propTypes.string.def('value'),
+      immediate: propTypes.bool.def(true),
+    },
+    emits: ['options-change', 'change'],
+    setup(props, { emit }) {
+      const options = ref<OptionsItem[]>([]);
+      const loading = ref(false);
+      const isFirstLoad = ref(true);
+      const emitData = ref<any[]>([]);
+      const attrs = useAttrs();
+      // Embedded in the form, just use the hook binding to perform form verification
+      const [state] = useRuleFormItem(props);
+
+      // Processing options value
+      const getOptions = computed(() => {
+        const { labelField, valueField, numberToString } = props;
+
+        return unref(options).reduce((prev, next: Recordable) => {
+          if (next) {
+            const value = next[valueField];
+            prev.push({
+              label: next[labelField],
+              value: numberToString ? `${value}` : value,
+              ...omit(next, [labelField, valueField]),
+            });
+          }
+          return prev;
+        }, [] as OptionsItem[]);
+      });
+
+      watchEffect(() => {
+        props.immediate && fetch();
+      });
+
+      watch(
+        () => props.params,
+        () => {
+          !unref(isFirstLoad) && fetch();
+        },
+        { deep: true },
+      );
+
+      async function fetch() {
+        const api = props.api;
+        if (!api || !isFunction(api)) return;
+        options.value = [];
+        try {
+          loading.value = true;
+          const res = await api(props.params);
+          if (Array.isArray(res)) {
+            options.value = res;
+            emitChange();
+            return;
+          }
+          if (props.resultField) {
+            options.value = get(res, props.resultField) || [];
+          }
+          emitChange();
+        } catch (error) {
+          console.warn(error);
+        } finally {
+          loading.value = false;
+        }
+      }
+
+      function emitChange() {
+        emit('options-change', unref(getOptions));
+      }
+
+      function handleChange(_, ...args) {
+        emitData.value = args;
+      }
+
+      return { state, getOptions, attrs, loading, handleChange, props };
+    },
+  });
+</script>

+ 1 - 1
src/components/Form/src/hooks/useFormEvents.ts

@@ -107,7 +107,7 @@ export function useFormEvents({
         });
       }
     });
-    validateFields(validKeys).catch(_ => { });
+    validateFields(validKeys).catch(_ => {});
   }
   /**
    * @description: Delete based on field name

+ 1 - 0
src/components/Form/src/types/index.ts

@@ -94,6 +94,7 @@ export type ComponentType =
   | 'ApiTree'
   | 'ApiTreeSelect'
   | 'ApiRadioGroup'
+  | 'ApiCheckboxGroup'
   | 'RadioButtonGroup'
   | 'RadioGroup'
   | 'Checkbox'

+ 1 - 1
src/views/biz/archives/diagnosisHistory/data.ts

@@ -308,7 +308,7 @@ export const columnsMulti: BasicColumn[] = [
   {
     title: '名称',
     dataIndex: 'name',
-    width: 220,
+    width: 200,
     edit: true,
     editable: true,
     editComponent: 'Select',

+ 7 - 4
src/views/biz/archives/formula/FormDrawer.vue

@@ -66,6 +66,7 @@
     archivesFormulaTemplateEdit,
   } from '@/api/biz/archives/formulaTemplateApi';
   import FormDrawerHistory from './FormDrawerHistory.vue';
+  import dayjs from 'dayjs';
   const emit = defineEmits(['success', 'register']);
 
   const getTitle = ref('透析处方');
@@ -108,13 +109,14 @@
     console.log('🚀 ~ file: FormDrawer.vue:49 ~ data:', data);
     await resetFields();
     setDrawerProps({ confirmLoading: false });
-    isUpdate.value = data?.isUpdate;
+    isUpdate.value = data.isUpdate;
     getTitle.value = `${isUpdate.value ? '编辑透析处方模板' : '新建透析处方模板'} ( ${
       data.record.name
     } | ${data.record.gender} | ${data.record.age}岁 )`;
     bizDictOptions.accessType = await listDictModel({ dictCode: 'va_type' });
     patientBasicId.value = data.record.patientBasicId;
     rowId.value = data.record?.id;
+    console.log('unref(isUpdate)', unref(isUpdate));
     if (unref(isUpdate)) {
       const resData = await archivesFormulaTemplateDetail(rowId.value);
       if (resData.suppliesTemplate) {
@@ -128,9 +130,6 @@
         await nextTick();
         await setTableData(tableData.value);
       }
-      // delete resData.suppliesTemplate;
-      // console.log('🚀 ~ file: FormDrawer.vue:119 ~ resData:', resData);
-      // const fieldData = resData.
       await setFieldsValue({
         ...resData,
       });
@@ -149,6 +148,10 @@
           },
         });
       }
+    } else {
+      await setFieldsValue({
+        enactedTime: dayjs().format('YYYY-MM-DD'),
+      });
     }
   });
 

+ 6 - 2
src/views/biz/archives/formula/data.ts

@@ -92,8 +92,12 @@ export const dataFormSchema: FormSchema[] = [
     field: 'enactedTime',
     required: true,
     component: 'DatePicker',
-    componentProps: {
-      placeholder: '请输入制定日期',
+    componentProps: () => {
+      return {
+        placeholder: '请输入制定日期',
+        getPopupContainer: () => document.body,
+        valueFormat: 'YYYY-MM-DD',
+      };
     },
   },
   {

+ 3 - 2
src/views/biz/archives/formula/index.vue

@@ -118,13 +118,14 @@
     });
     console.log('🚀 ~ file: index.vue:168 ~ getData ~ timeLineData.value :', timeLineData.value);
   }
-  function handleAdd(data) {
-    console.log('🚀 ~ file: index.vue:205 ~ handleAdd ~ data:', data);
+  function handleAdd() {
     const info = {
       ...props.info,
       patientBasicId: props.info.id,
     };
+    console.log('🚀 ~ file: index.vue:205 ~ handleAdd ~ data:', info);
     openDrawer(true, {
+      isUpdate: false,
       record: { ...info },
     });
   }

+ 27 - 17
src/views/biz/archives/index/index.vue

@@ -30,7 +30,17 @@
             }}
           </template>
           <template v-if="column.key === 'gender'">
-            {{ formatDictValue(bizDictOptions.gender, record.gender) }}
+            <span
+              :style="{
+                backgroundColor: formatDictColor(bizDictOptions.gender, record.gender),
+                color: formatDictFontColor(bizDictOptions.gender, record.gender),
+                padding: '1px 6px',
+                borderRadius: '2px',
+                marginRight: '4px',
+              }"
+            >
+              {{ formatDictValue(bizDictOptions.gender, record.gender) }}
+            </span>
           </template>
           <template v-if="column.key === 'firstDialysisType'">
             {{ formatDictValue(bizDictOptions.firstDialysisType, record.firstDialysisType) }}
@@ -39,22 +49,22 @@
             {{ formatDictValue(bizDictOptions.type, record.type) }}
           </template>
           <template v-if="column.key === 'infectiousDiseases'">
-            <span
-              :style="{
-                backgroundColor: formatDictColor(
-                  bizDictOptions.infectiousDiseases,
-                  record.infectiousDiseases,
-                ),
-                color: formatDictFontColor(
-                  bizDictOptions.infectiousDiseases,
-                  record.infectiousDiseases,
-                ),
-                padding: '1px 4px',
-                borderRadius: '6px',
-              }"
-            >
-              {{ formatDictValue(bizDictOptions.infectiousDiseases, record.infectiousDiseases) }}
-            </span>
+            <div class="flex">
+              <div
+                v-for="item in record.infectiousDiseases"
+                :key="item"
+                :style="{
+                  backgroundColor: formatDictColor(bizDictOptions.infectiousDiseases, item),
+                  color: formatDictFontColor(bizDictOptions.infectiousDiseases, item),
+                  padding: '1px 6px',
+                  borderRadius: '2px',
+                  marginRight: '4px',
+                }"
+              >
+                <!-- {{ record.infectiousDiseases }} -->
+                {{ formatDictValue(bizDictOptions.infectiousDiseases, item) }}
+              </div>
+            </div>
           </template>
           <template v-if="column.key === 'vascularAccess'">
             {{ formatDictValue(bizDictOptions.vascularAccess, record.vascularAccess) }}

+ 2 - 1
src/views/biz/archives/patientBasic/index.vue

@@ -137,6 +137,7 @@
           return ele;
         })) ||
       [];
+    basicData.value[2].data = [];
     // 诊断记录
     const DiagnosisHistoryMulti = await archivesDiagnosisHistoryQueryListMulti(props.info?.id);
     console.log(
@@ -176,7 +177,7 @@
     //   [];
     // const mapData = [];
     for (const i in DiagnosisHistoryMulti) {
-      console.log('🚀 ~ file: index.vue:178 ~ getData ~  i:', i);
+      // console.log('🚀 ~ file: index.vue:178 ~ getData ~  i:', i);
       getDiagnosisMulti(DiagnosisHistoryMulti[i], i);
     }
     const firstDialysisRes = await archivesDiagnosisHistoryQueryListSingle(props.info?.id);

+ 6 - 0
src/views/biz/archives/patientReturn/FormModal.vue

@@ -25,6 +25,7 @@
     archivesPatientReturnEdit,
     archivesPatientReturnDetail,
   } from '/@/api/biz/archives/patientReturnApi';
+  import dayjs from 'dayjs';
 
   const emit = defineEmits(['success', 'register']);
 
@@ -48,12 +49,17 @@
     setModalProps({ confirmLoading: false });
     isUpdate.value = !!data?.isUpdate;
     patientBasicId.value = data.record?.patientBasicId;
+
     if (unref(isUpdate)) {
       const resData = await archivesPatientReturnDetail(data.record.id);
       rowId.value = resData.id;
       await setFieldsValue({
         ...resData,
       });
+    } else {
+      await setFieldsValue({
+        returnTime: dayjs().format('YYYY-MM-DD'),
+      });
     }
   });
 

+ 1 - 0
src/views/biz/archives/vascularAccess/FormModal.vue

@@ -57,6 +57,7 @@
     if (unref(isUpdate)) {
       const resData = await archivesVascularAccessDetail(patientBasicId.value);
       rowId.value = resData.id;
+      patientBasicId.value = resData.patientBasicId;
       resData.accessType = resData.type;
       accessType.value = formatDictValue(bizDictOptions.accessType, resData.type);
       await setFieldsValue({

+ 3 - 0
src/views/biz/archives/vascularAccess/data.ts

@@ -188,6 +188,7 @@ export const dataFormSchemaVascularAccess: FormSchema[] = [
   {
     label: '手术部位 (动脉)',
     field: 'arteries',
+    required: true,
     component: 'ApiRadioGroup',
     componentProps: ({ formModel }) => {
       return {
@@ -209,6 +210,7 @@ export const dataFormSchemaVascularAccess: FormSchema[] = [
   {
     label: '手术部位 (静脉)',
     field: 'vein',
+    required: true,
     component: 'ApiRadioGroup',
     componentProps: ({ formModel }) => {
       return {
@@ -229,6 +231,7 @@ export const dataFormSchemaVascularAccess: FormSchema[] = [
   {
     label: '路径',
     field: 'path',
+    required: true,
     component: 'ApiRadioGroup',
     componentProps: ({ formModel }) => {
       return {

+ 80 - 0
src/views/biz/bed/memo/FormModal.vue

@@ -0,0 +1,80 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    destroyOnClose
+    @register="registerModal"
+    :title="getTitle"
+    :width="width"
+    @ok="handleSubmit"
+    :showFooter="true"
+  >
+    <BasicForm @register="registerForm" layout="vertical" class="!px-6 !pt-4" />
+  </BasicModal>
+</template>
+<script lang="ts" setup>
+  import { ref, computed, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { dataFormSchema } from './data';
+
+  import {
+    bedScheduledMemoAdd,
+    bedScheduledMemoEdit,
+    bedScheduledMemoDetail,
+  } from '/@/api/biz/bed/scheduledMemoApi';
+  import dayjs from 'dayjs';
+
+  const emit = defineEmits(['success', 'register']);
+
+  const getTitle = computed(() => (!unref(isUpdate) ? '新增排床备忘录' : '编辑排床备忘录'));
+  const width = '30%';
+  const isUpdate = ref(false);
+  const rowId = ref();
+
+  const { createMessage } = useMessage();
+  const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+    labelWidth: 100,
+    schemas: dataFormSchema,
+    showActionButtonGroup: false,
+    actionColOptions: {
+      span: 23,
+    },
+  });
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {
+    await resetFields();
+    setModalProps({ confirmLoading: false });
+    isUpdate.value = !!data?.isUpdate;
+
+    if (unref(isUpdate)) {
+      const resData = await bedScheduledMemoDetail(data.record.id);
+      rowId.value = resData.id;
+      await setFieldsValue({
+        ...resData,
+      });
+    } else {
+      await setFieldsValue({
+        appointmentDate: dayjs().format('YYYY-MM-DD'),
+      });
+    }
+  });
+
+  // 提交按钮事件
+  async function handleSubmit() {
+    try {
+      const values = await validate();
+      setModalProps({ confirmLoading: true });
+      !unref(isUpdate)
+        ? await bedScheduledMemoAdd({ ...values })
+        : await bedScheduledMemoEdit({ ...values, id: rowId.value });
+      !unref(isUpdate) ? createMessage.success('新增成功!') : createMessage.success('编辑成功!');
+      closeModal();
+      emit('success', {
+        isUpdate: unref(isUpdate),
+        values: { ...values, id: rowId.value },
+      });
+    } finally {
+      setModalProps({ confirmLoading: false });
+    }
+  }
+</script>

+ 113 - 0
src/views/biz/bed/memo/data.ts

@@ -0,0 +1,113 @@
+import dayjs from 'dayjs';
+import { BasicColumn, FormSchema } from '/@/components/Table';
+import { archivesPatientBasicQueryPage } from '@/api/biz/archives/patientBasicApi';
+
+export const columns: BasicColumn[] = [
+  {
+    title: '填写日期',
+    dataIndex: 'createTime',
+  },
+  {
+    title: '患者信息',
+    dataIndex: 'patientInfo',
+  },
+  {
+    title: '预约日期',
+    dataIndex: 'appointmentDate',
+  },
+  {
+    title: '预约班次',
+    dataIndex: 'appointmentSailingsName',
+  },
+  {
+    title: '备注',
+    dataIndex: 'remark',
+  },
+  {
+    title: '记录人',
+    dataIndex: 'creatorName',
+  },
+  {
+    title: '待办处理人',
+    dataIndex: 'todoName',
+  },
+];
+
+// 表单新增编辑
+export const dataFormSchema: FormSchema[] = [
+  {
+    label: '患者名称搜索',
+    field: 'patientBasicName',
+    component: 'Input',
+    ifShow: false,
+  },
+  {
+    label: '患者姓名',
+    field: 'patientBasicId',
+    required: true,
+    component: 'ApiSelect',
+    componentProps: ({ formModel }) => {
+      return {
+        api: archivesPatientBasicQueryPage,
+        params: {
+          name: formModel.patientBasicName,
+        },
+        labelField: 'name',
+        valueField: 'id',
+        resultField: 'data',
+        placeholder: '请输入患者姓名',
+        getPopupContainer: () => document.body,
+        showSearch: true,
+        filterOption: false,
+        onSearch: e => {
+          console.log('🚀 ~ file: data.ts:66 ~ e:', e);
+          formModel.patientBasicName = e;
+        },
+      };
+    },
+  },
+  {
+    label: '预约日期',
+    field: 'appointmentDate',
+    required: true,
+    component: 'DatePicker',
+    componentProps: {
+      placeholder: '请输入预约日期',
+      getPopupContainer: () => document.body,
+      valueFormat: 'YYYY-MM-DD',
+      disabledDate: current => {
+        return current < dayjs().subtract(1, 'day').endOf('day');
+      },
+    },
+  },
+  {
+    label: '预约班次',
+    field: 'appointmentSailingsSort',
+    required: true,
+    component: 'CheckboxGroup',
+    componentProps: {
+      options: [
+        {
+          label: '第一班',
+          value: '1',
+        },
+        {
+          label: '第二班',
+          value: '2',
+        },
+        {
+          label: '第三班',
+          value: '3',
+        },
+      ],
+    },
+  },
+  {
+    label: '备注',
+    field: 'remark',
+    component: 'InputTextArea',
+    componentProps: {
+      placeholder: '请输入备注',
+    },
+  },
+];

+ 148 - 3
src/views/biz/bed/memo/index.vue

@@ -1,7 +1,152 @@
 <template>
-  <div> 占位符 </div>
+  <div class="m-4">
+    <div class="mb-2">
+      <XTTitle title="排床备忘录" :right-data="titleData" @click="callTitleClick" />
+    </div>
+    <BasicTable @register="registerTable">
+      <template #bodyCell="{ column, record }">
+        <template v-if="column.key === 'createTime'">
+          {{ record.createTime ? dayjs(record.createTime).format('YYYY-MM-DD') : '' }}
+        </template>
+        <template v-if="column.key === 'appointmentDate'">
+          {{ record.appointmentDate ? dayjs(record.appointmentDate).format('YYYY-MM-DD') : '' }}
+        </template>
+        <template v-if="column.key === 'appointmentSailingsName'">
+          <span v-for="(item, index) in record.appointmentSailingsName" :key="item">
+            {{ item }}
+            {{ index == record.appointmentSailingsName.length - 1 ? '' : '、' }}
+          </span>
+        </template>
+        <template v-if="column.key === 'patientInfo'">
+          {{ record.patientName }}/
+          {{ formatDictValue(bizDictOptions.gender, record.patientGender) }}/
+          {{ record.age }}
+        </template>
+        <template v-if="column.key === 'action'">
+          <TableAction
+            :actions="[
+              {
+                auth: 'bed:scheduledMemo:remove',
+                icon: 'icon-xt-details_delete_default|iconfont',
+                tooltip: '删除',
+                popConfirm: {
+                  title: '是否确认删除',
+                  placement: 'left',
+                  confirm: handleDelete.bind(null, record),
+                },
+              },
+            ]"
+          />
+        </template>
+      </template>
+    </BasicTable>
+    <FormModal @register="registerModal" @success="callSuccess" />
+  </div>
 </template>
+<script lang="ts" setup>
+  import { onMounted, reactive, ref } from 'vue';
 
-<script setup lang="ts"></script>
+  import { BasicTable, useTable, TableAction } from '/@/components/TableCard';
+  import { XTTitle } from '/@/components/XTTitle/index';
+  // import { useModal } from '/@/components/Modal';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import FormModal from './FormModal.vue';
+  import { columns } from './data';
 
-<style lang="less" scoped></style>
+  import {
+    bedScheduledMemoQueryPage,
+    bedScheduledMemoRemove,
+  } from '/@/api/biz/bed/scheduledMemoApi';
+  import { listDictModelBatch } from '/@/api/common';
+  import { formatDictValue } from '/@/utils';
+  import { useModal } from '@/components/Modal';
+  import dayjs from 'dayjs';
+
+  const { createConfirm, createMessage } = useMessage();
+  const [registerModal, { openModal }] = useModal();
+
+  const tableSort = ref([
+    {
+      field: 'create_time',
+      direction: 'DESC',
+    },
+  ]) as any;
+  const bizDictOptions = reactive<any>({});
+  const bizDictData = ref([{ key: 'gender', dictCode: 'pb_sex' }]);
+  onMounted(async () => {
+    const res = await listDictModelBatch(bizDictData.value.map(ele => ele.dictCode));
+    for (const i in res) {
+      const filter = bizDictData.value.filter(ele => ele.dictCode == i)[0];
+      bizDictOptions[filter.key] = res[i];
+    }
+  });
+  const [registerTable, { reload, getSelectRowKeys }] = useTable({
+    api: bedScheduledMemoQueryPage,
+    rowKey: 'id',
+    columns,
+    useSearchForm: false,
+    showIndexColumn: false,
+    actionColumn: {
+      width: 80,
+      title: '操作',
+      dataIndex: 'action',
+    },
+    beforeFetch: handleBeforeFetch,
+  });
+
+  // 标题数据
+  const titleData = [
+    {
+      type: 'add',
+      btnIcon: 'icon-xt-add_default',
+      btnText: '新增备忘录',
+    },
+  ];
+
+  // 新增按钮事件
+  function callTitleClick(data) {
+    if (data.type == 'add') {
+      openModal(true, {
+        isUpdate: false,
+        record: data,
+      });
+    }
+  }
+
+  // 删除按钮事件
+  async function handleDelete(record: Recordable) {
+    if (record) {
+      await bedScheduledMemoRemove([record.id]);
+      createMessage.success('删除成功!');
+      await reload();
+    } else {
+      createConfirm({
+        content: '你确定要删除?',
+        iconType: 'warning',
+        onOk: async () => {
+          const keys = getSelectRowKeys();
+          await bedScheduledMemoRemove(keys);
+          createMessage.success('删除成功!');
+          await reload();
+        },
+      });
+    }
+  }
+
+  // 表格请求之前,对参数进行处理, 添加默认 排序
+  function handleBeforeFetch(params) {
+    return { ...params, orders: tableSort.value };
+  }
+
+  // 弹窗回调事件
+  async function callSuccess({ isUpdate, values }) {
+    console.log(isUpdate);
+    console.log(values);
+    await reload();
+  }
+</script>
+<style lang="less" scoped>
+  ::v-deep(.ant-btn-link) {
+    color: rgb(61 65 85 / 100%);
+  }
+</style>

+ 101 - 0
src/views/biz/bed/person/FormModal.vue

@@ -0,0 +1,101 @@
+<template>
+  <BasicModal
+    v-bind="$attrs"
+    destroyOnClose
+    @register="registerModal"
+    :title="getTitle"
+    :width="width"
+    @ok="handleSubmit"
+    :showFooter="true"
+  >
+    <BasicForm @register="registerForm" layout="vertical" class="!px-6 !pt-4" />
+  </BasicModal>
+</template>
+<script lang="ts" setup>
+  import { ref, unref } from 'vue';
+  import { BasicModal, useModalInner } from '/@/components/Modal';
+  import { BasicForm, useForm } from '/@/components/Form';
+  import { useMessage } from '/@/hooks/web/useMessage';
+  import { dataFormSchema } from './data';
+
+  import {
+    bedScheduledPersonAdd,
+    bedScheduledPersonEdit,
+    bedScheduledPersonDetail,
+  } from '/@/api/biz/bed/scheduledPersonApi';
+  import dayjs from 'dayjs';
+
+  const emit = defineEmits(['success', 'register']);
+
+  const getTitle = ref();
+  const width = '45%';
+  const isUpdate = ref(false);
+  const rowId = ref();
+
+  const { createMessage } = useMessage();
+  const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
+    labelWidth: 100,
+    schemas: dataFormSchema,
+    showActionButtonGroup: false,
+    baseColProps: {
+      span: 12,
+    },
+  });
+  const [registerModal, { setModalProps, closeModal }] = useModalInner(async data => {
+    await resetFields();
+    setModalProps({ confirmLoading: false });
+    isUpdate.value = !!data?.isUpdate;
+    getTitle.value = `${isUpdate.value ? '编辑排班' : '新建排班'} ( ${data.record.patientName} | ${
+      data.record.gender
+    } | ${data.record.age}岁 )`;
+
+    if (unref(isUpdate)) {
+      const resData = await bedScheduledPersonDetail(data.record.id);
+      console.log('🚀 ~ file: FormModal.vue:54 ~ resData:', resData);
+      rowId.value = resData.id;
+      const fieldsData = Object.assign(resData, {
+        frequency: {
+          input: 1,
+          dictValue: resData.frequency?.week == 1 ? 'week_1' : 'week_2',
+        },
+      });
+      console.log('🚀 ~ file: FormModal.vue:62 ~ fieldsData:', fieldsData);
+      await setFieldsValue({
+        ...fieldsData,
+        // ...resData,
+        // machine: ['pump_single'],
+        // patientUniqueNo: resData.patientUniqueNo,
+        // archivesCreateTime: resData.archivesCreateTime,
+        // patientType: resData.patientType,
+        // special: resData.special,
+        // frequency: {
+        //   input: 1,
+        //   dictValue: resData.frequency?.week == 1 ? 'week_1' : 'week_2',
+        // },
+      });
+    } else {
+      await setFieldsValue({
+        appointmentDate: dayjs().format('YYYY-MM-DD'),
+      });
+    }
+  });
+
+  // 提交按钮事件
+  async function handleSubmit() {
+    try {
+      const values = await validate();
+      setModalProps({ confirmLoading: true });
+      !unref(isUpdate)
+        ? await bedScheduledPersonAdd({ ...values })
+        : await bedScheduledPersonEdit({ ...values, id: rowId.value });
+      !unref(isUpdate) ? createMessage.success('新增成功!') : createMessage.success('编辑成功!');
+      closeModal();
+      emit('success', {
+        isUpdate: unref(isUpdate),
+        values: { ...values, id: rowId.value },
+      });
+    } finally {
+      setModalProps({ confirmLoading: false });
+    }
+  }
+</script>

+ 256 - 0
src/views/biz/bed/person/data.ts

@@ -0,0 +1,256 @@
+import { BasicColumn, FormSchema } from '/@/components/Table';
+import { listDictModel } from '@/api/common';
+
+// export const BasicWeek = [
+//   {
+//     field: 'monday',
+//     label: '星期一',
+//   },
+//   {
+//     field: 'tuesday',
+//     label: '星期二',
+//   },
+//   {
+//     field: 'wednesday',
+//     label: '星期三',
+//   },
+//   {
+//     field: 'thursday',
+//     label: '星期四',
+//   },
+//   {
+//     field: 'friday',
+//     label: '星期五',
+//   },
+//   {
+//     field: 'saturday',
+//     label: '星期六',
+//   },
+//   {
+//     field: 'sunday',
+//     label: '星期日',
+//   },
+// ];
+export enum BasicWeekEnum {
+  monday = '星期一',
+  monday_field = 'monday',
+  tuesday = '星期二',
+  tuesday_field = 'tuesday',
+  wednesday = '星期三',
+  wednesday_field = 'wednesday',
+  thursday = '星期四',
+  thursday_field = 'thursday',
+  friday = '星期五',
+  friday_field = 'friday',
+  saturday = '星期六',
+  saturday_field = 'saturday',
+  sunday = '星期日',
+  sunday_field = 'sunday',
+}
+
+export const BasicTab = [
+  {
+    key: '0',
+    label: '全部',
+    value: 0,
+    hasValue: true,
+    hasBracket: true,
+  },
+  {
+    key: '1',
+    label: '新患者',
+    value: 12,
+    hasValue: true,
+    prefixColor: '#1BC1B3',
+    // valueColor: 'red',
+    hasBracket: true,
+  },
+  {
+    key: '2',
+    label: '无排班患者',
+    value: 0,
+    hasValue: true,
+    prefixColor: '#F7B500',
+    hasBracket: true,
+  },
+];
+export const BasicTabActive = BasicTab[0].key;
+
+export const columns: BasicColumn[] = [
+  {
+    title: '编号',
+    dataIndex: 'patientUniqueNo',
+    align: 'left',
+    width: 160,
+  },
+  {
+    title: '姓名',
+    dataIndex: 'patientName',
+    align: 'left',
+    width: 120,
+  },
+  {
+    title: '性别',
+    dataIndex: 'patientGender',
+    align: 'left',
+    width: 80,
+  },
+  {
+    title: '年龄',
+    dataIndex: 'age',
+    align: 'left',
+    width: 80,
+  },
+  {
+    title: '建档时间',
+    dataIndex: 'archivesCreateTime',
+    align: 'left',
+    width: 200,
+  },
+  {
+    title: '类型',
+    dataIndex: 'patientType',
+    align: 'left',
+    width: 100,
+  },
+  {
+    title: '透析机器',
+    dataIndex: 'machine',
+    align: 'left',
+    width: 130,
+  },
+  {
+    title: '透析频率',
+    dataIndex: 'frequency',
+    align: 'left',
+    width: 120,
+  },
+  {
+    title: '特殊时间需求',
+    dataIndex: 'specialNeed',
+    align: 'left',
+    // width: 300,
+  },
+];
+
+// 表单新增编辑
+export const dataFormSchema: FormSchema[] = [
+  {
+    label: '编号',
+    field: 'patientUniqueNo',
+    component: 'PlainText',
+  },
+  {
+    label: '建档时间',
+    field: 'archivesCreateTime',
+    component: 'PlainText',
+  },
+  {
+    label: '类型',
+    field: 'patientType',
+    component: 'ApiSelect',
+    componentProps: {
+      api: listDictModel,
+      params: {
+        dictCode: 'pb_type',
+      },
+      disabled: true,
+    },
+  },
+  {
+    label: '透析机器',
+    field: 'machine',
+    component: 'ApiCheckboxGroup',
+    componentProps: {
+      api: listDictModel,
+      params: {
+        dictCode: 'bm_pump',
+      },
+    },
+  },
+  {
+    field: 'frequency',
+    label: '透析频次(次/周)',
+    component: 'ApiInputDict',
+    componentProps: ({ formModel }) => {
+      return {
+        api: listDictModel,
+        params: {
+          dictCode: 'sp_week',
+          dictSort: true,
+        },
+        onChange: e => {
+          console.log('🚀 ~ file: data.ts:81 ~ e:', e);
+          return (formModel['frequency'] = e);
+        },
+      };
+    },
+  },
+  {
+    label: '特殊时间需求',
+    field: 'special',
+    component: 'RadioGroup',
+    componentProps: {
+      options: [
+        { label: '无', value: 0 },
+        { label: '有', value: 1 },
+      ],
+    },
+  },
+  {
+    label: '期望周次',
+    field: 'specialNeedWeek',
+    required: true,
+    component: 'CheckboxGroup',
+    componentProps: {
+      options: [
+        {
+          label: '第一班',
+          value: '1',
+        },
+        {
+          label: '第二班',
+          value: '2',
+        },
+        {
+          label: '第三班',
+          value: '3',
+        },
+      ],
+    },
+    show: ({ values }) => {
+      return values.special == 1;
+    },
+    colProps: {
+      span: 24,
+    },
+  },
+  {
+    label: '期望班次',
+    field: 'sailingSorts',
+    required: true,
+    component: 'CheckboxGroup',
+    componentProps: {
+      options: [
+        {
+          label: '第一班',
+          value: '1',
+        },
+        {
+          label: '第二班',
+          value: '2',
+        },
+        {
+          label: '第三班',
+          value: '3',
+        },
+      ],
+    },
+    show: ({ values }) => {
+      return values.special == 1;
+    },
+    colProps: {
+      span: 24,
+    },
+  },
+];

+ 298 - 3
src/views/biz/bed/person/index.vue

@@ -1,7 +1,302 @@
 <template>
-  <div> 占位符 </div>
+  <div class="m-4">
+    <div>
+      <XTTitle title="个人排班" />
+      <div class="flex justify-between my-4">
+        <XTTab
+          type="illness"
+          :width="158"
+          :selected="activeKey"
+          :data="tabData"
+          @item-click="callTab"
+        />
+        <XTForm :form-data="formData" @change="callFormChange" />
+      </div>
+      <BasicTable @register="registerTable">
+        <template #bodyCell="{ column, record }">
+          <template v-if="column.key === 'name'">
+            <span :class="['table-dot', 'table-dot--' + record.status]" />
+            <span>{{ record.name }}</span>
+          </template>
+          <template v-if="column.key === 'patientGender'">
+            <span
+              :style="{
+                backgroundColor: formatDictColor(bizDictOptions.gender, record.patientGender),
+                color: formatDictFontColor(bizDictOptions.gender, record.patientGender),
+                padding: '1px 6px',
+                borderRadius: '2px',
+                marginRight: '4px',
+              }"
+            >
+              {{ formatDictValue(bizDictOptions.gender, record.patientGender) }}
+            </span>
+          </template>
+          <template v-if="column.key === 'patientType'">
+            {{ formatDictValue(bizDictOptions.type, record.patientType) }}
+          </template>
+          <!-- <template v-if="column.key === 'infectiousDiseases'">
+            <div class="flex">
+              <div
+                v-for="item in record.infectiousDiseases"
+                :key="item"
+                :style="{
+                  backgroundColor: formatDictColor(bizDictOptions.infectiousDiseases, item),
+                  color: formatDictFontColor(bizDictOptions.infectiousDiseases, item),
+                  padding: '1px 6px',
+                  borderRadius: '2px',
+                  marginRight: '4px',
+                }"
+              >
+                {{ formatDictValue(bizDictOptions.infectiousDiseases, item) }}
+              </div>
+            </div>
+          </template> -->
+          <template v-if="column.key === 'frequency'">
+            <span v-if="record.frequency">
+              {{ record.frequency?.times }}次/{{ record.frequency?.week }}周
+            </span>
+            <span v-else> 无 </span>
+          </template>
+          <template v-if="column.key === 'machine' && record.machine.length">
+            <div class="flex">
+              <div v-for="(item, index) in record.machine" :key="item" class="inline-flex">
+                <i
+                  v-if="item == 'pump_dual'"
+                  class="mr-1 iconfont icon-xt-dual-pump_default color-man"
+                />
+                {{ formatDictValue(bizDictOptions.pump, item) }}
+                <span v-if="index < record.machine.length - 1">、</span>
+              </div>
+            </div>
+          </template>
+          <template v-if="column.key === 'specialNeed'">
+            <div class="flex table-special">
+              <div class="inline-flex">
+                {{ record.specialNeedWeek }}
+              </div>
+              <div class="divider" v-if="record.specialNeedSailingSorts?.length" />
+              <div class="inline-flex"> 第二班、第三班 </div>
+            </div>
+          </template>
+          <template v-if="column.key === 'action'">
+            <TableAction
+              :actions="[
+                {
+                  auth: 'sys:log:query',
+                  icon: 'icon-xt-details_edit_default|iconfont',
+                  tooltip: '编辑',
+                  onClick: handleEdit.bind(null, record),
+                },
+                {
+                  auth: 'sys:log:query',
+                  disabled: !record.frequency,
+                  icon: 'icon-xt-bed_default|iconfont',
+                  tooltip: '排班',
+                  onClick: handleEdit.bind(null, record),
+                },
+                // {
+                //   auth: 'sys:log:query',
+                //   icon: 'icon-xt-details_delete_default|iconfont',
+                //   tooltip: '删除',
+                //   popConfirm: {
+                //     title: '是否确认删除',
+                //     placement: 'left',
+                //     confirm: handleDelete.bind(null, record),
+                //   },
+                // },
+              ]"
+            />
+          </template>
+        </template>
+      </BasicTable>
+    </div>
+    <FormModal @register="registerModal" @success="callSuccess" />
+  </div>
 </template>
 
-<script setup lang="ts"></script>
+<script setup lang="ts">
+  import { XTTitle } from '/@/components/XTTitle/index';
+  import { XTTab } from '/@/components/XTTab/index';
+  import { XTForm } from '/@/components/XTForm/index';
+  import { BasicTable, useTable, TableAction } from '/@/components/TableCard';
+  import { BasicTab, BasicTabActive, BasicWeekEnum, columns } from './data';
+  import { ref } from 'vue';
+  import {
+    bedScheduledPersonQueryPage,
+    bedScheduledPersonStats,
+    // bedScheduledPersonRemove,
+  } from '/@/api/biz/bed/scheduledPersonApi';
+  import { listDictModelBatch } from '@/api/common';
+  import { formatDictColor, formatDictFontColor, formatDictValue } from '/@/utils';
+  import { onMounted, reactive } from 'vue';
+  import { useModal } from '/@/components/Modal';
+  import FormModal from './FormModal.vue';
+  // import { useMessage } from '@/hooks/web/useMessage';
+  const bizDictOptions = reactive<any>({});
+  const bizDictData = ref([
+    { key: 'gender', dictCode: 'pb_sex' },
+    { key: 'type', dictCode: 'pb_type' },
+    { key: 'pump', dictCode: 'bm_pump' },
+  ]);
+  const activeKey = ref(BasicTabActive);
+  const tabData = ref(BasicTab);
+  const [registerModal, { openModal }] = useModal();
+  // const { createMessage } = useMessage();
 
-<style lang="less" scoped></style>
+  onMounted(async () => {
+    const res = await listDictModelBatch(bizDictData.value.map(ele => ele.dictCode));
+    for (const i in res) {
+      const filter = bizDictData.value.filter(ele => ele.dictCode == i)[0];
+      bizDictOptions[filter.key] = res[i];
+    }
+    const stats = await bedScheduledPersonStats();
+    tabData.value = tabData.value.map(ele => {
+      if (ele.key == '0') {
+        ele.value = stats.all;
+      }
+      if (ele.key == '1') {
+        ele.value = stats.newPatient;
+      }
+      if (ele.key == '2') {
+        ele.value = stats.noneScheduled;
+      }
+      return ele;
+    });
+  });
+  const [registerTable, { reload }] = useTable({
+    api: bedScheduledPersonQueryPage,
+    rowKey: 'id',
+    columns,
+    showIndexColumn: true,
+    bordered: true,
+    actionColumn: {
+      width: 100,
+      title: '操作',
+      dataIndex: 'action',
+      fixed: 'right',
+    },
+    beforeFetch: handleBeforeFetch,
+    afterFetch: handleAfterFetch,
+  });
+  // 筛选数据
+  const formData = ref([
+    {
+      name: 'tableSort',
+      componentType: 'Select',
+      placeholder: '请选择',
+      width: 120,
+      defaultValue: 'archivesCreateTime',
+      dicts: [
+        { label: '建档时间', value: 'archivesCreateTime' },
+        { label: '按姓氏', value: 'patientNamePinyin' },
+      ],
+    },
+    {
+      name: 'patientName',
+      componentType: 'Input',
+      placeholder: '请输入患者姓名',
+      prefix: 'icon-xt-search',
+      width: 240,
+    },
+  ]);
+
+  const formValue = reactive({
+    patientName: '',
+    tableSort: 'archivesCreateTime',
+  }) as any;
+
+  // 表格请求之前,对参数进行处理, 添加默认 排序
+  function handleBeforeFetch(params) {
+    return {
+      ...params,
+      // queryType: activeKey.value == '0' ? '0' : activeKey.value,
+      patientName: formValue.patientName,
+      orders: [{ field: formValue.tableSort, direction: 'DESC' }],
+    };
+  }
+
+  function handleAfterFetch(data) {
+    console.log('🚀 ~ file: index.vue:238 ~ handleAfterFetch ~ data:', data);
+    const res = data.map(ele => {
+      ele.specialNeedWeek = '';
+      for (const i in ele.specialNeed) {
+        if (ele.specialNeed[i] && i != 'sailingSorts') {
+          ele.specialNeedWeek = ele.specialNeedWeek.concat('、', BasicWeekEnum[i]);
+        }
+      }
+      ele.specialNeedWeek = ele.specialNeedWeek.substring(1);
+      // 班次需要请求
+      ele.specialNeedSailingSorts = ele.specialNeed?.sailingSorts;
+      // console.log('ele', ele);
+      return ele;
+    });
+    return res;
+  }
+
+  // 详情按钮事件
+  function handleEdit(record: Recordable) {
+    console.log('🚀 ~ file: index.vue:206 ~ handleView ~ record:', record);
+    record.gender = formatDictValue(bizDictOptions.gender, record.patientGender);
+    openModal(true, {
+      isUpdate: true,
+      record,
+    });
+  }
+  // 删除按钮事件
+  // async function handleDelete(record: Recordable) {
+  //   await bedScheduledPersonRemove([record.id]);
+  //   createMessage.success('删除成功!');
+  //   await reload();
+  // }
+
+  // 弹窗回调事件
+  async function callSuccess({ isUpdate, values }) {
+    console.log(isUpdate);
+    console.log(values);
+    await reload();
+  }
+  // 回调
+  async function callTab(data) {
+    activeKey.value = data.value;
+    await reload();
+  }
+
+  async function callFormChange(data) {
+    formValue.patientName = data.patientName ? data.patientName : '';
+    formValue.tableSort = data.tableSort ? data.tableSort : '';
+    await reload();
+  }
+</script>
+
+<style lang="less" scoped>
+  ::v-deep(.ant-btn-link) {
+    color: rgb(61 65 85 / 100%);
+  }
+
+  .table-dot {
+    display: inline-block;
+    width: 10px;
+    height: 10px;
+    margin-right: 6px;
+    border-radius: 50%;
+
+    &--1 {
+      background-color: #1bc1b3;
+    }
+
+    &--2 {
+      background-color: #f7b500;
+    }
+  }
+
+  .divider {
+    height: 16px;
+    width: 1px;
+    background-color: #ccc;
+    margin: 4px 6px 0;
+  }
+
+  .table-special .table-special-item:last-of-type {
+    color: red;
+  }
+</style>

+ 12 - 0
src/views/biz/visit/ready/data.ts

@@ -144,6 +144,18 @@ export const dataFormSchema: FormSchema[] = [
     },
     defaultValue: '1',
   },
+  {
+    field: 'apiCheck',
+    label: '系统内置',
+    component: 'ApiCheckboxGroup',
+    componentProps: {
+      api: listDictModel,
+      params: {
+        dictCode: 'bm_pump',
+      },
+    },
+    // defaultValue: ['pump_single'],
+  },
   // {
   //   field: 'disable',
   //   label: '状态',

+ 1 - 0
src/views/biz/visit/ready/index.vue

@@ -268,6 +268,7 @@
         input: '测试',
         dictValue: 'DIC_BIZ',
       },
+      apiCheck: ['pump_single'],
     });
   });
   // const count = ref(0);