feat(daily recipe page): [A] 增加每日菜谱页面
[A] 增加每日菜谱页面 Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
parent
d7a786f431
commit
b4e64333bc
4
frontend/dist/js/app.06e83add.js
vendored
4
frontend/dist/js/app.06e83add.js
vendored
File diff suppressed because one or more lines are too long
@ -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) {
|
||||||
|
|||||||
@ -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 {
|
||||||
|
|||||||
@ -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({
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
231
frontend/src/views/recipe-mobile/DailyRecipeDetail.vue
Normal file
231
frontend/src/views/recipe-mobile/DailyRecipeDetail.vue
Normal 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>
|
||||||
Loading…
x
Reference in New Issue
Block a user