feat(daily recipe detail page): [A] 增加每日菜谱接口及页面展示

[A] 增加每日菜谱接口及页面展示

Signed-off-by: Ching <loooching@gmail.com>
This commit is contained in:
Ching 2021-10-04 17:34:16 +08:00
parent 61ad33f439
commit 0cd1fd9358
8 changed files with 190 additions and 31 deletions

View 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>

View File

@ -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>

View File

@ -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({

View 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>

View File

@ -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

View File

@ -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__'

View File

@ -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'),
] ]

View File

@ -36,6 +36,7 @@ class WeekRecipeListAPI(rest_framework.generics.ListAPIView,
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