# RD-Rev

## 运行手册

主要技术栈一览

- 前端
  - 框架：Vue 3
  - 组件库：Quasar
  - 构建工具：Vite

- 后端
  - Java 17
  - 开发框架：Springboot 3
  - ORM：Mybatis (Plus)
  - 数据库：Postgresql
  - NoSQL：Redis

- 运行部署
  - 运行与部署：Docker
  - 阿里云CDN（示例站点）

自行部署的示例站点： https://rd-rev.lensfrex.net

## 后端

后端运行比较简单，可以使用已经打包好的 jar 包，也可以[自行编译 jar 运行](#2-自行打包编译运行)，还可以[使用 `docker compose` 来运行](#3-docker-compose)。

### 1. jar 包直接运行

相关数据库等配置已经配置好，直接运行即可，不用额外配置：

``` sh
java -jar ./radical-dreamers.jar
```

如确需修改配置，放置一份 `application.yml` 配置文件至 jar 文件同一目录下，即可覆盖原有配置，或者运行时添加参数（位于 jar 路径后） `--spring.config.location` 指定新的配置文件路径：

``` sh
java -jar ./radical-dreamers.jar --spring.config.location=./application.yml
```

以下是配置文件示例（可在代码中找到）：

``` yaml
mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.slf4j.Slf4jImpl
  mapper-locations: classpath*:/mapper/**/*.xml

logging:
  level:
    rd: debug
    druid.sql.Statement: trace
  pattern:
    console: "%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}"
    file: "%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}} ${LOG_LEVEL_PATTERN:-%5p} ${PID:- } --- [%t] %-40.40logger{39} : %m%n${LOG_EXCEPTION_CONVERSION_WORD:%wEx}"

spring:
  task:
    execution:
      pool:
        core-size: 16
        max-size: 32
        queue-capacity: 128
        keep-alive: 90s
  devtools:
    restart:
      enabled: true
  data:
    redis:
      client-name: neolaf
      host: 127.0.0.1
      port: 6379
      password: Test2333!
      database: 0

  datasource:
    driver-class-name: org.postgresql.Driver
    url: jdbc:postgresql://127.0.0.1:5432/little_busters?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
    username: postgres
    password: Test2333!

server:
  address: 127.0.0.1
  port: 8800
  servlet:
    context-path: /

sa-token:
  token-name: auth-token
  is-concurrent: true

rd:
  WusthelperBaseUrl: https://wusthelper.wustlinghang.cn/mobileapi/v2
```

## 2. 自行打包编译运行

该方式运行过程与上文 jar 包直接运行相同，差别在于需要手动编译和打包。

编译打包的过程很简单：

``` sh
mvn clean package
```

完成后，编译产物位于target文件夹中，名为 `radical-dreamers.jar`

打包完成后，运行方式同上文。

## 3. Docker Compose

在构建 Docker 镜像前，需要先打包好 jar 文件，过程参考上文打包过程。

完成后，运行：

``` sh
docker compose up --build
```

构建镜像并运行，由于网络原因，镜像拉取可能会很吃力，请自备代理。

以下是 `docker-compose.yml` 的内容（可在代码中找到）：

``` yaml
name: rd-srv-backend

services:
  # 主服务
  rd:
    build:
      context: .
      dockerfile: Dockerfile
    ports:
      - "8800:8800"
    environment:
      spring.data.redis.host: redis
      spring.data.redis.port: 6379
      spring.datasource.url: jdbc:postgresql://db:5432/rdrev?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=Asia/Shanghai
      spring.datasource.username: postgres
      spring.datasource.password: a7d929f76d45d13a4337f2d16f5634bc17e5b8b2
      server.port: 8800
    depends_on:
      redis:
        condition: service_started
      db:
        condition: service_healthy
    networks:
      - rd-network

  # Postgresql
  db:
    image: postgres:14.12-alpine3.19
    environment:
      PGUSER: postgres
      POSTGRES_USER: postgres
      POSTGRES_DB: rdrev
      POSTGRES_PASSWORD: a7d929f76d45d13a4337f2d16f5634bc17e5b8b2
    volumes:
      - ./docker:/docker-entrypoint-initdb.d/
    networks:
      - rd-network
    healthcheck:
      test: [ "CMD-SHELL", "pg_isready", "-d", "db_prod"]
      interval: 10s
      timeout: 60s
      retries: 5
      start_period: 5s

  # Redis
  redis:
    image: redis
    networks:
      - rd-network

networks:
  rd-network:
    internal: false
```

可以参考该配置根据需求自行修改。

## 前端

### 1. 安装npm依赖：

``` sh
# 使用yarn
yarn

# 使用npm
npm install
```

### 2. 运行 dev server

修改 baseUrl 配置（可选，默认情况下由 vite dev server 进行代理转发至本机`127.0.0.1:8800`，本地开发运行可以不做修改）

修改前端源码文件夹中的`config.js`配置文件：

``` javascript
export default {
  // backendBaseUrl: 'http://127.0.0.1:8800',
  backendBaseUrl: '',
}
```

修改完成后，运行 dev server：

``` sh
# 使用yarn
yarn dev

# 使用npm
npm run dev
```

运行起来后，会自动打开浏览器进入首页。

## 功能详情

设定信息：
  - 课程：一门课
  - *课堂*：实际上课的一门课程，即具体安排的一门课，同一个课程的不同时间安排，就是一个*课堂*
  - 选课：实际上就是在选课活动的时间内，学生对*课堂*的选择
  - 选课活动：一个学期的选课活动，在选课时间段内学生可以进行任意的选课，设定当前选课活动中的专业对象，其对应课程在查看待选*课堂*时进行筛选

> 选课信息是实时的，不需要等待选课活动结束才能得到名单，也可以立即导出，在选课活动结束后只是学生不能再进行选课以及修改

管理员可以设定课程（一门课的信息），并且指定上这门课的老师，而具体的上课信息（上课地点，学期，节次等）需要设置这门课程上课安排。

在选课活动进行中时，需要设置活动对象，指定在该活动中可以进行选择的年级和专业，以及可选的课程，只有符合条件的学生，才能选择指定课程的上课安排。

在同一个时间段内，只能有一个进行中的活动，即每个活动的时间不能有重叠。

管理员的用户名为root，初始默认密码：root，其他由管理员手动添加的账号信息默认情况下均与用户名相同，可在进入后修改。
学生账号可以直接使用武科大本科生系统的账号密码直接登入，会自动创号。

## 用户（学生）

1. 学生进入网页，使用教务处账号登录认证，获取学生信息，进入系统
2. 进入系统后可自动获取显示自己专业自己年级待选的实验课列表
3. 在选课时间段内，可点击相应的实验课后查看可选则的时间段。选择相应的时间段
4. 在选课时间段内，可以任意更改所选课程的时间段。
5. 选课结束后，可以查看已选择的时间
6. 课程结束后，可以按课程查看分数详情，包括平时分和考试分以及最后总分。

## 教师

1. 教师账号通过管理员手动添加
2. 教师登陆后可以查看自己教授的课程，
3. 查看自己教的课程列表，可以查看该课程相应的*课堂*，进而可以查看*课堂*信息（选课人数，时间等），包括学生名单，并将其导出为excel
4. 教师可以按照*课堂*对全班学生进行成绩登记，包括平时成绩与考试成绩，管理员设定该*课堂*的成绩占比后可以立即计算所有学生的最终成绩，并将其导出excel
5. 教师仍可以查看往期*课堂*的信息，包括学生名单和全班成绩信息等

## 管理员

1. 管理员是负责对*课堂*、课程等信息进行管理的用户
2. 管理员可以增删查改*课堂*、课程信息，设定相应的参数信息。
3. 由管理员发布选课活动，设定*课堂*的成绩比例
4. 管理员可以查看所有信息（学生+教师）
5. 管理员也可查看未完整进行选课（一个或多个课程仍未进行选课）的学生列表（需要提前导入学生列表）

一些信息的参数：
  -  选课活动：名称，学年学期（如2023-2024-1），目标年级（多选），目标专业（多选），开始时间，结束时间
  -  课程：名称，课时，目标年级（多选），目标专业（多选）
  -  *课堂*：对应课程id，起始周，上课时间（12345678节等等），上课地点，成绩占比
