feat(recipe edit page): 菜谱编辑页增加添加食材功能
菜谱编辑页增加添加食材功能 Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
parent
54819c6861
commit
1c424275f1
@ -27,7 +27,6 @@ DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = []
|
||||
|
||||
|
||||
# Application definition
|
||||
|
||||
INSTALLED_APPS = [
|
||||
|
||||
@ -138,7 +138,7 @@ export default {
|
||||
});
|
||||
} else {
|
||||
axios
|
||||
.put(config.publicPath + '/recipe/recipe/' + recipe_id, data)
|
||||
.put(config.publicPath + '/recipe/recipe/' + recipe_id + '/', data)
|
||||
.then(function () {
|
||||
ElMessage({
|
||||
message: '修改成功.',
|
||||
@ -152,7 +152,7 @@ export default {
|
||||
},
|
||||
onSubmitDelete(recipe_id) {
|
||||
axios
|
||||
.delete(config.publicPath + '/recipe/recipe/' + recipe_id)
|
||||
.delete(config.publicPath + '/recipe/recipe/' + recipe_id + '/')
|
||||
.then(function () {
|
||||
ElMessage.error('删除成功.');
|
||||
location.reload();
|
||||
|
||||
@ -42,6 +42,57 @@
|
||||
type="textarea"
|
||||
/>
|
||||
</van-cell-group>
|
||||
|
||||
<van-cell-group
|
||||
class="recipe-create"
|
||||
inset
|
||||
border
|
||||
v-if="form.recipe_ingredients && form.recipe_ingredients.length > 0"
|
||||
title="数量为 0 的食材将被删除"
|
||||
>
|
||||
<van-cell
|
||||
v-bind:title="recipe_ingredient.ingredient.name"
|
||||
v-for="recipe_ingredient in form.recipe_ingredients"
|
||||
:key="recipe_ingredient.id"
|
||||
>
|
||||
<template #value>
|
||||
<van-stepper
|
||||
v-model.number="recipe_ingredient.quantity"
|
||||
default-value="recipe_ingredient.quantity"
|
||||
:decimal-length="1"
|
||||
allow-empty="true"
|
||||
min="0"
|
||||
/>
|
||||
{{ recipe_ingredient.ingredient.unit }}
|
||||
</template>
|
||||
</van-cell>
|
||||
</van-cell-group>
|
||||
|
||||
<div class="recipe-create">
|
||||
<van-row gutter="20">
|
||||
<van-col span="24">
|
||||
<van-button
|
||||
icon="plus"
|
||||
type="primary"
|
||||
plain
|
||||
round
|
||||
hairline
|
||||
class="submit-button"
|
||||
@click="showIngredientPicker = true"
|
||||
>添加食材</van-button
|
||||
>
|
||||
</van-col>
|
||||
</van-row>
|
||||
</div>
|
||||
<van-popup v-model:show="showIngredientPicker" round position="bottom">
|
||||
<van-picker
|
||||
:columns="ingredient_columns"
|
||||
:columns-field-names="customFieldName"
|
||||
@cancel="showIngredientPicker = false"
|
||||
@confirm="onConfirmIngredient"
|
||||
/>
|
||||
</van-popup>
|
||||
|
||||
<div class="recipe-create">
|
||||
<van-row gutter="20">
|
||||
<van-col span="8" v-if="recipe_id">
|
||||
@ -93,6 +144,7 @@ import {
|
||||
Form,
|
||||
Field,
|
||||
CellGroup,
|
||||
Cell,
|
||||
Radio,
|
||||
RadioGroup,
|
||||
Rate,
|
||||
@ -100,11 +152,15 @@ import {
|
||||
Toast,
|
||||
Col,
|
||||
Row,
|
||||
Stepper,
|
||||
Popup,
|
||||
Picker,
|
||||
} from 'vant';
|
||||
import axios from 'axios';
|
||||
import config from '@/config/index';
|
||||
import router from '@/router/index';
|
||||
import constants from '@/utils/constants.js';
|
||||
import { ref } from 'vue';
|
||||
|
||||
export default {
|
||||
props: ['recipe_'],
|
||||
@ -118,14 +174,23 @@ export default {
|
||||
[Form.name]: Form,
|
||||
[Field.name]: Field,
|
||||
[CellGroup.name]: CellGroup,
|
||||
[Cell.name]: Cell,
|
||||
[Radio.name]: Radio,
|
||||
[RadioGroup.name]: RadioGroup,
|
||||
[Rate.name]: Rate,
|
||||
[Button.name]: Button,
|
||||
[Col.name]: Col,
|
||||
[Row.name]: Row,
|
||||
[Stepper.name]: Stepper,
|
||||
[Popup.name]: Popup,
|
||||
[Picker.name]: Picker,
|
||||
},
|
||||
data() {
|
||||
const customFieldName = {
|
||||
text: 'name',
|
||||
};
|
||||
const showIngredientPicker = ref(false);
|
||||
|
||||
return {
|
||||
form: {
|
||||
name: null,
|
||||
@ -133,12 +198,18 @@ export default {
|
||||
rate: 0,
|
||||
difficulty: 0,
|
||||
note: null,
|
||||
recipe_ingredients: null,
|
||||
},
|
||||
loading: false,
|
||||
recipe_id: null,
|
||||
ingredient_columns: null,
|
||||
customFieldName,
|
||||
showIngredientPicker,
|
||||
};
|
||||
},
|
||||
mounted() {},
|
||||
mounted() {
|
||||
this.getIngredients();
|
||||
},
|
||||
methods: {
|
||||
onSubmit(recipe_id) {
|
||||
if (!this.form.name) {
|
||||
@ -153,6 +224,9 @@ export default {
|
||||
difficulty: this.form.difficulty,
|
||||
rate: this.form.rate,
|
||||
note: this.form.note ? this.form.note : null,
|
||||
recipe_ingredients: this.form.recipe_ingredients
|
||||
? this.form.recipe_ingredients
|
||||
: [],
|
||||
};
|
||||
if (!recipe_id) {
|
||||
axios
|
||||
@ -161,13 +235,18 @@ export default {
|
||||
(response) => (response, router.push({ name: 'RecipeMobileHome' }))
|
||||
);
|
||||
} else {
|
||||
axios.put(config.publicPath + '/recipe/recipe/' + recipe_id, data).then(
|
||||
(Toast.success({
|
||||
axios
|
||||
.put(config.publicPath + '/recipe/recipe/' + recipe_id + '/', data)
|
||||
.then(
|
||||
(response) => (
|
||||
response,
|
||||
Toast.success({
|
||||
message: '修改成功',
|
||||
forbidClick: true,
|
||||
duration: 500,
|
||||
}),
|
||||
(this.loading = false))
|
||||
(this.loading = false)
|
||||
)
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -176,7 +255,9 @@ export default {
|
||||
return;
|
||||
}
|
||||
this.loading = true;
|
||||
axios.delete(config.publicPath + '/recipe/recipe/' + recipe_id).then(
|
||||
axios
|
||||
.delete(config.publicPath + '/recipe/recipe/' + recipe_id + '/')
|
||||
.then(
|
||||
(Toast.success({
|
||||
message: '删除成功',
|
||||
forbidClick: true,
|
||||
@ -185,6 +266,46 @@ export default {
|
||||
(this.loading = false))
|
||||
);
|
||||
},
|
||||
getIngredients() {
|
||||
axios.get(config.publicPath + '/recipe/ingredient/').then((response) => {
|
||||
(this.ingredient_columns = response.data['results']),
|
||||
console.log('ingredient_columns', this.ingredient_columns);
|
||||
});
|
||||
},
|
||||
onConfirmIngredient(value) {
|
||||
var exists = false;
|
||||
this.showIngredientPicker = false;
|
||||
if (this.form.recipe_ingredients === null) {
|
||||
this.form.recipe_ingredients = [];
|
||||
}
|
||||
for (let i = 0; i < this.form.recipe_ingredients.length; i++) {
|
||||
if (this.form.recipe_ingredients[i].ingredient.id == value.id) {
|
||||
exists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (exists) {
|
||||
Toast.fail({
|
||||
message: '该食材已存在',
|
||||
forbidClick: true,
|
||||
duration: 800,
|
||||
});
|
||||
} else {
|
||||
this.form.recipe_ingredients.push({
|
||||
id: 0,
|
||||
ingredient: {
|
||||
id: value.id,
|
||||
name: value.name,
|
||||
unit: value.unit,
|
||||
}, // 添加的食材
|
||||
});
|
||||
}
|
||||
},
|
||||
onChangeIngredientQuantity(value) {
|
||||
console.log('onChangeIngredientQuantity', value);
|
||||
console.log('recipe ingerdients ', this.form.recipe_ingredients);
|
||||
// this.form.recipe_ingredients[value.index].quantity = value.quantity;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@ -21,7 +21,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
axios
|
||||
.get(config.publicPath + '/recipe/recipe/' + this.$route.params.id)
|
||||
.get(config.publicPath + '/recipe/recipe/' + this.$route.params.id + '/')
|
||||
.then((response) => (this.recipe = response.data));
|
||||
},
|
||||
};
|
||||
|
||||
@ -2,12 +2,8 @@
|
||||
<el-container>
|
||||
<el-header>
|
||||
<el-menu mode="horizontal" default-active="#" router>
|
||||
<el-menu-item index="/">
|
||||
首页
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/week-recipe/">
|
||||
每周菜谱
|
||||
</el-menu-item>
|
||||
<el-menu-item index="/"> 首页 </el-menu-item>
|
||||
<el-menu-item index="/week-recipe/"> 每周菜谱 </el-menu-item>
|
||||
<el-menu-item index="#">
|
||||
{{ recipe.name }}
|
||||
</el-menu-item>
|
||||
@ -41,7 +37,7 @@ export default {
|
||||
},
|
||||
mounted() {
|
||||
axios
|
||||
.get(config.publicPath + '/recipe/recipe/' + this.$route.params.id)
|
||||
.get(config.publicPath + '/recipe/recipe/' + this.$route.params.id + '/')
|
||||
.then((response) => (this.recipe = response.data));
|
||||
},
|
||||
methods: {
|
||||
|
||||
@ -5,6 +5,8 @@ from utils import const
|
||||
|
||||
|
||||
class IngredientSerializer(serializers.ModelSerializer):
|
||||
id = serializers.IntegerField(read_only=True)
|
||||
|
||||
class Meta:
|
||||
model = recipe.models.Ingredient
|
||||
fields = '__all__'
|
||||
@ -28,16 +30,7 @@ class RecipeIngredientSerializer(serializers.ModelSerializer):
|
||||
|
||||
class RecipeSerializer(serializers.ModelSerializer):
|
||||
id = serializers.IntegerField(read_only=True)
|
||||
recipe_ingredients = RecipeIngredientSerializer(many=True)
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
if 'recipe_ingredients' in validated_data:
|
||||
recipe_ingredients = validated_data.pop('recipe_ingredients')
|
||||
if recipe_ingredients:
|
||||
for recipe_ingredient in recipe_ingredients:
|
||||
recipe_ingredient['recipe'] = instance
|
||||
RecipeIngredientSerializer.update(recipe_ingredient)
|
||||
return super().update(instance, validated_data)
|
||||
recipe_ingredients = RecipeIngredientSerializer(many=True, read_only=True)
|
||||
|
||||
def create(self, validated_data):
|
||||
if 'recipe_ingredients' in validated_data:
|
||||
|
||||
@ -25,6 +25,34 @@ class RecipeAPI(viewsets.ModelViewSet):
|
||||
instance.status = const.RECIPE_STATUS_DELETED
|
||||
instance.save(update_fields=['status'])
|
||||
|
||||
def perform_update(self, serializer):
|
||||
instance = self.get_object()
|
||||
if 'recipe_ingredients' in self.request.data:
|
||||
recipe_ingredients = self.request.data.pop('recipe_ingredients')
|
||||
if recipe_ingredients:
|
||||
for recipe_ingredient in recipe_ingredients:
|
||||
# 没有 id 则新增食材
|
||||
if not recipe_ingredient['id'] and recipe_ingredient['quantity']:
|
||||
ingredient = recipe.models.Ingredient.objects.get(id=recipe_ingredient['ingredient']['id'])
|
||||
del recipe_ingredient['ingredient']
|
||||
del recipe_ingredient['id']
|
||||
recipe.models.RecipeIngredient.objects.create(
|
||||
recipe=instance, ingredient=ingredient, **recipe_ingredient
|
||||
)
|
||||
# 有 id 没数量则删除食材
|
||||
elif recipe_ingredient['id'] and not recipe_ingredient['quantity']:
|
||||
recipe.models.RecipeIngredient.objects.filter(id=recipe_ingredient['id']).update(
|
||||
status=const.INGREDIENT_STATUS_DELETED
|
||||
)
|
||||
# 有 id 有数量则更新食材
|
||||
elif recipe_ingredient['id'] and recipe_ingredient['quantity']:
|
||||
del recipe_ingredient['ingredient']
|
||||
recipe.models.RecipeIngredient.objects.filter(id=recipe_ingredient['id']).update(
|
||||
**recipe_ingredient
|
||||
)
|
||||
|
||||
return super().perform_update(serializer)
|
||||
|
||||
def list(self, request, *args, **kwargs):
|
||||
self.queryset = recipe.models.Recipe.objects.exclude(status=const.RECIPE_STATUS_DELETED)
|
||||
return super().list(request, *args, **kwargs)
|
||||
|
||||
@ -10,7 +10,6 @@ reload(sys)
|
||||
|
||||
import utils.lark
|
||||
import git
|
||||
import ipdb
|
||||
|
||||
if __name__ == '__main__':
|
||||
# def notify():
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user