项目结构:
本项目采用 Vue3+Django+PostgresSQL 的结构
- 前端:使用 Router 搭建 SPA 网页应用,使用 CSS3 完成排版,使用 TypeScript 编写交互逻辑, 使用 axios 自定义逻辑实现前后端通信
- 后端:使用 django-restframework 定义 api 接口,并用 django-cors-headers 实现跨端口通信( Vue3 的默认端口为 5273,而 Django 默认为 8000),使用 simple-jwt 与 pyjwt 实现 token 验证, 所有的数据采用雪花主键+64位 UUID 的存储方式(UUID用于前后端通信,雪花主键用于后端内部逻辑)以增强数据安全性
功能实现:
- 完成了账号的注册与登录功能,完成了用户的登录认证(JWT)与路由保护,目前未登录的用户进入需认证的页面时会自动跳转到登录页面,令牌会定期刷新
- 完成了观众题目的获取,可以通过 api 获取后端的题目并显示在网页上
- 完成了演讲的创建与总览功能,可以看见演讲列表并点击进入演讲详情页
- 完成了演讲资料的提交
- 可以成功调用通义千问api,但具体细节还在打磨
用到的api:
- localhost:8000/api/upload-media/
- localhost:8000/api/token/refresh/
- localhost:8000/api/presentations/
- localhost:8000/api/login/
- localhost:8000/api/register/
- localhost:8000/api/popquiz/
数据库表:
RegisteredUser
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
主键,使用雪花算法生成的全局唯一 ID |
password |
VARCHAR(128) |
NOT NULL |
用户密码(加密存储) |
last_login |
TIMESTAMP WITH TIME ZONE |
NULLABLE |
最后登录时间,Django 认证系统字段 |
is_superuser |
BOOLEAN |
NOT NULL, DEFAULT FALSE |
是否为超级用户,Django 权限系统字段 |
username |
VARCHAR(150) |
UNIQUE, NOT NULL |
用户名(唯一标识,登录用) |
first_name |
VARCHAR(150) |
NOT NULL, DEFAULT |
名字 |
last_name |
VARCHAR(150) |
NOT NULL, DEFAULT |
姓氏 |
email |
VARCHAR(254) |
NOT NULL, DEFAULT |
邮箱地址 |
is_staff |
BOOLEAN |
NOT NULL, DEFAULT FALSE |
是否为后台管理用户 |
is_active |
BOOLEAN |
NOT NULL, DEFAULT TRUE |
是否激活账户 |
date_joined |
TIMESTAMP WITH TIME ZONE |
NOT NULL |
账户注册时间 |
Presentation
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
雪花算法生成的全局唯一主键 ID |
uuid |
UUID |
UNIQUE, NOT NULL, DEFAULT uuid_generate_v4() |
自动生成的全局唯一 UUID |
title |
VARCHAR(200) |
NOT NULL |
演讲标题 |
description |
TEXT |
NULL(可为空) |
演讲简要描述,可选 |
presenter_id |
BIGINT |
FOREIGN KEY → RegisteredUser(id), NOT NULL, ON DELETE CASCADE |
演讲者,关联已注册用户 |
scheduled_time |
TIMESTAMP |
NULL(可为空) |
预定开始时间 |
duration_minutes |
INTEGER |
NULL(可为空) |
预计时长(分钟) |
is_active |
BOOLEAN |
NOT NULL, DEFAULT TRUE |
是否处于进行中 / 可互动状态 |
created_at |
TIMESTAMP |
NOT NULL, DEFAULT CURRENT_TIMESTAMP |
创建时间,自动记录 |
updated_at |
TIMESTAMP |
NOT NULL, DEFAULT CURRENT_TIMESTAMP, ON UPDATE CURRENT_TIMESTAMP |
更新时间,自动记录 |
PresentationParticipant
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
雪花算法生成的全局唯一主键 ID |
uuid |
UUID |
UNIQUE, NOT NULL, DEFAULT uuid_generate_v4() |
自动生成的全局唯一 UUID |
user_id |
BIGINT |
FOREIGN KEY → RegisteredUser(id), NOT NULL, ON DELETE CASCADE |
关联的注册用户 |
presentation_id |
BIGINT |
FOREIGN KEY → Presentation(id), NOT NULL, ON DELETE CASCADE |
关联的演讲 |
role |
VARCHAR(20) |
NOT NULL, CHECK (role IN ( presenter , audience , organizer )) |
用户在该演讲中的角色(演讲者/观众/组织者) |
joined_at |
TIMESTAMP |
NOT NULL, DEFAULT CURRENT_TIMESTAMP |
加入时间,自动记录 |
MediaFile
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
雪花算法生成的全局唯一主键 ID |
uuid |
UUID |
UNIQUE, NOT NULL, DEFAULT uuid_generate_v4() |
自动生成的全局唯一 UUID |
presentation_id |
BIGINT |
FOREIGN KEY → Presentation(id), NOT NULL, ON DELETE CASCADE |
所属的演讲/课程 |
file |
FILE |
NOT NULL, upload_to= media_files/ |
上传的媒体文件 |
type |
VARCHAR(10) |
NOT NULL, CHECK (type IN ( ppt , video , audio , image , pdf , other )) |
媒体类型(PPT、视频、音频、图像、PDF、其他) |
title |
VARCHAR(255) |
NULL(可为空) |
媒体文件标题,选填 |
uploaded_at |
TIMESTAMP |
NOT NULL, DEFAULT CURRENT_TIMESTAMP |
上传时间,自动记录 |
order |
INTEGER |
NOT NULL, DEFAULT 0 |
媒体展示顺序,可用于手动排序 |
PopQuiz
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
雪花算法生成的全局唯一主键 ID |
uuid |
UUID |
UNIQUE, NOT NULL, DEFAULT uuid_generate_v4() |
自动生成的全局唯一 UUID |
created_at |
TIMESTAMP |
NOT NULL, DEFAULT CURRENT_TIMESTAMP |
创建时间,自动记录 |
question_type |
VARCHAR(20) |
NOT NULL, DEFAULT choice , CHECK (IN ( choice , fill )) |
题目类型:选择题(choice)或填空题(fill) |
question_text |
TEXT |
NOT NULL |
题干文本 |
options |
JSON |
NULL(可为空) |
题目选项,仅适用于选择题,格式如 ["A", "B", ...] |
correct_answers |
JSON |
NOT NULL |
标准答案列表,支持多选或填空 |
is_multiple |
BOOLEAN |
NOT NULL, DEFAULT FALSE |
是否为多选题,仅适用于选择题 |
quiz_index |
INTEGER |
NOT NULL |
该题在演讲中的编号(如第 0、1、2 题) |
presentation_id |
BIGINT |
FOREIGN KEY → Presentation(id), NOT NULL, ON DELETE CASCADE |
所属的演讲/课程 |
Answer
| 字段名 | 数据类型 | 约束 | 说明 |
|---|---|---|---|
id |
BIGINT |
PRIMARY KEY, NOT NULL |
雪花算法生成的全局唯一主键 ID |
user |
FOREIGN KEY |
NOT NULL, 关联 RegisteredUser(id) |
作答者,指向答题的用户 |
quiz |
FOREIGN KEY |
NOT NULL, 关联 PopQuiz(id) |
对应题目,指向所回答的具体题目 |
presentation |
FOREIGN KEY |
NOT NULL, 关联 Presentation(id) |
所属演讲或课程,用于归档和统计 |
selected_options |
JSON |
NOT NULL |
用户提交的选项列表,支持单选/多选,例如 ["A"] 或 ["A", "C"] |
is_correct |
BOOLEAN |
NULLABLE |
是否作答正确,可由后台评判后赋值 |
submitted_at |
DATETIME |
NOT NULL, auto_now_add=True |
作答时间,自动记录用户提交的时间 |
前端页面:
注册页面:

登录页面(忘记密码功能未实现):

演讲列表:

功能解释:
- 主页可以正常跳转,但页面为空,由于必要的功能都在演讲页面实现了,关于用户细节体验的功能不在第一周工程计划中
- 点击 ”新建演讲“ 按钮创建新演讲(设计为点击后自动进入新演讲的演讲详情页面,但此页面正在搭建,故目前只有创建功能)
- ”临时占位“ 暂时的讨论结果是改为 ”加入演讲“ ,不过不在第一周的工程计划中
- 点击对应的演讲元素会跳转到详情页面,页面正在搭建
- 搜索框支持对演讲名称的模糊搜索
- 指向演讲元素会在右下角显示三个点用于后续呼出扩展菜单(列如删除元素)
还在建设的演讲详情页:

© 版权声明
文章版权归作者所有,未经允许请勿转载。如内容涉嫌侵权,请在本页底部进入<联系我们>进行举报投诉!
THE END


















- 最新
- 最热
只看作者后续跟进呢?