feat(daily recipe detail page): [A] 增加每日菜谱接口及页面展示
[A] 增加每日菜谱接口及页面展示 Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
parent
61ad33f439
commit
0cd1fd9358
77
frontend/src/components/daily_recipe_detail.vue
Normal file
77
frontend/src/components/daily_recipe_detail.vue
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
<template>
|
||||||
|
<el-table border :data="daily_recipe">
|
||||||
|
<el-table-column prop="meat" label="肉">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag
|
||||||
|
id="meal"
|
||||||
|
v-for="recipe in scope.row.meat"
|
||||||
|
:key="recipe.name"
|
||||||
|
closable
|
||||||
|
size="small"
|
||||||
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
|
>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
<el-table-column prop="vegetable" label="菜">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag
|
||||||
|
id="meal"
|
||||||
|
v-for="recipe in scope.row.vegetable"
|
||||||
|
:key="recipe.name"
|
||||||
|
closable
|
||||||
|
size="small"
|
||||||
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
|
>
|
||||||
|
</template></el-table-column
|
||||||
|
>
|
||||||
|
<el-table-column prop="soup" label="汤">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-tag
|
||||||
|
id="meal"
|
||||||
|
v-for="recipe in scope.row.soup"
|
||||||
|
:key="recipe.name"
|
||||||
|
closable
|
||||||
|
size="small"
|
||||||
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
|
>
|
||||||
|
</template></el-table-column
|
||||||
|
>
|
||||||
|
</el-table>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import axios from 'axios';
|
||||||
|
export default {
|
||||||
|
name: 'DailyRecipeDetail',
|
||||||
|
data: function() {
|
||||||
|
return {
|
||||||
|
daily_recipe: [],
|
||||||
|
inputVisible: false,
|
||||||
|
inputValue: null,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
axios
|
||||||
|
.get('//localhost:8000/recipe/daily-recipe/' + this.$route.params.id)
|
||||||
|
.then((response) => {
|
||||||
|
var data = {
|
||||||
|
meat: [],
|
||||||
|
vegetable: [],
|
||||||
|
soup: [],
|
||||||
|
};
|
||||||
|
for (let i = 0; i < response.data.recipes.length; i++) {
|
||||||
|
if (response.data.recipes[i].recipe_type == 'meat') {
|
||||||
|
data.meat.push(response.data.recipes[i]);
|
||||||
|
} else if (response.data.recipes[i].recipe_type == 'vegetable') {
|
||||||
|
data.vegetable.push(response.data.recipes[i]);
|
||||||
|
} else if (response.data.recipes[i].recipe_type == 'soup') {
|
||||||
|
data.soup.push(response.data.recipes[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.daily_recipe = [data];
|
||||||
|
});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style></style>
|
||||||
@ -6,40 +6,48 @@
|
|||||||
prop="date"
|
prop="date"
|
||||||
label="日期"
|
label="日期"
|
||||||
:formatter="formatDate"
|
:formatter="formatDate"
|
||||||
|
width="50px"
|
||||||
></el-table-column>
|
></el-table-column>
|
||||||
<el-table-column prop="meat" label="肉">
|
<el-table-column prop="meat" label="肉">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ul id="meal">
|
<el-tag
|
||||||
<li v-for="recipe in scope.row.meat" :key="recipe.name">
|
id="meal"
|
||||||
<a :href="'/recipe/' + recipe.id">
|
v-for="recipe in scope.row.meat"
|
||||||
{{ recipe.name }}
|
:key="recipe.name"
|
||||||
</a>
|
size="small"
|
||||||
</li>
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
</ul>
|
>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column prop="vegetable" label="菜">
|
<el-table-column prop="vegetable" label="菜">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ul id="meal">
|
<el-tag
|
||||||
<li v-for="recipe in scope.row.vegetable" :key="recipe.name">
|
id="meal"
|
||||||
<a :href="'/recipe/' + recipe.id">
|
v-for="recipe in scope.row.vegetable"
|
||||||
{{ recipe.name }}
|
:key="recipe.name"
|
||||||
</a>
|
size="small"
|
||||||
</li>
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
</ul>
|
>
|
||||||
</template></el-table-column
|
</template></el-table-column
|
||||||
>
|
>
|
||||||
<el-table-column prop="soup" label="汤">
|
<el-table-column prop="soup" label="汤">
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<ul id="meal">
|
<el-tag
|
||||||
<li v-for="recipe in scope.row.soup" :key="recipe.name">
|
id="meal"
|
||||||
<a :href="'/recipe/' + recipe.id">
|
v-for="recipe in scope.row.soup"
|
||||||
{{ recipe.name }}
|
:key="recipe.name"
|
||||||
</a>
|
size="small"
|
||||||
</li>
|
><a :href="'/recipe/' + recipe.id">{{ recipe.name }}</a></el-tag
|
||||||
</ul>
|
>
|
||||||
</template></el-table-column
|
</template></el-table-column
|
||||||
>
|
>
|
||||||
|
<el-table-column label="操作">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button size="mini" @click="editDailyRecipe(scope.row)">
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
</el-table>
|
</el-table>
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col>
|
<el-col>
|
||||||
@ -56,13 +64,15 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
import router from '@/router/index';
|
||||||
|
|
||||||
function formatDate(row, column, cellValue) {
|
function formatDate(row, column, cellValue) {
|
||||||
if (cellValue === undefined) {
|
if (cellValue === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var date_ = new Date(cellValue * 1000);
|
var date_ = new Date(cellValue * 1000);
|
||||||
return date_.toDateString();
|
var days = ['周日', '周一', '周二', '周三', '周四', '周五', '周六'];
|
||||||
|
return days[date_.getDay()];
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatMeal(row, column, cellValue) {
|
function formatMeal(row, column, cellValue) {
|
||||||
@ -99,6 +109,9 @@ export default {
|
|||||||
})
|
})
|
||||||
.then((response) => (this.daily_recipes = response.data));
|
.then((response) => (this.daily_recipes = response.data));
|
||||||
},
|
},
|
||||||
|
editDailyRecipe(row) {
|
||||||
|
router.push({ name: 'DailyRecipeDetail', params: { id: row.id } });
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
@ -108,12 +121,23 @@ export default {
|
|||||||
margin: 20px 0;
|
margin: 20px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
ul#meal {
|
|
||||||
list-style-type: none;
|
.el-tag#meal a:link {
|
||||||
padding: 0;
|
text-decoration: none;
|
||||||
margin: 0;
|
|
||||||
}
|
}
|
||||||
ul#meal li {
|
.el-tag#meal a:visited {
|
||||||
margin: 0 10px;
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
.el-tag#meal a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.el-tag#meal a:active {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.el-tag {
|
||||||
|
margin: 0px 5px 0 0px;
|
||||||
|
}
|
||||||
|
.el-tag + .el-tag {
|
||||||
|
margin: 5px 0px 0 0px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@ -2,6 +2,7 @@ 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'
|
import WeekRecipe from '@/views/weekRecipe.vue'
|
||||||
|
import DailyRecipeDetail from '@/views/dailyRecipeDetail.vue'
|
||||||
|
|
||||||
const routes = [
|
const routes = [
|
||||||
{
|
{
|
||||||
@ -19,6 +20,11 @@ const routes = [
|
|||||||
name: "WeekRecipe",
|
name: "WeekRecipe",
|
||||||
component: WeekRecipe
|
component: WeekRecipe
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/daily-recipe/:id',
|
||||||
|
name: "DailyRecipeDetail",
|
||||||
|
component: DailyRecipeDetail
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
|
|||||||
33
frontend/src/views/dailyRecipeDetail.vue
Normal file
33
frontend/src/views/dailyRecipeDetail.vue
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
<template>
|
||||||
|
<el-container>
|
||||||
|
<el-header>
|
||||||
|
<el-menu mode="horizontal" router default-active="#">
|
||||||
|
<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>
|
||||||
|
</el-header>
|
||||||
|
<el-main>
|
||||||
|
<el-row justify="center">
|
||||||
|
<el-col> <daily_recipe_detail></daily_recipe_detail></el-col>
|
||||||
|
</el-row>
|
||||||
|
</el-main>
|
||||||
|
</el-container>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import daily_recipe_detail from '@/components/daily_recipe_detail.vue';
|
||||||
|
export default {
|
||||||
|
name: 'DailyRecipeDetail',
|
||||||
|
components: { daily_recipe_detail },
|
||||||
|
data: function() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
@ -99,4 +99,5 @@ class DailyRecipe(models.Model):
|
|||||||
date = date.replace(year=self.date.year, month=self.date.month,
|
date = date.replace(year=self.date.year, month=self.date.month,
|
||||||
day=self.date.day, hour=0, minute=0)
|
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))
|
||||||
|
data['id'] = self.id
|
||||||
return data
|
return data
|
||||||
|
|||||||
@ -1,17 +1,26 @@
|
|||||||
|
from os import read
|
||||||
from django.contrib.auth.models import User, Group
|
from django.contrib.auth.models import User, Group
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
import recipe.models
|
import recipe.models
|
||||||
|
|
||||||
class RecipeSerializer(serializers.HyperlinkedModelSerializer):
|
class RecipeSerializer(serializers.ModelSerializer):
|
||||||
id = serializers.IntegerField(read_only=True)
|
id = serializers.IntegerField(read_only=True)
|
||||||
class Meta:
|
class Meta:
|
||||||
model = recipe.models.Recipe
|
model = recipe.models.Recipe
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
class WeekRecipeSerializer(serializers.HyperlinkedModelSerializer):
|
class WeekRecipeSerializer(serializers.ModelSerializer):
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
model = recipe.models.DailyRecipe
|
model = recipe.models.DailyRecipe
|
||||||
fields = '__all__'
|
fields = '__all__'
|
||||||
|
|
||||||
|
|
||||||
|
class DailyRecipeSerializer(serializers.ModelSerializer):
|
||||||
|
id = serializers.IntegerField(read_only=True)
|
||||||
|
recipes = RecipeSerializer(many=True)
|
||||||
|
class Meta:
|
||||||
|
model = recipe.models.DailyRecipe
|
||||||
|
fields = '__all__'
|
||||||
|
|||||||
@ -11,4 +11,6 @@ urlpatterns = [
|
|||||||
url(r'^recipe/(?P<pk>\d+)$', views.RecipeAPI.as_view(), name='recipe-detail'),
|
url(r'^recipe/(?P<pk>\d+)$', views.RecipeAPI.as_view(), name='recipe-detail'),
|
||||||
url(r'^recipe/$', views.RecipeListAPI.as_view()),
|
url(r'^recipe/$', views.RecipeListAPI.as_view()),
|
||||||
url(r'^week-recipe/$', views.WeekRecipeListAPI.as_view()),
|
url(r'^week-recipe/$', views.WeekRecipeListAPI.as_view()),
|
||||||
|
url(r'^daily-recipe/(?P<pk>\d+)$', views.DailyRecipeAPI.as_view(),
|
||||||
|
name='dailyrecipe-detail'),
|
||||||
]
|
]
|
||||||
|
|||||||
@ -32,10 +32,11 @@ class RecipeListAPI(rest_framework.generics.ListAPIView,
|
|||||||
|
|
||||||
|
|
||||||
class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
|
class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
|
||||||
rest_framework.generics.CreateAPIView):
|
rest_framework.generics.CreateAPIView):
|
||||||
|
|
||||||
queryset = recipe.models.DailyRecipe.objects.all()
|
queryset = recipe.models.DailyRecipe.objects.all()
|
||||||
serializer_class = recipe.serializers.WeekRecipeSerializer
|
serializer_class = recipe.serializers.WeekRecipeSerializer
|
||||||
|
|
||||||
def post(self, request, *args, **kwargs):
|
def post(self, request, *args, **kwargs):
|
||||||
# Monday == 0 ... Sunday == 6
|
# Monday == 0 ... Sunday == 6
|
||||||
today = localtime()
|
today = localtime()
|
||||||
@ -62,3 +63,9 @@ class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
|
|||||||
data.append(daily_recipe.serialize())
|
data.append(daily_recipe.serialize())
|
||||||
|
|
||||||
return Response(data)
|
return Response(data)
|
||||||
|
|
||||||
|
|
||||||
|
class DailyRecipeAPI(rest_framework.generics.RetrieveUpdateAPIView):
|
||||||
|
|
||||||
|
queryset = recipe.models.DailyRecipe.objects.all()
|
||||||
|
serializer_class = recipe.serializers.DailyRecipeSerializer
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user