feat(week recipe page): [A] 增加重新生成每周菜谱逻辑;一些样式调整
[A] 增加重新生成每周菜谱逻辑;一些样式调整 Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
parent
1dd97b9e54
commit
7f6448d0ec
@ -54,7 +54,11 @@
|
|||||||
<el-input type="textarea" v-model="form.note"></el-input>
|
<el-input type="textarea" v-model="form.note"></el-input>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
<el-form-item>
|
<el-form-item>
|
||||||
<el-button type="primary" @click="onSubmit(recipe_id)"
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
class="summit-recipe"
|
||||||
|
@click="onSubmit(recipe_id)"
|
||||||
>提交</el-button
|
>提交</el-button
|
||||||
>
|
>
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
@ -119,3 +123,9 @@ export default {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.summit-recipe {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
103
frontend/src/components/recipe_list.vue
Normal file
103
frontend/src/components/recipe_list.vue
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
<template>
|
||||||
|
<el-table :data="recipes" max-height="500" class="recipe-table">
|
||||||
|
<el-table-column prop="name" label="名字"> </el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="recipe_type"
|
||||||
|
label="类型"
|
||||||
|
:formatter="formatRecipeType"
|
||||||
|
:filters="[
|
||||||
|
{ text: '青菜', value: 'vegetable' },
|
||||||
|
{ text: '肉', value: 'meat' },
|
||||||
|
{ text: '汤', value: 'soup' },
|
||||||
|
]"
|
||||||
|
:filter-method="filterRecipeType"
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="difficulty"
|
||||||
|
label="难度"
|
||||||
|
:formatter="formatDifficulty"
|
||||||
|
sortable
|
||||||
|
>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="rate" label="评分" :formatter="formatRate" sortable>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="mini" @click="editRecipe(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
import router from '@/router/index';
|
||||||
|
|
||||||
|
const type_map = {
|
||||||
|
vegetable: '青菜',
|
||||||
|
meat: '肉',
|
||||||
|
soup: '汤',
|
||||||
|
};
|
||||||
|
const rate_map = {
|
||||||
|
1: '🍚',
|
||||||
|
2: '🍚 🍚',
|
||||||
|
3: '🍚 🍚 🍚',
|
||||||
|
4: '🍚 🍚 🍚 🍚',
|
||||||
|
5: '🍚 🍚 🍚 🍚 🍚',
|
||||||
|
};
|
||||||
|
const difficulty_map = {
|
||||||
|
1: '⭐',
|
||||||
|
2: '⭐ ⭐',
|
||||||
|
3: '⭐ ⭐ ⭐',
|
||||||
|
4: '⭐ ⭐ ⭐ ⭐',
|
||||||
|
5: '⭐ ⭐ ⭐ ⭐ ⭐',
|
||||||
|
};
|
||||||
|
function formatRecipeType(row) {
|
||||||
|
return type_map[row.recipe_type];
|
||||||
|
}
|
||||||
|
function formatRate(row) {
|
||||||
|
return rate_map[row.rate];
|
||||||
|
}
|
||||||
|
function formatDifficulty(row) {
|
||||||
|
return difficulty_map[row.difficulty];
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'RecipeList',
|
||||||
|
// provide() {
|
||||||
|
// return {
|
||||||
|
// reload: this.reload,
|
||||||
|
// };
|
||||||
|
// },
|
||||||
|
methods: {
|
||||||
|
reload() {
|
||||||
|
this.isRouterAlive = false;
|
||||||
|
this.$nextTick(function() {
|
||||||
|
this.isRouterAlive = true;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
filterRecipeType(value, row) {
|
||||||
|
return row.recipe_type === value;
|
||||||
|
},
|
||||||
|
editRecipe(row) {
|
||||||
|
router.push({ name: 'RecipeDetail', params: { id: row.id } });
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
recipes: [],
|
||||||
|
formatRecipeType,
|
||||||
|
formatRate,
|
||||||
|
formatDifficulty,
|
||||||
|
isRouterAlive: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
axios
|
||||||
|
.get('//localhost:8000/recipe/recipe/')
|
||||||
|
.then((response) => (this.recipes = response.data));
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
93
frontend/src/components/week_recipe.vue
Normal file
93
frontend/src/components/week_recipe.vue
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<template>
|
||||||
|
<el-row justify="center">
|
||||||
|
<el-col>
|
||||||
|
<el-table border stripe :data="daily_recipes" max-height="500">
|
||||||
|
<el-table-column
|
||||||
|
prop="date"
|
||||||
|
label="日期"
|
||||||
|
:formatter="formatDate"
|
||||||
|
></el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="meat"
|
||||||
|
label="肉"
|
||||||
|
:formatter="formatMeal"
|
||||||
|
></el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="vegetable"
|
||||||
|
label="菜"
|
||||||
|
:formatter="formatMeal"
|
||||||
|
></el-table-column>
|
||||||
|
<el-table-column
|
||||||
|
prop="soup"
|
||||||
|
label="汤"
|
||||||
|
:formatter="formatMeal"
|
||||||
|
></el-table-column>
|
||||||
|
</el-table>
|
||||||
|
</el-col>
|
||||||
|
<el-col>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
class="re-generate"
|
||||||
|
@click="reGenerateRecipe()"
|
||||||
|
>重新生成</el-button
|
||||||
|
>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
|
function formatDate(row, column, cellValue) {
|
||||||
|
if (cellValue === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var date_ = new Date(cellValue * 1000);
|
||||||
|
return date_.toDateString();
|
||||||
|
}
|
||||||
|
|
||||||
|
function formatMeal(row, column, cellValue) {
|
||||||
|
var data = ['/ '];
|
||||||
|
if (cellValue === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (let i = 0; i < cellValue.length; i++) {
|
||||||
|
data.push(cellValue[i].name + ' / ');
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
export default {
|
||||||
|
name: 'WeekRecipe',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
daily_recipes: [],
|
||||||
|
formatDate,
|
||||||
|
formatMeal,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
axios
|
||||||
|
.get('//localhost:8000/recipe/week-recipe/')
|
||||||
|
.then((response) => (this.daily_recipes = response.data));
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
reGenerateRecipe() {
|
||||||
|
axios
|
||||||
|
.post('//localhost:8000/recipe/week-recipe/')
|
||||||
|
.then((response) => {
|
||||||
|
response;
|
||||||
|
return axios.get('//localhost:8000/recipe/week-recipe/');
|
||||||
|
})
|
||||||
|
.then((response) => (this.daily_recipes = response.data));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
.re-generate {
|
||||||
|
margin: 20px 0;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@ -1,6 +1,7 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
import Home from '@/views/home.vue'
|
import Home from '@/views/home.vue'
|
||||||
import RecipeDetail from '@/views/recipeDetail.vue'
|
import RecipeDetail from '@/views/recipeDetail.vue'
|
||||||
|
import WeekRecipe from '@/views/weekRecipe.vue'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -12,7 +13,12 @@ const routes = [
|
|||||||
path: '/recipe/:id',
|
path: '/recipe/:id',
|
||||||
name: "RecipeDetail",
|
name: "RecipeDetail",
|
||||||
component: RecipeDetail
|
component: RecipeDetail
|
||||||
}
|
},
|
||||||
|
{
|
||||||
|
path: '/week-recipe/',
|
||||||
|
name: "WeekRecipe",
|
||||||
|
component: WeekRecipe
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
@ -1,118 +1,40 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<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>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
<el-row justify="center">
|
<el-row justify="center">
|
||||||
<el-col :span="18">
|
<el-col>
|
||||||
<el-table :data="recipes" max-height="500" class="recipe-table">
|
<recipe_list></recipe_list>
|
||||||
<el-table-column prop="name" label="名字"> </el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="recipe_type"
|
|
||||||
label="类型"
|
|
||||||
:formatter="formatRecipeType"
|
|
||||||
:filters="[
|
|
||||||
{ text: '青菜', value: 'vegetable' },
|
|
||||||
{ text: '肉', value: 'meat' },
|
|
||||||
{ text: '汤', value: 'soup' },
|
|
||||||
]"
|
|
||||||
:filter-method="filterRecipeType"
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="difficulty"
|
|
||||||
label="难度"
|
|
||||||
:formatter="formatDifficulty"
|
|
||||||
sortable
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column
|
|
||||||
prop="rate"
|
|
||||||
label="评分"
|
|
||||||
:formatter="formatRate"
|
|
||||||
sortable
|
|
||||||
>
|
|
||||||
</el-table-column>
|
|
||||||
<el-table-column label="操作">
|
|
||||||
<template #default="scope">
|
|
||||||
<el-button size="mini" @click="editRecipe(scope.row)">
|
|
||||||
编辑
|
|
||||||
</el-button>
|
|
||||||
</template>
|
|
||||||
</el-table-column>
|
|
||||||
</el-table>
|
|
||||||
</el-col>
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
<el-row justify="center">
|
<el-row justify="center">
|
||||||
<el-col :span="18"> <input_recipe :recipe="{}"></input_recipe> </el-col>
|
<el-col>
|
||||||
|
<input_recipe :recipe="{}"></input_recipe>
|
||||||
|
</el-col>
|
||||||
</el-row>
|
</el-row>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
|
||||||
import input_recipe from '@/components/input_recipe.vue';
|
import input_recipe from '@/components/input_recipe.vue';
|
||||||
import router from '@/router/index';
|
import recipe_list from '@/components/recipe_list.vue';
|
||||||
import 'element-plus/dist/index.css';
|
import 'element-plus/dist/index.css';
|
||||||
// const api_root = 'localhost:8000'
|
|
||||||
const type_map = {
|
|
||||||
vegetable: '青菜',
|
|
||||||
meat: '肉',
|
|
||||||
soup: '汤',
|
|
||||||
};
|
|
||||||
const rate_map = {
|
|
||||||
1: '🍚',
|
|
||||||
2: '🍚 🍚',
|
|
||||||
3: '🍚 🍚 🍚',
|
|
||||||
4: '🍚 🍚 🍚 🍚',
|
|
||||||
5: '🍚 🍚 🍚 🍚 🍚',
|
|
||||||
};
|
|
||||||
const difficulty_map = {
|
|
||||||
1: '⭐',
|
|
||||||
2: '⭐ ⭐',
|
|
||||||
3: '⭐ ⭐ ⭐',
|
|
||||||
4: '⭐ ⭐ ⭐ ⭐',
|
|
||||||
5: '⭐ ⭐ ⭐ ⭐ ⭐',
|
|
||||||
};
|
|
||||||
function formatRecipeType(row) {
|
|
||||||
return type_map[row.recipe_type];
|
|
||||||
}
|
|
||||||
function formatRate(row) {
|
|
||||||
return rate_map[row.rate];
|
|
||||||
}
|
|
||||||
function formatDifficulty(row) {
|
|
||||||
return difficulty_map[row.difficulty];
|
|
||||||
}
|
|
||||||
export default {
|
export default {
|
||||||
components: { input_recipe },
|
|
||||||
name: 'Home',
|
name: 'Home',
|
||||||
provide() {
|
components: { input_recipe, recipe_list },
|
||||||
return {
|
|
||||||
reload: this.reload,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
reload() {
|
|
||||||
this.isRouterAlive = false;
|
|
||||||
this.$nextTick(function() {
|
|
||||||
this.isRouterAlive = true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
filterRecipeType(value, row) {
|
|
||||||
return row.recipe_type === value;
|
|
||||||
},
|
|
||||||
editRecipe(row) {
|
|
||||||
router.push({ name: 'RecipeDetail', params: { id: row.id } });
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: function() {
|
data: function() {
|
||||||
return {
|
return {};
|
||||||
recipes: '',
|
|
||||||
formatRecipeType,
|
|
||||||
formatRate,
|
|
||||||
formatDifficulty,
|
|
||||||
isRouterAlive: true,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
mounted() {
|
|
||||||
axios
|
|
||||||
.get('//localhost:8000/recipe/recipe/')
|
|
||||||
.then((response) => (this.recipes = response.data));
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
<template>
|
<template>
|
||||||
<el-page-header
|
<el-page-header
|
||||||
|
icon="el-icon-arrow-left"
|
||||||
@back="goHome"
|
@back="goHome"
|
||||||
title="首页"
|
title="首页"
|
||||||
v-bind:content="recipe.name"
|
v-bind:content="recipe.name"
|
||||||
|
|||||||
34
frontend/src/views/weekRecipe.vue
Normal file
34
frontend/src/views/weekRecipe.vue
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<el-menu mode="horizontal" default-active="/week-recipe/" router>
|
||||||
|
<el-menu-item index="/">
|
||||||
|
首页
|
||||||
|
</el-menu-item>
|
||||||
|
<el-menu-item index="/week-recipe/">
|
||||||
|
每周菜谱
|
||||||
|
</el-menu-item>
|
||||||
|
</el-menu>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-row justify="center">
|
||||||
|
<el-col>
|
||||||
|
<week_recipe></week_recipe>
|
||||||
|
</el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import week_recipe from '@/components/week_recipe.vue';
|
||||||
|
export default {
|
||||||
|
name: 'WeekRecipe',
|
||||||
|
components: { week_recipe },
|
||||||
|
data: function() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@ -96,6 +96,7 @@ class DailyRecipe(models.Model):
|
|||||||
value_.append(recipe.serialize())
|
value_.append(recipe.serialize())
|
||||||
|
|
||||||
date = now()
|
date = now()
|
||||||
date.replace(year=self.date.year, month=self.date.month, day=self.date.day,)
|
date = date.replace(year=self.date.year, month=self.date.month,
|
||||||
|
day=self.date.day, hour=0, minute=0)
|
||||||
data['date'] = utils.timestamp_of(utils.day_start(date))
|
data['date'] = utils.timestamp_of(utils.day_start(date))
|
||||||
return data
|
return data
|
||||||
|
|||||||
@ -42,7 +42,7 @@ class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
|
|||||||
recipes = []
|
recipes = []
|
||||||
for x in range(0, 7-today.weekday()):
|
for x in range(0, 7-today.weekday()):
|
||||||
daily_recipe, __ = recipe.models.DailyRecipe.objects.get_or_create(
|
daily_recipe, __ = recipe.models.DailyRecipe.objects.get_or_create(
|
||||||
date=today + datetime.timedelta(days=1)
|
date=today + datetime.timedelta(days=x)
|
||||||
)
|
)
|
||||||
daily_recipe.generate_recipe()
|
daily_recipe.generate_recipe()
|
||||||
recipes.append(daily_recipe.recipes.values_list('id', flat=True))
|
recipes.append(daily_recipe.recipes.values_list('id', flat=True))
|
||||||
@ -56,7 +56,9 @@ class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
|
|||||||
date__gte=week_start,
|
date__gte=week_start,
|
||||||
date__lte=week_end,
|
date__lte=week_end,
|
||||||
).order_by('date')
|
).order_by('date')
|
||||||
data = []
|
data = [{}] * (7 - len(daily_recipes))
|
||||||
|
|
||||||
for daily_recipe in daily_recipes:
|
for daily_recipe in daily_recipes:
|
||||||
data.append(daily_recipe.serialize())
|
data.append(daily_recipe.serialize())
|
||||||
|
|
||||||
return Response(data)
|
return Response(data)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user