<template>
<el-card shadow="never" class="mb-2" v-loading="cardLoading">
<div>
<el-divider content-position="left">用量录入</el-divider>
<el-form :model="formData" label-width="auto" style="max-width: 600px">
<el-form-item label="用餐客户">
<el-select @change="selectOrgId" v-model="formData.clientOrgId" placeholder="请选择客户">
<el-option v-for="item in customerData" :key="item.id" :label="item.orgName" :value="item.id"></el-option>
</el-select>
</el-form-item>
<!-- https://blog.csdn.net/qq_45104829/article/details/139085998 -->
<el-form-item label="用餐时间">
<el-date-picker @change="changeTime" :disabled="isEdit === true" style="width: 100%"
v-model="formData.measurementDate" type="date" placeholder="请选择时间" format="YYYY-MM-DD"
value-format="YYYY-MM-DD" />
</el-form-item>
</el-form>
</div>
<el-divider content-position="left">用餐录入</el-divider>
<div class="table-box">
<el-form :inline="true" label-width="auto" :model="formInline" class="meal-table-inline">
<el-form-item label="餐次">
<el-select style="width: 240px" v-model="whichMealID" placeholder="请选择餐次">
<el-option v-for="item in mealTimesData" :key="item.id" :label="item.scheduleName"
:value="item.id"></el-option>
</el-select>
</el-form-item>
<el-form-item label="食材名称">
<el-select v-model="formInline.foodObj" value-key="id" filterable remote reserve-keyword placeholder="请输入搜索食材"
:remote-method="remoteMethod" :loading="otherForm.loading" style="width: 240px">
<el-option v-for="item in foodAllData" :key="item.id" :label="item.ingredientName" :value="item" />
</el-select>
</el-form-item>
<el-form-item label="用量">
<el-input style="width: 240px" oninput="value=value.replace(/[^\d.]/g,'')" v-model="formInline.useNum"
placeholder="请输入用量">
<template #append>
<el-select value-key="unitValue" v-model="unitObj" placeholder="选择单位" style="width: 115px">
<el-option v-for="(item, index) in unitList" :key="index" :label="item.unitName" :value="item" />
</el-select>
</template>
</el-input>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="onSubmit">新增</el-button>
</el-form-item>
</el-form>
<!-- ttttttttttt -->
<el-table :data="tableData" border :span-method="objectSpanMethod">
<el-table-column align="center" prop="whichMealName" label="餐次" min-width="110" />
<el-table-column label="用餐人数" min-width="110">
<template v-slot="scope">
<el-input v-model="scope.row.dinersNum" type="text" />
</template>
</el-table-column>
<el-table-column label="权重值" min-width="110">
<template v-slot="scope">
<el-input v-model="scope.row.weightNum" type="text" />
</template>
</el-table-column>
<el-table-column align="center" prop="ingredientName" label="食品名称" min-width="150"><template v-slot="scope">
<span class="food-name" @click="handleEdit(scope.row)">{{
scope.row.ingredientName
}}</span>
</template>
</el-table-column>
<el-table-column label="用量">
<template v-slot="scope">
<!-- <span>{{ scope.row.consumptionValue }}</span> -->
<span>{{ scope.row.inputValue }}</span>
<span>{{ scope.row.inputUnit }}</span>
</template>
</el-table-column>
<el-table-column label="摄入量" min-width="110">
<template v-slot="scope">
<span>{{ scope.row.intakeValue }}克</span>
</template>
</el-table-column>
<el-table-column label="可食部分">
<template v-slot="scope">
<span>{{ scope.row.ediblePortion }}%</span>
</template>
</el-table-column>
<el-table-column label="烹调损失率" min-width="110">
<template v-slot="scope">
<span>{{ scope.row.attritionRate }}%</span>
</template>
</el-table-column>
<!-- <el-table-column label="营养成分">
<el-table-column
min-width="110"
v-for="(item, index) in standardNutritionDictionary"
:key="index"
:label="item.nutrientName"
>
<template v-slot="scope">
<span>
{{ scope.row.NutrientList[index].contentValue
}}{{ scope.row.NutrientList[index].unit }}</span
>
</template>
</el-table-column>
</el-table-column> -->
<el-table-column align="center" fixed="right" label="操作" width="180">
<template #default="scope">
<el-button type="danger" @click="delItem(scope.$index)">删除</el-button>
</template>
</el-table-column>
</el-table>
</div>
<div class="end-button">
<el-button size="large" @click="ClearClose">取消</el-button>
<el-button size="large" type="primary" :loading="submitLoading" @click="addNewSubmiss">提 交</el-button>
</div>
<editFoodIngredient ref="childRef" :fatherMessage="fatherMessage" @getvale="comeFromChild" />
</el-card>
</template>
<script setup lang="ts">
// https://juejin.cn/post/6942776008705572872?searchId=20240902093501275A4C7131E104E15BCD
import Decimal from "decimal.js";
Decimal.set({ precision: 3 });
import { ref, computed, onMounted, reactive } from "vue";
import { useRoute, useRouter } from "vue-router";
import { ElMessage, ElMessageBox } from "element-plus";
import API_FOODDICTIONARY from "@/api/foodDictionaryApi";
import API_NUTRIENT from "@/api/nutrientApi";
import API_FOOD from "@/api/foodApi";
import API_MEAL from "@/api/mealApi";
import { totalCustomer } from "@/hooks/selectCustomer";
import editFoodIngredient from "../FoodIngredientManagement/components/editFoodIngredient.vue";
const { requestAllCustomer } = totalCustomer();
let fatherMessage = ref<boolean>(false); // 字符
const route = useRoute();
const router = useRouter();
const standardNutritionDictionary = ref([]);
const cardLoading = ref(false);
const submitLoading = ref(false);
const customerData = ref([]);
const mealTimesData = ref([]);
const foodAllData = ref([]);
const tableData = ref([]);
const whichMealID = ref("");
const childRef = ref();
const formInline = ref({
foodObj: "",
useNum: "",
useUnit: ""
});
const otherForm = reactive({
other: "",
loading: false,
options: []
});
const unitList = ref([
{ unitName: "千克", unitValue: 1000 },
{ unitName: "克", unitValue: 1 },
{ unitName: "公斤", unitValue: "1000" },
{ unitName: "斤", unitValue: 500 }
]);
const unitObj = ref({
unitName: "斤",
unitValue: 500
});
const formData = ref({
clientOrgId: "",
// diners: "",
measurementDate: ""
});
const isEdit = ref(false);
const onChildClick = async val => { };
onMounted(() => {
getMealDictionary();
GetNutritionDictionary(null);
getAllCustomer();
});
async function getAllCustomer() {
let resList = await requestAllCustomer();
customerData.value = resList.resultData;
}
const selectOrgId = itemID => {
// let resData = customerData.value.find(item => item.id === itemID);
// formData.value.diners = resData.peopleCount;
};
const handleTableData = (tableData: any) => {
let rowSpanArr: any = [],
position = 0;
tableData.forEach((item: any, index: number) => {
if (index == 0) {
rowSpanArr.push(1);
position = 0;
} else {
if (item.whichMealName == tableData[index - 1].whichMealName) {
rowSpanArr[position] += 1; //id相同,数组中的某一项值+1
rowSpanArr.push(0); // 被合并的行,push 0 占位
} else {
rowSpanArr.push(1);
position = index;
}
}
});
return rowSpanArr;
};
const objectSpanMethod = ({ row, column, rowIndex, columnIndex }) => {
let rowSpanArr = handleTableData(tableData.value);
if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2) {
const rowSpan = rowSpanArr[rowIndex];
return {
rowspan: rowSpan, //行
colspan: 1 //列
};
}
};
const remoteMethod = val => {
if (val) {
const postData = {
pageSize: 9999,
pageNum: 1,
ingredientName: val
};
otherForm.loading = true;
API_FOOD.foodPageList(postData)
.then(resData => {
if (resData.data.list.length === 0) {
formInline.value.foodObj = "";
foodAllData.value.value = [];
return;
}
setTimeout(() => {
foodAllData.value = resData.data.list.filter(item => {
return item.ingredientName
.toLowerCase()
.includes(val.toLowerCase());
});
}, 100);
})
.finally(() => {
otherForm.loading = false;
});
} else {
foodAllData.value.value = [];
}
};
const getGoodsDetail = val => {
if (route.query.id === undefined) {
return;
}
API_MEAL.detailMeal(route.query.id)
.then(resData => {
formData.value = resData.data;
isEdit.value = true;
var CombineBackData = [];
resData.data.consumptionMealSchedules.map(item => {
item.consumptionItems.map(each => {
var floorData = combineNewArrayNutrient(
each.computed.contentValues,
standardNutritionDictionary.value
);
CombineBackData.push({
ediblePortion: each.ingredientEdiblePortion,
attritionRate: each.ingredientAttritionRate,
intakeValue: each.computed.intakeValue,
// ...each,
ingredientName: each.ingredientName,
consumptionValue: each.computed.consumptionValue,
ingredientId: each.ingredientId,
inputValue: each.inputValue,
inputUnit: each.inputUnit,
sortNum: each.sortNum,
mealScheduleId: item.refMealScheduleId,
dinersNum: item.diners,
weightNum: item.weight,
whichMealName: getMealName(item.refMealScheduleId),
NutrientList: floorData
});
});
});
console.log(CombineBackData);
sortFun(CombineBackData);
})
.finally(() => { });
};
// SSSSSSSSSSS?
const sortFun = sortList => {
sortList.sort((a, b) => {
return a.whichMealName > b.whichMealName ? 1 : -1;
});
const items = sortList;
const groupedItems = {};
// 先将所有元素按照 mealScheduleId 分组
for (const item of items) {
if (!groupedItems[item.mealScheduleId]) {
groupedItems[item.mealScheduleId] = [];
}
groupedItems[item.mealScheduleId].push(item);
}
const updatedItems = [];
// 遍历每个分组,为每个分组中的空 dinersNum 和 weightNum 附上有值的 dinersNum 和 weightNum
for (const mealScheduleId in groupedItems) {
const dinersNums = groupedItems[mealScheduleId].map(item => item.dinersNum);
const weightNums = groupedItems[mealScheduleId].map(item => item.weightNum);
const nonEmptyDinersNum = dinersNums.find(num => num !== '' && num !== undefined);
const nonEmptyWeightNum = weightNums.find(num => num !== '' && num !== undefined);
groupedItems[mealScheduleId].forEach(item => {
if (item.dinersNum === '' || item.dinersNum === undefined) {
item.dinersNum = nonEmptyDinersNum || '';
}
if (item.weightNum === '' || item.weightNum === undefined) {
item.weightNum = nonEmptyWeightNum || '';
}
updatedItems.push(item);
});
}
console.log(updatedItems);
tableData.value = updatedItems;
console.log(tableData.value)
};
function convertUnitValue(unit) {
let resData = unitList.value.find(item => item.unitName === unit);
return resData.unitValue
}
function findSameIngredientId(itemData, rowData) {
return new Promise((resolve, reject) => {
if (rowData.id === itemData.ingredientId) {
let edibleEatNum = getUsefulEatNum(
itemData.inputValue,
convertUnitValue(itemData.inputUnit),
itemData.ediblePortion
);
const postData = {
id: itemData.ingredientId,
consumptionValue: edibleEatNum
};
API_MEAL.computeMeal(postData)
.then(resdata => {
// console.log(resdata.data)
resolve(resdata.data)
// return Promise.resolve(resdata.data)
})
.finally(() => { });
// return rowData;
} else {
resolve(undefined)
// return Promise.resolve(undefined);;
}
});
// if (rowData.id === itemData.ingredientId) {
// let edibleEatNum = getUsefulEatNum(
// itemData.inputValue,
// convertUnitValue(itemData.inputUnit),
// itemData.ediblePortion
// );
// const postData = {
// id: itemData.ingredientId,
// consumptionValue: edibleEatNum
// };
// API_MEAL.computeMeal(postData)
// .then(resdata => {
// console.log(resdata.data)
// return Promise.resolve(resdata.data)
// })
// .finally(() => { });
// // return rowData;
// } else {
// return Promise.resolve(undefined);;
// }
}
function handleEdit(rowData) {
API_FOOD.foodClassify()
.then(res => {
childRef.value.childMethod(
{ ...rowData, id: rowData.ingredientId },
res.data,
standardNutritionDictionary.value
);
// classifyData.value = res.data;
})
.finally(() => { });
}
// zzzzzzz
const comeFromChild = async rowFoodData => {
const promises = tableData.value.map(async (item, index) => {
if(item.ingredientId==="1826183532297408516"){
console.log(item.ingredientName)
}
const resultData = await findSameIngredientId(item, rowFoodData);
if (resultData) {
// console.log(resultData)
var floorData = combineNewArrayNutrient(
rowFoodData.nutrients,
standardNutritionDictionary.value
);
// xxxxxx
return {
...item,
ediblePortion: resultData.ediblePortion,
attritionRate: resultData.attritionRate,
intakeValue: resultData.computed.intakeValue,
NutrientList: floorData
};
} else {
return {
...item
};
}
});
const numFruits = await Promise.all(promises);
tableData.value = numFruits;
};
const getMealName = mealScheduleId => {
const itemObj = mealTimesData.value.find(item => item.id === mealScheduleId);
return itemObj.scheduleName;
};
const GetNutritionDictionary = val => {
API_NUTRIENT.list()
.then(data => {
standardNutritionDictionary.value = data.data;
getGoodsDetail(val);
})
.finally(() => { });
};
const getMealDictionary = () => {
API_FOODDICTIONARY.listDictionary()
.then(data => {
mealTimesData.value = data.data;
})
.finally(() => { });
};
const getUsefulEatNum = (dosage, UnitNum, eatPart) => {
let newNum = new Decimal(dosage)
.mul(new Decimal(UnitNum));
return newNum.toString();
};
// 这是新增不是提交
const onSubmit = () => {
// console.log(tableData.value)
// let items = [
// { mealScheduleId: 1, dinersNum: '',weightNum: '',name: '小孩', },
// { mealScheduleId: 1, dinersNum: 'A',weightNum: '',name: '我只是', },
// { mealScheduleId: 1, dinersNum: '',weightNum: '', name: '色素',},
// { mealScheduleId: 2, dinersNum: 'B',weightNum: '', name: '啊实打实',},
// { mealScheduleId: 2, dinersNum: '',weightNum: '', name: '大幅度',},
// { mealScheduleId: 2, dinersNum: '',weightNum: '', name: '为的是', },
// { mealScheduleId: 3, dinersNum: 'D',weightNum: '',name: '温恩', },
// { mealScheduleId: 3, dinersNum: 'K', weightNum: '',name: '反感',}
// ];
// let items = [
// { mealScheduleId: 1, dinersNum: '', weightNum: '', name: '小孩' },
// { mealScheduleId: 1, dinersNum: 'A', weightNum: 'A', name: '我只是' },
// { mealScheduleId: 1, dinersNum: '', weightNum: '', name: '色素' },
// { mealScheduleId: 2, dinersNum: 'B', weightNum: 'B', name: '啊实打实' },
// { mealScheduleId: 2, dinersNum: '', weightNum: '', name: '大幅度' },
// { mealScheduleId: 2, dinersNum: '', weightNum: '', name: '为的是' },
// { mealScheduleId: 3, dinersNum: 'D', weightNum: 'D', name: '温恩' },
// { mealScheduleId: 3, dinersNum: 'K', weightNum: 'K', name: '反感' }
// ];
// console.log(changeTable(tableData.value))
// // let items = [
// // { id: 1, value: 'A' },
// // { id: 1, value: '' },
// // { id: 1, value: '' },
// // { id: 2, value: 'B' },
// // { id: 2, value: '' },
// // { id: 2, value: '' },
// // { id: 3, value: 'D' },
// // { id: 3, value: 'K' }
// // ];
// // const idToValue = {};
// // // 第一次遍历,找出每个 id 对应的有值的 value
// // for (const item of items) {
// // if (item.value && !idToValue[item.id]) {
// // idToValue[item.id] = item.value;
// // }
// // }
// // // 第二次遍历,将相同 id 的所有元素的 value 设置为这个有值的 value
// // items = items.map(item => {
// // if (idToValue[item.id]) {
// // return { ...item, value: idToValue[item.id] };
// // }
// // return item;
// // });
// // console.log(items);
// // 创建一个对象来存储每个 id 对应的有值的 value
// // console.log(tableData.value)
// return
if (whichMealID.value === "") {
ElMessage.error("请选择餐次");
return;
}
if (formInline.value.foodObj === "") {
ElMessage.error("请输入食材名称");
return;
}
if (formInline.value.useNum === "") {
ElMessage.error("请输入用量");
return;
}
if (unitObj.value === "") {
ElMessage.error("请输入单位");
return;
}
let edibleEatNum = getUsefulEatNum(
formInline.value.useNum,
unitObj.value.unitValue,
formInline.value.foodObj.ediblePortion
);
const postData = {
id: formInline.value.foodObj.id,
consumptionValue: edibleEatNum
};
API_MEAL.computeMeal(postData)
.then(data => {
const resuFind = findSameIDName(
tableData.value,
data.data.ingredientName,
whichMealID.value
);
if (resuFind) {
ElMessage.error(
"当前餐次已经包含" + data.data.ingredientName + ",不可重复添加"
);
return;
}
tableData.value.push({
ingredientName: formInline.value.foodObj.ingredientName,
NutrientList: combineNewArrayNutrient(
data.data.computed.contentValues,
standardNutritionDictionary.value
),
consumptionValue: edibleEatNum,
ingredientId: formInline.value.foodObj.id,
inputValue: formInline.value.useNum,
inputUnit: unitObj.value.unitName,
sortNum: tableData.value.length === 0 ? 0 : tableData.value.length,
mealScheduleId: whichMealID.value,
dinersNum: findDiners(tableData.value, whichMealID.value),
weightNum: findWeight(tableData.value, whichMealID.value),
whichMealName: getMealName(whichMealID.value),
ediblePortion: data.data.ediblePortion,
attritionRate: data.data.attritionRate,
intakeValue: data.data.computed.intakeValue
});
sortFun(tableData.value);
})
.finally(() => { });
};
// ffffffff/
function findWeight(list, Meal) {
// console.log(list)
var newData = list.filter(item => item.mealScheduleId === Meal);
if (newData.length > 0) {
console.log(newData)
const foundItem = newData.find(item => item.weightNum != "");
return foundItem ? foundItem.weightNum : "";
} else {
return "";
}
}
function findDiners(list, Meal) {
var newData = list.filter(item => item.mealScheduleId === Meal);
if (newData.length > 0) {
const foundItem = newData.find(item => item.dinersNum != "");
return foundItem ? foundItem.dinersNum : "";
} else {
return "";
}
}
// weightNum
function findSameIDName(array, nameFind, MealIDFind) {
return array.some(
item =>
item.ingredientName === nameFind && item.mealScheduleId === MealIDFind
);
}
function combineNewArrayNutrient(smallList, longList) {
longList.forEach((obj2, index) => {
const found = smallList.some(
obj1 => obj1.nutrientName === obj2.nutrientName
);
if (!found) {
smallList.splice(index, 0, {
...obj2,
contentValue: "0"
});
}
});
return smallList;
}
const delItem = indexNum => {
ElMessageBox.confirm("确定删除此条数据吗?", "提示", {
confirmButtonText: "删除",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
tableData.value.splice(indexNum, 1);
ElMessage({
type: "success",
message: "成功删除"
});
})
.catch(() => {
ElMessage({
type: "info",
message: "取消删除"
});
});
};
const emits = defineEmits(["FatherClick"]);
const ClearClose = () => {
router.go(-1)
};
const changeTime = value => {
if (formData.value.clientOrgId === "") {
ElMessage.error("用餐客户不可为空");
formData.value.measurementDate = "";
return;
}
let postData = {
date: formData.value.measurementDate,
clientOrgId: formData.value.clientOrgId
};
API_MEAL.mealInputByDate(postData)
.then(resData => {
if (resData.data != null) {
ElMessage.error(value + "已经录入,请重新选择时间。");
formData.value.measurementDate = "";
}
})
.finally(() => { });
};
const changeTable = listData => {
const result = [];
listData.forEach(item => {
const index = result.findIndex(
r => r.mealScheduleId === item.mealScheduleId
);
if (index === -1) {
result.push({
mealScheduleId: item.mealScheduleId,
sortNum: item.sortNum,
diners: item.dinersNum,
weight: item.weightNum,
consumptionItems: [
{
ingredientId: item.ingredientId,
consumptionValue: item.consumptionValue,
inputValue: item.inputValue,
inputUnit: item.inputUnit,
sortNum: item.sortNum
}
]
});
} else {
result[index].consumptionItems.push({
ingredientId: item.ingredientId,
consumptionValue: item.consumptionValue,
inputValue: item.inputValue,
inputUnit: item.inputUnit,
sortNum: item.sortNum
});
}
});
console.log(result);
return result;
};
// 这是提交数据
const addNewSubmiss = () => {
if (formData.value.id) {
ElMessageBox.confirm("确定提交此次编辑的数据吗?", "提示", {
confirmButtonText: "确认",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
SubmitData();
})
.catch(() => {
ElMessage({
type: "info",
message: "取消删除"
});
});
} else {
SubmitData();
}
};
const SubmitData = () => {
if (tableData.value.length === 0) {
ElMessage.error("请添加食材");
return;
}
const postData = {
...formData.value,
consumptionMealSchedules: changeTable(tableData.value)
};
submitLoading.value = true;
let promiseResule = formData.value.id
? API_MEAL.updateMeal(postData)
: API_MEAL.addMeal(postData);
promiseResule
.then(value => {
ElMessage({
message: "编辑成功",
type: "success",
plain: true
});
setTimeout(() => {
ClearClose();
}, 500);
})
.finally(() => {
submitLoading.value = false;
});
};
defineOptions({
// name 作为一种规范最好必须写上并且和路由的name保持一致
name: "mealUpdate"
});
defineExpose({ onChildClick });
</script>
<style scoped>
.food-name {
cursor: pointer;
color: #79bbff;
}
.end-button {
margin: 40px 0px 0px 0px;
display: flex;
justify-content: center;
}
.table-box {
box-sizing: border-box;
padding: 10px;
/* border: 1px solid #dcdfe6; */
}
.meal-table-inline {
border-top: 1px solid #dcdfe6;
border-left: 1px solid #dcdfe6;
border-right: 1px solid #dcdfe6;
/* background: sandybrown; */
box-sizing: border-box;
padding-left: 10px;
}
.meal-table-inline .el-form-item {
margin-top: 18px;
}
</style>
网友评论