feat(daily recipe page): [A] 增加每日菜谱页面

[A] 增加每日菜谱页面

Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
Ching 2021-10-07 19:02:30 +08:00
parent d7a786f431
commit b4e64333bc
6 changed files with 253 additions and 11 deletions

File diff suppressed because one or more lines are too long

View File

@ -48,6 +48,8 @@
type="primary" type="primary"
block block
plain plain
hairline
:disabled="disable_submit"
@click="onSubmit(recipe_id)" @click="onSubmit(recipe_id)"
:loading="loading" :loading="loading"
>提交</van-button >提交</van-button
@ -104,9 +106,9 @@ export default {
name: this.form.name, name: this.form.name,
recipe_type: this.form.recipe_type recipe_type: this.form.recipe_type
? this.form.recipe_type ? this.form.recipe_type
: constants.RECIPE_TYPE_META, : constants.RECIPE_TYPE_MEAT,
difficulty: this.form.difficulty ? this.form.difficulty : 1, difficulty: this.form.difficulty,
rate: this.form.rate ? this.form.rate : 1, rate: this.form.rate,
note: this.form.note ? this.form.note : null, note: this.form.note ? this.form.note : null,
}; };
if (!recipe_id) { if (!recipe_id) {

View File

@ -36,7 +36,7 @@
</van-col> </van-col>
</van-row> </van-row>
<van-row> <van-row>
<van-col span="3"> <van-col span="3" class="recipe_type">
<van-grid :column-num="1"> <van-grid :column-num="1">
<van-grid-item text="菜" class="recipe_type"></van-grid-item> <van-grid-item text="菜" class="recipe_type"></van-grid-item>
</van-grid> </van-grid>
@ -59,7 +59,7 @@
</van-col> </van-col>
</van-row> </van-row>
<van-row v-if="daily_recipe.soup.length > 0"> <van-row v-if="daily_recipe.soup.length > 0">
<van-col span="3"> <van-col span="3" class="recipe_type">
<van-grid :column-num="1"> <van-grid :column-num="1">
<van-grid-item text="汤" class="recipe_type"></van-grid-item> <van-grid-item text="汤" class="recipe_type"></van-grid-item>
</van-grid> </van-grid>
@ -113,7 +113,6 @@ import {
PullRefresh, PullRefresh,
Row, Row,
SwipeCell, SwipeCell,
Tag,
} from 'vant'; } from 'vant';
import axios from 'axios'; import axios from 'axios';
import config from '@/config/index'; import config from '@/config/index';
@ -130,7 +129,6 @@ export default {
[PullRefresh.name]: PullRefresh, [PullRefresh.name]: PullRefresh,
[Row.name]: Row, [Row.name]: Row,
[SwipeCell.name]: SwipeCell, [SwipeCell.name]: SwipeCell,
[Tag.name]: Tag,
}, },
data() { data() {
return { return {

View File

@ -7,6 +7,7 @@ import RecipeMobileHome from '@/views/recipe-mobile/Home.vue'
import RecipeMobileRecipeCreate from '@/views/recipe-mobile/RecipeCreate.vue' import RecipeMobileRecipeCreate from '@/views/recipe-mobile/RecipeCreate.vue'
import RecipeMobileWeekRecipe from '@/views/recipe-mobile/WeekRecipe.vue' import RecipeMobileWeekRecipe from '@/views/recipe-mobile/WeekRecipe.vue'
import RecipeMobileRecipeDetail from '@/views/recipe-mobile/RecipeDetail.vue' import RecipeMobileRecipeDetail from '@/views/recipe-mobile/RecipeDetail.vue'
import RecipeMobileDailyRecipeDetail from '@/views/recipe-mobile/DailyRecipeDetail.vue'
const routes = [ const routes = [
{ {
@ -51,6 +52,11 @@ const routes = [
name: "RecipeMobileRecipeDetail", name: "RecipeMobileRecipeDetail",
component: RecipeMobileRecipeDetail component: RecipeMobileRecipeDetail
}, },
{
path: '/recipe-mobile/daily-recipe/:id',
name: "RecipeMobileDailyRecipeDetail",
component: RecipeMobileDailyRecipeDetail
},
]; ];
const router = createRouter({ const router = createRouter({

View File

@ -27,11 +27,16 @@ function formatDifficulty(difficulty) {
return difficulty_map[difficulty]; return difficulty_map[difficulty];
} }
const RECIPE_TYPES = [
{ key: 'meat', value: '肉' },
{ key: 'vegetable', value: '菜' },
{ key: 'soup', value: '汤' },
];
module.exports = { module.exports = {
RECIPE_TYPE_VEGETABLE: 'vegetable', RECIPE_TYPE_VEGETABLE: 'vegetable',
RECIPE_TYPE_META: 'meat', RECIPE_TYPE_MEAT: 'meat',
RECIPE_TYPE_SOUP: 'soup', RECIPE_TYPE_SOUP: 'soup',
RECIPE_TYPES,
formatRecipeType, formatRecipeType,
formatDifficulty, formatDifficulty,
formatRate, formatRate,

View File

@ -0,0 +1,231 @@
<template>
<van-cell-group
inset
v-for:="recipe_type in constants.RECIPE_TYPES"
:title="recipe_type.value"
>
<van-cell
v-for:="recipe in daily_recipe[recipe_type.key]"
:title="recipe.name"
>
<template #right-icon>
<van-icon
name="cross"
class="delete-icon"
@click="deleteRecipe(recipe)"
color="#969799"
/>
</template>
</van-cell>
<van-cell>
<template #value>
<van-button
plain
hairline
block
icon="plus"
color="#969799"
size="small"
@click="addRecipe(recipe_type.key)"
/>
</template>
</van-cell>
</van-cell-group>
<div class="recipe-create">
<van-button
type="primary"
round
hairline
plain
block
:disabled="disable_submit"
@click="submitRecipe"
>保存</van-button
>
</div>
<tabbar />
<van-popup
v-model:show="show_picker"
round
position="bottom"
safe-area-inset-bottom
>
<van-picker
ref="picker"
:columns="picker_columns[picker_recipe_type]"
@cancel="show_picker = false"
@confirm="onConfirm"
/>
</van-popup>
</template>
<script>
import tabbar from '@/components/recipe-mobile/tabbar.vue';
import axios from 'axios';
import config from '@/config/index';
import constants from '@/utils/constants.js';
import {
Picker,
Icon,
Button,
Cell,
CellGroup,
Col,
Grid,
GridItem,
PullRefresh,
Row,
SwipeCell,
Popup,
} from 'vant';
export default {
components: {
[Icon.name]: Icon,
[Picker.name]: Picker,
[Popup.name]: Popup,
[Button.name]: Button,
[Cell.name]: Cell,
[CellGroup.name]: CellGroup,
[Col.name]: Col,
[Grid.name]: Grid,
[GridItem.name]: GridItem,
[PullRefresh.name]: PullRefresh,
[Row.name]: Row,
[SwipeCell.name]: SwipeCell,
tabbar,
},
data() {
return {
daily_recipe: {
meat: [],
vegetable: [],
soup: [],
},
payload: {
meat: [],
vegetable: [],
soup: [],
},
constants: constants,
show_picker: false,
picker_recipe_type: null,
picker_columns: {},
disable_submit: true,
};
},
mounted() {
axios
.get(config.publicPath + '/recipe/daily-recipe/' + this.$route.params.id)
.then(
(response) => (this.daily_recipe = this.serializeData(response.data))
);
for (let i = 0; i < constants.RECIPE_TYPES.length; i++) {
axios
.get(
config.publicPath +
'/recipe/recipe/?recipe_type=' +
constants.RECIPE_TYPES[i]['key'] +
'&page_size=500'
)
.then(
(response) =>
(this.picker_columns[
constants.RECIPE_TYPES[i]['key']
] = this.serializeDataForPicker(response.data.results))
);
}
},
methods: {
serializeData(data) {
let data_ = {};
data_['id'] = data['id'];
data_['date'] = data['date'];
data_['meat'] = [];
data_['vegetable'] = [];
data_['soup'] = [];
for (let i = 0; i < data['recipes'].length; i++) {
if (data['recipes'][i]['recipe_type'] == constants.RECIPE_TYPE_MEAT) {
data_.meat.push(data['recipes'][i]);
this.payload[data['recipes'][i]['recipe_type']].push(
data['recipes'][i]['id']
);
} else if (
data['recipes'][i]['recipe_type'] == constants.RECIPE_TYPE_VEGETABLE
) {
data_.vegetable.push(data['recipes'][i]);
this.payload[data['recipes'][i]['recipe_type']].push(
data['recipes'][i]['id']
);
} else if (
data['recipes'][i]['recipe_type'] == constants.RECIPE_TYPE_SOUP
) {
data_.soup.push(data['recipes'][i]);
this.payload[data['recipes'][i]['recipe_type']].push(
data['recipes'][i]['id']
);
}
}
return data_;
},
serializeDataForPicker(data) {
let data_ = [];
for (let i = 0; i < data.length; i++) {
data_.push({ value: data[i]['id'], text: data[i]['name'] });
}
return data_;
},
deleteRecipe(recipe) {
for (const recipe_type of ['meat', 'vegetable', 'soup']) {
for (let i = 0; i < this.daily_recipe[recipe_type].length; i++) {
if (this.daily_recipe[recipe_type][i] == recipe) {
this.daily_recipe[recipe_type].splice(i, 1);
var index = this.payload[recipe_type].indexOf(recipe.id);
this.payload[recipe_type].splice(index, 1);
console.log(222, this.payload[recipe_type]);
this.disable_submit = false;
return;
}
}
}
},
addRecipe(recipe_type) {
this.show_picker = true;
this.picker_recipe_type = recipe_type;
},
onConfirm(val) {
this.show_picker = false;
this.payload[this.picker_recipe_type].push(val.value);
this.daily_recipe[this.picker_recipe_type].push({
name: val.text,
id: val.value,
});
this.disable_submit = false;
},
submitRecipe() {
axios.put(
config.publicPath + '/recipe/daily-recipe/' + this.$route.params.id,
this.payload
);
this.disable_submit = true;
},
},
};
</script>
<style>
.daily_recipe {
margin-top: 20px;
}
.delete-button {
width: 100%;
height: 100%;
}
.delete-icon {
font-size: 16px;
line-height: inherit;
padding: 0 5px;
}
</style>