java中的接口是类吗
476
2022-09-08
基于Django的在线选修课程推荐系统(附源码)
一、搭建项目
python解释器版本使用3.7.8。
1、创建虚拟环境
在d盘下创建一个文件夹my_work,然后在里面创建两个文件夹:pro和venv。
win+R输入cmd进入文件夹venv,然后执行以下命令创建虚拟环境:
python -m venv course_manager
激活虚拟环境:
cd course_manager cd Scripts activate
导入django:
pip install Django==3.0.7 -i https://pypi.mirrors.ustc.edu.cn/simple/ pip install PyMySQL==0.9.2 -i https://pypi.mirrors.ustc.edu.cn/simple/ pip install xadmin-django==3.0.2 -i https://pypi.mirrors.ustc.edu.cn/simple/ pip install mysqlclient==2.0.1 -i https://pypi.mirrors.ustc.edu.cn/simple/ pip install numpy==1.21.6 -i .. cd .. cd .. cd pro
2、创建项目
执行命令:
django-admin startproject course_manager
3、创建子应用
切换到项目根目录:
cd course_manager
创建子应用:
python manage.py startapp course
自此项目创建完成。
二、settings.py配置
1、创建数据库
使用MySQL可视化工具创建一个数据库course_manager。
2、PyCharm打开项目
使用PyCharm打开项目:file->open.
在项目根目录下创建以下文件夹:
static、media、imgs、log、templates。
其中media中再创建一个文件夹course_cover存放课程封面。
选中templates->右键->Make Directory as- >Template Folder.
3、配置项目虚拟环境
4、允许所有网站访问
在course_manager\settings.py中做修改:
ALLOWED_HOSTS = ['*']
5、添加子应用
在course_manager\settings.py中的INSTALLED_APPS加入子应用course,如下:
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'xadmin', 'crispy_forms', 'course' ]
6、添加templates目录
在course_manager\settings.py中的TEMPLATES中DIRS改为:
'DIRS': [os.path.join(BASE_DIR, 'templates')],
7、使用mysql数据库
把在course_manager\settings.py中的DATABASES注释掉,改为:
ip = '127.0.0.1' DATABASE_NAME = 'course_manager' # mysql数据库名称 DATABASE_USER = 'root' # mysql数据库用户名 DATABASE_PASS = 'xxx' # mysql数据库密码 DATABASE_HOST = ip # mysql数据库IP DATABASE_PORT = 3306 # mysql数据库端口 # 配置数据库 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', # 修改数据库为MySQL,并进行配置 'NAME': DATABASE_NAME, # 'USER': DATABASE_USER, # 用户名 'PASSWORD': DATABASE_PASS, # 密码 'HOST': DATABASE_HOST, 'PORT': DATABASE_PORT, 'OPTIONS': {'charset': 'utf8mb4', } } }
8、使用中文
把course_manager\settings.py的LANGUAGE_CODE、TIME_ZONE和USE_TZ改为:
LANGUAGE_CODE = 'zh-hans' # 使用中国时区 TIME_ZONE = 'Asia/Shanghai' USE_I18N = True USE_L10N = True USE_TZ = False
9、配置静态文件路由
把course_manager\settings.py的STATIC_URL改为:
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ] # STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 收集静态文件时打开,然后关闭STATICFILES_DIRS MEDIA_URL = '/media/' MEDIA_ROOT = os.path.join(BASE_DIR, 'media') MEDIA_USER_ICON = os.path.join(BASE_DIR, 'media/user_icon')
三、models.py数据表
在course\models.py中创建用户表、课程类别表、课程表、用户选课表、评分表、收藏表、评论表:
from django.db import models # 用户表 class User(models.Model): username = models.CharField(max_length=255, unique=True, verbose_name="账号") password = models.CharField(default='123456', max_length=32, verbose_name="密码") class Meta: db_table = 'user' verbose_name_plural = "用户" verbose_name = "用户" def __str__(self): return self.username # 课程类别表 class Tags(models.Model): name = models.CharField(max_length=200, verbose_name="类别") class Meta: db_table = 'tags' verbose_name = "课程类别" verbose_name_plural = "课程类别" def __str__(self): return self.name # 课程表 class CourseInfo(models.Model): name = models.CharField(verbose_name="课程名", max_length=255) course_code = models.CharField(unique=True, verbose_name="课程编号", max_length=255) teacher = models.CharField(verbose_name="讲师", max_length=255) about = models.TextField(verbose_name="描述") pic = models.FileField(verbose_name="封面图片", max_length=64, upload_to='course_cover') tags = models.ForeignKey( Tags, on_delete=models.CASCADE, verbose_name="类别", related_name="tags", blank=True, null=True, ) select_num = models.IntegerField(verbose_name="选修人数", default=0) look_num = models.IntegerField(verbose_name="浏览人数", default=0) collect_num = models.IntegerField(verbose_name="收藏人数", default=0) course_url = models.TextField(verbose_name="课程网址", default='https://xuetangx.com/') add_time = models.DateTimeField(verbose_name="创建时间", auto_now_add=True) class Meta: db_table = 'course_info' verbose_name = "课程" verbose_name_plural = "课程" def __str__(self): return self.name # 用户选课表 class UserCourse(models.Model): course = models.ForeignKey( CourseInfo, to_field='course_code', on_delete=models.CASCADE, blank=True, null=True, verbose_name="课程id" ) user = models.ForeignKey( User, on_delete=models.CASCADE, blank=True, null=True, verbose_name="用户id", ) enroll_time = models.DateTimeField(verbose_name="选修时间", auto_now_add=True) class Meta: db_table = 'user_course' verbose_name = "用户选课信息" verbose_name_plural = verbose_name # 评分表 class RateCourse(models.Model): course = models.ForeignKey( CourseInfo, to_field='course_code', on_delete=models.CASCADE, related_name='rate_course', blank=True, null=True, verbose_name="课程id" ) user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, verbose_name="用户id") mark = models.FloatField(verbose_name="评分") create_time = models.DateTimeField(verbose_name="添加时间", auto_now_add=True) class Meta: db_table = 'rate_course' verbose_name = "评分信息" verbose_name_plural = verbose_name # 收藏表 class CollectCourse(models.Model): course = models.ForeignKey( CourseInfo, to_field='course_code', on_delete=models.CASCADE, related_name='collect_course', blank=True, null=True, verbose_name="课程id" ) user = models.ForeignKey( User, on_delete=models.CASCADE, blank=True, null=True, verbose_name="用户id", ) is_delete = models.BooleanField(default=False, verbose_name='是否取消') create_time = models.DateTimeField(verbose_name="收藏时间", auto_now_add=True) class Meta: db_table = 'collect_course' verbose_name = "课程收藏" verbose_name_plural = verbose_name # 评论表 class CommentCourse(models.Model): course = models.ForeignKey( CourseInfo, to_field='course_code', on_delete=models.CASCADE, related_name='comment_course', blank=True, null=True, verbose_name="课程id" ) user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True, null=True, verbose_name="用户") content = models.TextField(verbose_name="评论内容") create_time = models.DateTimeField(verbose_name='评论时间', auto_now_add=True) like_num = models.IntegerField(verbose_name="点赞数", default=0) like_users = models.TextField(null=True, blank=True, default=None, verbose_name="点赞用户") is_show = models.BooleanField(default=True, verbose_name='是否显示') class Meta: db_table = 'comment_course' verbose_name = "课程评论" verbose_name_plural = verbose_name
四、urls.py路由配置
1、修改course_manager\urls.py
在course下创建一个urls.py,并让course_manager\urls.py分配路由,
其中course_manager\urls.py改为:
import xadmin
from django.urls import path, re_path, include
from django.views.generic import RedirectView
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('xadmin/', xadmin.site.urls),
path("", include("course.urls")),
# favicon.cio
re_path(r'^favicon\.ico$', RedirectView.as_view(url=r'media/favicon.ico')),
re_path(r'^media/(?P
2、修改course\urls.py
先改为:
from django.urls import path, re_path from course import views urlpatterns = [ ]
后面会添加各种路由。
3、数据迁移
在pycharm左下角的Terminal里执行数据迁移命令
python manage.py makemigrations python manage.py migrate
4、创建缓存表
python manage.py createcachetable
5、收集静态文件
先把course_manager\settings.py中的静态文件路由改为:
STATIC_URL = '/static/' # STATICFILES_DIRS = [ # os.path.join(BASE_DIR, 'static'), # ] STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 收集静态文件时打开,然后关闭STATICFILES_DIRS
然后执行:
python manage.py collectstatic
执行成功后,把course_manager\settings.py中的静态文件路由改为:
STATIC_URL = '/static/' STATICFILES_DIRS = [ os.path.join(BASE_DIR, 'static'), ] # STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 收集静态文件时打开,然后关闭STATICFILES_DIRS
把course_manager\urls.py改为:
import xadmin
from django.urls import path, re_path, include
from django.views.generic import RedirectView
from django.views.static import serve
from django.conf import settings
urlpatterns = [
path('xadmin/', xadmin.site.urls),
path("", include("course.urls")),
# favicon.cio
re_path(r'^favicon\.ico$', RedirectView.as_view(url=r'media/favicon.ico')),
re_path(r'^media/(?P
6、创建后台管理员
python manage.py createsuperuser
设置账号为 root 邮箱为 1@qq.com 密码为 course-root
五、导入基础数据
把根目录下的course.sql在mysql可视化工具中执行即可。
六、核心代码
1、static创建文件夹
在static目录下创建三个文件夹image、css、js和fonts用来存放前端需要使用到的文件。
2、base.html前端框架
在目录templates下创建前端页面框架base.html,代码如下:
3、course/urls.py创建基础路由
course/urls.py创建搜索、全部课程、新课速递、热门课程、课程分类、猜你喜欢、个人中心等路由,代码如下:
# !/usr/bin/python
# -*- coding: utf-8 -*-
from django.urls import path
from course import views
urlpatterns = [
path("", views.index, name="index"), # 首页
path("login/", views.login, name="login"), # 登录
path("register/", views.register, name="register"), # 注册
path("logout/", views.logout, name="logout"), # 退出
path("modify_pwd/", views.modify_pwd, name="modify_pwd"), # 修改密码
path("search/", views.search, name="search"), # 搜索
path("all_course/", views.all_course, name="all_course"), # 所有课程
path("course/
在course\views.py中为每个路由创建响应。
4、登录
5、注册
6、登出
def logout(request): if not request.session.get("login_in", None): # 不在登录状态跳转回首页 return redirect(reverse("index")) request.session.flush() # 清除session信息 return redirect(reverse("index"))
7、修改密码
8、搜索
def search(request): # 搜索 if request.method == "POST": # 如果搜索界面 key = request.POST["search"] request.session["search"] = key # 记录搜索关键词解决跳页问题 else: key = request.session.get("search") # 得到关键词 # 课程名称、简介、老师模糊搜索 courses = CourseInfo.objects.filter(Q(name__icontains=key) | Q(about__icontains=key) | Q(teacher__icontains=key)) page_num = request.GET.get("page", 1) courses = courses_paginator(courses, page_num) return render(request, "all_course.html", {"courses": courses})
9、所有课程
10、具体的课程
11、选修课程
@login_in def select_course(request, course_id): # 用户选修课程 course = CourseInfo.objects.get(pk=course_id) user_id = request.session.get("user_id") user = User.objects.get(pk=user_id) if not UserCourse.objects.filter(user_id=user_id, course_id=course.course_code): # 创建一条用户选修课程记录 UserCourse.objects.create(course=course, user=user) course.select_num += 1 # 增加选修人数 course.save() return redirect(course.course_url) # 跳转到课程观看页面
12、评分
@login_in def score(request, course_id): user_id = request.session.get("user_id") user = User.objects.get(id=user_id) course = CourseInfo.objects.get(id=course_id) score = float(request.POST.get("score", 0)) # 获取评分 is_rate = RateCourse.objects.filter(course=course, user=user).first() if not is_rate: # 用户未评分则创建一条评分记录 RateCourse.objects.get_or_create(user=user, course=course, defaults={"mark": score}) is_rate = {'mark': score} comments = course.comment_course.filter(is_show=True).order_by("-create_time") # 获取可展示的评论,按时间降序 rate = RateCourse.objects.filter(course=course).aggregate(Avg("mark")).get("mark__avg", 0) # 获取平均评分 course_rate = round(rate, 2) if rate else 0 # 取评分两位小数 is_collect = True if course.collect_course.filter(user_id=user_id, is_delete=False) else False # 判断是否收藏 # 判断是否选修 is_select = True if UserCourse.objects.filter(user_id=user_id, course_id=course.course_code) else False return render(request, "course.html", locals())
13、评论
14、给评论点赞
@login_in def comment_like(request, comment_id): user_id = request.session.get("user_id") user = User.objects.get(id=user_id) comment = CommentCourse.objects.get(id=comment_id) if not comment.like_users: # 还没有用户点过赞 comment.like_users = '{},'.format(user_id) # 添加用户点赞记录 comment.like_num += 1 elif str(user_id) not in comment.like_users.split(','): # 用户未给该评论点过赞 comment.like_users += '{},'.format(user_id) # 添加用户点赞记录 comment.like_num += 1 else: pass comment.save() course = comment.course comments = course.comment_course.filter(is_show=True).order_by("-create_time") # 获取可展示的评论,按时间降序 rate = RateCourse.objects.filter(course=course).aggregate(Avg("mark")).get("mark__avg", 0) # 获取平均评分 course_rate = round(rate, 2) if rate else 0 # 取评分两位小数 is_collect = True if course.collect_course.filter(user_id=user_id, is_delete=False) else False # 判断是否收藏 is_rate = RateCourse.objects.filter(course=course, user=user).first() # 判断是否评分过 # 判断是否选修 is_select = True if UserCourse.objects.filter(user_id=user_id, course_id=course.course_code) else False return render(request, "course.html", locals())
15、收藏
16、新课速递
def new_course(request): page_number = request.GET.get("page", 1) # 按创建时间排序,取前10门课程 courses = courses_paginator(CourseInfo.objects.all().order_by("-add_time")[:10], page_number) return render(request, "all_course.html", {"courses": courses, "title": "新课速递"})
17、热门课程
def hot_course(request): page_number = request.GET.get("page", 1) # 按收藏量查询,降序,取前10门课程 courses = CourseInfo.objects.all().order_by('-collect_num')[:10] courses = courses_paginator(courses, page_number) return render(request, "all_course.html", {"courses": courses, "title": "热门课程"})
18、课程分类
19、猜你喜欢
20、推荐算法
在项目根目录下的recommend_courses.py文件中:
# -*-coding:utf-8-*- import math import os import django import operator import numpy as np from course.models import * os.environ["DJANGO_SETTINGS_MODULE"] = "course_master.settings" django.setup() class UserCf: # 基于用户协同算法来获取推荐列表 """ 利用用户的群体行为来计算用户的相关性。 计算用户相关性的时候我们就是通过对比他们选修过多少相同的课程相关度来计算的 举例: --------+--------+--------+--------+--------+ | X | Y | Z | R | --------+--------+--------+--------+--------+ a | 1 | 1 | 1 | 0 | --------+--------+--------+--------+--------+ b | 1 | 0 | 1 | 0 | --------+--------+--------+--------+--------+ c | 1 | 1 | 0 | 1 | --------+--------+--------+--------+--------+ a用户选修了:X、Y、Z b用户选修了:X、Z c用户选修了:X、Y、R 那么很容易看到a用户和b、c用户非常相似,给a用户推荐课程R, 给b用户推荐课程Y 给c用户推荐课程Z 这就是基于用户的协同过滤。 a用户向量为(1,1,1,0) b用户向量为(1,0,1,0) c用户向量为(1,1,0,1) 找a用户的相似用户,则计算a向量与其他向量的夹角即可,夹角越小则说明越相近 利用求高维空间向量的夹角,可以估计两组数据的吻合程度 """ # 获得初始化数据 def __init__(self, data): self.data = data # 计算N维向量的夹角 def calc_vector_cos(self, a, b): ''' cos=(ab的内积)/(|a||b|) :param a: 向量a :param b: 向量b :return: 夹角值 ''' a_n = np.array(a) b_n = np.array(b) if any(b_n) == 0: return 0 cos_ab = a_n.dot(b_n) / (np.linalg.norm(a_n) * np.linalg.norm(b_n)) return round(cos_ab, 2) # 计算与当前用户的距离,获得最临近的用户 def nearest_user(self, username, n=1): distances = {} # 用户,相似度 # 遍历整个数据集 for user, rate_set in self.data.items(): # 非当前的用户 if user != username: vector_a = tuple(self.data[username].values()) vector_b = tuple(self.data[user].values()) distance = self.calc_vector_cos(vector_a, vector_b) # 计算两个用户的相似度 distances[user] = distance # 排序,按向量夹角由小到到排序 closest_distance = sorted(distances.items(), key=operator.itemgetter(1), reverse=True) # 最相似的N个用户 # print("closest user:", closest_distance[:n]) return closest_distance[:n] # 给用户推荐课程 def recommend(self, username, n=1): recommend = set() nearest_user = self.nearest_user(username, n) # 获取最相近的n个用户 for user_id, _ in nearest_user: for usercourse in UserCourse.objects.filter(user_id=user_id): if usercourse.course.id not in self.data[username].keys(): recommend.add(usercourse.course.id) return recommend def recommend_by_user_id(user_id): # 通过用户协同算法来进行推荐 current_user = User.objects.get(id=user_id) # 如果当前用户没有选修过课程,则按照收藏量降序返回 if current_user.usercourse_set.count() == 0: courses = CourseInfo.objects.all().order_by('-collect_num') if courses.count() > 30: courses = courses[:30] return courses data = {} course_ids = [] other_user_ids = set() # 把该用户选修过的课程变成向量字典:{'用户id': {'课程1id': 1, '课程2id': 1...}} for u_course in current_user.usercourse_set.all(): # 遍历用户选修过的课程 if not data: data[current_user.id] = {u_course.course.id: 1} # 已选课程,设置值为1 else: data[current_user.id][u_course.course.id] = 1 course_ids.append(u_course.course) # 获取其他选修过该课程的用户id for usercourse in UserCourse.objects.filter(course=u_course.course): if usercourse.user.id != current_user.id: other_user_ids.add(usercourse.user.id) # 把选修过其中课程的用户选修过的课程变成向量字典:{'用户2id': {'课程1id': 0, '课程2id': 1...}} for other_user in User.objects.filter(pk__in=other_user_ids): other_user_id = other_user.id for i in range(len(course_ids)): course = course_ids[i] if UserCourse.objects.filter(user_id=other_user_id, course=course): is_select = 1 else: is_select = 0 if other_user_id not in data: data[other_user_id] = {course.id: is_select} # 已选课程,设置值为1,未选课程设置为0 else: data[other_user_id][course.id] = is_select user_cf = UserCf(data=data) recommend_ids = user_cf.recommend(current_user.id, 1) if not recommend_ids: # 如果没有找到相似用户则按照收藏量降序返回 courses = CourseInfo.objects.all().order_by('-collect_num') if courses.count() > 30: courses = courses[:30] return courses return CourseInfo.objects.filter(id__in=recommend_ids).order_by('-select_num')
21、个人中心
22、我的选修
23、我的收藏
@login_in def my_collect(request): collect_courses = CollectCourse.objects.filter(user_id=request.session.get("user_id"), is_delete=False) return render(request, "my_collect.html", {"collect_courses": collect_courses})
24、我的评分
@login_in def my_rate(request): rate_courses = RateCourse.objects.filter(user_id=request.session.get("user_id")) return render(request, "my_rate.html", {"rate_courses": rate_courses})
25、删除我的评分
@login_in def delete_rate(request, rate_id): rate = RateCourse.objects.filter(pk=rate_id) if not rate: return render(request, "404.html") rate = rate.first() rate.delete() rate_courses = RateCourse.objects.filter(user_id=request.session.get("user_id")) return render(request, "my_rate.html", {"rate_courses": rate_courses})
26、我的评论
@login_in def my_comments(request): comment_courses = CommentCourse.objects.filter(user_id=request.session.get("user_id"), is_show=True) return render(request, "my_comment.html", {"comment_courses": comment_courses})
27、删除我的评论
@login_in def delete_comment(request, comment_id): # 删除评论 comment = CommentCourse.objects.get(pk=comment_id) comment.is_show = False comment.save() comment_courses = CommentCourse.objects.filter(user_id=request.session.get("user_id"), is_show=True) return render(request, "my_comment.html", {"comment_courses": comment_courses})
七、后台管理
1、创建adminx.py文件
在子应用course下创建一个adminx.py文件:
里面代码为:
2、修改course\apps.py
代码改为如下:
from django.apps import AppConfig class CourseConfig(AppConfig): name = 'course' verbose_name = "课程推荐系统"
3、修改course\__init__.py
代码改为:
default_app_config = 'course.apps.CourseConfig'
4、浏览器登录
浏览器访问.. cd home/venv/ python3 -m venv course_manager
激活虚拟环境:
source course_manager/bin/activate
更新pip:
pip install --upgrade pip
退回项目根目录:
cd .. cd course_manager
批量安装第三方库:
pip install -r requirements.txt -i manage.py migrate
创建缓存表:
python manage.py createcachetable
创建后台管理员
python manage.py createsuperuser
设置账号为 root 邮箱为 1@qq.com 密码为 book-root
数据库图形化工具执行course.sql
2、配置uwsgi.ini
uwsgi.ini内容如下:
[uwsgi] # 使用nginx连接时 使用 socket=0.0.0.0:8102 # 直接作为web服务器使用 #http=127.0.0.1:8102 # 配置工程目录 chdir=/home/course_manager # 配置项目的wsgi目录。相对于工程目录 wsgi-file=course_manager/wsgi.py virtualenv =/home/venv/course_manager #配置进程,线程信息 listen=1024 processes=2 threads=4 enable-threads=True master=True pidfile=uwsgi.pid daemonize=uwsgi.log #django项目修改完文件后自动重启 py-autoreload=1
把uwsgi.ini放到根目录下。
导入uwsgi:
pip install uwsgi
启动uwsgi:
uwsgi --ini uwsgi.ini
查看是否启动成功:
netstat -lnp|grep uwsgi
若出现类似:
tcp 0 0 0.0.0.0:8102 0.0.0.0:* LISTEN 927/uwsgi
则说明启动成功
2、配置nginx
创建一个course_manager_nginx文件,内容如下:
#设定虚拟主机配置 server { #侦听80端口 listen 80; #listen 443 ssl; #定义使用 nginx.cn访问 #ssl on; server_name xxx.xxx.com; #server_name xxx.xxx.xxx.30; #定义服务器的默认网站根目录位置 root /home/course_manager; #ssl_session_timeout 5m; #ssl_certificate /etc/nginx/cert/xxx.pem; #ssl_certificate_key /etc/nginx/cert/xxx.key; #ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4; #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #ssl_prefer_server_ciphers on; #设定本虚拟主机的访问日志 #access_log logs/nginx.access.log main; #默认请求 location / { #倒入了uwsgi的配置 include uwsgi_params; client_max_body_size 50m; #连接uwsgi的超时时间 # uwsgi_connect_timeout 30; #设定了uwsig服务器位置 uwsgi_pass 127.0.0.1:8102; } location /static{ alias /home/course_manager/static; } location /media { alias /home/course_manager/media; } }
文件放到/etc/nginx/sites-available下面。
然后通过以下命令映射到/etc/nginx/sites-enabled
ln -s /etc/nginx/sites-available/course_manager_nginx /etc/nginx/sites-enabled/course_manager_nginx
nginx重启:
nginx -s reload
在浏览器中访问网站就可以看到课程了。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~