HuRongxin hai 1 mes
pai
achega
be0524d55c

+ 77 - 0
src/api/patients/nutritionEducation/index.ts

@@ -0,0 +1,77 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { EducationVO, EducationForm, EducationQuery } from '@/api/patients/nutritionEducation/types';
+
+/**
+ * 查询营养宣教列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listEducation = (query?: EducationQuery): AxiosPromise<EducationVO[]> => {
+  return request({
+    url: '/patients/nutritionEducation/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询营养宣教详细
+ * @param id
+ */
+export const getEducation = (id: string | number): AxiosPromise<EducationVO> => {
+  return request({
+    url: '/patients/nutritionEducation/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 查询模板列表
+ * @param query
+ * @returns {*}
+ */
+
+export const queryTemplateList = () => {
+    return request({
+        url: '/patients/nutritionEducation/queryTemplateList',
+        method: 'get',
+    });
+};
+
+
+/**
+ * 新增营养宣教
+ * @param data
+ */
+export const addEducation = (data: EducationForm) => {
+  return request({
+    url: '/patients/nutritionEducation',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改营养宣教
+ * @param data
+ */
+export const updateEducation = (data: EducationForm) => {
+  return request({
+    url: '/patients/nutritionEducation',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除营养宣教
+ * @param id
+ */
+export const delEducation = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/patients/nutritionEducation/' + id,
+    method: 'delete'
+  });
+};

+ 156 - 0
src/api/patients/nutritionEducation/types.ts

@@ -0,0 +1,156 @@
+export interface EducationVO {
+    /**
+     * 
+     */
+    id: string | number;
+
+    /**
+     * 患者id
+     */
+    patientId: string | number;
+
+    /**
+     * 营养宣教标题
+     */
+    educationTitle: string;
+
+    /**
+     * 营养宣教模板id
+     */
+    educationTemplateId: string | number;
+
+    /**
+     * 描述
+     */
+    description: string;
+
+    /**
+     * 正文
+     */
+    content: string;
+
+    /**
+     * 看诊类型
+     */
+    type: string;
+
+    /**
+     * 科室
+     */
+    deptId: string | number;
+
+    /**
+     * 门诊号
+     */
+    outpatientNo: string;
+
+}
+
+export interface EducationForm extends BaseEntity {
+    /**
+     * 
+     */
+    id?: string | number;
+
+    /**
+     * 患者id
+     */
+    patientId?: string | number;
+
+    /**
+     * 营养宣教标题
+     */
+    educationTitle?: string;
+
+    /**
+     * 营养宣教模板id
+     */
+    educationTemplateId?: string | number;
+
+    /**
+     * 描述
+     */
+    description?: string;
+
+    /**
+     * 正文
+     */
+    content?: string;
+
+    contentStr?: string;
+
+    /**
+     * 看诊类型
+     */
+    type?: string;
+
+    /**
+     * 科室
+     */
+    deptId?: string | number;
+
+    deptName?: string;
+
+    /**
+     * 门诊号
+     */
+    outpatientNo?: string;
+
+}
+
+export interface EducationQuery extends PageQuery {
+
+    /**
+     * 患者id
+     */
+    patientId?: string | number;
+
+    /**
+     * 营养宣教标题
+     */
+    educationTitle?: string;
+
+    /**
+     * 营养宣教模板id
+     */
+    educationTemplateId?: string | number;
+
+    /**
+     * 描述
+     */
+    description?: string;
+
+    /**
+     * 正文
+     */
+    content?: string;
+
+    /**
+     * 看诊类型
+     */
+    type?: string;
+
+    /**
+     * 科室
+     */
+    deptId?: string | number;
+
+    /**
+     * 门诊号
+     */
+    outpatientNo?: string;
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+
+    dateRange?: string[];
+
+    visitType?: string | number;
+
+    searchValue?: string;
+}
+
+
+

+ 63 - 0
src/api/patients/nutritionSetting/index.ts

@@ -0,0 +1,63 @@
+import request from '@/utils/request';
+import { AxiosPromise } from 'axios';
+import { NutritionSettingVO, NutritionSettingForm, NutritionSettingQuery } from '@/api/patients/nutritionSetting/types';
+
+/**
+ * 查询营养设定列表
+ * @param query
+ * @returns {*}
+ */
+
+export const listSetting = (query?: NutritionSettingQuery): AxiosPromise<NutritionSettingVO[]> => {
+  return request({
+    url: '/patients/nutritionSetting/list',
+    method: 'get',
+    params: query
+  });
+};
+
+/**
+ * 查询营养设定详细
+ * @param id
+ */
+export const getSetting = (id: string | number): AxiosPromise<NutritionSettingVO> => {
+  return request({
+    url: '/patients/nutritionSetting/' + id,
+    method: 'get'
+  });
+};
+
+/**
+ * 新增营养设定
+ * @param data
+ */
+export const addSetting = (data: NutritionSettingForm) => {
+  return request({
+    url: '/patients/nutritionSetting',
+    method: 'post',
+    data: data
+  });
+};
+
+/**
+ * 修改营养设定
+ * @param data
+ */
+export const updateSetting = (data: NutritionSettingForm) => {
+  return request({
+    url: '/patients/nutritionSetting',
+    method: 'put',
+    data: data
+  });
+};
+
+/**
+ * 删除营养设定
+ * @param id
+ */
+export const delSetting = (id: string | number | Array<string | number>) => {
+  return request({
+    url: '/patients/nutritionSetting/' + id,
+    method: 'delete'
+  });
+};

+ 528 - 0
src/api/patients/nutritionSetting/types.ts

@@ -0,0 +1,528 @@
+export interface NutritionSettingVO {
+  /**
+   * 主键
+   */
+  id: string | number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKcalPerDay: number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKcalPerKgDay: number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKjPerDay: number;
+
+  /**
+   * 蛋白质热量占比
+   */
+  proteinCaloriePercentage: number;
+
+  /**
+   * 脂肪热量占比
+   */
+  fatCaloriePercentage: number;
+
+  /**
+   * 碳水化合物热量占比
+   */
+  carbohydrateCaloriePercentage: number;
+
+  /**
+   * 所需蛋白质
+   */
+  proteinGPerKgDay: number;
+
+  /**
+   * 所需蛋白质
+   */
+  proteinGPerDay: number;
+
+  /**
+   * 所需脂肪
+   */
+  fatGPerKgDay: number;
+
+  /**
+   * 所需脂肪
+   */
+  fatGPerDay: number;
+
+  /**
+   * 所需碳水化合物
+   */
+  carbohydrateGPerKgDay: number;
+
+  /**
+   * 所需碳水化合物
+   */
+  carbohydrateGPerDay: number;
+
+  /**
+   * 钙
+   */
+  calcium: number;
+
+  /**
+   * 钾
+   */
+  potassium: number;
+
+  /**
+   * 钠
+   */
+  sodium: number;
+
+  /**
+   * 镁
+   */
+  magnesium: number;
+
+  /**
+   * 磷
+   */
+  phosphorus: number;
+
+  /**
+   * 氯
+   */
+  chloride: string | number;
+
+  /**
+   * 铁
+   */
+  iron: number;
+
+  /**
+   * 硒
+   */
+  selenium: number;
+
+  /**
+   * 锰
+   */
+  manganese: number;
+
+  /**
+   * 氟
+   */
+  fluoride: string | number;
+
+  /**
+   * 钼
+   */
+  molybdenum: number;
+
+  /**
+   * 锌
+   */
+  zinc: number;
+
+  /**
+   * 铜
+   */
+  copper: number;
+
+  /**
+   * 碘
+   */
+  iodine: number;
+
+  /**
+   * 铬
+   */
+  chromium: number;
+
+  /**
+   * 维生素A
+   */
+  vitaminA: number;
+
+  /**
+   * 维生素D
+   */
+  vitaminD: number;
+
+  /**
+   * 维生素E
+   */
+  vitaminE: number;
+
+  /**
+   * 维生素K
+   */
+  vitaminK: number;
+
+  /**
+   * 维生素B1
+   */
+  vitaminBOne: number;
+
+  /**
+   * 维生素B2
+   */
+  vitaminBTwo: number;
+
+  /**
+   * 维生素B6
+   */
+  vitaminBSix: number;
+
+  /**
+   * 维生素B12
+   */
+  vitaminBTwelve: number;
+
+  /**
+   * 烟酸(尼克酸)
+   */
+  niacin: number;
+
+  /**
+   * 维生素C
+   */
+  vitaminC: number;
+
+  /**
+   * 叶酸
+   */
+  folicAcid: string | number;
+
+  /**
+   * 胆碱
+   */
+  choline: number;
+
+  /**
+   * 生物素
+   */
+  biotin: number;
+
+  /**
+   * 泛酸
+   */
+  pantothenicAcid: string | number;
+
+  /**
+   * 膳食纤维
+   */
+  dietaryFiber: number;
+
+  /**
+   * 设定方式
+   */
+  settingType: string;
+
+  /**
+   * 患者id
+   */
+  patientId: string | number;
+
+  /**
+   * 看诊类型
+   */
+  type: string;
+
+  /**
+   * 科室
+   */
+  deptId: string | number;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo: string;
+
+}
+
+export interface NutritionSettingForm extends BaseEntity {
+  /**
+   * 主键
+   */
+  id?: string | number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKcalPerDay?: number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKcalPerKgDay?: number;
+
+  /**
+   * 所需热量
+   */
+  caloriesKjPerDay?: number;
+
+  /**
+   * 蛋白质热量占比
+   */
+  proteinCaloriePercentage?: number;
+
+  /**
+   * 脂肪热量占比
+   */
+  fatCaloriePercentage?: number;
+
+  /**
+   * 碳水化合物热量占比
+   */
+  carbohydrateCaloriePercentage?: number;
+
+  /**
+   * 所需蛋白质
+   */
+  proteinGPerKgDay?: number;
+
+  /**
+   * 所需蛋白质
+   */
+  proteinGPerDay?: number;
+
+  /**
+   * 所需脂肪
+   */
+  fatGPerKgDay?: number;
+
+  /**
+   * 所需脂肪
+   */
+  fatGPerDay?: number;
+
+  /**
+   * 所需碳水化合物
+   */
+  carbohydrateGPerKgDay?: number;
+
+  /**
+   * 所需碳水化合物
+   */
+  carbohydrateGPerDay?: number;
+
+  /**
+   * 钙
+   */
+  calcium?: number;
+
+  /**
+   * 钾
+   */
+  potassium?: number;
+
+  /**
+   * 钠
+   */
+  sodium?: number;
+
+  /**
+   * 镁
+   */
+  magnesium?: number;
+
+  /**
+   * 磷
+   */
+  phosphorus?: number;
+
+  /**
+   * 氯
+   */
+  chloride?: string | number;
+
+  /**
+   * 铁
+   */
+  iron?: number;
+
+  /**
+   * 硒
+   */
+  selenium?: number;
+
+  /**
+   * 锰
+   */
+  manganese?: number;
+
+  /**
+   * 氟
+   */
+  fluoride?: string | number;
+
+  /**
+   * 钼
+   */
+  molybdenum?: number;
+
+  /**
+   * 锌
+   */
+  zinc?: number;
+
+  /**
+   * 铜
+   */
+  copper?: number;
+
+  /**
+   * 碘
+   */
+  iodine?: number;
+
+  /**
+   * 铬
+   */
+  chromium?: number;
+
+  /**
+   * 维生素A
+   */
+  vitaminA?: number;
+
+  /**
+   * 维生素D
+   */
+  vitaminD?: number;
+
+  /**
+   * 维生素E
+   */
+  vitaminE?: number;
+
+  /**
+   * 维生素K
+   */
+  vitaminK?: number;
+
+  /**
+   * 维生素B1
+   */
+  vitaminBOne?: number;
+
+  /**
+   * 维生素B2
+   */
+  vitaminBTwo?: number;
+
+  /**
+   * 维生素B6
+   */
+  vitaminBSix?: number;
+
+  /**
+   * 维生素B12
+   */
+  vitaminBTwelve?: number;
+
+  /**
+   * 烟酸(尼克酸)
+   */
+  niacin?: number;
+
+  /**
+   * 维生素C
+   */
+  vitaminC?: number;
+
+  /**
+   * 叶酸
+   */
+  folicAcid?: string | number;
+
+  /**
+   * 胆碱
+   */
+  choline?: number;
+
+  /**
+   * 生物素
+   */
+  biotin?: number;
+
+  /**
+   * 泛酸
+   */
+  pantothenicAcid?: string | number;
+
+  /**
+   * 膳食纤维
+   */
+  dietaryFiber?: number;
+
+  /**
+   * 设定方式
+   */
+  settingType?: string;
+
+  deptName?: string;    
+
+  /**
+   * 患者id
+   */
+  patientId?: string | number;
+
+  /**
+   * 看诊类型
+   */
+  type?: string;
+
+  /**
+   * 科室
+   */
+  deptId?: string | number;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo?: string;
+
+}
+
+export interface NutritionSettingQuery extends PageQuery {
+
+  
+  /**
+   * 设定方式
+   */
+  settingType?: string;
+
+  /**
+   * 患者id
+   */
+  patientId?: string | number;
+
+  /**
+   * 看诊类型
+   */
+  type?: string;
+
+  /**
+   * 科室
+   */
+  deptId?: string | number;
+
+  /**
+   * 门诊号
+   */
+  outpatientNo?: string;
+
+  searchValue?: string;
+
+  dateRange?: string[];
+
+    /**
+     * 日期范围参数
+     */
+    params?: any;
+}
+
+
+

+ 0 - 0
src/views/patients/dietTherapy/addForm.vue


+ 1 - 0
src/views/patients/dietTherapy/index.vue

@@ -0,0 +1 @@
+<template>膳食治疗</template>

+ 12 - 4
src/views/patients/medicalRecord/index.vue

@@ -39,9 +39,6 @@
                     <el-menu-item index="parenteralNutrition">肠外营养</el-menu-item>
                     <el-menu-item index="dietTherapy">膳食治疗</el-menu-item>
                 </el-sub-menu>
-                <el-menu-item index="nutritionPlan">
-                    <span>营养计划</span>
-                </el-menu-item>
                 <el-menu-item index="nutritionMonitor">
                     <span>营养监测</span>
                 </el-menu-item>
@@ -130,14 +127,23 @@
     const NutritionScreeningAdd = defineAsyncComponent(() => import('@/views/patients/screening/add.vue'));
     const NutritionEvaluationAdd = defineAsyncComponent(() => import('@/views/patients/evaluation/add.vue'));
 
+    const NutritionEducation = defineAsyncComponent(() => import('@/views/patients/nutritionEducation/index.vue'));
+    const NutritionSetting = defineAsyncComponent(() => import('@/views/patients/nutritionSetting/index.vue'));
+    const DietTherapy = defineAsyncComponent(() => import('@/views/patients/dietTherapy/index.vue'));
+
     const componentMap = {
         medicalRecord: MedicalRecord, // “营养病例”对应MedicalRecord.vue
         checkLabel: CheckLabel, // “检查标签”对应CheckLabel.vue
         nutritionDiagnosis: NutriDiagnosis,
+
         nutritionScreening: NutritionScreening,
         nutritionScreeningAdd: NutritionScreeningAdd,
         nutritionEvaluation:NutritionEvaluation,
         nutritionEvaluationAdd: NutritionEvaluationAdd,
+
+        nutritionEducation: NutritionEducation,
+        nutritionSetting: NutritionSetting,
+        dietTherapy: DietTherapy,
         // ... 其它映射
     };
     const currentComponent = ref(componentMap['medicalRecord']); // 默认显示
@@ -153,8 +159,9 @@
         age: '',
         gender: '',
         type: '',
+        deptId: '',
+        deptName: '',
         outpatientNo: '',
-        deptName: '',         
 
     });
 
@@ -311,6 +318,7 @@
                 id: item.id,
                 name: item.treatName,
                 type: item.type, // 0: 门诊,1: 住院
+                deptId: item.doorId,
                 deptName: item.deptName,
                 outpatientNo: item.outpatientNo,
                 gender: item.sex === '0' ? '男' : item.sex === '1' ? '女' : '',

+ 0 - 1
src/views/patients/nutriDiagnosis/index.vue

@@ -362,7 +362,6 @@
                     form.value.consultantResultStr = window.btoa(encodeURIComponent(form.value.consultantResult))
                     await updateDiagnosis(form.value).finally(() => buttonLoading.value = false);
                 } else {
-                    console.log('addForm', JSON.stringify(form.value));
 
                     form.value.consultantResultStr = window.btoa(encodeURIComponent(form.value.consultantResult))
                     await addDiagnosis(form.value).finally(() => buttonLoading.value = false);

+ 57 - 0
src/views/patients/nutritionEducation/detailDialog.vue

@@ -0,0 +1,57 @@
+<template>
+  <el-dialog v-model="visible" title="营养诊断详情" width="880px" :close-on-click-modal="false" :destroy-on-close="true" top="20px">
+    <el-form label-width="120px" class="detail-form">
+      <el-form-item label="营养宣教标题:">
+        <el-input :model-value="detail.educationTitle" readonly />
+      </el-form-item>
+      <el-form-item label="内容描述:">
+        <el-input :model-value="detail.description" type="textarea" :rows="3" readonly />
+      </el-form-item>
+      <el-form-item label="正文:">
+        <el-input :model-value="detail.content" type="textarea" :rows="6" readonly />
+      </el-form-item>
+    </el-form>
+    <template #footer>
+      <el-button @click="visible = false">关闭</el-button>
+    </template>
+  </el-dialog>
+</template>
+
+<script setup lang="ts">
+import { ref, defineProps, watch, defineExpose } from 'vue';
+const emit = defineEmits(['update:modelValue']);
+const props = defineProps({
+  modelValue: Boolean,
+  detail: {
+    type: Object,
+    default: () => ({})
+  }
+});
+const visible = ref(props.modelValue);
+watch(
+  () => props.modelValue,
+  (v) => {
+    visible.value = v;
+  }
+);
+watch(visible, (v) => {
+  if (!v) emit('update:modelValue', false);
+});
+defineExpose({ visible });
+</script>
+<script lang="ts">
+export default {};
+</script>
+
+<style scoped>
+.detail-form {
+  padding: 10px 20px 0 20px;
+}
+.el-form-item {
+  margin-bottom: 24px;
+}
+.el-input[readonly] .el-input__inner {
+  background: #f5f7fa;
+  color: #333;
+}
+</style> 

+ 106 - 0
src/views/patients/nutritionEducation/educationTemplateDialog.vue

@@ -0,0 +1,106 @@
+<template>
+    <el-dialog :model-value="visible" title="营养宣教模板" width="480px" @close="$emit('update:visible', false)" append-to-body class="consultant-template-dialog">
+        <div class="dialog-header-row">
+            <el-input v-model="searchValue" placeholder="请输入模板名称" size="small" class="search-input" @keyup.enter="handleSearch" />
+            <el-button type="primary" size="small" class="search-btn" @click="handleSearch">确定</el-button>
+        </div>
+        <el-tree :data="treeData" :props="defaultProps" node-key="id" default-expand-all class="template-tree" highlight-current :expand-on-click-node="false" :show-checkbox="false" @node-click="handleNodeClick" />
+        <template #footer>
+            <div class="dialog-footer">
+                <el-button type="primary" @click="handleConfirm">确定</el-button>
+                <el-button @click="handleCancel">取消</el-button>
+            </div>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup lang="ts">
+    import { ref, watch, onMounted } from 'vue';
+    import { queryTemplateList } from '@/api/patients/nutritionEducation';
+import { json } from 'stream/consumers';
+
+    const props = defineProps({
+        visible: Boolean
+    });
+    const emit = defineEmits(['update:visible', 'select']);
+
+    const searchValue = ref('');
+    const treeData = ref<any[]>([]);
+    const defaultProps = {
+        children: 'children',
+        label: 'label'
+    };
+
+    const handleSearch = async () => {
+        await fetchTemplates();
+    };
+
+    const handleConfirm = () => {
+        // 只传递有 template 字段的节点 
+        emit('select', selectedTemplate.value || '');
+        emit('update:visible', false);
+    };
+
+    const handleCancel = () => {
+        emit('update:visible', false);
+    };
+
+    const selectedTemplate = ref<any>(null);
+
+    const fetchTemplates = async () => {
+        // Fetch template list from API
+        const res = await queryTemplateList();
+        treeData.value = res.data;        
+
+    };
+
+    const handleNodeClick = (data: any) => {
+        selectedTemplate.value = data;
+    };
+
+    watch(() => props.visible, (val) => {
+        if (val) fetchTemplates();
+    });
+
+    onMounted(() => {
+        if (props.visible) fetchTemplates();
+    });
+</script>
+
+<style scoped>
+    .consultant-template-dialog .el-dialog__body {
+        padding-top: 10px;
+        padding-bottom: 0;
+    }
+
+    .dialog-header-row {
+        display: flex;
+        align-items: center;
+        margin-bottom: 12px;
+    }
+
+    .search-input {
+        flex: 1;
+        margin-right: 8px;
+    }
+
+    .search-btn {
+        min-width: 60px;
+    }
+
+    .template-tree {
+        margin: 12px 0 24px 0;
+        min-height: 180px;
+        max-height: 260px;
+        overflow-y: auto;
+        background: #fff;
+        border: none;
+    }
+
+    .dialog-footer {
+        display: flex;
+        justify-content: center;
+        gap: 16px;
+        padding-bottom: 8px;
+    }
+</style>

+ 402 - 1
src/views/patients/nutritionEducation/index.vue

@@ -1 +1,402 @@
-<template></template>
+<template>
+    <div class="p-2">
+        <div v-show="type === 'list'">
+            <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+                <div v-show="showSearch" class="mb-[10px]">
+                    <el-card shadow="hover">
+                        <el-form ref="queryFormRef" :model="queryParams" :inline="true">
+                            <el-form-item>
+                                <el-date-picker v-model="queryParams.dateRange" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
+                            </el-form-item>
+                            <el-form-item label="看诊类型">
+                                <el-select v-model="queryParams.type" class="spec-unit-select">
+                                    <el-option v-for="dict in treatment_user_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-input v-model="queryParams.searchValue" placeholder="姓名/门诊/住院号" style="width: 240px; " clearable />
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </el-card>
+                </div>
+            </transition>
+
+            <el-card shadow="never">
+                <template #header>
+                    <el-row :gutter="10" class="mb8">
+                        <el-col :span="1.5">
+                            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['patients:nutritionEducation:add']">新增营养宣教</el-button>
+                        </el-col>
+                        <el-col :span="1.5">
+                            <el-button disabled>打印已选病历</el-button>
+                        </el-col>
+                        <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+                    </el-row>
+                </template>
+
+                <el-table v-loading="loading" border :data="educationList" @selection-change="handleSelectionChange">
+                    <el-table-column type="selection" width="55" align="center" />
+                    <el-table-column label="时间" align="center" prop="createTime" />
+                    <el-table-column label="看诊类型" align="center" prop="createTime">
+                        <template #default="scope">
+                            <span>{{ scope.row.patientType == 1 ? '门诊' : '住院' }}</span>
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="科室" align="center" prop="deptName" />
+                    <el-table-column label="门诊/住院号" align="center" prop="outpatientNo" />
+                    <el-table-column label="营养宣教标题" align="center" prop="educationTitle" />
+                    <el-table-column label="内容描述" align="center" prop="description">
+                        <template #default="scope">
+                            <div class="description-cell" @mouseenter="showTooltip($event, scope.row.description)" @mouseleave="hideTooltip">
+                                {{ scope.row.description }}
+                            </div>
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="正文" align="center" prop="content">
+                        <template #default="scope">
+                            <div class="description-cell" @mouseenter="showTooltip($event, scope.row.content)" @mouseleave="hideTooltip">
+                                {{ stripHtml(scope.row.content) }}
+                            </div>
+                        </template>
+                    </el-table-column>
+                    <el-table-column label="宣教医生/护士" align="center" prop="createByUser" />
+                    <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                        <template #default="scope">
+                            <el-tooltip content="详情" placement="top">
+                                <el-button link type="primary" icon="Edit" @click="handleDetail(scope.row)">详情</el-button>
+                            </el-tooltip>
+                            <el-tooltip content="删除" placement="top">
+                                <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)">删除</el-button>
+                            </el-tooltip>
+                        </template>
+                    </el-table-column>
+                </el-table>
+
+                <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+            </el-card>
+        </div>
+        <div v-show="type === 'addForm'">
+            <!-- 添加或修改营养宣教对话框 -->
+            <el-button type="primary" @click="handleBack">返回</el-button> <span style="margin-left: 20px;">新增营养宣教</span>
+            <el-form ref="educationFormRef" :model="form" :rules="rules" label-width="120px" style="margin-top: 20px;">
+                <el-form-item label="科室:" prop="deptName">
+                    <el-input v-model="form.deptName" placeholder="请输入科室" :disabled="true" style="width: 30%;" />
+                </el-form-item>
+                <el-form-item label="营养宣教标题:" prop="educationTitle">
+                    <el-input v-model="form.educationTitle" placeholder="请输入营养宣教标题" style="width: 30%;" />
+                    <el-button style="margin-left: 10px;" type="primary" @click="showTemplateDialog = true">导入模板</el-button>
+                </el-form-item>
+                <el-form-item label="描述:" prop="description">
+                    <el-input v-model="form.description" type="textarea" :rows="5" placeholder="请输入内容" style="width: 30%;" />
+                </el-form-item>
+                <el-form-item label="正文:">
+                    <editor v-model="form.content" :min-height="192" style="width: 75%;" />
+                </el-form-item>
+            </el-form>
+            <EducationTemplateDialog v-model:visible="showTemplateDialog" @select="onTemplateSelect" />
+            <div class="dialog-footer" style="text-align: center; margin-top: 100px">
+                <el-button @click="handleCancel">取 消</el-button>
+                <el-button :loading="buttonLoading" type="primary" @click="submitForm">提 交</el-button>
+            </div>
+        </div>
+    </div>
+    <Teleport to="body">
+        <Transition name="fade">
+            <div v-if="tooltipVisible" class="custom-tooltip" :style="tooltipStyle">
+                {{ tooltipContent }}
+            </div>
+        </Transition>
+    </Teleport>
+    <!-- 详情弹窗始终挂载在最外层div内 -->
+    <detail-dialog v-model="showDetailDialog" :detail="currentDetail" />
+</template>
+
+<script setup name="Education" lang="ts">
+    import { listEducation, getEducation, delEducation, addEducation, updateEducation } from '@/api/patients/nutritionEducation';
+    import { EducationVO, EducationQuery, EducationForm } from '@/api/patients/nutritionEducation/types';
+    const EducationTemplateDialog = defineAsyncComponent(() => import('./educationTemplateDialog.vue'));
+    import DetailDialog from './detailDialog.vue';
+    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+    const { treatment_user_type } = toRefs < any > (proxy ?.useDict('treatment_user_type'));
+
+    const educationList = ref < EducationVO[] > ([]);
+    const buttonLoading = ref(false);
+    const loading = ref(true);
+    const type = ref('list');
+    const showSearch = ref(true);
+    const ids = ref < Array < string | number >> ([]);
+    const single = ref(true);
+    const multiple = ref(true);
+    const total = ref(0);
+    const showTemplateDialog = ref(false);
+    const showDetailDialog = ref(false);
+    const currentDetail = ref({});
+    const queryFormRef = ref < ElFormInstance > ();
+    const educationFormRef = ref < ElFormInstance > ();
+
+    const dialog = reactive < DialogOption > ({
+        visible: false,
+        title: ''
+    });
+    // 声明接收的 props
+    const props = defineProps({
+        patientInfo: {
+            type: Object,
+            required: true,
+            default: () => ({
+                id: '',
+                name: '',
+                age: '',
+                deptId: '',
+                gender: ''
+            })
+        }
+    });
+    const initFormData: EducationForm = {
+        id: undefined,
+        patientId: props.patientInfo ?.id,
+        educationTitle: undefined,
+        educationTemplateId: undefined,
+        description: undefined,
+        content: undefined,
+        contentStr: undefined,
+        type: props.patientInfo ?.type,
+        deptId: props.patientInfo ?.deptId,
+        deptName: undefined,
+        outpatientNo: props.patientInfo ?.outpatientNo,
+    }
+    const data = reactive < PageData < EducationForm,
+        EducationQuery >> ({
+            form: { ...initFormData },
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                patientId: props.patientInfo ?.id,
+                dateRange: undefined,
+                searchValue: undefined,
+                params: {}
+            },
+            rules: {
+                id: [
+                    { required: true, message: "不能为空", trigger: "blur" }
+                ],
+                patientId: [
+                    { required: true, message: "患者id不能为空", trigger: "blur" }
+                ],
+            }
+        });
+
+    const { queryParams, form, rules } = toRefs(data);
+
+    // 监听患者ID变化,自动同步到表单和查询参数
+    watch(
+        () => props.patientInfo.id,
+        (newId) => {
+            form.value.patientId = newId;
+            queryParams.value.patientId = newId;
+        }, { immediate: true }
+    );
+    /** 查询营养宣教列表 */
+    const getList = async () => {
+        loading.value = true;
+        const res = await listEducation(queryParams.value);
+        educationList.value = res.rows;
+        total.value = res.total;
+        loading.value = false;
+    }
+    // 添加tooltip相关的状态和方法
+    const tooltipVisible = ref(false);
+    const tooltipContent = ref('');
+    const tooltipStyle = ref({
+        left: '0px',
+        top: '0px'
+    });
+    const hideTooltip = () => {
+        tooltipVisible.value = false;
+    };
+    const showTooltip = (event: MouseEvent, content: string) => {
+        const target = event.target as HTMLElement;
+        const rect = target.getBoundingClientRect();
+
+        tooltipContent.value = content;
+        tooltipStyle.value = {
+            left: `${rect.left + window.scrollX}px`,
+            top: `${rect.bottom + window.scrollY + 5}px`
+        };
+        tooltipVisible.value = true;
+    };
+    const onTemplateSelect = async (data) => {
+        form.value.content = data.template;
+        form.value.educationTitle = data.label;
+        form.value.educationTemplateId = data.id;
+        form.value.description = data.description;
+
+    };
+
+    /** 取消按钮 */
+    const cancel = () => {
+        reset();
+        dialog.visible = false;
+    }
+    const handleDetail = (row) => {
+        currentDetail.value = row;
+        currentDetail.value.content = stripHtml(currentDetail.value.content);
+        showDetailDialog.value = true;
+    }
+
+    function stripHtml(html) {
+        const div = document.createElement('div');
+        div.innerHTML = html;
+        return div.textContent || div.innerText || '';
+    }
+
+    const handleBack = () => {
+        type.value = 'list';
+    }
+    const handleCancel = () => {
+        type.value = 'list';
+    };
+
+    /** 表单重置 */
+    const reset = () => {
+        form.value = {
+            ...initFormData,
+            patientId: props.patientInfo ?.id // 用最新id
+        };
+        educationFormRef.value ?.resetFields();
+    }
+
+    /** 搜索按钮操作 */
+    const handleQuery = () => {
+        queryParams.value.pageNum = 1;
+        getList();
+    }
+    // 字典label工具
+    function getDictLabel(dictList: any[], value: string) {
+        if (!dictList || !Array.isArray(dictList)) return value || '--';
+        const found = dictList.find(item => item.value === value);
+        return found ? found.label : value || '--';
+    }
+    /** 重置按钮操作 */
+    const resetQuery = () => {
+        queryFormRef.value ?.resetFields();
+        queryParams.value.dateRange = undefined;
+        queryParams.value.type = undefined;
+        queryParams.value.searchValue = undefined;
+        handleQuery();
+    }
+
+    /** 多选框选中数据 */
+    const handleSelectionChange = (selection: EducationVO[]) => {
+        ids.value = selection.map(item => item.id);
+        single.value = selection.length != 1;
+        multiple.value = !selection.length;
+    }
+
+    /** 新增按钮操作 */
+    const handleAdd = () => {
+        reset();
+        type.value = 'addForm';
+        form.value.deptName = props.patientInfo ?.deptName;
+        form.value.deptId = props.patientInfo ?.deptId;
+        form.value.patientId = props.patientInfo ?.id;
+        dialog.visible = true;
+        dialog.title = "添加营养宣教";
+    }
+
+    /** 修改按钮操作 */
+    const handleUpdate = async (row ? : EducationVO) => {
+        reset();
+        const _id = row ?.id || ids.value[0]
+        const res = await getEducation(_id);
+        Object.assign(form.value, res.data);
+        dialog.visible = true;
+        dialog.title = "修改营养宣教";
+    }
+
+    /** 提交按钮 */
+    const submitForm = () => {
+        educationFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                if (form.value.id) {
+                    form.value.contentStr = window.btoa(encodeURIComponent(form.value.content))
+                    await updateEducation(form.value).finally(() => buttonLoading.value = false);
+                } else {
+                    form.value.contentStr = window.btoa(encodeURIComponent(form.value.content))
+                    await addEducation(form.value).finally(() => buttonLoading.value = false);
+                }
+                proxy ?.$modal.msgSuccess("操作成功");
+                dialog.visible = false;
+                await getList();
+                type.value = 'list';
+            }
+        });
+    }
+
+    /** 删除按钮操作 */
+    const handleDelete = async (row ? : EducationVO) => {
+        const _ids = row ?.id || ids.value;
+        await proxy ?.$modal.confirm('是否确认删除营养宣教编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+        await delEducation(_ids);
+        type.value = 'list';
+        proxy ?.$modal.msgSuccess("删除成功");
+        await getList();
+    }
+
+    /** 导出按钮操作 */
+    const handleExport = () => {
+        proxy ?.download('patients/nutritionEducation/export', {
+            ...queryParams.value
+        }, `education_${new Date().getTime()}.xlsx`)
+    }
+
+    onMounted(() => {
+        getList();
+    });
+</script>
+
+<style scoped>
+    .description-cell {
+        display: -webkit-box;
+        -webkit-box-orient: vertical;
+        -webkit-line-clamp: 2;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        word-break: break-all;
+        line-height: 1.5;
+        max-height: 3em;
+        text-align: left;
+        padding: 0 8px;
+        cursor: pointer;
+    }
+
+    .custom-tooltip {
+        position: fixed;
+        z-index: 9999;
+        background: white;
+        border: 1px solid #e4e7ed;
+        border-radius: 4px;
+        padding: 12px;
+        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+        max-width: 400px;
+        line-height: 1.5;
+        font-size: 14px;
+        word-break: break-all;
+        text-align: left;
+    }
+
+    .fade-enter-active,
+    .fade-leave-active {
+        transition: opacity 0.2s ease;
+    }
+
+    .fade-enter-from,
+    .fade-leave-to {
+        opacity: 0;
+    }
+</style>

+ 187 - 0
src/views/patients/nutritionSetting/addForm.vue

@@ -0,0 +1,187 @@
+<template>
+  <el-form ref="NutritionSettingFormRef" :model="form" :rules="rules" label-width="80px">
+    <el-form-item label="所需热量" prop="caloriesKcalPerDay">
+      <el-input v-model="form.caloriesKcalPerDay" placeholder="请输入所需热量" />
+    </el-form-item>
+    <el-form-item label="所需热量" prop="caloriesKcalPerKgDay">
+      <el-input v-model="form.caloriesKcalPerKgDay" placeholder="请输入所需热量" />
+    </el-form-item>
+    <el-form-item label="所需热量" prop="caloriesKjPerDay">
+      <el-input v-model="form.caloriesKjPerDay" placeholder="请输入所需热量" />
+    </el-form-item>
+    <el-form-item label="蛋白质热量占比" prop="proteinCaloriePercentage">
+      <el-input v-model="form.proteinCaloriePercentage" placeholder="请输入蛋白质热量占比" />
+    </el-form-item>
+    <el-form-item label="脂肪热量占比" prop="fatCaloriePercentage">
+      <el-input v-model="form.fatCaloriePercentage" placeholder="请输入脂肪热量占比" />
+    </el-form-item>
+    <el-form-item label="碳水化合物热量占比" prop="carbohydrateCaloriePercentage">
+      <el-input v-model="form.carbohydrateCaloriePercentage" placeholder="请输入碳水化合物热量占比" />
+    </el-form-item>
+    <el-form-item label="所需蛋白质" prop="proteinGPerKgDay">
+      <el-input v-model="form.proteinGPerKgDay" placeholder="请输入所需蛋白质" />
+    </el-form-item>
+    <el-form-item label="所需蛋白质" prop="proteinGPerDay">
+      <el-input v-model="form.proteinGPerDay" placeholder="请输入所需蛋白质" />
+    </el-form-item>
+    <el-form-item label="所需脂肪" prop="fatGPerKgDay">
+      <el-input v-model="form.fatGPerKgDay" placeholder="请输入所需脂肪" />
+    </el-form-item>
+    <el-form-item label="所需脂肪" prop="fatGPerDay">
+      <el-input v-model="form.fatGPerDay" placeholder="请输入所需脂肪" />
+    </el-form-item>
+    <el-form-item label="所需碳水化合物" prop="carbohydrateGPerKgDay">
+      <el-input v-model="form.carbohydrateGPerKgDay" placeholder="请输入所需碳水化合物" />
+    </el-form-item>
+    <el-form-item label="所需碳水化合物" prop="carbohydrateGPerDay">
+      <el-input v-model="form.carbohydrateGPerDay" placeholder="请输入所需碳水化合物" />
+    </el-form-item>
+    <el-form-item label="钙" prop="calcium">
+      <el-input v-model="form.calcium" placeholder="请输入钙" />
+    </el-form-item>
+    <el-form-item label="钾" prop="potassium">
+      <el-input v-model="form.potassium" placeholder="请输入钾" />
+    </el-form-item>
+    <el-form-item label="钠" prop="sodium">
+      <el-input v-model="form.sodium" placeholder="请输入钠" />
+    </el-form-item>
+    <el-form-item label="镁" prop="magnesium">
+      <el-input v-model="form.magnesium" placeholder="请输入镁" />
+    </el-form-item>
+    <el-form-item label="磷" prop="phosphorus">
+      <el-input v-model="form.phosphorus" placeholder="请输入磷" />
+    </el-form-item>
+    <el-form-item label="氯" prop="chloride">
+      <el-input v-model="form.chloride" placeholder="请输入氯" />
+    </el-form-item>
+    <el-form-item label="铁" prop="iron">
+      <el-input v-model="form.iron" placeholder="请输入铁" />
+    </el-form-item>
+    <el-form-item label="硒" prop="selenium">
+      <el-input v-model="form.selenium" placeholder="请输入硒" />
+    </el-form-item>
+    <el-form-item label="锰" prop="manganese">
+      <el-input v-model="form.manganese" placeholder="请输入锰" />
+    </el-form-item>
+    <el-form-item label="氟" prop="fluoride">
+      <el-input v-model="form.fluoride" placeholder="请输入氟" />
+    </el-form-item>
+    <el-form-item label="钼" prop="molybdenum">
+      <el-input v-model="form.molybdenum" placeholder="请输入钼" />
+    </el-form-item>
+    <el-form-item label="锌" prop="zinc">
+      <el-input v-model="form.zinc" placeholder="请输入锌" />
+    </el-form-item>
+    <el-form-item label="铜" prop="copper">
+      <el-input v-model="form.copper" placeholder="请输入铜" />
+    </el-form-item>
+    <el-form-item label="碘" prop="iodine">
+      <el-input v-model="form.iodine" placeholder="请输入碘" />
+    </el-form-item>
+    <el-form-item label="铬" prop="chromium">
+      <el-input v-model="form.chromium" placeholder="请输入铬" />
+    </el-form-item>
+    <el-form-item label="维生素A" prop="vitaminA">
+      <el-input v-model="form.vitaminA" placeholder="请输入维生素A" />
+    </el-form-item>
+    <el-form-item label="维生素D" prop="vitaminD">
+      <el-input v-model="form.vitaminD" placeholder="请输入维生素D" />
+    </el-form-item>
+    <el-form-item label="维生素E" prop="vitaminE">
+      <el-input v-model="form.vitaminE" placeholder="请输入维生素E" />
+    </el-form-item>
+    <el-form-item label="维生素K" prop="vitaminK">
+      <el-input v-model="form.vitaminK" placeholder="请输入维生素K" />
+    </el-form-item>
+    <el-form-item label="维生素B1" prop="vitaminBOne">
+      <el-input v-model="form.vitaminBOne" placeholder="请输入维生素B1" />
+    </el-form-item>
+    <el-form-item label="维生素B2" prop="vitaminBTwo">
+      <el-input v-model="form.vitaminBTwo" placeholder="请输入维生素B2" />
+    </el-form-item>
+    <el-form-item label="维生素B6" prop="vitaminBSix">
+      <el-input v-model="form.vitaminBSix" placeholder="请输入维生素B6" />
+    </el-form-item>
+    <el-form-item label="维生素B12" prop="vitaminBTwelve">
+      <el-input v-model="form.vitaminBTwelve" placeholder="请输入维生素B12" />
+    </el-form-item>
+    <el-form-item label="烟酸" prop="niacin">
+      <el-input v-model="form.niacin" placeholder="请输入烟酸" />
+    </el-form-item>
+    <el-form-item label="维生素C" prop="vitaminC">
+      <el-input v-model="form.vitaminC" placeholder="请输入维生素C" />
+    </el-form-item>
+    <el-form-item label="叶酸" prop="folicAcid">
+      <el-input v-model="form.folicAcid" placeholder="请输入叶酸" />
+    </el-form-item>
+    <el-form-item label="胆碱" prop="choline">
+      <el-input v-model="form.choline" placeholder="请输入胆碱" />
+    </el-form-item>
+    <el-form-item label="生物素" prop="biotin">
+      <el-input v-model="form.biotin" placeholder="请输入生物素" />
+    </el-form-item>
+    <el-form-item label="泛酸" prop="pantothenicAcid">
+      <el-input v-model="form.pantothenicAcid" placeholder="请输入泛酸" />
+    </el-form-item>
+    <el-form-item label="膳食纤维" prop="dietaryFiber">
+      <el-input v-model="form.dietaryFiber" placeholder="请输入膳食纤维" />
+    </el-form-item>
+    <el-form-item label="患者id" prop="patientId">
+      <el-input v-model="form.patientId" placeholder="请输入患者id" />
+    </el-form-item>
+    <el-form-item label="科室" prop="deptId">
+      <el-input v-model="form.deptId" placeholder="请输入科室" />
+    </el-form-item>
+    <el-form-item label="门诊号" prop="outpatientNo">
+      <el-input v-model="form.outpatientNo" placeholder="请输入门诊号" />
+    </el-form-item>
+    <template>
+      <div class="dialog-footer">
+        <el-button :loading="buttonLoading" type="primary" @click="() => submitForm()">确 定</el-button>
+        <el-button @click="() => cancel()">取 消</el-button>
+      </div>
+    </template>
+  </el-form>
+</template>
+
+<script setup lang="ts">
+import { ref } from 'vue';
+import { addSetting, updateSetting } from '@/api/patients/nutritionSetting';
+import type { FormInstance } from 'element-plus';
+
+// 接收父组件传递的参数
+const props = defineProps({
+  form: {
+    type: Object,
+    required: true
+  },
+  rules: {
+    type: Object,
+    required: true
+  },
+  buttonLoading: {
+    type: Boolean,
+    required: true
+  },
+  submitForm: {
+    type: Function,
+    required: true
+  },
+  cancel: {
+    type: Function,
+    required: true
+  }
+});
+
+// 表单ref
+const NutritionSettingFormRef = ref<FormInstance>();
+
+// 新增
+const handleAdd = async () => {
+  await addSetting({ ...props.form });
+};
+// 更新
+const handleUpdate = async () => {
+  await updateSetting({ ...props.form });
+};
+</script>

+ 337 - 0
src/views/patients/nutritionSetting/index.vue

@@ -0,0 +1,337 @@
+<template>
+    <div class="p-2">
+        <div v-show="type=='list'">
+            <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
+                <div v-show="showSearch" class="mb-[10px]">
+                    <el-card shadow="hover">
+                        <el-form ref="queryFormRef" :model="queryParams" :inline="true" label-width="120px">
+                            <el-form-item label="时间:">
+                                <el-date-picker v-model="queryParams.dateRange" type="daterange" range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期" />
+                            </el-form-item>
+                            <el-form-item label="看诊类型:">
+                                <el-select v-model="queryParams.type" class="spec-unit-select">
+                                    <el-option v-for="dict in treatment_user_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item label="营养设定方式:">
+                                <el-select v-model="queryParams.type" class="spec-unit-select">
+                                    <el-option v-for="dict in nutrition_setting_type" :key="dict.value" :label="dict.label" :value="dict.value" />
+                                </el-select>
+                            </el-form-item>
+                            <el-form-item>
+                                <el-input v-model="queryParams.searchValue" placeholder="门诊/住院号、医生" style="width: 240px; " clearable />
+                            </el-form-item>
+                            <el-form-item>
+                                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
+                                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
+                            </el-form-item>
+                        </el-form>
+                    </el-card>
+                </div>
+            </transition>
+
+            <el-card shadow="never">
+                <template #header>
+                    <el-row :gutter="10" class="mb8">
+                        <el-col :span="1.5">
+                            <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['patients:nutritionSetting:add']">新增营养设定</el-button>
+                        </el-col>
+                        <!-- <el-col :span="1.5">
+                            <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['patients:nutritionSetting:edit']">修改</el-button>
+                        </el-col>
+                        <el-col :span="1.5">
+                            <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['patients:nutritionSetting:remove']">删除</el-button>
+                        </el-col>
+                        <el-col :span="1.5">
+                            <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['patients:nutritionSetting:export']">导出</el-button>
+                        </el-col> -->
+                        <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
+                    </el-row>
+                </template>
+
+                <el-table v-loading="loading" border :data="settingList" @selection-change="handleSelectionChange">
+                    <el-table-column type="selection" width="55" align="center" />
+                    <el-table-column label="时间" align="center" prop="createTime" />
+                    <el-table-column label="看诊类型" align="center" prop="type" />
+                    <el-table-column label="门诊/住院号" align="center" prop="outpatientNo" />
+                    <el-table-column label="营养设定方式" align="center" prop="settingType" />
+                    <el-table-column label="所需热量(kcal/d)" align="center" prop="type" />
+                    <el-table-column label="评估医生" align="center" prop="createByUser" />
+                    <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+                        <template #default="scope">
+                            <el-tooltip content="修改" placement="top">
+                                <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['patients:nutritionSetting:edit']"></el-button>
+                            </el-tooltip>
+                            <el-tooltip content="删除" placement="top">
+                                <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['patients:nutritionSetting:remove']"></el-button>
+                            </el-tooltip>
+                        </template>
+                    </el-table-column>
+                </el-table>
+
+                <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" />
+            </el-card>
+        </div>
+        <div>
+            <el-dialog :title="'选择营养设定'" v-model="dialog.visible" width="737px" append-to-body :close-on-click-modal="false" :show-close="true" class="nutrition-setting-dialog">
+                <el-row :gutter="20" style="margin-bottom: 10px;">
+                    <el-col :span="12">
+                        <el-button :class="['setting-type-btn', form.settingType === '1' ? 'active' : '']" style="width: 100%; height: 46px;" @click="handleSelectSettingType('1')">BEE</el-button>
+                    </el-col>
+                    <el-col :span="12">
+                        <el-button :class="['setting-type-btn', form.settingType === '2' ? 'active' : '']" style="width: 100%; height: 46px;" @click="handleSelectSettingType('2')">DRIS</el-button>
+                    </el-col>
+                </el-row>
+                <el-row :gutter="20">
+                    <el-col :span="12">
+                        <el-button :class="['setting-type-btn', form.settingType === '3' ? 'active' : '']" style="width: 100%; height: 46px;" @click="handleSelectSettingType('3')">拇指测法</el-button>
+                    </el-col>
+                    <el-col :span="12">
+                        <el-button :class="['setting-type-btn', form.settingType === '4' ? 'active' : '']" style="width: 100%; height: 46px;" @click="handleSelectSettingType('4')">烧伤公式</el-button>
+                    </el-col>
+                </el-row>
+            </el-dialog>
+        </div>
+        <div v-show="type=='addForm'">
+            <!-- 添加或修改营养设定对话框 -->
+            <add-form :form="form" :rules="rules" :buttonLoading="buttonLoading" :submitForm="submitForm" :cancel="cancel" />
+        </div>
+    </div>
+</template>
+
+<script setup name="NutritionSetting" lang="ts">
+    import { listSetting, getSetting, delSetting, addSetting, updateSetting } from '@/api/patients/nutritionSetting';
+    import { NutritionSettingVO, NutritionSettingQuery, NutritionSettingForm } from '@/api/patients/nutritionSetting/types';
+    import AddForm from './addForm.vue';
+
+    const { proxy } = getCurrentInstance() as ComponentInternalInstance;
+    const { treatment_user_type, nutrition_setting_type } = toRefs < any > (proxy ?.useDict('treatment_user_type', 'nutrition_setting_type'));
+
+    const settingList = ref < NutritionSettingVO[] > ([]);
+    const buttonLoading = ref(false);
+    const loading = ref(true);
+    const showSearch = ref(true);
+    const ids = ref < Array < string | number >> ([]);
+    const single = ref(true);
+    const multiple = ref(true);
+    const total = ref(0);
+    const type = ref('list');
+
+    const queryFormRef = ref < ElFormInstance > ();
+    const NutritionSettingFormRef = ref < ElFormInstance > ();
+
+    const dialog = reactive < DialogOption > ({
+        visible: false,
+        title: ''
+    });
+
+    // 声明接收的 props
+    const props = defineProps({
+        patientInfo: {
+            type: Object,
+            required: true,
+            default: () => ({
+                id: '',
+                name: '',
+                age: '',
+                deptId: '',
+                gender: ''
+            })
+        }
+    });
+
+    const initFormData: NutritionSettingForm = {
+        id: undefined,
+        caloriesKcalPerDay: undefined,
+        caloriesKcalPerKgDay: undefined,
+        caloriesKjPerDay: undefined,
+        proteinCaloriePercentage: undefined,
+        fatCaloriePercentage: undefined,
+        carbohydrateCaloriePercentage: undefined,
+        proteinGPerKgDay: undefined,
+        proteinGPerDay: undefined,
+        fatGPerKgDay: undefined,
+        fatGPerDay: undefined,
+        carbohydrateGPerKgDay: undefined,
+        carbohydrateGPerDay: undefined,
+        calcium: undefined,
+        potassium: undefined,
+        sodium: undefined,
+        magnesium: undefined,
+        phosphorus: undefined,
+        chloride: undefined,
+        iron: undefined,
+        selenium: undefined,
+        manganese: undefined,
+        fluoride: undefined,
+        molybdenum: undefined,
+        zinc: undefined,
+        copper: undefined,
+        iodine: undefined,
+        chromium: undefined,
+        vitaminA: undefined,
+        vitaminD: undefined,
+        vitaminE: undefined,
+        vitaminK: undefined,
+        vitaminBOne: undefined,
+        vitaminBTwo: undefined,
+        vitaminBSix: undefined,
+        vitaminBTwelve: undefined,
+        niacin: undefined,
+        vitaminC: undefined,
+        folicAcid: undefined,
+        choline: undefined,
+        biotin: undefined,
+        pantothenicAcid: undefined,
+        dietaryFiber: undefined,
+        settingType: undefined,
+        type: props.patientInfo ?.type,
+        deptId: props.patientInfo ?.deptId,
+        deptName: undefined,
+        outpatientNo: props.patientInfo ?.outpatientNo,
+    }
+    const data = reactive < PageData < NutritionSettingForm,
+        NutritionSettingQuery >> ({
+            form: { ...initFormData },
+            queryParams: {
+                pageNum: 1,
+                pageSize: 10,
+                patientId: props.patientInfo ?.id,
+                dateRange: undefined,
+                searchValue: undefined,
+                settingType: undefined,
+                type: undefined,
+                deptId: undefined,
+                outpatientNo: undefined,
+                params: {}
+            },
+            rules: {
+                id: [
+                    { required: true, message: "主键不能为空", trigger: "blur" }
+                ],
+            }
+        });
+
+    const { queryParams, form, rules } = toRefs(data);
+
+    /** 查询营养设定列表 */
+    const getList = async () => {
+        loading.value = true;
+        const res = await listSetting(queryParams.value);
+        settingList.value = res.rows;
+        total.value = res.total;
+        loading.value = false;
+    }
+
+    const handleSelectSettingType = (settingType) => {
+        form.value.settingType = settingType;
+        
+        dialog.visible = false;
+        // 切换到表单填写界面
+        nextTick(() => {
+            type.value = 'addForm';
+        });
+    };
+
+    /** 取消按钮 */
+    const cancel = () => {
+        reset();
+        dialog.visible = false;
+    }
+
+    /** 表单重置 */
+    const reset = () => {
+        form.value = { ...initFormData };
+        NutritionSettingFormRef.value ?.resetFields();
+    }
+
+    /** 搜索按钮操作 */
+    const handleQuery = () => {
+        queryParams.value.pageNum = 1;
+        getList();
+    }
+
+    /** 重置按钮操作 */
+    const resetQuery = () => {
+        queryFormRef.value ?.resetFields();
+        handleQuery();
+    }
+
+    /** 多选框选中数据 */
+    const handleSelectionChange = (selection: NutritionSettingVO[]) => {
+        ids.value = selection.map(item => item.id);
+        single.value = selection.length != 1;
+        multiple.value = !selection.length;
+    }
+
+    /** 新增按钮操作 */
+    const handleAdd = () => {
+        reset();
+        dialog.visible = true;
+        dialog.title = "添加营养设定";
+    }
+
+    /** 修改按钮操作 */
+    const handleUpdate = async (row ? : NutritionSettingVO) => {
+        reset();
+        const _id = row ?.id || ids.value[0]
+        const res = await getSetting(_id);
+        Object.assign(form.value, res.data);
+        dialog.visible = true;
+        dialog.title = "修改营养设定";
+    }
+
+    /** 提交按钮 */
+    const submitForm = () => {
+        NutritionSettingFormRef.value ?.validate(async (valid: boolean) => {
+            if (valid) {
+                buttonLoading.value = true;
+                if (form.value.id) {
+                    await updateSetting(form.value).finally(() => buttonLoading.value = false);
+                } else {
+                    await addSetting(form.value).finally(() => buttonLoading.value = false);
+                }
+                proxy ?.$modal.msgSuccess("操作成功");
+                dialog.visible = false;
+                await getList();
+            }
+        });
+    }
+
+    /** 删除按钮操作 */
+    const handleDelete = async (row ? : NutritionSettingVO) => {
+        const _ids = row ?.id || ids.value;
+        await proxy ?.$modal.confirm('是否确认删除营养设定编号为"' + _ids + '"的数据项?').finally(() => loading.value = false);
+        await delSetting(_ids);
+        proxy ?.$modal.msgSuccess("删除成功");
+        await getList();
+    }
+
+    /** 导出按钮操作 */
+    const handleExport = () => {
+        proxy ?.download('/patients/nutritionSetting/export', {
+            ...queryParams.value
+        }, `setting_${new Date().getTime()}.xlsx`)
+    }
+
+    onMounted(() => {
+        getList();
+    });
+</script>
+<style scoped>
+    .nutrition-setting-dialog .setting-type-btn {
+        font-size: 18px;
+        border: 1.5px solid #409EFF;
+        color: #409EFF;
+        background: #fff;
+        transition: background 0.2s, color 0.2s;
+    }
+
+    .nutrition-setting-dialog .setting-type-btn.active,
+    .nutrition-setting-dialog .setting-type-btn:active,
+    .nutrition-setting-dialog .setting-type-btn:focus {
+        background: #e6f0ff;
+        color: #409EFF;
+        border-color: #409EFF;
+    }
+</style>