|
@@ -9,8 +9,8 @@
|
|
|
v-model="dateRange"
|
|
|
type="daterange"
|
|
|
range-separator="-"
|
|
|
- start-placeholder="2024-11-19"
|
|
|
- end-placeholder="2025-07-30"
|
|
|
+ start-placeholder="开始日期"
|
|
|
+ end-placeholder="结束日期"
|
|
|
format="YYYY-MM-DD"
|
|
|
value-format="YYYY-MM-DD"
|
|
|
size="default"
|
|
@@ -39,7 +39,7 @@
|
|
|
|
|
|
<!-- 搜索框 -->
|
|
|
<div class="search-item">
|
|
|
- <el-input v-model="searchKeyword" placeholder="姓名/姓名/门诊号/住院号" style="width: 200px" />
|
|
|
+ <el-input v-model="searchKeyword" placeholder="医院姓名/门诊号/住院号" style="width: 200px" />
|
|
|
</div>
|
|
|
|
|
|
<!-- 按钮组 -->
|
|
@@ -54,9 +54,6 @@
|
|
|
<div class="main-content">
|
|
|
<!-- 左侧时间线区域 -->
|
|
|
<div class="left-timeline">
|
|
|
- <!-- 左侧虚线 -->
|
|
|
- <div class="timeline-line"></div>
|
|
|
-
|
|
|
<div class="timeline-content">
|
|
|
<!-- 日期节点 -->
|
|
|
<div class="timeline-node date-node">
|
|
@@ -83,83 +80,318 @@
|
|
|
<div class="record-type active">营养筛查</div>
|
|
|
|
|
|
<div class="record-list">
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-07-07 17:57:07</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:yingpai</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>1.00分,每周复查营养风险筛查</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-07-07 17:53:39</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:yingpai</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>0.00分,每周复查营养风险筛查</div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-05-27 10:34:40</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>4.00分,患者存在营养风险,开始制定营养支持/治疗计划</div>
|
|
|
+ <!-- 动态营养筛查记录 -->
|
|
|
+ <div v-for="screening in recordScreeningVoList" :key="screening.id" class="record-item">
|
|
|
+ <div class="record-time">{{ screening.createTime }}</div>
|
|
|
+ <div class="record-doctor">筛查医生/护士:{{ screening.createByUser }}</div>
|
|
|
+ <div class="record-detail">
|
|
|
+ <strong>{{ screening.configName }}:</strong>{{ screening.screeningScore }}分,{{
|
|
|
+ screening.screeningConclusion || '每周复查营养风险筛查'
|
|
|
+ }}
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
+ <!-- 无数据提示 -->
|
|
|
+ <div v-if="recordScreeningVoList.length === 0" class="record-item">
|
|
|
+ <div class="record-detail" style="color: #909399; text-align: center">暂无营养筛查数据</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
+ <!-- 营养评估节点 -->
|
|
|
+ <div class="timeline-node normal-node">
|
|
|
+ <div class="node-blue-marker"></div>
|
|
|
+ <div class="node-content">
|
|
|
+ <div class="record-type active">营养评估</div>
|
|
|
+ <div class="record-list">
|
|
|
+ <!-- 动态营养评估记录 -->
|
|
|
+ <div v-for="evaluation in recordEvaluationVoList" :key="evaluation.id" class="record-item">
|
|
|
+ <div class="record-time">{{ evaluation.createTime }}</div>
|
|
|
+ <div class="record-doctor">评估医生/护士:{{ evaluation.createByUser }}</div>
|
|
|
+ <div class="record-detail assessment-detail">
|
|
|
+ <a href="#" class="detail-link">详情</a>
|
|
|
+ <div class="assessment-content">
|
|
|
+ <div class="assessment-title-row">
|
|
|
+ <strong>{{ evaluation.configName }}:</strong>
|
|
|
+ <span class="calorie-data">{{ parseEvaluationContent(evaluation.content)?.summary || '数据解析中...' }}</span>
|
|
|
+ </div>
|
|
|
+ <div class="assessment-suggestion">
|
|
|
+ {{ parseEvaluationContent(evaluation.content)?.suggestion || '暂无建议内容' }}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
+ <!-- 无数据提示 -->
|
|
|
+ <div v-if="recordEvaluationVoList.length === 0" class="record-item">
|
|
|
+ <div class="record-detail" style="color: #909399; text-align: center">暂无营养评估数据</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
+ <!-- 营养诊断节点 -->
|
|
|
+ <div class="timeline-node normal-node">
|
|
|
+ <div class="node-blue-marker"></div>
|
|
|
+ <div class="node-content">
|
|
|
+ <div class="record-type active">营养诊断</div>
|
|
|
+ <div class="record-list">
|
|
|
+ <div v-for="diagnosis in recordDiagnosisVoList" :key="diagnosis.id" class="record-item">
|
|
|
+ <div class="record-time">{{ diagnosis.createTime }}</div>
|
|
|
+ <div class="record-doctor">诊断医生:{{ diagnosis.createByUser }}</div>
|
|
|
+ <div class="record-detail">{{ diagnosis.diagnosisLabelStr }}</div>
|
|
|
</div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
+ <!-- 无数据提示 -->
|
|
|
+ <div v-if="recordDiagnosisVoList.length === 0" class="record-item">
|
|
|
+ <div class="record-detail" style="color: #909399; text-align: center">暂无营养诊断数据</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2025-01-03 10:35:09</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>2.00分,每周复查营养风险筛查</div>
|
|
|
- </div>
|
|
|
+ <!-- 营养处方节点 -->
|
|
|
+ <div class="timeline-node normal-node">
|
|
|
+ <div class="node-blue-marker"></div>
|
|
|
+ <div class="node-content">
|
|
|
+ <div class="record-type active">营养处方</div>
|
|
|
+ <div class="record-list">
|
|
|
+ <div class="record-item prescription-item" v-for="settlement in recordSettlementVoList" :key="settlement.id">
|
|
|
+ <!-- 处方头部 -->
|
|
|
+ <div class="prescription-header">
|
|
|
+ <!-- 标签区域 -->
|
|
|
+ <div class="prescription-tags">
|
|
|
+ <span class="prescription-tag">引用处方</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 日期 -->
|
|
|
+ <div class="prescription-date">{{ formatDate(settlement.orderTime) }}</div>
|
|
|
+
|
|
|
+ <!-- 时间按钮 -->
|
|
|
+ <div class="prescription-time-btn">
|
|
|
+ <span v-for="(products, timeKey) in settlement.enteralMap" :key="timeKey" class="time-btn active">
|
|
|
+ {{ timeKey }}
|
|
|
+ </span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2024-11-19 09:24:56</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail">
|
|
|
- <strong>营养不良筛查工具(MUST):</strong
|
|
|
- >4.00分,患者风险:治疗转介营养师。营养师方案评估应动用处方规划程序,监测和审视营养支持计划;除非营养师常规临床检查:护理营养支持,但若病房没有住院,请与医院营养小区安排一次,护理之后和社区每月一次。
|
|
|
+ <!-- 处方表格 -->
|
|
|
+ <div class="prescription-table-wrapper">
|
|
|
+ <table class="prescription-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>组号</th>
|
|
|
+ <th>产品名称</th>
|
|
|
+ <th>规格</th>
|
|
|
+ <th>用量/次</th>
|
|
|
+ <th>餐次时间</th>
|
|
|
+ <th>首日</th>
|
|
|
+ <th>用法</th>
|
|
|
+ <th>用量/日</th>
|
|
|
+ <th>制剂浓度/次</th>
|
|
|
+ <th>制剂流量/次</th>
|
|
|
+ <th>能量密度/次</th>
|
|
|
+ <th>处方备注</th>
|
|
|
+ <th>每日摄量</th>
|
|
|
+ <th>医生</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(product, index) in getAllEnteralProducts(settlement.enteralMap)" :key="product.fid || index">
|
|
|
+ <td>{{ Number(product.groupNo) + 1 || '--' }}</td>
|
|
|
+ <td>{{ product.nutritionProduct || '--' }}</td>
|
|
|
+ <td>{{ product.specification || '--' }}</td>
|
|
|
+ <td>{{ product.dosagePerTime || '--' }}</td>
|
|
|
+ <td>{{ product.mealTime || '--' }}</td>
|
|
|
+ <td>{{ product.firstDay || '--' }}</td>
|
|
|
+ <td>{{ product.usage || '--' }}</td>
|
|
|
+ <td>{{ product.dailyDosage || '--' }}</td>
|
|
|
+ <td>{{ product.concentration || '--' }}</td>
|
|
|
+ <td>{{ product.flowRate || '--' }}</td>
|
|
|
+ <td>{{ product.energyDensity || '--' }}</td>
|
|
|
+ <td>{{ product.remarks || '--' }}</td>
|
|
|
+ <td>{{ product.dailyIntake || '--' }}</td>
|
|
|
+ <td>{{ product.doctor || settlement.createByUser || '--' }}</td>
|
|
|
+ </tr>
|
|
|
+
|
|
|
+ <!-- 无数据提示 -->
|
|
|
+ <tr v-if="getAllEnteralProducts(settlement.enteralMap).length === 0">
|
|
|
+ <td colspan="14" style="text-align: center; color: #909399">暂无处方数据</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
</div>
|
|
|
</div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <div class="record-item">
|
|
|
- <div class="record-time">2024-11-19 09:24:50</div>
|
|
|
- <div class="record-doctor">筛查医生/护士:系统管理员</div>
|
|
|
- <div class="record-detail"><strong>NRS2002营养风险筛查:</strong>3.00分,患者存在营养风险,开始制定营养支持/治疗计划</div>
|
|
|
+ <!-- 营养膳食 timeline 节点 -->
|
|
|
+ <div class="timeline-node normal-node">
|
|
|
+ <div class="node-blue-marker"></div>
|
|
|
+ <div class="node-content">
|
|
|
+ <div class="record-type active">营养膳食</div>
|
|
|
+ <div class="record-list">
|
|
|
+ <!-- 第一个营养膳食 -->
|
|
|
+ <div class="record-item" v-for="hospitalMealPlan in recordHospitalMealPlanVoList" :key="hospitalMealPlan.id">
|
|
|
+ <div class="record-header">
|
|
|
+ <span class="record-time">{{ hospitalMealPlan.createTime }}</span>
|
|
|
+ <button class="record-btn">引用处方</button>
|
|
|
+ </div>
|
|
|
+ <!-- 院内膳食 -->
|
|
|
+ <div class="meal-section">
|
|
|
+ <div class="meal-header">
|
|
|
+ <div class="meal-info">
|
|
|
+ <span class="meal-title">院内膳食</span>
|
|
|
+ <span class="meal-time"
|
|
|
+ >用餐时间:{{ formatDate(hospitalMealPlan.recommendStartDate) }} 至
|
|
|
+ {{ formatDate(hospitalMealPlan.recommendEndDate) }}</span
|
|
|
+ >
|
|
|
+ <span class="meal-calories">实际热量:{{ hospitalMealPlan.totalCalorie || 0 }}kcal/d</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 食谱标签 -->
|
|
|
+ <div class="meal-tags">
|
|
|
+ <button
|
|
|
+ v-for="recipeName in Object.keys(hospitalMealPlan.recipeMap || {}).sort()"
|
|
|
+ :key="recipeName"
|
|
|
+ class="meal-tag-btn"
|
|
|
+ :class="{active: activeRecipeMap[hospitalMealPlan.id] === recipeName}"
|
|
|
+ @click="switchRecipe(hospitalMealPlan.id, recipeName)"
|
|
|
+ >
|
|
|
+ 食谱{{ recipeName.replace('recipeNo', '') }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="meal-table-wrapper">
|
|
|
+ <table class="meal-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>餐次</th>
|
|
|
+ <th>用餐时间</th>
|
|
|
+ <th>食谱名称</th>
|
|
|
+ <th>膳食种类</th>
|
|
|
+ <th>份数</th>
|
|
|
+ <th>食材重量</th>
|
|
|
+ <th>热量</th>
|
|
|
+ <th>推荐医生</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(item, itemIndex) in getCurrentRecipeData(hospitalMealPlan)" :key="itemIndex">
|
|
|
+ <td>{{ item.mealTime || '早餐' }}</td>
|
|
|
+ <td>{{ formatTime(item.eatTime) || '08:00' }}</td>
|
|
|
+ <td>{{ item.foodName || '馒头(小麦)' }}</td>
|
|
|
+ <td>{{ item.foodCategoryName || '素菜' }}</td>
|
|
|
+ <td>{{ item.amount || 1 }}</td>
|
|
|
+ <td>{{ item.foodWeight || '50.00' }}g</td>
|
|
|
+ <td>{{ item.calorie || '175.0000' }}kcal</td>
|
|
|
+ <td v-if="itemIndex === 0" :rowspan="getCurrentRecipeData(hospitalMealPlan).length">
|
|
|
+ {{ hospitalMealPlan.createByUser || '系统管理员' }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <!-- 如果没有数据,显示默认数据 -->
|
|
|
+ <tr v-if="getCurrentRecipeData(hospitalMealPlan).length === 0">
|
|
|
+ <td>早餐</td>
|
|
|
+ <td>08:00</td>
|
|
|
+ <td>馒头(小麦)</td>
|
|
|
+ <td>素菜</td>
|
|
|
+ <td>1</td>
|
|
|
+ <td>50.00g</td>
|
|
|
+ <td>175.0000kcal</td>
|
|
|
+ <td>{{ hospitalMealPlan.createByUser || '系统管理员' }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
|
-
|
|
|
- <!-- 营养评估节点 -->
|
|
|
+ <!-- 日常膳食 timeline 节点 -->
|
|
|
<div class="timeline-node normal-node">
|
|
|
<div class="node-blue-marker"></div>
|
|
|
<div class="node-content">
|
|
|
- <div class="record-type">营养评估</div>
|
|
|
+ <div class="record-type active">日常膳食</div>
|
|
|
+ <div class="record-list">
|
|
|
+ <!-- 第一个日常膳食记录 -->
|
|
|
+ <div class="record-item" v-for="dailyMeal in recordDailyMealPlanVoList" :key="dailyMeal.id">
|
|
|
+ <div class="record-header">
|
|
|
+ <span class="record-time">{{ dailyMeal.createTime }}</span>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 日常膳食 -->
|
|
|
+ <div class="meal-section">
|
|
|
+ <div class="meal-header">
|
|
|
+ <div class="meal-info">
|
|
|
+ <span class="meal-title">日常膳食</span>
|
|
|
+ <span class="meal-time"
|
|
|
+ >用餐时间:{{ formatDate(dailyMeal.recommendStartDate) }} 至 {{ formatDate(dailyMeal.recommendEndDate) }}</span
|
|
|
+ >
|
|
|
+ <span class="meal-calories">实际热量:{{ dailyMeal.totalCalorie || 0 }}kcal/d</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <!-- 食谱标签 -->
|
|
|
+ <div class="meal-tags">
|
|
|
+ <button
|
|
|
+ v-for="recipeName in Object.keys(dailyMeal.recipeMap || {}).sort()"
|
|
|
+ :key="recipeName"
|
|
|
+ class="meal-tag-btn"
|
|
|
+ :class="{active: activeRecipeMap[dailyMeal.id] === recipeName}"
|
|
|
+ @click="switchRecipe(dailyMeal.id, recipeName)"
|
|
|
+ >
|
|
|
+ 食谱{{ recipeName.replace('recipeNo', '') }}
|
|
|
+ </button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class="meal-table-wrapper">
|
|
|
+ <table class="meal-table">
|
|
|
+ <thead>
|
|
|
+ <tr>
|
|
|
+ <th>餐次</th>
|
|
|
+ <th>用餐时间</th>
|
|
|
+ <th>食谱名称</th>
|
|
|
+ <th>膳食种类</th>
|
|
|
+ <th>份数</th>
|
|
|
+ <th>食材重量</th>
|
|
|
+ <th>热量</th>
|
|
|
+ <th>推荐医生</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody>
|
|
|
+ <tr v-for="(item, itemIndex) in getCurrentRecipeData(dailyMeal)" :key="itemIndex">
|
|
|
+ <td>{{ item.mealTime || '早餐' }}</td>
|
|
|
+ <td>{{ formatTime(item.eatTime) || '08:00' }}</td>
|
|
|
+ <td>{{ item.foodName || '随口菜' }}</td>
|
|
|
+ <td>{{ item.foodCategoryName || '素菜' }}</td>
|
|
|
+ <td>{{ item.amount || 1 }}</td>
|
|
|
+ <td>{{ item.foodWeight || '192.00' }}g</td>
|
|
|
+ <td>{{ item.calorie || '113.5000' }}kcal</td>
|
|
|
+ <td v-if="itemIndex === 0" :rowspan="getCurrentRecipeData(dailyMeal).length">
|
|
|
+ {{ dailyMeal.createByUser || 'yingpai' }}
|
|
|
+ </td>
|
|
|
+ </tr>
|
|
|
+ <!-- 如果没有数据,显示默认数据 -->
|
|
|
+ <tr v-if="getCurrentRecipeData(dailyMeal).length === 0">
|
|
|
+ <td>早餐</td>
|
|
|
+ <td>08:00</td>
|
|
|
+ <td>珍珠圆子</td>
|
|
|
+ <td>荤菜</td>
|
|
|
+ <td>1</td>
|
|
|
+ <td>53g</td>
|
|
|
+ <td>0kcal</td>
|
|
|
+ <td>{{ dailyMeal.createByUser || 'yingpai' }}</td>
|
|
|
+ </tr>
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
</div>
|
|
@@ -180,13 +412,91 @@
|
|
|
</template>
|
|
|
|
|
|
<script setup lang="ts" name="HospitalRecord">
|
|
|
-import {ref} from 'vue';
|
|
|
+import {ref, onMounted} from 'vue';
|
|
|
+import {getHistoryRecordListAPI} from '@/api/patients/historytRecord';
|
|
|
+import {
|
|
|
+ DiagnosisRecord,
|
|
|
+ recordDailyMealPlanVoList,
|
|
|
+ recordHospitalMealPlanVoList,
|
|
|
+ recordScreeningVoList,
|
|
|
+ recordEvaluationVoList,
|
|
|
+ recordSettlementVoList,
|
|
|
+ HistoryRecordResponse
|
|
|
+} from '@/api/patients/historytRecord/type';
|
|
|
+
|
|
|
+// Props 定义
|
|
|
+const {patientInfo} = defineProps<{patientInfo: any}>();
|
|
|
|
|
|
// 响应式数据
|
|
|
-const dateRange = ref(['2024-11-19', '2025-07-30']);
|
|
|
+const dateRange = ref<string[]>([]); // 修复:明确指定泛型类型
|
|
|
const selectedDept = ref('');
|
|
|
const visitType = ref('');
|
|
|
const searchKeyword = ref('');
|
|
|
+// 定义营养诊断列表数据
|
|
|
+const recordDiagnosisVoList = ref<DiagnosisRecord[]>([]);
|
|
|
+// 定义日常膳食列表数据
|
|
|
+const recordDailyMealPlanVoList = ref<recordDailyMealPlanVoList[]>([]);
|
|
|
+// 定义院内膳食列表数据
|
|
|
+const recordHospitalMealPlanVoList = ref<recordHospitalMealPlanVoList[]>([]);
|
|
|
+// 定义营养筛查列表数据
|
|
|
+const recordScreeningVoList = ref<recordScreeningVoList[]>([]);
|
|
|
+// 营养评估列表数据
|
|
|
+const recordEvaluationVoList = ref<recordEvaluationVoList[]>([]);
|
|
|
+// 营养处方列表数据
|
|
|
+const recordSettlementVoList = ref<recordSettlementVoList[]>([]);
|
|
|
+// 当前选中的食谱(为每个膳食记录维护独立的选中状态)
|
|
|
+const activeRecipeMap = ref<{[key: string]: string}>({});
|
|
|
+
|
|
|
+// 格式化日期时间去掉后面的时分秒
|
|
|
+const formatDate = (date: string) => {
|
|
|
+ if (!date) return '';
|
|
|
+ return date.split(' ')[0]; // 去掉时分秒,只保留日期部分
|
|
|
+};
|
|
|
+
|
|
|
+// 格式化时间(只保留时:分)
|
|
|
+const formatTime = (timeString: string) => {
|
|
|
+ if (!timeString) return '';
|
|
|
+ const timePart = timeString.split(' ')[1]; // 获取时间部分
|
|
|
+ if (!timePart) return '';
|
|
|
+ return timePart.substring(0, 5); // 只保留 HH:MM
|
|
|
+};
|
|
|
+
|
|
|
+// 解析营养评估内容
|
|
|
+const parseEvaluationContent = (content: string) => {
|
|
|
+ try {
|
|
|
+ return JSON.parse(content);
|
|
|
+ } catch (error) {
|
|
|
+ console.error('解析营养评估内容失败:', error);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+// 获取营养处方的所有产品数据(合并所有时间段的产品)
|
|
|
+const getAllEnteralProducts = (enteralMap: any) => {
|
|
|
+ if (!enteralMap) return [];
|
|
|
+ const allProducts: any[] = [];
|
|
|
+ Object.values(enteralMap).forEach((products: any) => {
|
|
|
+ if (Array.isArray(products)) {
|
|
|
+ allProducts.push(...products);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ console.log('getAllEnteralProducts result:', allProducts);
|
|
|
+ return allProducts;
|
|
|
+};
|
|
|
+
|
|
|
+// 切换食谱标签
|
|
|
+const switchRecipe = (mealId: string, recipeKey: string) => {
|
|
|
+ activeRecipeMap.value[mealId] = recipeKey;
|
|
|
+};
|
|
|
+
|
|
|
+// 获取当前选中的食谱数据
|
|
|
+const getCurrentRecipeData = (mealData: any) => {
|
|
|
+ const activeRecipe = activeRecipeMap.value[mealData.id];
|
|
|
+ if (!activeRecipe || !mealData.recipeMap || !mealData.recipeMap[activeRecipe]) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+ return mealData.recipeMap[activeRecipe] || [];
|
|
|
+};
|
|
|
|
|
|
// 右侧导航数据
|
|
|
const navigationItems = ref([
|
|
@@ -233,6 +543,56 @@ const handleNavClick = (key: string) => {
|
|
|
console.log('导航切换到:', key);
|
|
|
// 这里可以添加具体的页面切换逻辑
|
|
|
};
|
|
|
+
|
|
|
+// 初始化调用获取列表的入参
|
|
|
+const queryParams = ref({
|
|
|
+ dateRange: dateRange.value,
|
|
|
+ deptId: selectedDept.value,
|
|
|
+ type: visitType.value,
|
|
|
+ searchValue: searchKeyword.value,
|
|
|
+ patientId: patientInfo.id
|
|
|
+});
|
|
|
+// 就诊记录列表数据
|
|
|
+const getHistoryRecordList = async () => {
|
|
|
+ const res = (await getHistoryRecordListAPI(queryParams.value)) as unknown as HistoryRecordResponse;
|
|
|
+ console.log(res, '就诊列表数据');
|
|
|
+
|
|
|
+ // 处理返回的营养诊断数据
|
|
|
+ if (res) {
|
|
|
+ // 处理API返回的数据
|
|
|
+ recordDiagnosisVoList.value = res.recordDiagnosisVoList || [];
|
|
|
+ recordDailyMealPlanVoList.value = res.recordDailyMealPlanVoList || [];
|
|
|
+ recordHospitalMealPlanVoList.value = res.recordHospitalMealPlanVoList || [];
|
|
|
+ recordScreeningVoList.value = res.recordScreeningVoList || [];
|
|
|
+ recordEvaluationVoList.value = res.recordEvaluationVoList || [];
|
|
|
+ recordSettlementVoList.value = res.recordSettlementVoList || [];
|
|
|
+
|
|
|
+ // 初始化每个日常膳食记录的默认选中食谱
|
|
|
+ recordDailyMealPlanVoList.value.forEach((meal) => {
|
|
|
+ if (meal.recipeMap && Object.keys(meal.recipeMap).length > 0) {
|
|
|
+ const firstRecipeKey = Object.keys(meal.recipeMap)[0];
|
|
|
+ activeRecipeMap.value[meal.id] = firstRecipeKey;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 初始化每个院内膳食记录的默认选中食谱
|
|
|
+ recordHospitalMealPlanVoList.value.forEach((meal) => {
|
|
|
+ if (meal.recipeMap && Object.keys(meal.recipeMap).length > 0) {
|
|
|
+ const firstRecipeKey = Object.keys(meal.recipeMap)[0];
|
|
|
+ activeRecipeMap.value[meal.id] = firstRecipeKey;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // console.log(recordHospitalMealPlanVoList.value, 'recordHospitalMealPlanVoList');
|
|
|
+ console.log(recordScreeningVoList.value, 'recordScreeningVoList');
|
|
|
+ console.log(recordEvaluationVoList.value, 'recordEvaluationVoList');
|
|
|
+ console.log(recordSettlementVoList.value, 'recordSettlementVoList');
|
|
|
+ }
|
|
|
+};
|
|
|
+
|
|
|
+onMounted(() => {
|
|
|
+ getHistoryRecordList();
|
|
|
+});
|
|
|
</script>
|
|
|
|
|
|
<style lang="scss" scoped>
|
|
@@ -286,19 +646,20 @@ const handleNavClick = (key: string) => {
|
|
|
border-right: 1px solid #e4e7ed;
|
|
|
position: relative;
|
|
|
|
|
|
- .timeline-line {
|
|
|
- position: absolute;
|
|
|
- left: 40px;
|
|
|
- top: 0;
|
|
|
- height: 100%;
|
|
|
- width: 0;
|
|
|
- border-left: 2px dashed #d0d7de;
|
|
|
- z-index: 1;
|
|
|
- }
|
|
|
-
|
|
|
.timeline-content {
|
|
|
position: relative;
|
|
|
z-index: 2;
|
|
|
+
|
|
|
+ &::before {
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ left: 20px;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ width: 0;
|
|
|
+ border-left: 2px dashed #d0d7de;
|
|
|
+ z-index: 1;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
.timeline-node {
|
|
@@ -409,6 +770,22 @@ const handleNavClick = (key: string) => {
|
|
|
margin-bottom: 4px;
|
|
|
}
|
|
|
|
|
|
+ .record-btn {
|
|
|
+ padding: 4px 12px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #409eff;
|
|
|
+ background: transparent;
|
|
|
+ border: 1px solid #409eff;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ background: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
.record-doctor {
|
|
|
font-size: 13px;
|
|
|
color: #606266;
|
|
@@ -550,6 +927,243 @@ const handleNavClick = (key: string) => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 营养处方样式
|
|
|
+ .record-list {
|
|
|
+ .prescription-item {
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ .prescription-header {
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ .prescription-tags {
|
|
|
+ margin-bottom: 8px;
|
|
|
+
|
|
|
+ .prescription-tag {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 4px 12px;
|
|
|
+ margin-right: 8px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ background: #f5f5f5;
|
|
|
+ color: #666;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #409eff;
|
|
|
+ border-color: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-date {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #303133;
|
|
|
+ margin: 8px 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-time-btn {
|
|
|
+ .time-btn {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 6px 12px;
|
|
|
+ border-radius: 4px;
|
|
|
+ font-size: 12px;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ background: #f5f5f5;
|
|
|
+ color: #666;
|
|
|
+ &.active {
|
|
|
+ background: #409eff;
|
|
|
+ border-color: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-table-wrapper {
|
|
|
+ overflow-x: auto;
|
|
|
+
|
|
|
+ .prescription-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ background: white;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ th,
|
|
|
+ td {
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ padding: 10px 12px;
|
|
|
+ text-align: center;
|
|
|
+ vertical-align: middle;
|
|
|
+ min-width: 90px;
|
|
|
+ white-space: nowrap;
|
|
|
+ overflow: hidden;
|
|
|
+ text-overflow: ellipsis;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ background: #e8f4fd !important;
|
|
|
+ color: #303133 !important;
|
|
|
+ font-weight: 600 !important;
|
|
|
+ font-size: 14px !important;
|
|
|
+ height: 40px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ td {
|
|
|
+ color: #303133;
|
|
|
+ font-size: 14px;
|
|
|
+ height: 36px;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 斑马纹
|
|
|
+ tbody tr:nth-child(even) {
|
|
|
+ background: #fafbfc;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 悬停效果
|
|
|
+ tbody tr:hover {
|
|
|
+ background: #f0f9ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 营养处方专用样式 - 使用更高优先级
|
|
|
+ .prescription-item {
|
|
|
+ .prescription-header {
|
|
|
+ .prescription-tags .prescription-tag {
|
|
|
+ display: inline-block !important;
|
|
|
+ padding: 4px 12px !important;
|
|
|
+ margin-right: 8px !important;
|
|
|
+ border-radius: 4px !important;
|
|
|
+ font-size: 12px !important;
|
|
|
+ border: 1px solid #ddd !important;
|
|
|
+ background: #f5f5f5 !important;
|
|
|
+ color: #666 !important;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #409eff !important;
|
|
|
+ border-color: #409eff !important;
|
|
|
+ color: white !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-date {
|
|
|
+ font-size: 16px !important;
|
|
|
+ font-weight: 500 !important;
|
|
|
+ color: #303133 !important;
|
|
|
+ margin: 8px 0 !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-time-btn .time-btn {
|
|
|
+ display: inline-block !important;
|
|
|
+ padding: 6px 12px !important;
|
|
|
+ border-radius: 4px !important;
|
|
|
+ font-size: 12px !important;
|
|
|
+ border: 1px solid #ddd !important;
|
|
|
+ background: #f5f5f5 !important;
|
|
|
+ color: #666 !important;
|
|
|
+ margin-bottom: 20px;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #409eff !important;
|
|
|
+ border-color: #409eff !important;
|
|
|
+ color: white !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-actions {
|
|
|
+ margin: 10px 0 !important;
|
|
|
+
|
|
|
+ .prescription-btn {
|
|
|
+ display: inline-block !important;
|
|
|
+ padding: 6px 12px !important;
|
|
|
+ margin-right: 8px !important;
|
|
|
+ border-radius: 4px !important;
|
|
|
+ font-size: 12px !important;
|
|
|
+ border: 1px solid #ddd !important;
|
|
|
+ background: #f5f5f5 !important;
|
|
|
+ color: #666 !important;
|
|
|
+ cursor: pointer !important;
|
|
|
+ transition: all 0.3s ease !important;
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #409eff !important;
|
|
|
+ border-color: #409eff !important;
|
|
|
+ color: white !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ &:hover:not(.active) {
|
|
|
+ background: #e6f7ff !important;
|
|
|
+ border-color: #91d5ff !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .prescription-table-wrapper {
|
|
|
+ overflow-x: auto !important;
|
|
|
+ overflow-y: hidden !important;
|
|
|
+ margin-top: 10px !important;
|
|
|
+ width: 100% !important;
|
|
|
+
|
|
|
+ .prescription-table {
|
|
|
+ min-width: 1200px !important;
|
|
|
+ border-collapse: collapse !important;
|
|
|
+ border: 1px solid #ddd !important;
|
|
|
+ background: white !important;
|
|
|
+ font-size: 14px !important;
|
|
|
+
|
|
|
+ th,
|
|
|
+ td {
|
|
|
+ border: 1px solid #ddd !important;
|
|
|
+ padding: 8px 10px !important;
|
|
|
+ text-align: center !important;
|
|
|
+ vertical-align: middle !important;
|
|
|
+ min-width: 80px !important;
|
|
|
+ white-space: nowrap !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ background: #e8f4fd !important;
|
|
|
+ color: #303133 !important;
|
|
|
+ font-weight: 600 !important;
|
|
|
+ font-size: 14px !important;
|
|
|
+ height: 40px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ td {
|
|
|
+ color: #303133 !important;
|
|
|
+ font-size: 13px !important;
|
|
|
+ height: 32px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 特定列宽度优化
|
|
|
+ th:first-child,
|
|
|
+ td:first-child {
|
|
|
+ min-width: 50px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ th:nth-child(2),
|
|
|
+ td:nth-child(2) {
|
|
|
+ min-width: 120px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ th:nth-child(3),
|
|
|
+ td:nth-child(3) {
|
|
|
+ min-width: 100px !important;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -571,5 +1185,186 @@ const handleNavClick = (key: string) => {
|
|
|
background: #a8a8a8;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // 营养评估样式
|
|
|
+ .assessment-detail {
|
|
|
+ position: relative;
|
|
|
+
|
|
|
+ .detail-link {
|
|
|
+ position: absolute;
|
|
|
+ top: 0;
|
|
|
+ right: 0;
|
|
|
+ color: #409eff;
|
|
|
+ text-decoration: none;
|
|
|
+ font-size: 14px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .assessment-content {
|
|
|
+ margin-right: 50px;
|
|
|
+
|
|
|
+ .assessment-title-row {
|
|
|
+ margin-bottom: 6px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #303133;
|
|
|
+
|
|
|
+ strong {
|
|
|
+ font-weight: 600;
|
|
|
+ }
|
|
|
+
|
|
|
+ .calorie-data {
|
|
|
+ margin-left: 8px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .assessment-second-row {
|
|
|
+ margin-bottom: 8px;
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+ margin-left: 134px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .assessment-suggestion {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #606266;
|
|
|
+ line-height: 1.6;
|
|
|
+ margin-left: 134px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 院内膳食样式
|
|
|
+ .meal-section {
|
|
|
+ margin-top: 20px;
|
|
|
+
|
|
|
+ .meal-header {
|
|
|
+ margin-bottom: 16px;
|
|
|
+ padding: 12px 16px;
|
|
|
+ background: #f8f9fa;
|
|
|
+ border-radius: 6px;
|
|
|
+
|
|
|
+ .meal-info {
|
|
|
+ display: flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 20px;
|
|
|
+
|
|
|
+ .meal-title {
|
|
|
+ font-size: 16px;
|
|
|
+ font-weight: 500;
|
|
|
+ color: #303133;
|
|
|
+ }
|
|
|
+
|
|
|
+ .meal-time,
|
|
|
+ .meal-calories {
|
|
|
+ font-size: 13px;
|
|
|
+ color: #606266;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .meal-tags {
|
|
|
+ margin-bottom: 16px;
|
|
|
+
|
|
|
+ .meal-tag-btn {
|
|
|
+ display: inline-block;
|
|
|
+ padding: 6px 16px;
|
|
|
+ font-size: 12px;
|
|
|
+ color: #409eff;
|
|
|
+ background: #f0f9ff;
|
|
|
+ border: 1px solid #409eff;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ transition: all 0.3s ease;
|
|
|
+ margin: 0px 5px !important;
|
|
|
+ &:hover {
|
|
|
+ background: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+
|
|
|
+ &.active {
|
|
|
+ background: #409eff;
|
|
|
+ color: white;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ .meal-table-wrapper {
|
|
|
+ overflow-x: auto;
|
|
|
+
|
|
|
+ .meal-table {
|
|
|
+ width: 100%;
|
|
|
+ border-collapse: collapse;
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ background: white;
|
|
|
+ font-size: 13px;
|
|
|
+
|
|
|
+ th,
|
|
|
+ td {
|
|
|
+ border: 1px solid #ddd;
|
|
|
+ padding: 8px 10px;
|
|
|
+ text-align: center;
|
|
|
+ vertical-align: middle;
|
|
|
+ white-space: nowrap;
|
|
|
+ }
|
|
|
+
|
|
|
+ th {
|
|
|
+ background: #e8f4fd !important;
|
|
|
+ color: #303133 !important;
|
|
|
+ font-weight: 600 !important;
|
|
|
+ font-size: 14px !important;
|
|
|
+ height: 40px !important;
|
|
|
+ }
|
|
|
+
|
|
|
+ td {
|
|
|
+ color: #303133;
|
|
|
+ height: 32px;
|
|
|
+
|
|
|
+ &:first-child {
|
|
|
+ font-weight: 500;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 斑马纹
|
|
|
+ tbody tr:nth-child(even) {
|
|
|
+ background: #fafbfc;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 悬停效果
|
|
|
+ tbody tr:hover {
|
|
|
+ background: #f0f9ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 平衡膳食样式
|
|
|
+ .balanced-diet-section {
|
|
|
+ margin-top: 16px;
|
|
|
+
|
|
|
+ .balanced-diet-content {
|
|
|
+ font-size: 14px;
|
|
|
+ color: #303133;
|
|
|
+ line-height: 1.5;
|
|
|
+
|
|
|
+ .balanced-diet-title {
|
|
|
+ font-weight: 500;
|
|
|
+ margin-right: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .balanced-diet-calories {
|
|
|
+ color: #606266;
|
|
|
+ margin-right: 12px;
|
|
|
+ }
|
|
|
+
|
|
|
+ .balanced-diet-detail {
|
|
|
+ color: #409eff;
|
|
|
+ text-decoration: none;
|
|
|
+ font-size: 14px;
|
|
|
+
|
|
|
+ &:hover {
|
|
|
+ color: #66b1ff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
</style>
|