|
@@ -20,7 +20,7 @@
|
|
|
<el-form-item label="基本膳食" prop="baseDiet">
|
|
|
<el-radio-group v-model="form.baseDiet" :disabled="isView">
|
|
|
<el-radio v-for="item in dietary_types" :key="item.value" :label="item.value">{{ item.label
|
|
|
- }}</el-radio>
|
|
|
+ }}</el-radio>
|
|
|
</el-radio-group>
|
|
|
</el-form-item>
|
|
|
</el-col>
|
|
@@ -152,8 +152,8 @@
|
|
|
<el-divider />
|
|
|
<div style="font-size: 14px;margin-top: -10px;margin-bottom: -10px;">食材组成</div>
|
|
|
<el-divider />
|
|
|
- <div style="margin-top: 10px; margin-bottom: 20px;"><span>食材总量:{{quantitySum}} g</span><span
|
|
|
- style="margin-left: 100px;">膳食总热量:{{caloriesSum}}kcal</span></div>
|
|
|
+ <div style="margin-top: 10px; margin-bottom: 20px;"><span>食材总量:{{ quantitySum }} g</span><span
|
|
|
+ style="margin-left: 100px;">膳食总热量:{{ caloriesSum }}kcal</span></div>
|
|
|
|
|
|
|
|
|
<el-table border :data="selectedIngredientListBak">
|
|
@@ -163,7 +163,7 @@
|
|
|
<template #default="scope">
|
|
|
<el-input v-model="scope.row.quantity" placeholder="请输入" :disabled="isView"
|
|
|
@input="editFoodquantity(scope.row)">
|
|
|
- <template #append><span>{{scope.row.unitName}}</span></template>
|
|
|
+ <template #append><span>{{ scope.row.unitName }}</span></template>
|
|
|
</el-input>
|
|
|
</template>
|
|
|
</el-table-column>
|
|
@@ -472,50 +472,53 @@
|
|
|
|
|
|
|
|
|
<!-- 营养数据分析 -->
|
|
|
- <el-dialog :title="dialog4.title" v-model="dialog4.visible" width="70%" append-to-body >
|
|
|
+ <el-dialog :title="dialog4.title" v-model="dialog4.visible" width="70%" append-to-body>
|
|
|
<div class="p-2">
|
|
|
<el-menu class="el-menu-demo" mode="horizontal" @select="handleMenumSelect" :default-active="currentIndex">
|
|
|
<el-menu-item index="1">三大营养素分析</el-menu-item>
|
|
|
<el-menu-item index="2">营养数据分析</el-menu-item>
|
|
|
</el-menu>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
|
|
|
- <el-row :gutter="10" class="mb8" v-show="leftIndex==currentIndex">
|
|
|
+ <el-row :gutter="10" class="mb8" v-show="leftIndex == currentIndex">
|
|
|
<el-col :span="14">
|
|
|
- <div style="margin-top: 20px;margin-bottom: 20px;">实际热量:26.90kcal/d</div>
|
|
|
+ <div style="margin-top: 20px;margin-bottom: 20px;">实际热量:{{ leftCalories }}kcal/d</div>
|
|
|
<div style="height: 300px;">
|
|
|
- <el-table border stripe :data="diseaseLabelList" @select-all="handleSelectAllChange"
|
|
|
- @select="handleSelectChange" ref="diseaseLabelRef" @selection-change="handleSelectionChange">
|
|
|
- <el-table-column label="三大营养素" align="center" prop="labelName" />
|
|
|
- <el-table-column label="质量(g)" align="center" prop="labelCode" />
|
|
|
- <el-table-column label="热量占比" align="center" prop="categoryName" />
|
|
|
- <el-table-column label="参考值" align="center"/>
|
|
|
+ <el-table border stripe :data="leftList">
|
|
|
+ <el-table-column label="三大营养素" align="center" prop="nutrientName" />
|
|
|
+ <el-table-column label="质量(g)" align="center" prop="nutrientQuantity" >
|
|
|
+ <template #default="scope">
|
|
|
+ {{ scope.row.nutrientQuantity.toFixed(4)}}
|
|
|
+ </template>
|
|
|
+ </el-table-column>
|
|
|
+ <el-table-column label="热量占比" align="center" prop="nutrientRatio" />
|
|
|
+ <el-table-column label="参考值" align="center" prop="nutrientRefVal" />
|
|
|
</el-table>
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
</el-col>
|
|
|
<el-col :span="10" align="center">
|
|
|
<div style="height: 300px;">
|
|
|
<v-chart :option="pieOption" style="width: 400px; height: 200px;" class="chart-center" />
|
|
|
- </div>
|
|
|
+ </div>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
|
|
|
- <el-row :gutter="10" class="mb8" v-show="rightIndex==currentIndex">
|
|
|
+ <el-row :gutter="10" class="mb8" v-show="rightIndex == currentIndex">
|
|
|
<el-col :span="24">
|
|
|
<div style="height: 400px;overflow-y: scroll;">
|
|
|
- <el-table border stripe :data="diseaseLabelList" @select-all="handleSelectAllChange"
|
|
|
- @select="handleSelectChange" ref="diseaseLabelRef" @selection-change="handleSelectionChange">
|
|
|
- <el-table-column label="元素名称" align="center" prop="labelName" />
|
|
|
- <el-table-column label="单位" align="center" prop="labelCode" />
|
|
|
- <el-table-column label="食谱营养素含量" align="center" prop="categoryName" />
|
|
|
+ <el-table border stripe :data="rightList">
|
|
|
+ <el-table-column label="元素名称" align="center" prop="nutrientName" />
|
|
|
+ <el-table-column label="单位" align="center" prop="nutrientUnit" />
|
|
|
+ <el-table-column label="食谱营养素含量" align="center" prop="nutrientQuantity" />
|
|
|
</el-table>
|
|
|
- </div>
|
|
|
- </el-col>
|
|
|
+ </div>
|
|
|
+ </el-col>
|
|
|
</el-row>
|
|
|
|
|
|
<el-row :gutter="10" class="mb8">
|
|
|
<el-col :span="24" align="center">
|
|
|
- <el-button type="primary" @click="handleSelectedconfirm"> 确定 </el-button>
|
|
|
+ <el-button type="primary"
|
|
|
+ @click="dialog4.visible = !dialog4.visible"> 确定 </el-button>
|
|
|
</el-col>
|
|
|
</el-row>
|
|
|
</el-dialog>
|
|
@@ -526,20 +529,20 @@ import { listTree } from '@/api/system/foodCategory';
|
|
|
import { FoodCategoryVO } from '@/api/system/foodCategory/types';
|
|
|
import { listDiseaseLabel, getDiseaseLabel, delDiseaseLabel, addDiseaseLabel, updateDiseaseLabel } from '@/api/system/diseaseLabel';
|
|
|
import { DiseaseLabelVO, DiseaseLabelQuery, DiseaseLabelForm } from '@/api/system/diseaseLabel/types';
|
|
|
-import { listRecipe, getRecipe, delRecipe, addRecipe, updateRecipe,nutrientAnalysis } from '@/api/system/recipe';
|
|
|
+import { listRecipe, getRecipe, delRecipe, addRecipe, updateRecipe, nutrientAnalysis } from '@/api/system/recipe';
|
|
|
import { RecipeVO, RecipeQuery, RecipeForm } from '@/api/system/recipe/types';
|
|
|
import { listRecipeCategory, getRecipeCategory, delRecipeCategory, addRecipeCategory, updateRecipeCategory } from '@/api/system/recipeCategory';
|
|
|
import { RecipeCategoryVO, RecipeCategoryQuery, RecipeCategoryForm } from '@/api/system/recipeCategory/types';
|
|
|
import { DeptTreeVO } from '@/api/system/dept/types';
|
|
|
import api from '@/api/system/user';
|
|
|
-import { FoodIngredientVO,FoodIngredientQuery } from '@/api/system/foodIngredient/types';
|
|
|
+import { FoodIngredientVO, FoodIngredientQuery } from '@/api/system/foodIngredient/types';
|
|
|
import { listFoodIngredient, getFoodIngredient, delFoodIngredient, addFoodIngredient, updateFoodIngredient } from '@/api/system/foodIngredient';
|
|
|
-
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
|
|
|
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
|
|
|
-const { intelligent_recommendation, meal_times, dietary_types, disease_label } = toRefs<any>(
|
|
|
- proxy?.useDict('intelligent_recommendation', 'meal_times', 'dietary_types', 'disease_label'));
|
|
|
+const { intelligent_recommendation, meal_times, dietary_types, disease_label, nutrient_reference } = toRefs<any>(
|
|
|
+ proxy?.useDict('intelligent_recommendation', 'meal_times', 'dietary_types', 'disease_label', 'nutrient_reference'));
|
|
|
|
|
|
const foodCategoryList = ref<FoodCategoryVO[]>([]);
|
|
|
const diseaseLabelFormRef = ref<ElFormInstance>();
|
|
@@ -564,25 +567,31 @@ const foodIngredientList = ref<FoodIngredientVO[]>([]);
|
|
|
const selectedIngredientList = ref<FoodIngredientVO[]>([]);
|
|
|
const selectedIngredientListBak = ref<FoodIngredientVO[]>([]);
|
|
|
const foodIngredienRef = ref<ElTableInstance>();
|
|
|
-
|
|
|
+
|
|
|
+const leftList = ref<FoodIngredientVO[]>([]);
|
|
|
+const leftCalories = ref<number>(0.0);
|
|
|
+const rightList = ref<FoodIngredientVO[]>([]);
|
|
|
+
|
|
|
const caloriesSum = ref('0.0000');
|
|
|
const quantitySum = ref('0.00');
|
|
|
|
|
|
const leftIndex = ref('1')
|
|
|
-const rightIndex = ref('2')
|
|
|
-const currentIndex = ref('1')
|
|
|
+const rightIndex = ref('2')
|
|
|
+const currentIndex = ref('1')
|
|
|
+
|
|
|
+
|
|
|
const pieOption = ref({
|
|
|
legend: {
|
|
|
orient: 'horizontal',
|
|
|
- bottom:'bottom',
|
|
|
- data: ['蛋白质 30%', '脂肪 20%', '碳水化合物 50%']
|
|
|
+ bottom: 'bottom',
|
|
|
+ data: ['蛋白质 30%', '脂肪 20%', '碳水化合物 50%']
|
|
|
},
|
|
|
- title:{
|
|
|
- text:'三大营养素元素质量占比',
|
|
|
- left:'center'
|
|
|
+ title: {
|
|
|
+ text: '三大营养素元素质量占比',
|
|
|
+ left: 'center'
|
|
|
},
|
|
|
series: [
|
|
|
- {
|
|
|
+ {
|
|
|
type: 'pie',
|
|
|
radius: ['50%', '70%'],
|
|
|
avoidLabelOverlap: false,
|
|
@@ -603,7 +612,7 @@ const pieOption = ref({
|
|
|
data: [
|
|
|
{ value: 30, name: '蛋白质 30%' },
|
|
|
{ value: 20, name: '脂肪 20%' },
|
|
|
- { value: 50, name: '碳水化合物 50%' },
|
|
|
+ { value: 50, name: '碳水化合物 50%' },
|
|
|
]
|
|
|
}
|
|
|
]
|
|
@@ -747,17 +756,17 @@ const data = reactive<PageData<RecipeForm, RecipeQuery>>({
|
|
|
],
|
|
|
price: [
|
|
|
{ required: true, message: "食谱价格不能为空", trigger: "blur" }
|
|
|
- ],
|
|
|
+ ],
|
|
|
}
|
|
|
});
|
|
|
|
|
|
const { queryParams, form, rules } = toRefs(data);
|
|
|
|
|
|
/** 查询食材分类列表 */
|
|
|
-const getListTree = async () => {
|
|
|
- const res = await listTree();
|
|
|
+const getListTree = async () => {
|
|
|
+ const res = await listTree();
|
|
|
foodCategoryList.value = res.rows;
|
|
|
-
|
|
|
+
|
|
|
}
|
|
|
|
|
|
/** 关闭按钮 */
|
|
@@ -893,7 +902,7 @@ const handleSelectChange2 = (selection: DiseaseLabelVO[], row: DiseaseLabelVO) =
|
|
|
selecteddiseaseLabelList2.value = tList.value;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
|
|
|
/** 多选框选中数据 */
|
|
|
const handleSelectAllChange3 = (selection: FoodIngredientVO[]) => {
|
|
@@ -928,7 +937,7 @@ const handleSelectChange3 = (selection: FoodIngredientVO[], row: FoodIngredientV
|
|
|
selectedIngredientList.value.push(row);
|
|
|
} else {
|
|
|
let tList = ref<FoodIngredientVO[]>([]);
|
|
|
- selectedIngredientList.value.forEach(item => {
|
|
|
+ selectedIngredientList.value.forEach(item => {
|
|
|
if (item.foodIngredientId != row.foodIngredientId) {
|
|
|
tList.value.push(item);
|
|
|
}
|
|
@@ -969,7 +978,7 @@ const handleSelectedDelete2 = (row?: DiseaseLabelVO[]) => {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
+
|
|
|
|
|
|
/** 查询食谱管理列表 */
|
|
|
const getRecipeCategoryList = async () => {
|
|
@@ -1054,10 +1063,10 @@ const handleSelectedconfirm2 = async () => {
|
|
|
}
|
|
|
|
|
|
const handleSelectedconfirm3 = async () => {
|
|
|
- dialog3.visible = false;
|
|
|
- selectedIngredientListBak.value = selectedIngredientList.value;
|
|
|
- selectedIngredientList.value=[];
|
|
|
- foodIngredienRef.value?.clearSelection();
|
|
|
+ dialog3.visible = false;
|
|
|
+ selectedIngredientListBak.value = selectedIngredientList.value;
|
|
|
+ selectedIngredientList.value = [];
|
|
|
+ foodIngredienRef.value?.clearSelection();
|
|
|
}
|
|
|
|
|
|
const addDiseaseLabelDialog = async () => {
|
|
@@ -1162,40 +1171,40 @@ const diseaseLabelSubmitForm2 = async () => {
|
|
|
|
|
|
/** 查询食材管理列表 */
|
|
|
const getListFoodIngredient = async () => {
|
|
|
- const res = await listFoodIngredient(foodIngredientQuery.value);
|
|
|
+ const res = await listFoodIngredient(foodIngredientQuery.value);
|
|
|
foodIngredientList.value = res.rows;
|
|
|
- totalFood.value = res.total;
|
|
|
- if (res.rows&&res.rows.length>0&&selectedIngredientList.value&&selectedIngredientList.value.length>0) {
|
|
|
+ totalFood.value = res.total;
|
|
|
+ if (res.rows && res.rows.length > 0 && selectedIngredientList.value && selectedIngredientList.value.length > 0) {
|
|
|
setTimeout(() => {
|
|
|
let tJson = ref({})
|
|
|
- selectedIngredientList.value.forEach(item => {
|
|
|
- tJson.value[item.foodIngredientId] = true;
|
|
|
- })
|
|
|
-
|
|
|
- foodIngredientList.value.forEach(item => {
|
|
|
- if (tJson.value[item.foodIngredientId]) {
|
|
|
- foodIngredienRef.value.toggleRowSelection(item, true);
|
|
|
- }
|
|
|
- })
|
|
|
- }, 500);
|
|
|
+ selectedIngredientList.value.forEach(item => {
|
|
|
+ tJson.value[item.foodIngredientId] = true;
|
|
|
+ })
|
|
|
+
|
|
|
+ foodIngredientList.value.forEach(item => {
|
|
|
+ if (tJson.value[item.foodIngredientId]) {
|
|
|
+ foodIngredienRef.value.toggleRowSelection(item, true);
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }, 500);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const handleNodeClick = async (data: FoodCategoryVO) => {
|
|
|
- if(foodIngredientQuery.value.foodCategoryId!=data.foodCategoryId){
|
|
|
- foodIngredientQuery.value.foodCategoryId=data.foodCategoryId;
|
|
|
- await getListFoodIngredient();
|
|
|
+ if (foodIngredientQuery.value.foodCategoryId != data.foodCategoryId) {
|
|
|
+ foodIngredientQuery.value.foodCategoryId = data.foodCategoryId;
|
|
|
+ await getListFoodIngredient();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
const openAddFoodDialog = async () => {
|
|
|
dialog3.visible = true;
|
|
|
dialog3.title = '添加食材';
|
|
|
- foodIngredientQuery.value.name=undefined;
|
|
|
- foodIngredientQuery.value.foodCategoryId=undefined;
|
|
|
+ foodIngredientQuery.value.name = undefined;
|
|
|
+ foodIngredientQuery.value.foodCategoryId = undefined;
|
|
|
await getListTree();
|
|
|
await getListFoodIngredient();
|
|
|
-
|
|
|
+
|
|
|
if (selectedIngredientListBak.value && selectedIngredientListBak.value.length > 0) {
|
|
|
let dataMap = ref({});
|
|
|
selectedIngredientListBak.value.forEach(item => {
|
|
@@ -1212,41 +1221,41 @@ const openAddFoodDialog = async () => {
|
|
|
}
|
|
|
|
|
|
const editFoodquantity = async (data: FoodIngredientVO) => {
|
|
|
- let quantity=Number(data.quantity)/100;
|
|
|
- let calories=Number(data.calories);
|
|
|
- data.caloriesForInput=Math.floor(quantity*calories*100)/100;
|
|
|
-
|
|
|
- let qSum=ref(0.0);
|
|
|
- let cSum=ref(0.0);
|
|
|
- selectedIngredientListBak.value.forEach(item=>{
|
|
|
- if(item.caloriesForInput){
|
|
|
- cSum.value+=item.caloriesForInput;
|
|
|
+ let quantity = Number(data.quantity) / 100;
|
|
|
+ let calories = Number(data.calories);
|
|
|
+ data.caloriesForInput = Math.floor(quantity * calories * 100) / 100;
|
|
|
+
|
|
|
+ let qSum = ref(0.0);
|
|
|
+ let cSum = ref(0.0);
|
|
|
+ selectedIngredientListBak.value.forEach(item => {
|
|
|
+ if (item.caloriesForInput) {
|
|
|
+ cSum.value += item.caloriesForInput;
|
|
|
}
|
|
|
- if(item.quantity){
|
|
|
- qSum.value+=Number(item.quantity);
|
|
|
+ if (item.quantity) {
|
|
|
+ qSum.value += Number(item.quantity);
|
|
|
}
|
|
|
- });
|
|
|
- caloriesSum.value=(Math.floor(cSum.value*100)/100).toString();
|
|
|
- quantitySum.value=(Math.floor(qSum.value*100)/100).toString();
|
|
|
+ });
|
|
|
+ caloriesSum.value = (Math.floor(cSum.value * 100) / 100).toString();
|
|
|
+ quantitySum.value = (Math.floor(qSum.value * 100) / 100).toString();
|
|
|
}
|
|
|
|
|
|
const deleteFoodquantity = async (data: FoodIngredientVO) => {
|
|
|
let tList = ref<FoodIngredientVO[]>([]);
|
|
|
selectedIngredientListBak.value.forEach(item => {
|
|
|
- if(data.foodIngredientId!=item.foodIngredientId){
|
|
|
+ if (data.foodIngredientId != item.foodIngredientId) {
|
|
|
tList.value.push(item);
|
|
|
}
|
|
|
});
|
|
|
- selectedIngredientListBak.value= tList.value
|
|
|
- selectedIngredientList.value=[];
|
|
|
- foodIngredienRef.value?.clearSelection();
|
|
|
+ selectedIngredientListBak.value = tList.value
|
|
|
+ selectedIngredientList.value = [];
|
|
|
+ foodIngredienRef.value?.clearSelection();
|
|
|
}
|
|
|
|
|
|
/** 提交按钮 */
|
|
|
-const submitForm = () => {
|
|
|
+const submitForm = () => {
|
|
|
foodIngredientFormRef.value?.validate(async (valid: boolean) => {
|
|
|
if (valid) {
|
|
|
- if(!selectedIngredientListBak.value||selectedIngredientListBak.value.length==0){
|
|
|
+ if (!selectedIngredientListBak.value || selectedIngredientListBak.value.length == 0) {
|
|
|
proxy?.$modal.msgError("请先添加【食材组成】部分的信息");
|
|
|
return;
|
|
|
}
|
|
@@ -1255,23 +1264,23 @@ const submitForm = () => {
|
|
|
Object.assign(params.value, form.value);
|
|
|
params.value.suitableDept = form.value.suitableDeptList.join(',')
|
|
|
params.value.suitableDisease = selecteddiseaseLabelList.value.map(v => v.labelId).join(',')
|
|
|
- params.value.avoidDisease = selecteddiseaseLabelList2.value.map(v => v.labelId).join(',')
|
|
|
+ params.value.avoidDisease = selecteddiseaseLabelList2.value.map(v => v.labelId).join(',')
|
|
|
params.value.mealTime = params.value.mealTimes.join(',')
|
|
|
- params.value.foodList=[];
|
|
|
+ params.value.foodList = [];
|
|
|
|
|
|
- for(let item of selectedIngredientListBak.value){
|
|
|
- let dataJSon={};
|
|
|
- dataJSon['foodIngredientId']=item.foodIngredientId;
|
|
|
- dataJSon['quantity']=item.quantity;
|
|
|
- if(!item.quantity){
|
|
|
+ for (let item of selectedIngredientListBak.value) {
|
|
|
+ let dataJSon = {};
|
|
|
+ dataJSon['foodIngredientId'] = item.foodIngredientId;
|
|
|
+ dataJSon['quantity'] = item.quantity;
|
|
|
+ if (!item.quantity) {
|
|
|
buttonLoading.value = false;
|
|
|
proxy?.$modal.msgError("【食材用量】不能为空");
|
|
|
return;
|
|
|
}
|
|
|
- dataJSon['calories']=item.caloriesForInput;
|
|
|
- dataJSon['remark']=item.remark;
|
|
|
+ dataJSon['calories'] = item.caloriesForInput;
|
|
|
+ dataJSon['remark'] = item.remark;
|
|
|
params.value.foodList.push(dataJSon);
|
|
|
- }
|
|
|
+ }
|
|
|
|
|
|
if (form.value.recipeId) {
|
|
|
await updateRecipe(params.value).finally(() => buttonLoading.value = false);
|
|
@@ -1279,7 +1288,7 @@ const submitForm = () => {
|
|
|
await addRecipe(params.value).then(res => {
|
|
|
form.value.recipeId = res.data;
|
|
|
}).finally(() => buttonLoading.value = false);
|
|
|
- }
|
|
|
+ }
|
|
|
proxy?.$modal.msgSuccess("操作成功");
|
|
|
close();
|
|
|
}
|
|
@@ -1290,77 +1299,154 @@ const submitForm = () => {
|
|
|
const getList = async () => {
|
|
|
const recipeId = route.params && route.params.id;
|
|
|
const vRecipeId = route.params && route.params.vid;
|
|
|
- let id=undefined;
|
|
|
- if(vRecipeId){
|
|
|
- isView.value=true;
|
|
|
- id=vRecipeId;
|
|
|
- }else{
|
|
|
- isView.value=false ;
|
|
|
- id=recipeId;
|
|
|
+ let id = undefined;
|
|
|
+ if (vRecipeId) {
|
|
|
+ isView.value = true;
|
|
|
+ id = vRecipeId;
|
|
|
+ } else {
|
|
|
+ isView.value = false;
|
|
|
+ id = recipeId;
|
|
|
}
|
|
|
-
|
|
|
- if (id&&id!='0') {
|
|
|
+
|
|
|
+ if (id && id != '0') {
|
|
|
dataLoading.value = true;
|
|
|
const res = await getRecipe(id as string);
|
|
|
Object.assign(form.value, res.data);
|
|
|
-
|
|
|
- if(res.data.suitableDept&&res.data.suitableDept.length>0){
|
|
|
- form.value.suitableDeptList=res.data.suitableDept.split(',');
|
|
|
- }
|
|
|
- if(res.data.avoidDiseaseList&&res.data.avoidDiseaseList.length>0){
|
|
|
- selecteddiseaseLabelListBak2.value=res.data.avoidDiseaseList;
|
|
|
- selecteddiseaseLabelList2.value=res.data.avoidDiseaseList;
|
|
|
+
|
|
|
+ if (res.data.suitableDept && res.data.suitableDept.length > 0) {
|
|
|
+ form.value.suitableDeptList = res.data.suitableDept.split(',');
|
|
|
+ }
|
|
|
+ if (res.data.avoidDiseaseList && res.data.avoidDiseaseList.length > 0) {
|
|
|
+ selecteddiseaseLabelListBak2.value = res.data.avoidDiseaseList;
|
|
|
+ selecteddiseaseLabelList2.value = res.data.avoidDiseaseList;
|
|
|
form.value.avoidDisease = selecteddiseaseLabelList2.value.map(v => v.labelName).join(',')
|
|
|
- }
|
|
|
- if(res.data.suitableDiseaseList&&res.data.suitableDiseaseList.length>0){
|
|
|
- selecteddiseaseLabelListBak.value=res.data.suitableDiseaseList;
|
|
|
- selecteddiseaseLabelList.value=res.data.suitableDiseaseList;
|
|
|
+ }
|
|
|
+ if (res.data.suitableDiseaseList && res.data.suitableDiseaseList.length > 0) {
|
|
|
+ selecteddiseaseLabelListBak.value = res.data.suitableDiseaseList;
|
|
|
+ selecteddiseaseLabelList.value = res.data.suitableDiseaseList;
|
|
|
form.value.suitableDisease = selecteddiseaseLabelList.value.map(v => v.labelName).join(',')
|
|
|
- }
|
|
|
- if(res.data.mealTime&&res.data.mealTime.length>0){
|
|
|
+ }
|
|
|
+ if (res.data.mealTime && res.data.mealTime.length > 0) {
|
|
|
form.value.mealTimes = res.data.mealTime.split(',')
|
|
|
- }
|
|
|
- if(res.data.foodList&&res.data.foodList.length>0){
|
|
|
- selectedIngredientListBak.value=res.data.foodList;
|
|
|
- let qSum=ref(0.0);
|
|
|
- let cSum=ref(0.0);
|
|
|
- selectedIngredientListBak.value.forEach(item=>{
|
|
|
- let quantity=Number(item.quantity)/100;
|
|
|
- let calories=Number(item.calories);
|
|
|
- item.caloriesForInput=Math.floor(quantity*calories*100)/100;
|
|
|
-
|
|
|
- if(item.caloriesForInput){
|
|
|
- cSum.value+=item.caloriesForInput;
|
|
|
+ }
|
|
|
+ if (res.data.foodList && res.data.foodList.length > 0) {
|
|
|
+ selectedIngredientListBak.value = res.data.foodList;
|
|
|
+ let qSum = ref(0.0);
|
|
|
+ let cSum = ref(0.0);
|
|
|
+ selectedIngredientListBak.value.forEach(item => {
|
|
|
+ let quantity = Number(item.quantity) / 100;
|
|
|
+ let calories = Number(item.calories);
|
|
|
+ item.caloriesForInput = Math.floor(quantity * calories * 100) / 100;
|
|
|
+
|
|
|
+ if (item.caloriesForInput) {
|
|
|
+ cSum.value += item.caloriesForInput;
|
|
|
}
|
|
|
- if(item.quantity){
|
|
|
- qSum.value+=Number(item.quantity);
|
|
|
+ if (item.quantity) {
|
|
|
+ qSum.value += Number(item.quantity);
|
|
|
}
|
|
|
});
|
|
|
- caloriesSum.value=(Math.floor(cSum.value*100)/100).toString();
|
|
|
- quantitySum.value=(Math.floor(qSum.value*100)/100).toString();
|
|
|
- }
|
|
|
-
|
|
|
+ caloriesSum.value = (Math.floor(cSum.value * 100) / 100).toString();
|
|
|
+ quantitySum.value = (Math.floor(qSum.value * 100) / 100).toString();
|
|
|
+ }
|
|
|
+
|
|
|
dataLoading.value = false;
|
|
|
- }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
const handleMenumSelect = async (key: string, keyPath: string[]) => {
|
|
|
- currentIndex.value=key.toString()
|
|
|
+ currentIndex.value = key.toString()
|
|
|
}
|
|
|
|
|
|
-const showNutrientAnalysisDialog =async ( ) => {
|
|
|
- dialog4.visible=true;
|
|
|
- dialog4.title='营养数据分析';
|
|
|
+const nutrientAnalysisLeftData = async () => {
|
|
|
+ let dataTemplate = JSON.stringify({
|
|
|
+ nutrientName: '',
|
|
|
+ nutrientQuantity: 0,
|
|
|
+ nutrientRatio: 0,
|
|
|
+ nutrientRefVal: ''
|
|
|
+ })
|
|
|
+
|
|
|
+ leftList.value=[];
|
|
|
+ let protein = ref<FoodIngredientVO>();
|
|
|
+ let fat = ref<FoodIngredientVO>();
|
|
|
+ let carbohydrate = ref<FoodIngredientVO>();
|
|
|
+ protein.value = JSON.parse(dataTemplate);
|
|
|
+ fat.value = JSON.parse(dataTemplate);
|
|
|
+ carbohydrate.value = JSON.parse(dataTemplate);
|
|
|
+ leftList.value.push(protein.value);
|
|
|
+ leftList.value.push(fat.value);
|
|
|
+ leftList.value.push(carbohydrate.value);
|
|
|
+
|
|
|
+ let nrJson = {};
|
|
|
+ nutrient_reference.value.forEach(nr => {
|
|
|
+ nrJson[nr.label] = nr;
|
|
|
+ })
|
|
|
+ protein.value.nutrientRefVal = nrJson['nutrient_protein'].value;
|
|
|
+ fat.value.nutrientRefVal = nrJson['nutrient_fat'].value;
|
|
|
+ carbohydrate.value.nutrientRefVal = nrJson['nutrient_carbohydrate'].value;
|
|
|
+ protein.value.nutrientName = '蛋白质';
|
|
|
+ fat.value.nutrientName = '脂肪';
|
|
|
+ carbohydrate.value.nutrientName = '碳水化合物';
|
|
|
+
|
|
|
+ let sum: number = 0.0;
|
|
|
+
|
|
|
+ selectedIngredientListBak.value.forEach(item => {
|
|
|
+ protein.value.nutrientQuantity += Number(item.protein);
|
|
|
+ fat.value.nutrientQuantity += Number(item.fat);
|
|
|
+ carbohydrate.value.nutrientQuantity += Number(item.carbohydrate);
|
|
|
+ sum += protein.value.nutrientQuantity + fat.value.nutrientQuantity + carbohydrate.value.nutrientQuantity;
|
|
|
+ leftCalories.value += Number(item.caloriesForInput);
|
|
|
+ })
|
|
|
+
|
|
|
+ protein.value.nutrientRatio = (sum > 0 ? (protein.value.nutrientQuantity / sum * 100).toFixed(2) : '0.00') + '%';
|
|
|
+ fat.value.nutrientRatio = (sum > 0 ? (fat.value.nutrientQuantity / sum * 100).toFixed(2) : '0.00') + '%';
|
|
|
+ carbohydrate.value.nutrientRatio = (sum > 0 ? (carbohydrate.value.nutrientQuantity / sum * 100).toFixed(2) : '0.00') + '%';
|
|
|
+
|
|
|
+ pieOption.value.legend.data = []
|
|
|
+ pieOption.value.series[0].data = []
|
|
|
+ leftList.value.forEach(item => {
|
|
|
+ pieOption.value.series[0].data.push({ value: Number(item.nutrientRatio.replace('%', '')), name: item.nutrientName + ' ' + item.nutrientRatio })
|
|
|
+ pieOption.value.legend.data.push(item.nutrientName + ' ' + item.nutrientRatio);
|
|
|
+ });
|
|
|
+
|
|
|
+ return nrJson['nutritional_data_analysis'].remark
|
|
|
}
|
|
|
|
|
|
-// nutrientAnalysis
|
|
|
+
|
|
|
+const nutrientAnalysisRightData = async (jsonStr:string) => {
|
|
|
+ let nutritionalDataAnalysis = JSON.parse(jsonStr);
|
|
|
+ nutritionalDataAnalysis.forEach((na:any) => {
|
|
|
+ let showData={}
|
|
|
+ selectedIngredientListBak.value.forEach(item => {
|
|
|
+ if(!showData['nutrientName']){
|
|
|
+ showData['nutrientUnit'] =na.unit;
|
|
|
+ showData['nutrientName'] = na.remark;
|
|
|
+ showData['nutrientQuantity'] = item[na.name]?Number(item[na.name]) : 0;
|
|
|
+ } else{
|
|
|
+ showData['nutrientQuantity'] = (item[na.name]?Number(item[na.name]):0)+showData['nutrientQuantity'];
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ rightList.value.push(JSON.parse(JSON.stringify(showData)));
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+const nutrientAnalysisData = async () => {
|
|
|
+ let jsonStr:string=await nutrientAnalysisLeftData();
|
|
|
+ await nutrientAnalysisRightData(jsonStr);
|
|
|
+}
|
|
|
+
|
|
|
+const showNutrientAnalysisDialog = async () => {
|
|
|
+ dialog4.visible = true;
|
|
|
+ dialog4.title = '营养数据分析';
|
|
|
+ nutrientAnalysisData();
|
|
|
+}
|
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
getDiseaseLabelList()
|
|
|
getDeptTree();
|
|
|
- getRecipeCategoryList();
|
|
|
- getList();
|
|
|
+ getRecipeCategoryList();
|
|
|
+ getList();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
@@ -1402,12 +1488,18 @@ onMounted(() => {
|
|
|
.el-pagination__sizes {
|
|
|
width: 100px;
|
|
|
}
|
|
|
+
|
|
|
.chart-center {
|
|
|
display: flex;
|
|
|
- flex-direction: column; /* 垂直方向排列 */
|
|
|
- justify-content: center; /* 垂直居中 */
|
|
|
- align-items: center; /* 水平居中 */
|
|
|
- height: 100%; /* 父容器需有高度 */
|
|
|
- min-height: 300px; /* 可根据需要设置 */
|
|
|
+ flex-direction: column;
|
|
|
+ /* 垂直方向排列 */
|
|
|
+ justify-content: center;
|
|
|
+ /* 垂直居中 */
|
|
|
+ align-items: center;
|
|
|
+ /* 水平居中 */
|
|
|
+ height: 100%;
|
|
|
+ /* 父容器需有高度 */
|
|
|
+ min-height: 300px;
|
|
|
+ /* 可根据需要设置 */
|
|
|
}
|
|
|
</style>
|