avatar CyanTachyon's Blog

CyanTachyon的个人博客

  • 首页
  • 分类
  • 标签
  • 归档
  • 关于
首页 SubQuiz Docs
文章

SubQuiz Docs

发表于 2025/04/13 更新于 2025/06/07
作者 CyanTachyon
17 分钟阅读
SubQuiz Docs
SubQuiz Docs

概述

SubQuiz原为SubIT社团开发的一款智能答题系统,之后该系统将移交北大附中科协,作为北大附中学生刷题练习网站,成为北大附中信息化的一部分。

功能

1.0

题目

题目结构及分类:

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|- 学科1
|  |- 学科描述
|  |- 题目类型1
|  |  |- 题目类型描述(markdown可选)
|  |  |- 大题1
|  |  |  |- 大题描述(可选)
|  |  |  |- 权重(学生不可见,用于影响推荐概率)
|  |  |  |- 可见(若不可见则不会被推荐)
|  |  |  |- 小题1
|  |  |  |  |- 小题题目描述
|  |  |  |  |- 小题类型
|  |  |  |  |- 选项(仅单选/多选有选项)
|  |  |  |  |- 标准答案(学生作答期间不可见)
|  |  |  |  |- 解析(学生作答期间不可见)
|  |  |  |  |- 用户答案(作答后)
|  |  |  |- 小题2
|  |  |  |- 小题3
|  |  |- 大题2
|  |  |  |-...
|  |  |-...
|  |- 题目类型2
|  |  |- ...
|- 学科2
|  |- ...
|-...

即学科->题目类型->大题->小题

其中大题是推荐题目、计算得分、等等的基本单位。

每道小题的类型可以是以下5种之一:

  • 单选
  • 多选
  • 判断
  • 填空
  • 简答

每道大题有自己独立的图片存储空间,可上传图片并通过markdown语法插入图片

测试

学生可以指定题目数量(大题数量)及学科(可选)开始一次测试,测试开始后,在测试结束并完成判卷前无法再次开始其他测试。

在答题过程中测试会自动保存。

可在答题记录中查看之前的全部测试。

若有未结束的测试可从答题记录中进入或在主页点开始新测试进入。

判卷

客观题(单选、多选、判断)由系统完成,简答和填空会将大题描述、小题描述、标准答案、用户答案合成提示词由大模型进行判卷

推荐

推荐即将全部符合要求的题目(可见、没有做过、学科限制)按“$权重\times错误率\times{random}$”进行排序

其中权重由老师设置,错误率是指该学生对于该题目类型的错误率,学生完成某道大题后按如下公式更新其对于该题目类型的错误率,其中$x$是这道大题的得分率

\[new\leftarrow1-\left(0.95\times\left(1-old\right)+0.05\times{x}\right)\]

权限

首先所有权限都分为4级,从低到高依次是:

  • BANNED
  • NORMAL
  • ADMIN
  • ROOT

权限分为全局权限和学科权限两种,学科权限指某一用户在某一学科的权限

权限更改

若修改某人的全局权限,有如下限制:

  • 自己的全局权限不低于 ADMIN
  • 若修改他人权限:自己的全局权限高于对方当前(修改前)的全局权限
  • 若修改他人权限:自己的全局权限高于目标(修改后)的全局权限
  • 若修改自己权限:修改后的权限不高于当前权限

若修改某人的某一学科的权限有如下限制:

  • 若自己全局权限不低于 ADMIN,则修改成功,忽略以下限制
  • 自己在该学科的权限不低于 ADMIN
  • 若修改他人权限:自己在该学科的权限高于对方当前(修改前)在该学科的权限
  • 若修改他人权限:自己在该学科的权限高于目标(修改后)在该学科的权限
  • 若修改自己权限:修改后的权限不高于当前权限

权限作用/限制

  • 若全局权限为 BANNED无法进行登陆
  • 若全局权限为 ROOT有权进入终端
  • 若全局权限不低于 ADMIN或在某一学科的权限不低于 ADMIN则有权按上述权限修改规则修改自己/他人的全局权限/学科权限
  • 若全局权限不低于 ADMIN或在某一学科的权限不低于 ADMIN,则有权编辑该学科的信息,包括但不限于学科名称、描述、增/删/改该学科的题目类型、增/删/改该学科下全部题目

2.0

主要调整结构,在学科下增加备课组概念,备课组下有知识点,知识点以树形结构存储,且对深度没有限制。知识点下有题目类型,这部分与1.0版本相同。

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|- 学科1
|  |- 学科描述
|  |- 备课组1
|  |  |- 知识点文件夹
|  |  |  |- 知识点文件夹
|  |  |  |  |- 知识点1
|  |  |  |  |- 知识点2
|  |  |  |- 知识点3
|  |  |  |  |- 题目类型1
|  |  |  |  |  |- 题目类型描述(markdown可选)
|  |  |  |  |  |- 大题1
|  |  |  |  |  |  |- 大题描述(可选)
|  |  |  |  |  |  |- 权重(学生不可见,用于影响推荐概率)
|  |  |  |  |  |  |- 可见(若不可见则不会被推荐)
|  |  |  |  |  |  |- 小题1
|  |  |  |  |  |  |  |- 小题题目描述
|  |  |  |  |  |  |  |- 小题类型
|  |  |  |  |  |  |  |- 选项(仅单选/多选有选项)
|  |  |  |  |  |  |  |- 标准答案(学生作答期间不可见)
|  |  |  |  |  |  |  |- 解析(学生作答期间不可见)
|  |  |  |  |  |  |  |- 用户答案(作答后)
|  |  |  |  |  |  |- 小题2
|  |  |  |  |  |  |- 小题3
|  |  |  |  |  |- 大题2
|  |  |  |  |  |  |-...
|  |  |  |  |  |-...
|  |  |  |  |- 题目类型2
|  |  |  |  |  |- ...
|- 学科2
|  |- ...
|-...

开发

项目结构及技术栈

整体采用前后端分离

后端

  • 语言: Kotlin
  • Web框架: Ktor
  • SQL数据库: PostgreSQL
  • 数据库交互: Exposed(Github)
  • 文件存储: 腾讯云COS

前端

  • 框架: Vue
  • 语言: TypeScript+SCSS
  • 安卓: Capacitor

开发环境

BOTH

JDK(17或以上,推荐OpenJDK17)

后端

JetBrains IntelliJ Idea

前端

NodeJS

VSCode

Android Studio(仅安卓端构建需要)

构建&部署

前期准备

域名/服务器购买备案等这里不再赘述

若将前后端部署在同一域名下,则需要2个域名,例如cdn.bdfzscc.com和quiz.bdfzscc.com,若前后端不在同一域名下,则需要3个域名。

由于SubQuiz使用腾讯云的COS服务,因此建议购买腾讯云的域名和服务器。

建议将后端与前端部署在同一域名下,可以减少跨域问题,例如前端在https://example.com/,后端在https://example.com/api/。后面的文档将都按照部署在同一域名下配置,如有需要可以调整

PostgreSQL

  1. 安装PostgreSQL
  2. 修改必要的配置文件,如配置监听端口等。保证PostgreSQL可以被SubQuiz后端所访问
  3. 为SubQuiz准备一个PostgreSQL用户,可以创建新的用户也可以使用默认的postgres
  4. 为SubQuiz准备一个database,请确认3中准备的用户有足够的权限访问该database,如创建表等。注意你只需要创建一个空的database,无需手动添加任何表或数据
  5. DONE! 留着用户名/密码/数据库备用

AI

  1. 物色一个大语言模型的服务商,需要注意的是,该服务商的接口必须遵循OpenAI协议。目前测试过的有Deepseek和硅基流动。
  2. 注册账户(若每个用户有请求频率/并发量限制,且限制过低,不足以支撑使用)
  3. 获取API TOKEN(如有需要可以获得多个TOKEN,原因同上)和API的URL
  4. DONE!留着URL和TOKEN备用

SSubitO

  1. 打开SSubITO注册并进入个人信息界面,点击 服务管理,创建一个新的服务。名字和简介自行填写,授权后权限选择 全部
  2. 等待审核通过,你可能需要联系SubIT以进行协商
  3. 审核通过后打开服务信息界面,查看服务id并获取服务密钥
  4. DONE!留着服务id和服务密钥备用

腾讯云COS及CDN

  1. 打开腾讯云COS,创建一个存储桶,地区建议选择和服务器相同,访问权限选择 共有读私有写。其余配置不限
  2. 在存储桶的安全配置中,配置允许访问的域名(即你准备部署的域名)
  3. 打开腾讯云EO按提示创建一个站点。进入 域名服务->域名管理->添加域名按提示创建一个对于刚刚创建的存储桶的加速服务
  4. 参考腾讯云文档为EO配置响应仅允许你的域名访问
  5. 打开腾讯云API密钥管理创建新的API密钥,记录ID和KEY
  6. DONE!留着你的存储桶名称、API密钥(ID和KEY)备用

恭喜你!准备工作到此结束,现在开始代码构建和部署:

后端的构建和部署

编译打包

在项目目录运行 ./gradlew clean build(linux)或 ./gradlew.bat clean build(windows)或在IntelliJ Idea中创建一个gradle任务,并在命令处输入 clean build并运行

运行结束后你可以找到 build/libs/SubQuiz.jar即为构建结果

配置并运行

使用命令java -jar SubQuiz.jar运行构建出的jar文件,其中有几个可选参数:

  • -workDir=$dir:工作目录,默认为当前目录
  • -dataDir=$dir:数据目录,默认为workDir下的data文件夹
  • -config=$file:配置文件,默认为workDir下的config.yaml
  • -debug=$debug:调试模式,默认为false

首次运行后,应该绘立刻退出,并生成主配置文件(-config),以及在(workDir)下的一个配置文件夹(configs)。

你需要逐一浏览并编辑主配置文件和配置文件夹下的全部配置文件,这些配置文件基本都带有注释,按提示编辑将准备工作中活动的秘钥/域名等填入即可。

恭喜你!后端部署已经全部结束了!

前端的配置和构建

打开前端项目的.env文件

0
1
2
3
4
5
6
VITE_APP_SUB_QUIZ_CDN=https://cdn.bdfzscc.com   #你的EO的URL
VITE_APP_SUB_QUIZ_BACKEND=https://quiz.bdfzscc.com/api   #你的后端的url
VITE_APP_SUB_QUIZ_FRONTEND=https://quiz.bdfzscc.com   #你的前端的URL

VITE_APP_SUB_QUIZ_SSO_FRONTEND=https://pkus.sso.subit.org.cn   #sso前端的url,应该不用该
VITE_APP_SUB_QUIZ_SSO_BACKEND=https://pkus.sso.subit.org.cn/api   #sso后端的url,应该不用该
VITE_APP_SUB_QUIZ_SSO_SERVICE_ID=3   #你在sso创建的服务的id

依次运行:

  • npm install
  • npm run build-web

此时你应当会看到一个/dist文件夹,即为前端构建结果

前端部署及反向代理后端

安装nginx,添加一个新的站点配置

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
server {
    listen 80;
    server_name quiz.bdfzscc.com; # 你的域名

    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    client_max_body_size 1024M;

    location / {
        root /var/www/SubQuiz; # 你的前端构建结果文件夹
        index index.html;
        try_files $uri $uri/ /index.html;
        location /android_latest.json {
            add_header Access-Control-Allow-Origin "*";
        }

        location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff2)$ {
           expires 1y;
           add_header Cache-Control "public, no-transform";
        }

        gzip on;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript;
    }

    location /api/ {
        proxy_pass http://localhost:8080; # 你的后端地址
    }

    location /api/terminal/api {
        proxy_pass http://localhost:8080; # 你的后端地址
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}
结束了!
部署全部完成!你可以打开`http://你的域名`查看结果,如需配置https只需要在上面的nginx配置中添加ssl配置即可
project, SubQuiz
kotlin vue project
本文由作者按照 CC BY-NC 4.0 进行授权, 未经许可不得转载。
分享

最近更新

  • SubQuiz Docs
  • FuckBrainfuck
  • Kotlin序列化多态
  • Java快速入门指南
  • c++快读快写

热门标签

develop kotlin cpp工具 java project vue 信息作业

外部链接

  •  此博客的 Github 仓库
  •  此博客的评论仓库

文章内容

相关文章

2024/11/28

FuckBrainfuck

FuckBrainfuck 先叠甲 以下内容纯属娱乐,不具有任何实际意义。我无法保证我的实现没有问题,如有问题欢迎指出。 Brainfuck简述 若你已经知道何为Brainfuck,请跳过此部分. Brainfuck是一种极简单的编程语言,由Urban Müller于1993年创造。它只包含八个命令,分别是> < + - [ ] . ,。它的内存模型是一个无限长度的字节数...

2024/11/25

Kotlin序列化多态

Kotlin序列化多态 关于Kt多态简述 当在序列化中出现多态时,会在序列化结果中带上类判别器(classDiscriminator),以区分不同的class。默认为type,并且可以通过classDiscriminator修改。也可以通过classDiscriminatorMode修改何时添加判别器 @file:OptIn(ExperimentalSerializationApi::cla...

FuckBrainfuck

-

© 2025 CyanTachyon. 保留部分权利。

|

本站采用 Jekyll 主题 Chirpy

热门标签

develop kotlin cpp工具 java project vue 信息作业