完成菜品修改
This commit is contained in:
@ -0,0 +1,69 @@
|
||||
<template>
|
||||
<div class="editable_text_wrapper">
|
||||
<div class="value" v-if="!editing" @click="handleOnClick">{{ value }}</div>
|
||||
<input
|
||||
v-else
|
||||
class="input"
|
||||
ref="inputRef"
|
||||
type="number"
|
||||
:step="5"
|
||||
:value="value"
|
||||
@blur="handleOnBlur"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "EditableText",
|
||||
data() {
|
||||
return {
|
||||
editing: false,
|
||||
};
|
||||
},
|
||||
props: ["value"],
|
||||
methods: {
|
||||
handleOnClick(e) {
|
||||
if (!this.editing) {
|
||||
this.editing = true;
|
||||
this.$nextTick(() => {
|
||||
this.$refs["inputRef"].focus();
|
||||
});
|
||||
}
|
||||
},
|
||||
handleOnBlur(e) {
|
||||
const { value } = e.target;
|
||||
if (value > 0) {
|
||||
this.editing = false;
|
||||
const mValue = parseFloat(value)
|
||||
if (mValue !== parseFloat(this.value)) {
|
||||
this.$emit("onChange", mValue);
|
||||
}
|
||||
} else {
|
||||
this.$message.error("数字必须大于0");
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.editable_text_wrapper {
|
||||
.value {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.input {
|
||||
width: 96%;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
border: 1px solid #dcdfe6;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,147 @@
|
||||
<template>
|
||||
<div class="editable_unit_wrapper">
|
||||
<div class="value" v-if="!editing" @click="handleOnClick">
|
||||
<span>{{ unitWeight }}</span>
|
||||
</div>
|
||||
<div v-else class="selector">
|
||||
<select
|
||||
:value="mWeight"
|
||||
@click="handleOnSelectClick"
|
||||
@change="handleOnWeightChange"
|
||||
>
|
||||
<option
|
||||
v-for="item in cusWeightOptions"
|
||||
:key="item.dictValue"
|
||||
:value="item.dictValue"
|
||||
>
|
||||
{{ item.dictLabel }}
|
||||
</option>
|
||||
</select>
|
||||
<select
|
||||
:value="mUnit"
|
||||
@click="handleOnSelectClick"
|
||||
@change="handleOnUnitChange"
|
||||
>
|
||||
<option
|
||||
v-for="item in cusUnitOptions"
|
||||
:key="item.dictValue"
|
||||
:value="item.dictValue"
|
||||
>
|
||||
{{ item.dictLabel }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { createNamespacedHelpers } from "vuex";
|
||||
const { mapState, mapGetters } = createNamespacedHelpers("recipes");
|
||||
export default {
|
||||
name: "EditableUnit",
|
||||
props: ["weight", "unit"],
|
||||
mounted() {
|
||||
window.addEventListener("click", this.handleOnWindowClick);
|
||||
},
|
||||
unmounted() {
|
||||
window.removeEventListener("click", this.handleOnWindowClick);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
editing: false,
|
||||
mWeight: this.weight,
|
||||
mUnit: this.unit,
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
handleOnClick(e) {
|
||||
if (!this.editing) {
|
||||
setTimeout(() => {
|
||||
this.editing = true;
|
||||
}, 0);
|
||||
}
|
||||
},
|
||||
handleOnWindowClick(e) {
|
||||
if (this.editing) {
|
||||
// console.log("handleOnWindowClick");
|
||||
this.editing = false;
|
||||
if (
|
||||
String(this.mWeight) !== String(this.weight) ||
|
||||
String(this.mUnit) !== String(this.unit)
|
||||
) {
|
||||
// console.log({
|
||||
// mWeight: this.mWeight,
|
||||
// mUnit: this.mUnit,
|
||||
// weight: this.weight,
|
||||
// unit: this.unit,
|
||||
// });
|
||||
this.$emit("onChange", {
|
||||
cusWeight: this.mWeight,
|
||||
cusUnit: this.mUnit,
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
handleOnSelectClick(e) {
|
||||
if (this.editing) {
|
||||
e.stopPropagation();
|
||||
}
|
||||
},
|
||||
handleOnWeightChange(e) {
|
||||
const { value } = e.target;
|
||||
this.mWeight = value;
|
||||
},
|
||||
handleOnUnitChange(e) {
|
||||
const { value } = e.target;
|
||||
this.mUnit = value;
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
unitWeight() {
|
||||
return (
|
||||
`${this.cusWeightDict[this.mWeight] || ""}${
|
||||
this.cusUnitDict[this.mUnit] || ""
|
||||
}` || "_"
|
||||
);
|
||||
},
|
||||
...mapState(["cusUnitOptions", "cusWeightOptions"]),
|
||||
...mapGetters(["cusUnitDict", "cusWeightDict"]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.editable_unit_wrapper {
|
||||
.value {
|
||||
cursor: pointer;
|
||||
}
|
||||
.selector {
|
||||
display: flex;
|
||||
|
||||
select:nth-child(1) {
|
||||
margin-right: 2px;
|
||||
}
|
||||
|
||||
select {
|
||||
font-size: 11px;
|
||||
border: solid 1px #dcdfe6;
|
||||
border-radius: 4px;
|
||||
appearance: none;
|
||||
-moz-appearance: none;
|
||||
-webkit-appearance: none;
|
||||
padding: 3px 6px;
|
||||
|
||||
&:hover {
|
||||
border-color: #409eff;
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
border-color: #409eff;
|
||||
}
|
||||
}
|
||||
|
||||
/*清除ie的默认选择框样式清除,隐藏下拉箭头*/
|
||||
select::-ms-expand {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -0,0 +1,321 @@
|
||||
<template>
|
||||
<div class="recipes_com_wrapper">
|
||||
<el-table
|
||||
:data="mData"
|
||||
border
|
||||
:span-method="spanMethod"
|
||||
:cell-style="{ padding: '2px 0' }"
|
||||
:header-cell-style="{ padding: '4px 0', height: 'unset' }"
|
||||
size="mini"
|
||||
:style="`outline: ${
|
||||
currentDay + 1 === num ? '1px solid #d96969' : 'none'
|
||||
}`"
|
||||
>
|
||||
<el-table-column
|
||||
prop="type"
|
||||
:formatter="typeFormatter"
|
||||
:width="100"
|
||||
align="center"
|
||||
>
|
||||
<template slot="header">
|
||||
<span class="num_day" @click="handleOnOneDayAnalysis">{{
|
||||
`${name}第${num}天`
|
||||
}}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="菜品" prop="name" align="center">
|
||||
<template slot="header">
|
||||
<el-popover placement="top" trigger="hover">
|
||||
<el-button
|
||||
type="primary"
|
||||
size="mini"
|
||||
icon="el-icon-edit"
|
||||
class="fun_button"
|
||||
@click="handleOnAdd"
|
||||
>添加</el-button
|
||||
>
|
||||
<span class="num_day" slot="reference">菜品</span>
|
||||
</el-popover>
|
||||
</template>
|
||||
<template slot-scope="scope">
|
||||
<el-popover placement="right" trigger="hover">
|
||||
<div>
|
||||
<el-button
|
||||
type="danger"
|
||||
size="mini"
|
||||
icon="el-icon-delete"
|
||||
class="fun_button"
|
||||
@click="handleOnDelete(scope.row)"
|
||||
>删除</el-button
|
||||
>
|
||||
</div>
|
||||
<span class="num_day" slot="reference">{{ scope.row.name }}</span>
|
||||
</el-popover>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="食材" prop="igdName" align="center" />
|
||||
<el-table-column label="分量估算" :width="80" align="center">
|
||||
<template slot-scope="scope">
|
||||
<EditableUnit
|
||||
:weight="scope.row.cusWeight"
|
||||
:unit="scope.row.cusUnit"
|
||||
@onChange="(val) => handleOnCustomUnitChange(scope.row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="质量(g)" prop="weight" :width="80" align="center">
|
||||
<template slot-scope="scope">
|
||||
<EditableText
|
||||
:value="scope.row.weight"
|
||||
@onChange="(val) => handleOnWeightChange(scope.row, val)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
label="蛋白质/100g"
|
||||
prop="proteinRatio"
|
||||
:width="100"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="脂肪/100g"
|
||||
prop="fatRatio"
|
||||
:width="90"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="碳水/100g"
|
||||
prop="carbonRatio"
|
||||
:width="90"
|
||||
align="center"
|
||||
/>
|
||||
<el-table-column
|
||||
label="蛋白质含量"
|
||||
prop="proteinRatio"
|
||||
:width="90"
|
||||
align="center"
|
||||
:formatter="nutriFormatter"
|
||||
/>
|
||||
<el-table-column
|
||||
label="脂肪含量"
|
||||
prop="fatRatio"
|
||||
:width="90"
|
||||
align="center"
|
||||
:formatter="nutriFormatter"
|
||||
/>
|
||||
<el-table-column
|
||||
label="碳水含量"
|
||||
prop="carbonRatio"
|
||||
:width="90"
|
||||
align="center"
|
||||
:formatter="nutriFormatter"
|
||||
/>
|
||||
<el-table-column label="做法" prop="methods" />
|
||||
</el-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { createNamespacedHelpers } from "vuex";
|
||||
const {
|
||||
mapActions,
|
||||
mapGetters,
|
||||
mapState,
|
||||
mapMutations,
|
||||
} = createNamespacedHelpers("recipes");
|
||||
|
||||
import EditableText from "./EditableText";
|
||||
import EditableUnit from "./EditableUnit";
|
||||
|
||||
export default {
|
||||
name: "RecipesCom",
|
||||
props: {
|
||||
data: {
|
||||
type: Object,
|
||||
default: [],
|
||||
required: true,
|
||||
},
|
||||
name: {
|
||||
type: String,
|
||||
default: "",
|
||||
},
|
||||
num: {
|
||||
type: Number,
|
||||
default: 0,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
EditableText,
|
||||
EditableUnit,
|
||||
},
|
||||
mounted() {
|
||||
// console.log(this.data);
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {
|
||||
mData() {
|
||||
if (!this.data.dishes) {
|
||||
return [];
|
||||
}
|
||||
const mData = this.data.dishes
|
||||
.sort((a, b) => a.type - b.type)
|
||||
.reduce((arr, cur, idx) => {
|
||||
if (cur.id > 0 && cur.type !== "0") {
|
||||
cur.igdList.forEach((igd) => {
|
||||
let lastTypeHit = false,
|
||||
lastNameHit = false;
|
||||
if (arr.length > 0) {
|
||||
// 倒推,找到第一个出现的位置
|
||||
lastTypeHit = arr[arr.length - 1].type === cur.type;
|
||||
if (lastTypeHit) {
|
||||
let typePos = arr.length - 1;
|
||||
for (let i = typePos; i >= 0; i--) {
|
||||
if (arr[i].type !== cur.type) {
|
||||
break;
|
||||
}
|
||||
typePos = i;
|
||||
}
|
||||
arr[typePos].typeSpan.rowspan += 1;
|
||||
}
|
||||
lastNameHit = arr[arr.length - 1].name === cur.name;
|
||||
if (lastNameHit) {
|
||||
let namePos = arr.length - 1;
|
||||
for (let i = namePos; i >= 0; i--) {
|
||||
if (arr[i].name !== cur.name) {
|
||||
break;
|
||||
}
|
||||
namePos = i;
|
||||
}
|
||||
arr[namePos].nameSpan.rowspan += 1;
|
||||
arr[namePos].methodsSpan.rowspan += 1;
|
||||
}
|
||||
}
|
||||
|
||||
arr.push({
|
||||
id: cur.id,
|
||||
name: cur.name,
|
||||
type: cur.type,
|
||||
isMain: cur.isMain,
|
||||
methods: cur.methods,
|
||||
igdId: igd.id,
|
||||
igdName: igd.name,
|
||||
proteinRatio: igd.proteinRatio,
|
||||
fatRatio: igd.fatRatio,
|
||||
carbonRatio: igd.carbonRatio,
|
||||
rec: igd.rec,
|
||||
notRec: igd.notRec,
|
||||
weight: igd.weight,
|
||||
cusWeight: igd.cusWeight,
|
||||
cusUnit: igd.cusUnit,
|
||||
typeSpan: lastTypeHit
|
||||
? {
|
||||
rowspan: 0,
|
||||
colspan: 0,
|
||||
}
|
||||
: {
|
||||
rowspan: 1,
|
||||
colspan: 1,
|
||||
},
|
||||
nameSpan: lastNameHit
|
||||
? {
|
||||
rowspan: 0,
|
||||
colspan: 0,
|
||||
}
|
||||
: {
|
||||
rowspan: 1,
|
||||
colspan: 1,
|
||||
},
|
||||
methodsSpan: lastNameHit
|
||||
? {
|
||||
rowspan: 0,
|
||||
colspan: 0,
|
||||
}
|
||||
: {
|
||||
rowspan: 1,
|
||||
colspan: 1,
|
||||
},
|
||||
});
|
||||
});
|
||||
}
|
||||
return arr;
|
||||
}, []);
|
||||
// console.log(mData);
|
||||
return mData;
|
||||
},
|
||||
...mapGetters(["typeDict"]),
|
||||
...mapState(["currentDay"]),
|
||||
},
|
||||
methods: {
|
||||
spanMethod({ row, column, rowIndex, columnIndex }) {
|
||||
if (columnIndex === 0) {
|
||||
return row.typeSpan;
|
||||
} else if (columnIndex === 1) {
|
||||
return row.nameSpan;
|
||||
} else if (columnIndex === 11) {
|
||||
return row.methodsSpan;
|
||||
}
|
||||
},
|
||||
typeFormatter(row) {
|
||||
return this.typeDict[row.type];
|
||||
},
|
||||
nutriFormatter(row, col) {
|
||||
return ((row.weight / 100) * row[col.property]).toFixed(1);
|
||||
},
|
||||
handleOnOneDayAnalysis(e) {
|
||||
// 校验某天
|
||||
this.setCurrentDay({ currentDay: this.num - 1 });
|
||||
},
|
||||
handleOnAdd() {
|
||||
console.log(this.num);
|
||||
},
|
||||
handleOnEdit(data) {
|
||||
console.log(data);
|
||||
},
|
||||
handleOnDelete(data) {
|
||||
// console.log(data);
|
||||
this.deleteSomeDayDishes({ num: this.num - 1, dishesId: data.id });
|
||||
},
|
||||
handleOnWeightChange(data, weight) {
|
||||
// console.log({ data, weight });
|
||||
this.updateRecipesDishesWeight({
|
||||
num: this.num - 1,
|
||||
dishesId: data.id,
|
||||
igdId: data.igdId,
|
||||
weight,
|
||||
});
|
||||
},
|
||||
handleOnCustomUnitChange(data, { cusWeight, cusUnit }) {
|
||||
this.updateRecipesDishesCustomWeight({
|
||||
num: this.num - 1,
|
||||
dishesId: data.id,
|
||||
igdId: data.igdId,
|
||||
cusWeight,
|
||||
cusUnit,
|
||||
});
|
||||
},
|
||||
...mapMutations([
|
||||
"setCurrentDay",
|
||||
"deleteSomeDayDishes",
|
||||
"updateRecipesDishesWeight",
|
||||
"updateRecipesDishesCustomWeight",
|
||||
]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
.recipes_com_wrapper {
|
||||
margin-bottom: 24px;
|
||||
padding: 1px;
|
||||
|
||||
.num_day {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
<style lang="scss">
|
||||
.fun_button {
|
||||
font-size: 12px;
|
||||
padding: 4px 8px;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user