feat(notification): 实现通知功能,支持角色层级发送和课程群发

1. 修改 SysNotification 实体,新增 senderId, senderName, targetType 字段

2. 新增 SendNotificationRequest 请求DTO

3. 扩展通知类型至6种(新增用户通知、课程通知)

4. 实现角色层级权限控制,支持多级管理员通知下级

5. 支持老师群发课程通知给学生

6. 新增批量发送接口和权限配置
This commit is contained in:
wangzhiwei 2026-05-15 16:57:07 +08:00
parent a8faaebc79
commit 5f5c0759ce
403 changed files with 12057 additions and 11082 deletions

View File

@ -0,0 +1,558 @@
# 实训平台客户端后端开发计划
## 一、需求分析
根据《实训平台客户端完整需求文档V2.0)》,需要实现以下核心模块:
| 模块 | 功能点 | 状态 |
| :--- | :--- | :--- |
| **注册登录** | 手机号验证码注册、账号密码注册、微信扫码登录、自动注册 | 部分实现 |
| **通知中心** | 通知列表、详情查看、单条/全部已读 | 未实现 |
| **充值中心** | 充值套餐、套餐支付、自定义充值 | 已实现沿用account/accountTransaction/paymentOrder表 |
| **教学管理** | 课程管理、作业管理、考试管理、考勤管理 | 未实现 |
| **优秀作品** | 作品展示、点赞互动 | 未实现 |
| **个人中心** | 个人信息、消费记录、订单记录、密码修改、手机号修改 | 部分实现 |
## 二、技术架构
### 2.1 技术栈
- **语言**: Java 17
- **框架**: Spring Boot 3.2.2
- **数据库**: MySQL
- **ORM**: MyBatis
- **缓存**: Redis + Redisson
- **认证**: Sa-Token
- **支付**: 微信支付 SDK、支付宝 SDK
- **文档**: SpringDoc OpenAPI
### 2.2 代码结构
```
src/main/java/com/kexue/skills/
├── annotation/ # 自定义注解
├── aspect/ # AOP切面
├── common/ # 通用工具类
├── config/ # 配置类
├── controller/ # 控制器
├── entity/ # 实体类
│ ├── base/ # 基础实体
│ ├── dto/ # 数据传输对象
│ ├── request/ # 请求对象
│ └── response/ # 响应对象
├── exception/ # 异常处理
├── interceptor/ # 拦截器
├── mapper/ # MyBatis映射器
├── service/ # 业务服务
│ └── impl/ # 服务实现
└── SkillsApp.java # 启动类
```
## 三、开发计划
### 阶段一数据库表设计与初始化预计1天
**任务1.1:设计并创建教学管理相关表**
- `edu_course` - 课程表
- `edu_course_student` - 课程学生关联表
- `edu_homework` - 作业表
- `edu_homework_submit` - 作业提交表
- `edu_exam` - 考试表
- `edu_exam_paper` - 考试答卷表
- `edu_attendance` - 考勤表
- `edu_attendance_record` - 考勤记录表
**任务1.2:设计并创建通知表**
- `sys_notification` - 通知表
- `sys_notification_read` - 通知已读记录表
**任务1.3:设计并创建优秀作品表**
- `edu_excellent_work` - 优秀作品表
- `edu_work_like` - 作品点赞表
**任务1.4:扩展用户表字段**
- 添加院校相关字段school_id, college_id, major_id, grade, class_name
- 添加角色字段role_type (1-学生, 2-老师)
- 添加账户状态字段account_status (1-可学用户, 2-试用用户, 3-学校用户, 4-冻结用户)
- 添加激活码相关字段activation_code, binding_status
### 阶段二用户体系模块开发预计2天
**任务2.1:完善注册功能**
- 添加学校/学院/专业/年级/班级选择接口
- 实现手机号验证码注册
- 实现账号密码注册
- 支持默认角色为学生
**任务2.2:完善登录功能**
- 实现微信扫码登录绑定wxid
- 实现手机号密码登录
- 完善自动注册逻辑
**任务2.3:院校绑定功能**
- 实现身份信息填写接口
- 实现院校预校验接口
- 实现激活码绑定接口
**任务2.4:个人中心功能**
- 个人信息查看与修改
- 密码修改(含找回密码)
- 绑定手机号修改
### 阶段三通知模块开发预计1天
**任务3.1:通知管理接口**
- 获取通知列表(按时间倒序)
- 查看通知详情(自动标记已读)
- 单条通知已读
- 全部通知已读
### 阶段四教学管理模块开发预计4天
**任务4.1:课程管理**
- 老师端:创建课程、管理课程、课程学生管理、导出成绩
- 学生端:查看课程、查看课程内容
**任务4.2:作业管理**
- 老师端:作业草稿管理、发布作业、作业批改、优秀标记、删除作业
- 学生端:查看作业、提交作业、修改作业、重做退回作业
**任务4.3:考试管理**
- 老师端:考试草稿管理、发布考试、阅卷管理、补考管理、删除考试
- 学生端:查看考试、参加考试、参加补考
**任务4.4:考勤管理**
- 老师端:发起签到(二维码/手动点名)、管理签到记录、修改考勤状态
- 学生端:扫码签到、查看考勤记录
### 阶段五优秀作品模块开发预计1天
**任务5.1:优秀作品展示**
- 获取优秀作品列表
- 作品点赞每个作品仅可点赞1次
### 阶段六统一异常处理与安全加固预计1天
**任务6.1:统一异常处理**
- 实现统一错误提示语
- 完善全局异常处理器
**任务6.2:安全加固**
- 权限双重校验
- 数据隔离机制
- 操作日志留存
## 四、接口清单
### 4.1 用户体系接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/register/phone` | POST | 手机号验证码注册 |
| `/api/register/password` | POST | 账号密码注册 |
| `/api/login/wechat` | POST | 微信扫码登录 |
| `/api/login/phone` | POST | 手机号验证码登录 |
| `/api/login/password` | POST | 账号密码登录 |
| `/api/binding/school/check` | POST | 院校预校验 |
| `/api/binding/activation` | POST | 激活码绑定 |
| `/api/user/info` | GET | 获取个人信息 |
| `/api/user/info` | PUT | 修改个人信息 |
| `/api/user/password` | PUT | 修改密码 |
| `/api/user/phone` | PUT | 修改绑定手机号 |
### 4.2 通知接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/notification/list` | GET | 获取通知列表 |
| `/api/notification/detail/{id}` | GET | 查看通知详情 |
| `/api/notification/read/{id}` | PUT | 标记单条已读 |
| `/api/notification/read/all` | PUT | 标记全部已读 |
### 4.3 课程管理接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/course/list` | GET | 获取课程列表 |
| `/api/course/create` | POST | 创建课程 |
| `/api/course/update` | PUT | 修改课程信息 |
| `/api/course/delete/{id}` | DELETE | 删除课程 |
| `/api/course/students/{courseId}` | GET | 获取课程学生列表 |
| `/api/course/addStudents` | POST | 批量添加学生 |
| `/api/course/removeStudent` | DELETE | 踢出学生 |
| `/api/course/exportScore/{courseId}` | GET | 导出成绩 |
### 4.5 作业管理接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/homework/list/{courseId}` | GET | 获取作业列表 |
| `/api/homework/create` | POST | 创建作业草稿 |
| `/api/homework/update` | PUT | 修改作业草稿 |
| `/api/homework/delete/{id}` | DELETE | 删除作业 |
| `/api/homework/publish` | PUT | 发布作业 |
| `/api/homework/submit` | POST | 提交作业 |
| `/api/homework/correct` | PUT | 批改作业 |
| `/api/homework/excellent/{id}` | PUT | 标记优秀 |
| `/api/homework/return` | PUT | 退回作业 |
### 4.6 考试管理接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/exam/list/{courseId}` | GET | 获取考试列表 |
| `/api/exam/create` | POST | 创建考试草稿 |
| `/api/exam/update` | PUT | 修改考试草稿 |
| `/api/exam/delete/{id}` | DELETE | 删除考试 |
| `/api/exam/publish` | PUT | 发布考试 |
| `/api/exam/take/{examId}` | POST | 参加考试 |
| `/api/exam/correct` | PUT | 阅卷打分 |
| `/api/exam/makeup` | POST | 创建补考 |
### 4.7 考勤管理接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/attendance/start` | POST | 发起签到 |
| `/api/attendance/list/{courseId}` | GET | 获取签到记录列表 |
| `/api/attendance/detail/{id}` | GET | 查看签到详情 |
| `/api/attendance/sign` | POST | 扫码签到 |
| `/api/attendance/status` | PUT | 修改考勤状态 |
| `/api/attendance/myList` | GET | 个人考勤记录 |
### 4.8 优秀作品接口
| API路径 | 方法 | 功能描述 |
| :--- | :--- | :--- |
| `/api/excellent/list` | GET | 获取优秀作品列表 |
| `/api/excellent/like/{workId}` | POST | 点赞作品 |
## 五、数据库表设计
### 5.1 用户表扩展字段
```sql
-- sys_user 表新增字段(仅添加通用字段,角色专属字段移至扩展表)
ALTER TABLE `sys_user`
ADD COLUMN `account_status` TINYINT(1) DEFAULT '1' COMMENT '账户状态1-可学用户2-试用用户3-学校用户4-冻结用户',
ADD COLUMN `wxid` VARCHAR(100) DEFAULT NULL COMMENT '微信ID';
```
### 5.2 用户角色关联表
```sql
CREATE TABLE `sys_user_role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
`role_code` VARCHAR(50) NOT NULL COMMENT '角色编码student-学生teacher-老师admin-管理员',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_role` (`user_id`, `role_code`),
KEY `idx_user_id` (`user_id`),
KEY `idx_role_code` (`role_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';
```
### 5.3 学生扩展表
```sql
CREATE TABLE `edu_student` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID关联sys_user',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID',
`college_id` BIGINT(20) DEFAULT NULL COMMENT '学院ID',
`major_id` BIGINT(20) DEFAULT NULL COMMENT '专业ID',
`grade` VARCHAR(20) DEFAULT NULL COMMENT '年级',
`class_name` VARCHAR(50) DEFAULT NULL COMMENT '班级',
`student_no` VARCHAR(50) DEFAULT NULL COMMENT '学号',
`real_name` VARCHAR(50) DEFAULT NULL COMMENT '真实姓名',
`activation_code` VARCHAR(50) DEFAULT NULL COMMENT '激活码',
`binding_status` TINYINT(1) DEFAULT '0' COMMENT '绑定状态0-未绑定1-已绑定',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_college_id` (`college_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生扩展表';
```
### 5.4 教师扩展表
```sql
CREATE TABLE `edu_teacher` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID关联sys_user',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID',
`college_id` BIGINT(20) DEFAULT NULL COMMENT '学院ID',
`real_name` VARCHAR(50) DEFAULT NULL COMMENT '真实姓名',
`teacher_no` VARCHAR(50) DEFAULT NULL COMMENT '教师编号',
`title` VARCHAR(50) DEFAULT NULL COMMENT '职称',
`activation_code` VARCHAR(50) DEFAULT NULL COMMENT '激活码',
`binding_status` TINYINT(1) DEFAULT '0' COMMENT '绑定状态0-未绑定1-已绑定',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_college_id` (`college_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='教师扩展表';
```
### 5.5 通知表
```sql
CREATE TABLE `sys_notification` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
`title` VARCHAR(100) NOT NULL COMMENT '通知标题',
`content` TEXT NOT NULL COMMENT '通知内容',
`type` TINYINT(1) DEFAULT '1' COMMENT '通知类型1-系统通知2-作业通知3-考试通知4-考勤通知',
`is_read` TINYINT(1) DEFAULT '0' COMMENT '是否已读0-未读1-已读',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_is_read` (`is_read`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知表';
```
### 5.6 课程表
```sql
CREATE TABLE `edu_course` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`name` VARCHAR(100) NOT NULL COMMENT '课程名称',
`cover` VARCHAR(255) DEFAULT NULL COMMENT '课程封面',
`description` TEXT DEFAULT NULL COMMENT '课程简介',
`class_time` VARCHAR(100) DEFAULT NULL COMMENT '上课时间',
`teaching_method` TINYINT(1) DEFAULT '1' COMMENT '授课方式1-线上2-线下3-混合',
`teacher_id` BIGINT(20) NOT NULL COMMENT '创建老师ID',
`status` TINYINT(1) DEFAULT '1' COMMENT '课程状态1-进行中2-已结课',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_teacher_id` (`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程表';
```
### 5.7 课程学生关联表
```sql
CREATE TABLE `edu_course_student` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`join_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '加入时间',
`is_kicked` TINYINT(1) DEFAULT '0' COMMENT '是否被踢出0-正常1-已踢出',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_course_student` (`course_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程学生关联表';
```
### 5.8 作业表
```sql
CREATE TABLE `edu_homework` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) NOT NULL COMMENT '作业名称',
`requirement` TEXT DEFAULT NULL COMMENT '作业要求',
`questions` TEXT NOT NULL COMMENT '题目JSON',
`allow_late` TINYINT(1) DEFAULT '0' COMMENT '是否允许迟交',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME NOT NULL COMMENT '截止时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-草稿2-已发布',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作业表';
```
### 5.9 作业提交表
```sql
CREATE TABLE `edu_homework_submit` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`homework_id` BIGINT(20) NOT NULL COMMENT '作业ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`answers` TEXT NOT NULL COMMENT '答案JSON',
`submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '提交时间',
`is_late` TINYINT(1) DEFAULT '0' COMMENT '是否迟交',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-待批改2-已批改3-已退回',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
`is_excellent` TINYINT(1) DEFAULT '0' COMMENT '是否优秀',
`redo_end_time` DATETIME DEFAULT NULL COMMENT '重做截止时间',
`redo_count` INT(11) DEFAULT '0' COMMENT '重做次数',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_homework_id` (`homework_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作业提交表';
```
### 5.10 考试表
```sql
CREATE TABLE `edu_exam` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) NOT NULL COMMENT '考试名称',
`requirement` TEXT DEFAULT NULL COMMENT '考试要求',
`questions` TEXT NOT NULL COMMENT '考卷JSON',
`duration` INT(11) NOT NULL COMMENT '考试时长(分钟)',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME NOT NULL COMMENT '截止时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-草稿2-已发布3-已结束',
`is_makeup` TINYINT(1) DEFAULT '0' COMMENT '是否补考',
`parent_exam_id` BIGINT(20) DEFAULT NULL COMMENT '关联主考ID',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试表';
```
### 5.11 考试答卷表
```sql
CREATE TABLE `edu_exam_paper` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`exam_id` BIGINT(20) NOT NULL COMMENT '考试ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`answers` TEXT NOT NULL COMMENT '答案JSON',
`submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '提交时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-待阅卷2-已阅卷',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_exam_student` (`exam_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_exam_id` (`exam_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试答卷表';
```
### 5.12 考勤表
```sql
CREATE TABLE `edu_attendance` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) DEFAULT NULL COMMENT '签到名称(按时间自动生成)',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`duration` INT(11) DEFAULT '15' COMMENT '签到时长(分钟)',
`type` TINYINT(1) DEFAULT '1' COMMENT '签到类型1-二维码签到2-手动点名',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-进行中2-已结束',
`qr_code` VARCHAR(255) DEFAULT NULL COMMENT '二维码内容',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤表';
```
### 5.13 考勤记录表
```sql
CREATE TABLE `edu_attendance_record` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`attendance_id` BIGINT(20) NOT NULL COMMENT '考勤ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`status` TINYINT(1) DEFAULT '1' COMMENT '考勤状态1-出勤2-迟到3-缺勤4-请假',
`sign_time` DATETIME DEFAULT NULL COMMENT '签到时间',
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注(手动点名时填写)',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_attendance_student` (`attendance_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_attendance_id` (`attendance_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤记录表';
```
### 5.14 优秀作品表
```sql
CREATE TABLE `edu_excellent_work` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`work_type` TINYINT(1) NOT NULL COMMENT '作品类型1-作业2-考试',
`work_id` BIGINT(20) NOT NULL COMMENT '关联作业/考试ID',
`submit_id` BIGINT(20) NOT NULL COMMENT '关联提交ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '标记时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_work_type_work_id` (`work_type`, `work_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优秀作品表';
```
### 5.15 作品点赞表
```sql
CREATE TABLE `edu_work_like` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`work_id` BIGINT(20) NOT NULL COMMENT '优秀作品ID',
`user_id` BIGINT(20) NOT NULL COMMENT '点赞用户ID',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_work_user` (`work_id`, `user_id`),
KEY `idx_school_id` (`school_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作品点赞表';
```
## 六、开发进度安排
| 阶段 | 任务 | 预计天数 | 负责人 |
| :--- | :--- | :--- | :--- |
| 第一阶段 | 数据库表设计与初始化 | 1 | 开发人员 |
| 第二阶段 | 用户体系模块开发 | 2 | 开发人员 |
| 第三阶段 | 通知模块开发 | 1 | 开发人员 |
| 第四阶段 | 教学管理模块开发 | 4 | 开发人员 |
| 第五阶段 | 优秀作品模块开发 | 1 | 开发人员 |
| 第六阶段 | 统一异常处理与安全加固 | 1 | 开发人员 |
| **总计** | | **10天** | |
## 七、风险与注意事项
### 7.1 风险识别
| 风险 | 描述 | 应对措施 |
| :--- | :--- | :--- |
| 数据权限安全 | 用户可能越权访问其他用户数据 | 前端展示+后端接口双重校验token验证 |
| 并发问题 | 高并发场景下的数据一致性问题 | 使用Redis分布式锁数据库事务 |
| 支付安全 | 支付回调可能被篡改 | 验证签名,使用安全的回调地址 |
| 接口幂等性 | 重复提交导致数据重复 | 使用防重复提交注解唯一业务ID |
### 7.2 注意事项
1. **权限校验**所有API查询严格校验token与对应用户ID
2. **数据排序**:所有数据获取接口默认按日期最新排序
3. **操作留痕**:课程/作业/考试/考勤/充值操作全量日志留存≥1年
4. **流程不可逆**:院校绑定、注册登录、作业考试发布流程严格按文档执行
5. **异常处理**:统一错误提示语,返回标准化错误信息
---
**文档版本**: V1.0
**创建时间**: 2026-04-30
**创建人**: 系统生成

View File

@ -0,0 +1,206 @@
# 通知功能实现方案
## 1. 需求分析
根据业务描述,通知系统需要支持以下功能:
### 1.1 系统通知
- 次级管理员增加/删除学校管理员 → 主要管理员可见
- 次级管理员增加/修改/删除套餐 → 主要管理员可见
- 老师的系统通知 → 主要管理员可见
### 1.2 管理员对用户通知(层级发送)
| 角色 | 可通知对象 | 说明 |
|------|-----------|------|
| 主要管理员(SUPER) | 次级管理员、学校管理员、学院管理员、老师、学生 | 可多选 |
| 次级管理员(SUPER1) | 学校管理员、学院管理员、老师、学生 | 可多选 |
| 学校管理员(SCOOL_ADMIN) | 学院管理员、老师、学生 | 可多选 |
| 学院管理员(COLLEGE_ADMIN) | 老师、学生 | 可多选 |
| 老师(TEACHER) | 指定课程的学生 | 课程可多选 |
| 学生(STUDENT) | 仅收件箱 | 无发送权限 |
### 1.3 核心需求(用户明确)
1. **通知创建人** - 需要记录发送者信息
2. **发送目标** - 需要记录接收人信息
3. **通知类型** - 需要支持多种类型
---
## 2. 当前代码分析
### 2.1 现有通知实体 (`SysNotification`)
| 字段 | 类型 | 说明 | 当前状态 |
|------|------|------|----------|
| id | Long | 主键ID | ✅ 存在 |
| schoolId | Long | 学校ID数据隔离 | ✅ 存在 |
| userId | Long | 用户ID | ✅ 存在作为接收者ID |
| title | String | 通知标题 | ✅ 存在 |
| content | String | 通知内容 | ✅ 存在 |
| type | Integer | 通知类型 | ✅ 存在仅4种 |
| isRead | Integer | 是否已读 | ✅ 存在(用户表示可保留) |
| createTime | Date | 创建时间 | ✅ 存在 |
### 2.2 现有问题
| 问题 | 说明 |
|------|------|
| 缺少发送者信息 | 当前只有接收者ID(userId)缺少发送者ID和姓名 |
| 通知类型不足 | 只有4种类型缺少用户通知和课程通知 |
| 缺少批量发送功能 | 当前只能单条发送给单个用户 |
| 缺少角色层级控制 | 没有实现角色层级的发送权限控制 |
---
## 3. 实现方案(最小化修改)
### 3.1 数据库表结构调整
**新增字段到 `sys_notification` 表:**
| 字段名 | 类型 | 约束 | 说明 |
|--------|------|------|------|
| sender_id | BIGINT | NULL | 发送者用户ID |
| sender_name | VARCHAR(100) | NULL | 发送者姓名 |
| target_type | TINYINT(1) | DEFAULT 1 | 目标类型1-单个用户2-角色3-课程 |
**更新通知类型定义:**
| 类型值 | 类型名称 | 说明 |
|--------|----------|------|
| 1 | 系统通知 | 系统自动生成的通知 |
| 2 | 作业通知 | 作业相关通知 |
| 3 | 考试通知 | 考试相关通知 |
| 4 | 考勤通知 | 考勤相关通知 |
| 5 | 用户通知 | 管理员发送给用户的通知 |
| 6 | 课程通知 | 老师发送给课程学生的通知 |
### 3.2 实体类修改 (`SysNotification.java`)
```java
// 新增字段
@Schema(description = "发送者用户ID")
private Long senderId;
@Schema(description = "发送者姓名")
private String senderName;
@Schema(description = "目标类型1-单个用户2-角色3-课程")
private Integer targetType;
```
### 3.3 新增请求DTO
**`SendNotificationRequest.java`** - 发送通知请求
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| schoolId | Long | 是 | 学校ID |
| title | String | 是 | 通知标题 |
| content | String | 是 | 通知内容 |
| type | Integer | 是 | 通知类型(5-用户通知, 6-课程通知) |
| targetUserIds | List<Long> | 否 | 目标用户ID列表 |
| targetRoleTypes | List<Integer> | 否 | 目标角色类型列表 |
| courseIds | List<Long> | 否 | 课程ID列表老师群发 |
### 3.4 Service层增强
**新增接口方法 (`SysNotificationService.java`)**
```java
/**
* 发送用户通知(批量发送给指定角色或用户)
*/
void sendUserNotification(Long schoolId, Long senderId, String senderName,
String title, String content,
List<Long> targetUserIds, List<Integer> targetRoleTypes);
/**
* 发送课程通知(老师群发课程消息)
*/
void sendCourseNotification(Long schoolId, Long teacherId, String teacherName,
String title, String content, List<Long> courseIds);
/**
* 发送系统通知给指定用户
*/
void sendSystemNotification(Long schoolId, List<Long> targetUserIds,
String title, String content);
/**
* 获取当前用户可通知的下级角色类型
*/
List<Integer> getAvailableTargetRoles(Long currentUserId);
/**
* 获取指定角色类型下的用户列表
*/
List<SysUser> getUsersByRoleTypes(Long schoolId, List<Integer> roleTypes);
```
### 3.5 Controller层增强
**新增接口 (`SysNotificationController.java`)**
| 接口 | 方法 | 权限 | 说明 |
|------|------|------|------|
| `/api/notification/send-to-users` | POST | 管理员/老师 | 发送通知给指定用户 |
| `/api/notification/send-to-roles` | POST | 管理员/老师 | 发送通知给指定角色 |
| `/api/notification/send-to-course` | POST | TEACHER | 发送课程通知 |
| `/api/notification/available-targets` | GET | 登录用户 | 获取当前用户可通知的目标角色 |
### 3.6 角色层级权限控制
**角色层级关系与可通知范围:**
| 当前角色 | roleType | 可通知角色类型 |
|----------|----------|---------------|
| SUPER | 1 | [1, 2, 3, 4, 5] |
| SUPER1 | 1 | [2, 3, 4, 5] |
| SCOOL_ADMIN | 2 | [3, 4, 5] |
| COLLEGE_ADMIN | 3 | [4, 5] |
| TEACHER | 4 | [5] (仅限自己课程的学生) |
| STUDENT | 5 | [] (无发送权限) |
---
## 4. 文件修改清单
| 文件路径 | 修改类型 | 说明 |
|----------|----------|------|
| `entity/SysNotification.java` | 修改 | 新增 senderId, senderName, targetType 字段 |
| `entity/request/SendNotificationRequest.java` | 新增 | 发送通知请求DTO |
| `service/SysNotificationService.java` | 修改 | 新增接口方法 |
| `service/impl/SysNotificationServiceImpl.java` | 修改 | 实现新增方法 |
| `controller/SysNotificationController.java` | 修改 | 新增接口 |
| `mapper/SysNotificationMapper.java` | 修改 | 新增批量插入方法 |
| `mapper/SysNotificationMapper.xml` | 修改 | 新增批量插入SQL |
| `db/create_edu_tables.sql` | 修改 | 添加新字段 |
| `db/sys_role_permission_data_init_merged.sql` | 修改 | 添加发送通知权限 |
---
## 5. 权限配置
**新增权限码:**
| 权限码 | 权限名称 | 适用角色 |
|--------|----------|----------|
| `notification:send:users` | 发送通知给用户 | SUPER, SUPER1, SCOOL_ADMIN, COLLEGE_ADMIN |
| `notification:send:course` | 发送课程通知 | TEACHER |
---
## 6. 总结
**当前代码是否满足需求:**
| 需求 | 当前状态 | 需要修改 |
|------|----------|----------|
| 通知创建人 | ❌ 缺少发送者信息 | 新增 senderId, senderName |
| 发送目标 | ✅ userId作为接收者 | 支持批量发送 |
| 通知类型 | ❌ 只有4种 | 新增类型5和6 |
| 角色层级控制 | ❌ 未实现 | 新增权限验证逻辑 |
**结论:当前代码不满足需求,需要进行上述修改。**

View File

@ -1,5 +0,0 @@
FROM openjdk:8-jdk-alpine
MAINTAINER kexue
VOLUME /tmp
ADD target/hyxp-portal.jar app.jar
ENTRYPOINT ["java","-Djava.security.egd=file:/dev/./urandom","-jar","/app.jar"]

View File

@ -1,603 +0,0 @@
# 支付功能使用指南
## 📋 概述
本项目已完整接入**微信支付**和**支付宝支付**,支持内容购买、账户充值等支付场景。
---
## 一、配置信息
### 1.1 微信支付配置
位置:`src/main/resources/application-dev.yml` 和 `src/main/resources/application-prod.yml`
```yaml
payment:
wechat:
appId: wx7d13d99de5be3bfa # 微信应用 ID
mchId: 1673321732 # 商户号
mchKey: UDuZXDcmy5Eb6o0nTNZhu6ek4DDh4K8B # 商户密钥
mchSerialNo: 5EFC47D3AA59BFD1AAE548F96B5E19E1C60F067D # 商户证书序列号
privateKeyPath: apiclient_key.pem # 商户私钥文件路径
domain: https://api.mch.weixin.qq.com # 微信服务器地址
notifyUrl: http://127.0.0.1:19001/api/pay/wx/notify # 支付回调地址
returnUrl: http://127.0.0.1:19001/api/pay/success # 支付成功跳转地址
```
### 1.2 支付宝支付配置
```yaml
payment:
alipay:
appId: 2021004138642603 # 支付宝应用 ID
publicKey: "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnakP04nUmsoFoveIvOhbLqkA1xQuYtvkrqq2AVvTsbtqpsEOTm9G095e2rBYLp89oDcf6L6BhtJPwdrhnA+qifUyVmACI9sprrsGeRYQgndK7y4c6spQcSnsnakSxlIp22j7pvBXNAZuqud2hQV+TOLKEUh1W3izTgMj/Ejoh3ZsCjgDRtTVgaytzSdHYrhNku+pIrl15/xVGJED99RYXkR8GHawxuK+vWVmxU0tiTCwTsqLz43v6TtCZ+/UfLL/luwp9B4ZvB+0qon82LILYr6oxs10kE2IAvryuDToAc1s/v/36jgt+7DXwqzfUDksHhVLHdJHChyc4ax5HmMsBwIDAQAB" # 支付宝公钥
privateKey: "" # 商户私钥(需配置)
notifyUrl: http://127.0.0.1:19001/api/pay/alipay/trade/notify # 支付回调地址
returnUrl: https://shuziren.xueai.art/alipay-success # 支付成功跳转地址
signType: RSA2 # 签名类型
charset: UTF-8 # 字符编码
gatewayUrl: https://openapi.alipay.com/gateway.do # 支付宝网关
```
---
## 二、API 接口说明
### 2.1 创建微信支付订单
**接口地址:** `POST /api/pay/wx/create`
**请求参数:**
| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| orderNo | String | 否 | 订单号(不传则自动生成) |
| userId | Long | 是 | 用户 ID |
| userName | String | 是 | 用户名 |
| amount | BigDecimal | 是 | 支付金额(单位:元) |
| productName | String | 是 | 商品名称 |
| productDesc | String | 否 | 商品描述 |
| businessId | Long | 是 | 关联业务 ID |
| businessType | String | 是 | 业务类型recharge(充值)/purchase_content(购买内容) |
**请求示例:**
```bash
curl -X POST http://localhost:19001/api/pay/wx/create \
-H "Content-Type: application/json" \
-d '{
"userId": 123,
"userName": "张三",
"amount": 0.01,
"productName": "测试商品",
"productDesc": "商品描述",
"businessId": 456,
"businessType": "purchase_content"
}'
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": {
"code_url": "weixin://wxpay/bizpayurl?pr=xxx",
"order_no": "ORDER_20260331_001"
}
}
```
**字段说明:**
- `code_url`: 微信支付二维码链接,前端可使用此链接生成二维码
- `order_no`: 支付订单号,用于后续查询订单状态
---
### 2.2 创建支付宝支付订单
**接口地址:** `POST /api/pay/alipay/create`
**请求参数:** 与微信支付相同
**请求示例:**
```bash
curl -X POST http://localhost:19001/api/pay/alipay/create \
-H "Content-Type: application/json" \
-d '{
"userId": 123,
"userName": "张三",
"amount": 0.01,
"productName": "测试商品",
"businessId": 456,
"businessType": "purchase_content"
}'
```
**响应示例:**
```json
{
"code": 200,
"message": "success",
"data": "<form name=\"alipay\" method=\"post\" action=\"https://openapi.alipay.com/gateway.do\">...</form>"
}
```
**使用说明:**
- 返回的是 HTML 表单字符串
- 前端将此外壳写入页面后会自动提交跳转到支付宝支付页面
---
### 2.3 支付回调接口(系统自动处理)
#### 微信支付回调
**接口地址:** `POST /api/pay/wx/notify`
**说明:**
- 由微信支付服务器自动调用
- 处理支付结果并更新订单状态
- 返回 XML 格式响应给微信服务器
#### 支付宝支付回调
**异步回调:** `POST /api/pay/alipay/trade/notify`
**同步回调:** `GET /api/pay/alipay/trade/return`
**说明:**
- 异步回调由支付宝服务器自动调用
- 同步回调用于用户支付完成后跳转回指定页面
---
## 三、使用场景示例
### 3.1 场景 1购买付费内容
**业务流程:**
1. 用户点击购买按钮
2. 创建购买记录(待支付状态)
3. 创建支付订单
4. 用户扫码或跳转支付
5. 支付成功后更新订单和购买记录状态
**前端调用示例:**
```javascript
// 步骤 1创建购买记录
const purchaseResponse = await fetch('/api/content/purchase', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123,
contentId: 456,
payType: 3 // 3=微信支付4=支付宝支付
})
});
const purchaseResult = await purchaseResponse.json();
// 步骤 2创建支付订单
const payResponse = await fetch('/api/pay/wx/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123,
amount: 9.99,
productName: 'AI 技能教程',
productDesc: '高级 AI 技能培训内容',
businessId: 456,
businessType: 'purchase_content'
})
});
const payResult = await payResponse.json();
if (payResult.code === 200) {
// 步骤 3显示支付二维码
const codeUrl = payResult.data.code_url;
// 使用 QRCode 库生成二维码
new QRCode(document.getElementById('qrcode'), {
text: codeUrl,
width: 200,
height: 200
});
// 步骤 4轮询查询订单状态
const checkOrderStatus = setInterval(async () => {
const statusResponse = await fetch(`/api/pay/order/query?orderNo=${payResult.data.order_no}`);
const statusResult = await statusResponse.json();
if (statusResult.data.status === 2) { // 2=已支付
clearInterval(checkOrderStatus);
alert('支付成功!');
window.location.reload();
}
}, 3000); // 每 3 秒查询一次
// 设置超时15 分钟后停止查询)
setTimeout(() => {
clearInterval(checkOrderStatus);
alert('支付超时,请重新下单');
}, 900000);
}
```
---
### 3.2 场景 2账户充值
**业务流程:**
```javascript
// 创建充值订单
const rechargeResponse = await fetch('/api/pay/wx/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123,
amount: 100.00, // 充值 100 元
productName: '账户充值',
businessId: 123,
businessType: 'recharge' // 充值业务类型
})
});
const result = await rechargeResponse.json();
if (result.code === 200) {
// 显示支付二维码
showQRCode(result.data.code_url);
}
```
**说明:**
- 支付成功后,系统会自动通过回调将充值金额添加到用户账户余额
---
### 3.3 场景 3支付宝网页支付
```javascript
// 创建支付宝订单
const aliPayResponse = await fetch('/api/pay/alipay/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123,
amount: 0.01,
productName: '测试商品',
businessId: 456,
businessType: 'purchase_content'
})
});
const result = await aliPayResponse.json();
if (result.code === 200) {
// 将返回的 HTML 表单写入页面
document.body.innerHTML = result.data;
// 表单会自动提交,跳转到支付宝支付页面
}
```
---
## 四、前端集成完整示例
### 4.1 微信支付页面
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>微信支付</title>
<script src="https://cdn.jsdelivr.net/npm/qrcode@1.5.0/build/qrcode.min.js"></script>
<style>
.payment-container {
max-width: 600px;
margin: 50px auto;
padding: 20px;
text-align: center;
}
.qrcode-box {
border: 1px solid #ddd;
padding: 20px;
display: inline-block;
margin: 20px 0;
}
.status-tip {
color: #666;
font-size: 14px;
margin-top: 10px;
}
</style>
</head>
<body>
<div class="payment-container">
<h2>微信支付</h2>
<div class="qrcode-box">
<div id="qrcode"></div>
</div>
<p class="status-tip">请使用微信扫码支付</p>
<p class="status-tip" id="statusTip">等待支付...</p>
</div>
<script>
// 从 URL 参数获取商品信息
const urlParams = new URLSearchParams(window.location.search);
const productId = urlParams.get('productId');
const amount = urlParams.get('amount');
// 创建支付订单
async function createPayment() {
try {
const response = await fetch('/api/pay/wx/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123, // 实际应从登录信息中获取
amount: parseFloat(amount),
productName: '商品-' + productId,
businessId: productId,
businessType: 'purchase_content'
})
});
const result = await response.json();
if (result.code === 200) {
// 生成二维码
QRCode.toCanvas(document.getElementById('qrcode'), result.data.code_url, {
width: 200,
height: 200
});
// 开始轮询订单状态
checkOrderStatus(result.data.order_no);
} else {
alert('创建订单失败:' + result.message);
}
} catch (error) {
console.error('创建订单失败:', error);
alert('网络错误,请稍后重试');
}
}
// 轮询订单状态
async function checkOrderStatus(orderNo) {
const maxAttempts = 300; // 最多查询 300 次15 分钟)
let attempts = 0;
const timer = setInterval(async () => {
try {
const response = await fetch(`/api/pay/order/query?orderNo=${orderNo}`);
const result = await response.json();
if (result.code === 200 && result.data) {
const status = result.data.status;
const statusText = document.getElementById('statusTip');
if (status === 2) { // 已支付
clearInterval(timer);
statusText.textContent = '✅ 支付成功!';
statusText.style.color = 'green';
setTimeout(() => {
window.location.href = '/pay-success.html?orderNo=' + orderNo;
}, 1000);
return;
} else if (status === 3 || status === 4) { // 支付失败或已取消
clearInterval(timer);
statusText.textContent = '❌ 支付失败';
statusText.style.color = 'red';
return;
}
attempts++;
if (attempts >= maxAttempts) {
clearInterval(timer);
statusText.textContent = '⏰ 支付超时,请重新下单';
statusText.style.color = 'orange';
}
}
} catch (error) {
console.error('查询订单状态失败:', error);
}
}, 3000); // 每 3 秒查询一次
}
// 页面加载时创建支付订单
createPayment();
</script>
</body>
</html>
```
### 4.2 支付宝支付页面
```html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>支付宝支付</title>
</head>
<body>
<div style="text-align: center; padding: 50px;">
<h2>正在跳转到支付宝支付页面...</h2>
<p>请稍候</p>
</div>
<script>
// 从 URL 获取商品信息
const urlParams = new URLSearchParams(window.location.search);
const productId = urlParams.get('productId');
const amount = urlParams.get('amount');
// 创建支付订单
async function createAlipay() {
try {
const response = await fetch('/api/pay/alipay/create', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
userId: 123,
amount: parseFloat(amount),
productName: '商品-' + productId,
businessId: productId,
businessType: 'purchase_content'
})
});
const result = await response.json();
if (result.code === 200) {
// 将返回的 HTML 表单写入页面并提交
document.body.innerHTML = result.data;
document.forms[0].submit();
} else {
alert('创建订单失败:' + result.message);
setTimeout(() => {
window.location.href = '/index.html';
}, 2000);
}
} catch (error) {
console.error('创建订单失败:', error);
alert('网络错误,请稍后重试');
}
}
createAlipay();
</script>
</body>
</html>
```
---
## 五、核心代码文件
| 文件路径 | 说明 |
|---------|------|
| `src/main/java/com/kexue/skills/controller/PayController.java` | 支付接口控制器 |
| `src/main/java/com/kexue/skills/service/PayService.java` | 支付服务接口 |
| `src/main/java/com/kexue/skills/service/impl/PayServiceImpl.java` | 支付服务实现类 |
| `src/main/java/com/kexue/skills/config/PaymentConfig.java` | 支付配置类 |
| `src/main/java/com/kexue/skills/entity/PaymentOrder.java` | 支付订单实体类 |
| `src/main/java/com/kexue/skills/service/PaymentOrderService.java` | 支付订单服务接口 |
| `src/main/java/com/kexue/skills/service/impl/PaymentOrderServiceImpl.java` | 支付订单服务实现类 |
---
## 六、注意事项
### 6.1 开发环境测试
⚠️ **重要提示:** 本地开发环境下,微信和支付宝无法直接访问到你的 localhost 回调地址。
**解决方案:**
1. **使用内网穿透工具**(推荐)
```bash
# 使用 ngrok
ngrok http 19001
# 将生成的域名配置到回调地址
# 例如https://abc123.ngrok.io/api/pay/wx/notify
```
2. **部署到测试服务器**
- 直接部署到具有公网 IP 的服务器进行测试
3. **修改配置文件**
```yaml
payment:
wechat:
notifyUrl: https://your-domain.ngrok.io/api/pay/wx/notify
alipay:
notifyUrl: https://your-domain.ngrok.io/api/pay/alipay/trade/notify
```
### 6.2 金额单位
- 前端传入金额单位:**元**
- 微信支付内部转换:**分**(代码自动处理)
- 建议最小金额0.01 元
### 6.3 业务类型说明
| 业务类型 | 说明 | 支付成功后操作 |
|---------|------|--------------|
| `recharge` | 账户充值 | 增加用户账户余额 |
| `purchase_content` | 购买内容 | 更新内容购买记录状态 |
### 6.4 支付状态码
| 状态码 | 说明 |
|-------|------|
| 1 | 待支付 |
| 2 | 已支付 |
| 3 | 支付失败 |
| 4 | 已取消 |
| 5 | 已退款 |
### 6.5 安全建议
1. **权限验证**:所有支付接口都应添加权限验证(已部分实现)
2. **签名验证**:确保支付回调的签名验证正确
3. **幂等性处理**:支付回调应支持重复通知(已实现)
4. **日志记录**:完整的支付日志便于问题排查
---
## 七、常见问题
### Q1: 如何查询订单状态?
```java
// 通过订单号查询
PaymentOrder order = paymentOrderService.queryByOrderNo(orderNo);
// 或通过主键查询
PaymentOrder order = paymentOrderService.queryById(orderId);
```
### Q2: 如何处理支付回调失败?
系统已实现幂等性处理,同一订单多次回调不会重复处理。如果回调失败,微信/支付宝会按一定频率重试。
### Q3: 如何申请退款?
当前版本暂未实现退款功能,如需退款,需要:
1. 调用微信/支付宝退款 API
2. 更新支付订单状态为已退款5
3. 恢复用户余额或购买权限
### Q4: 测试时使用真实资金吗?
是的,对接的是正式环境。如需测试环境,需要:
- 微信:申请沙箱环境
- 支付宝:使用测试账号
---
## 八、技术支持
如遇问题,请检查以下内容:
1. ✅ 配置文件中的商户号、密钥是否正确
2. ✅ 回调地址是否可被外网访问
3. ✅ 商户私钥文件是否存在且路径正确
4. ✅ 查看日志文件中的详细错误信息
5. ✅ 确认微信/支付宝商户号状态正常
---
**文档版本:** v1.0
**更新时间:** 2026-03-31
**维护人员:** 系统开发团队

View File

@ -1,7 +0,0 @@
-- 给account表添加create_by和update_by字段
-- 作者: 王志维
-- 创建时间: 2026-01-26
ALTER TABLE `account`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;

View File

@ -1,5 +0,0 @@
-- 为 account_frozen 表添加 question 字段
-- 用于记录用户的问题或需求
ALTER TABLE `account_frozen`
ADD COLUMN `question` text DEFAULT NULL COMMENT '对应回答的问题或需求' AFTER `model_name`;

View File

@ -1,9 +0,0 @@
-- 为 account_transaction 表添加 call_id 字段
-- 用于关联冻结单释放时的调用ID
ALTER TABLE `account_transaction`
ADD COLUMN `call_id` varchar(100) DEFAULT NULL COMMENT '调用ID关联冻结单' AFTER `business_type`;
-- 添加索引以提高查询性能
ALTER TABLE `account_transaction`
ADD INDEX `idx_call_id` (`call_id`);

View File

@ -1,90 +0,0 @@
-- 为所有表添加create_by和update_by字段
-- 作者: 王志维
-- 创建时间: 2026-01-26
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- 1. 账户表
ALTER TABLE `account`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 2. 积分账户表
ALTER TABLE `points_account`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 3. 客户表
ALTER TABLE `customer`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 4. 内容购买记录表
ALTER TABLE `content_purchase`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 5. 用户角色关联表
ALTER TABLE `sys_user_role`
ADD COLUMN `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `user_id`,
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `delete_flag` tinyint(1) DEFAULT '0' COMMENT '是否删除 0 未删除1已删除' AFTER `update_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 6. 系统菜单表
ALTER TABLE `sys_menu`
ADD COLUMN `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `delete_flag`,
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 7. 系统角色表
ALTER TABLE `sys_role`
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 8. 支付订单表
ALTER TABLE `payment_order`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 9. 系统日志表
ALTER TABLE `sys_log`
ADD COLUMN `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间' AFTER `note`,
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `delete_flag` tinyint(1) DEFAULT '0' COMMENT '是否删除 0 未删除1已删除' AFTER `update_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 10. 系统用户表
ALTER TABLE `sys_user`
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 11. 供应商表
ALTER TABLE `supplier`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `update_time`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 12. 系统字典表
ALTER TABLE `sys_dict`
ADD COLUMN `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' AFTER `create_time`,
ADD COLUMN `delete_flag` tinyint(1) DEFAULT '0' COMMENT '是否删除 0 未删除1已删除' AFTER `update_time`,
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 13. 内容点赞记录表
ALTER TABLE `cms_content_like`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
-- 14. 内容查看记录表
ALTER TABLE `cms_content_view`
ADD COLUMN `create_by` varchar(50) DEFAULT NULL COMMENT '创建人' AFTER `delete_flag`,
ADD COLUMN `update_by` varchar(50) DEFAULT NULL COMMENT '更新人' AFTER `create_by`;
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -1,5 +0,0 @@
-- 修改payment_order表为pay_type字段添加默认值
ALTER TABLE `payment_order` MODIFY COLUMN `pay_type` tinyint(1) NOT NULL DEFAULT 1 COMMENT '支付方式1.微信 2.支付宝';
-- 输出修改结果
SELECT '修改payment_order表pay_type字段默认值完成' AS result;

View File

@ -1,46 +0,0 @@
-- 更新 sys_log 表结构以支持新的日志功能
-- 作者: 王志维
-- 创建时间: 2026-04-14
-- 备份旧数据(可选)
-- CREATE TABLE sys_log_backup AS SELECT * FROM sys_log;
-- 删除旧表(如果存在)
DROP TABLE IF EXISTS `sys_log`;
-- 创建新表
CREATE TABLE `sys_log` (
`log_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`trace_id` varchar(255) DEFAULT NULL COMMENT '链路ID',
`description` varchar(255) DEFAULT NULL COMMENT '日志描述',
`module` varchar(50) DEFAULT NULL COMMENT '所属模块',
`request_url` varchar(512) DEFAULT NULL COMMENT '请求URL',
`request_method` varchar(10) DEFAULT NULL COMMENT '请求方式',
`request_headers` text COMMENT '请求头',
`request_body` text COMMENT '请求体',
`status_code` int(11) DEFAULT NULL COMMENT '状态码',
`response_headers` text COMMENT '响应头',
`response_body` mediumtext COMMENT '响应体',
`time_taken` bigint(20) DEFAULT NULL COMMENT '耗时ms',
`ip` varchar(100) DEFAULT NULL COMMENT 'IP',
`address` varchar(255) DEFAULT NULL COMMENT 'IP归属地',
`browser` varchar(100) DEFAULT NULL COMMENT '浏览器',
`os` varchar(100) DEFAULT NULL COMMENT '操作系统',
`status` tinyint(1) DEFAULT '1' COMMENT '状态1成功2失败',
`error_msg` text COMMENT '错误信息',
`create_user` bigint(20) DEFAULT NULL COMMENT '创建人',
`create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`delete_flag` tinyint(1) DEFAULT '0' COMMENT '是否删除 0 未删除1已删除',
`create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
`update_by` varchar(50) DEFAULT NULL COMMENT '更新人',
PRIMARY KEY (`log_id`) USING BTREE,
KEY `idx_module` (`module`) USING BTREE COMMENT '模块查询优化',
KEY `idx_ip` (`ip`) USING BTREE COMMENT 'IP查询优化',
KEY `idx_create_time` (`create_time`) USING BTREE COMMENT '时间范围查询优化',
KEY `idx_status` (`status`) USING BTREE COMMENT '状态查询优化'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='系统操作日志表';
-- 插入测试数据(可选)
-- INSERT INTO `sys_log` (`description`, `module`, `request_url`, `request_method`, `status_code`, `time_taken`, `ip`, `status`, `create_time`)
-- VALUES ('用户登录', '登录认证', '/api/login/accountLogin', 'POST', 200, 150, '127.0.0.1', 1, NOW());

View File

@ -0,0 +1,8 @@
-- 给 sys_role_permission 表添加 permission_name 字段
-- 创建时间2026-05-07
SET NAMES utf8mb4;
-- 检查字段是否存在,如果不存在则添加
ALTER TABLE `sys_role_permission`
ADD COLUMN IF NOT EXISTS `permission_name` VARCHAR(255) DEFAULT NULL COMMENT '权限名称' AFTER `permission_code`;

View File

@ -0,0 +1,13 @@
-- 给 sys_user 表添加 wxid 和 roleType 字段
-- 创建时间2026-04-30
SET NAMES utf8mb4;
-- 检查字段是否存在,如果不存在则添加
ALTER TABLE `sys_user`
ADD COLUMN IF NOT EXISTS `wxid` VARCHAR(100) DEFAULT NULL COMMENT '微信ID' AFTER `user_icon`,
ADD COLUMN IF NOT EXISTS `role_type` TINYINT(1) DEFAULT NULL COMMENT '角色类型1-超级管理员2-学校管理员3-学院管理员4-教师5-学生' AFTER `wxid`;
-- 为新增字段添加索引
ALTER TABLE `sys_user` ADD INDEX IF NOT EXISTS `idx_wxid` (`wxid`);
ALTER TABLE `sys_user` ADD INDEX IF NOT EXISTS `idx_role_type` (`role_type`);

View File

@ -1,14 +0,0 @@
-- 创建cms_content_like表用户点赞记录
CREATE TABLE `cms_content_like` (
`like_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '点赞记录ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`user_name` varchar(50) NOT NULL COMMENT '用户名',
`content_id` bigint(20) NOT NULL COMMENT '内容ID',
`content_title` varchar(200) NOT NULL COMMENT '内容标题',
`like_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间',
`delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标志0未删除1已删除',
PRIMARY KEY (`like_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_content_id` (`content_id`),
KEY `idx_like_time` (`like_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='CMS内容点赞记录表';

View File

@ -1,14 +0,0 @@
-- 创建cms_content_view表用户查看记录
CREATE TABLE `cms_content_view` (
`view_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '查看记录ID',
`user_id` bigint(20) NOT NULL COMMENT '用户ID',
`user_name` varchar(50) NOT NULL COMMENT '用户名',
`content_id` bigint(20) NOT NULL COMMENT '内容ID',
`content_title` varchar(200) NOT NULL COMMENT '内容标题',
`view_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '查看时间',
`delete_flag` tinyint(4) NOT NULL DEFAULT '0' COMMENT '删除标志0未删除1已删除',
PRIMARY KEY (`view_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_content_id` (`content_id`),
KEY `idx_view_time` (`view_time`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='CMS内容查看记录表';

267
db/create_edu_tables.sql Normal file
View File

@ -0,0 +1,267 @@
-- 创建实训平台教学管理相关表
-- 作者: 王志维
-- 创建时间: 2026-04-30
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- 1. 用户角色关联表
DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
`role_code` VARCHAR(50) NOT NULL COMMENT '角色编码student-学生teacher-老师admin-管理员',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_role` (`user_id`, `role_code`),
KEY `idx_user_id` (`user_id`),
KEY `idx_role_code` (`role_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户角色关联表';
-- 2. 学生扩展表
DROP TABLE IF EXISTS `edu_student`;
CREATE TABLE `edu_student` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID关联sys_user',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID',
`college_id` BIGINT(20) DEFAULT NULL COMMENT '学院ID',
`major_id` BIGINT(20) DEFAULT NULL COMMENT '专业ID',
`grade` VARCHAR(20) DEFAULT NULL COMMENT '年级',
`class_name` VARCHAR(50) DEFAULT NULL COMMENT '班级',
`student_no` VARCHAR(50) DEFAULT NULL COMMENT '学号',
`real_name` VARCHAR(50) DEFAULT NULL COMMENT '真实姓名',
`activation_code` VARCHAR(50) DEFAULT NULL COMMENT '激活码',
`binding_status` TINYINT(1) DEFAULT '0' COMMENT '绑定状态0-未绑定1-已绑定',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_college_id` (`college_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='学生扩展表';
-- 3. 教师扩展表
DROP TABLE IF EXISTS `edu_teacher`;
CREATE TABLE `edu_teacher` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID关联sys_user',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID',
`college_id` BIGINT(20) DEFAULT NULL COMMENT '学院ID',
`real_name` VARCHAR(50) DEFAULT NULL COMMENT '真实姓名',
`teacher_no` VARCHAR(50) DEFAULT NULL COMMENT '教师编号',
`title` VARCHAR(50) DEFAULT NULL COMMENT '职称',
`activation_code` VARCHAR(50) DEFAULT NULL COMMENT '激活码',
`binding_status` TINYINT(1) DEFAULT '0' COMMENT '绑定状态0-未绑定1-已绑定',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_user_id` (`user_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_college_id` (`college_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='教师扩展表';
-- 4. 通知表
DROP TABLE IF EXISTS `sys_notification`;
CREATE TABLE `sys_notification` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`user_id` BIGINT(20) NOT NULL COMMENT '用户ID',
`title` VARCHAR(100) NOT NULL COMMENT '通知标题',
`content` TEXT NOT NULL COMMENT '通知内容',
`type` TINYINT(1) DEFAULT '1' COMMENT '通知类型1-系统通知2-作业通知3-考试通知4-考勤通知5-用户通知6-课程通知',
`is_read` TINYINT(1) DEFAULT '0' COMMENT '是否已读0-未读1-已读',
`sender_id` BIGINT(20) DEFAULT NULL COMMENT '发送者用户ID',
`sender_name` VARCHAR(100) DEFAULT NULL COMMENT '发送者姓名',
`target_type` TINYINT(1) DEFAULT '1' COMMENT '目标类型1-单个用户2-角色3-课程',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_user_id` (`user_id`),
KEY `idx_is_read` (`is_read`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='通知表';
-- 5. 课程表
DROP TABLE IF EXISTS `edu_course`;
CREATE TABLE `edu_course` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`name` VARCHAR(100) NOT NULL COMMENT '课程名称',
`cover` VARCHAR(255) DEFAULT NULL COMMENT '课程封面',
`description` TEXT DEFAULT NULL COMMENT '课程简介',
`class_time` VARCHAR(100) DEFAULT NULL COMMENT '上课时间',
`teaching_method` TINYINT(1) DEFAULT '1' COMMENT '授课方式1-线上2-线下3-混合',
`teacher_id` BIGINT(20) NOT NULL COMMENT '创建老师ID',
`status` TINYINT(1) DEFAULT '1' COMMENT '课程状态1-进行中2-已结课',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_teacher_id` (`teacher_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程表';
-- 6. 课程学生关联表
DROP TABLE IF EXISTS `edu_course_student`;
CREATE TABLE `edu_course_student` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`join_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '加入时间',
`is_kicked` TINYINT(1) DEFAULT '0' COMMENT '是否被踢出0-正常1-已踢出',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_course_student` (`course_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='课程学生关联表';
-- 7. 作业表
DROP TABLE IF EXISTS `edu_homework`;
CREATE TABLE `edu_homework` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) NOT NULL COMMENT '作业名称',
`requirement` TEXT DEFAULT NULL COMMENT '作业要求',
`questions` TEXT NOT NULL COMMENT '题目JSON',
`allow_late` TINYINT(1) DEFAULT '0' COMMENT '是否允许迟交',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME NOT NULL COMMENT '截止时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-草稿2-已发布',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作业表';
-- 8. 作业提交表
DROP TABLE IF EXISTS `edu_homework_submit`;
CREATE TABLE `edu_homework_submit` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`homework_id` BIGINT(20) NOT NULL COMMENT '作业ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`answers` TEXT NOT NULL COMMENT '答案JSON',
`submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '提交时间',
`is_late` TINYINT(1) DEFAULT '0' COMMENT '是否迟交',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-待批改2-已批改3-已退回',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
`is_excellent` TINYINT(1) DEFAULT '0' COMMENT '是否优秀',
`redo_end_time` DATETIME DEFAULT NULL COMMENT '重做截止时间',
`redo_count` INT(11) DEFAULT '0' COMMENT '重做次数',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_homework_id` (`homework_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作业提交表';
-- 9. 考试表
DROP TABLE IF EXISTS `edu_exam`;
CREATE TABLE `edu_exam` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) NOT NULL COMMENT '考试名称',
`requirement` TEXT DEFAULT NULL COMMENT '考试要求',
`questions` TEXT NOT NULL COMMENT '考卷JSON',
`duration` INT(11) NOT NULL COMMENT '考试时长(分钟)',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`end_time` DATETIME NOT NULL COMMENT '截止时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-草稿2-已发布3-已结束',
`is_makeup` TINYINT(1) DEFAULT '0' COMMENT '是否补考',
`parent_exam_id` BIGINT(20) DEFAULT NULL COMMENT '关联主考ID',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试表';
-- 10. 考试答卷表
DROP TABLE IF EXISTS `edu_exam_paper`;
CREATE TABLE `edu_exam_paper` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`exam_id` BIGINT(20) NOT NULL COMMENT '考试ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`answers` TEXT NOT NULL COMMENT '答案JSON',
`submit_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '提交时间',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-待阅卷2-已阅卷',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_exam_student` (`exam_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_exam_id` (`exam_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考试答卷表';
-- 11. 考勤表
DROP TABLE IF EXISTS `edu_attendance`;
CREATE TABLE `edu_attendance` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`course_id` BIGINT(20) NOT NULL COMMENT '课程ID',
`name` VARCHAR(100) DEFAULT NULL COMMENT '签到名称(按时间自动生成)',
`start_time` DATETIME NOT NULL COMMENT '开始时间',
`duration` INT(11) DEFAULT '15' COMMENT '签到时长(分钟)',
`type` TINYINT(1) DEFAULT '1' COMMENT '签到类型1-二维码签到2-手动点名',
`status` TINYINT(1) DEFAULT '1' COMMENT '状态1-进行中2-已结束',
`qr_code` VARCHAR(255) DEFAULT NULL COMMENT '二维码内容',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_course_id` (`course_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤表';
-- 12. 考勤记录表
DROP TABLE IF EXISTS `edu_attendance_record`;
CREATE TABLE `edu_attendance_record` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`attendance_id` BIGINT(20) NOT NULL COMMENT '考勤ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`status` TINYINT(1) DEFAULT '1' COMMENT '考勤状态1-出勤2-迟到3-缺勤4-请假',
`sign_time` DATETIME DEFAULT NULL COMMENT '签到时间',
`remark` VARCHAR(255) DEFAULT NULL COMMENT '备注(手动点名时填写)',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_attendance_student` (`attendance_id`, `student_id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_attendance_id` (`attendance_id`),
KEY `idx_student_id` (`student_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='考勤记录表';
-- 13. 优秀作品表
DROP TABLE IF EXISTS `edu_excellent_work`;
CREATE TABLE `edu_excellent_work` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`work_type` TINYINT(1) NOT NULL COMMENT '作品类型1-作业2-考试',
`work_id` BIGINT(20) NOT NULL COMMENT '关联作业/考试ID',
`submit_id` BIGINT(20) NOT NULL COMMENT '关联提交ID',
`student_id` BIGINT(20) NOT NULL COMMENT '学生ID',
`score` DECIMAL(5,2) DEFAULT NULL COMMENT '分数',
`comment` TEXT DEFAULT NULL COMMENT '评语',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '标记时间',
PRIMARY KEY (`id`),
KEY `idx_school_id` (`school_id`),
KEY `idx_work_type_work_id` (`work_type`, `work_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='优秀作品表';
-- 14. 作品点赞表
DROP TABLE IF EXISTS `edu_work_like`;
CREATE TABLE `edu_work_like` (
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`school_id` BIGINT(20) NOT NULL COMMENT '学校ID数据隔离',
`work_id` BIGINT(20) NOT NULL COMMENT '优秀作品ID',
`user_id` BIGINT(20) NOT NULL COMMENT '点赞用户ID',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '点赞时间',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_work_user` (`work_id`, `user_id`),
KEY `idx_school_id` (`school_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='作品点赞表';
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -0,0 +1,23 @@
-- 创建角色权限关联表
-- 作者: 王志维
-- 创建时间: 2026-04-30
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- 角色权限关联表
DROP TABLE IF EXISTS `sys_role_permission`;
CREATE TABLE `sys_role_permission` (
`permission_id` BIGINT(20) NOT NULL COMMENT '权限主键ID关联权限主表主键',
`role_id` BIGINT(20) NOT NULL COMMENT '角色主键ID关联角色主表主键',
`role_code` VARCHAR(64) NOT NULL COMMENT '角色标识码如student、teacher、school_admin',
`permission_code` VARCHAR(128) NOT NULL COMMENT '接口/按钮权限码如system:user:add',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '权限绑定关系创建时间',
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '权限绑定关系最后更新时间',
PRIMARY KEY (`permission_id`, `role_id`),
KEY `idx_role_id` (`role_id`),
KEY `idx_role_code` (`role_code`),
KEY `idx_permission_code` (`permission_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='角色权限关联表';
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -79,3 +79,12 @@ SELECT '用户表初始化行数:', ROW_COUNT() AS count FROM `sys_user`;
SELECT '用户角色关联表初始化行数:', ROW_COUNT() AS count FROM `sys_user_role`; SELECT '用户角色关联表初始化行数:', ROW_COUNT() AS count FROM `sys_user_role`;
SELECT '账户表初始化行数:', ROW_COUNT() AS count FROM `account`; SELECT '账户表初始化行数:', ROW_COUNT() AS count FROM `account`;
SELECT '积分账户表初始化行数:', ROW_COUNT() AS count FROM `points_account`; SELECT '积分账户表初始化行数:', ROW_COUNT() AS count FROM `points_account`;
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('super', '5f1d7a84db00d2fce00b31a7fc73224f', '超级管理员', '13800138000', 'admin@example.com', '123456', '超级管理员', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 1);
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('super2', '5f1d7a84db00d2fce00b31a7fc73224f', '次要管理员', '13800138000', 'admin@example.com', '123456', '次要管理员', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 2);
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('school_admin', '5f1d7a84db00d2fce00b31a7fc73224f', '学校管理员管理员', '13800138000', 'admin@example.com', '123456', '学校管理员管理员', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 3);
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('college_admin', '5f1d7a84db00d2fce00b31a7fc73224f', '次要管理员', '13800138000', 'admin@example.com', '123456', '次要管理员', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 4);
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('teacher', '5f1d7a84db00d2fce00b31a7fc73224f', '老师', '13800138000', 'admin@example.com', '123456', '老师', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 5);
INSERT INTO `kexue_server`.`sys_user` (`user_name`, `pwd`, `real_name`, `tel`, `email`, `salt`, `remark`, `create_time`, `update_time`, `enable`, `delete_flag`, `create_by`, `update_by`, `session_id`, `invite_code`, `invited_code`, `invited_by`, `user_icon`, `wxid`, `role_type`) VALUES ('student', '5f1d7a84db00d2fce00b31a7fc73224f', '学生', '13800138000', 'admin@example.com', '123456', '学生', '2026-01-20 18:10:20', '2026-04-15 14:28:09', 1, 0, NULL, NULL, 'bf281237-88e6-4b18-b51e-98f047693fa4', 'b8b6dbb3', NULL, NULL, 'defaultUserIcon.png', NULL, 6);

View File

@ -0,0 +1,281 @@
-- 角色权限初始化数据
-- 作者: 王志维
-- 创建时间: 2026-04-30
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ========================================
-- 系统管理权限 (system)
-- ========================================
-- 超级管理员 - 系统管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(1, 1, 'SUPER', 'system:user:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(2, 1, 'SUPER', 'system:user:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(3, 1, 'SUPER', 'system:user:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(4, 1, 'SUPER', 'system:user:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(5, 1, 'SUPER', 'system:role:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(6, 1, 'SUPER', 'system:role:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(7, 1, 'SUPER', 'system:role:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(8, 1, 'SUPER', 'system:role:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(9, 1, 'SUPER', 'system:menu:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(10, 1, 'SUPER', 'system:menu:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(11, 1, 'SUPER', 'system:menu:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(12, 1, 'SUPER', 'system:dict:manage', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(13, 1, 'SUPER', 'system:log:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学校管理员 - 系统管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(14, 2, 'SCOOL_ADMIN', 'system:user:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(15, 2, 'SCOOL_ADMIN', 'system:role:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 用户管理权限 (user)
-- ========================================
-- 超级管理员 - 用户管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(16, 1, 'SUPER', 'user:student:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(17, 1, 'SUPER', 'user:student:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(18, 1, 'SUPER', 'user:student:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(19, 1, 'SUPER', 'user:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(20, 1, 'SUPER', 'user:teacher:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(21, 1, 'SUPER', 'user:teacher:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(22, 1, 'SUPER', 'user:teacher:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(23, 1, 'SUPER', 'user:teacher:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(24, 1, 'SUPER', 'user:teacher:bind', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(25, 1, 'SUPER', 'user:student:bind', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学校管理员 - 用户管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(26, 2, 'SCOOL_ADMIN', 'user:student:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(27, 2, 'SCOOL_ADMIN', 'user:student:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(28, 2, 'SCOOL_ADMIN', 'user:student:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(29, 2, 'SCOOL_ADMIN', 'user:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(30, 2, 'SCOOL_ADMIN', 'user:teacher:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(31, 2, 'SCOOL_ADMIN', 'user:teacher:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(32, 2, 'SCOOL_ADMIN', 'user:teacher:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(33, 2, 'SCOOL_ADMIN', 'user:teacher:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(34, 2, 'SCOOL_ADMIN', 'user:teacher:bind', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(35, 2, 'SCOOL_ADMIN', 'user:student:bind', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学院管理员 - 用户管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(36, 3, 'COLLEGE_ADMIN', 'user:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(37, 3, 'COLLEGE_ADMIN', 'user:teacher:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 课程管理权限 (course)
-- ========================================
-- 超级管理员 - 课程管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(38, 1, 'SUPER', 'course:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(39, 1, 'SUPER', 'course:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(40, 1, 'SUPER', 'course:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(41, 1, 'SUPER', 'course:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(42, 1, 'SUPER', 'course:student:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(43, 1, 'SUPER', 'course:student:remove', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(44, 1, 'SUPER', 'course:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(45, 1, 'SUPER', 'course:score:export', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学校管理员 - 课程管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(46, 2, 'SCOOL_ADMIN', 'course:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(47, 2, 'SCOOL_ADMIN', 'course:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学院管理员 - 课程管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(48, 3, 'COLLEGE_ADMIN', 'course:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(49, 3, 'COLLEGE_ADMIN', 'course:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 课程管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(50, 4, 'TEACHER', 'course:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(51, 4, 'TEACHER', 'course:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(52, 4, 'TEACHER', 'course:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(53, 4, 'TEACHER', 'course:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(54, 4, 'TEACHER', 'course:student:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(55, 4, 'TEACHER', 'course:student:remove', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(56, 4, 'TEACHER', 'course:student:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(57, 4, 'TEACHER', 'course:score:export', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 课程管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(58, 5, 'STUDENT', 'course:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(59, 5, 'STUDENT', 'course:join', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(60, 5, 'STUDENT', 'course:quit', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 作业管理权限 (homework)
-- ========================================
-- 超级管理员 - 作业管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(61, 1, 'SUPER', 'homework:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(62, 1, 'SUPER', 'homework:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(63, 1, 'SUPER', 'homework:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(64, 1, 'SUPER', 'homework:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(65, 1, 'SUPER', 'homework:publish', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(66, 1, 'SUPER', 'homework:grade', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(67, 1, 'SUPER', 'homework:excellent', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(68, 1, 'SUPER', 'homework:redo', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 作业管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(69, 4, 'TEACHER', 'homework:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(70, 4, 'TEACHER', 'homework:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(71, 4, 'TEACHER', 'homework:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(72, 4, 'TEACHER', 'homework:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(73, 4, 'TEACHER', 'homework:publish', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(74, 4, 'TEACHER', 'homework:grade', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(75, 4, 'TEACHER', 'homework:excellent', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(76, 4, 'TEACHER', 'homework:redo', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 作业管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(77, 5, 'STUDENT', 'homework:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(78, 5, 'STUDENT', 'homework:submit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(79, 5, 'STUDENT', 'homework:update', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(80, 5, 'STUDENT', 'homework:redo', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 考试管理权限 (exam)
-- ========================================
-- 超级管理员 - 考试管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(81, 1, 'SUPER', 'exam:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(82, 1, 'SUPER', 'exam:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(83, 1, 'SUPER', 'exam:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(84, 1, 'SUPER', 'exam:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(85, 1, 'SUPER', 'exam:publish', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(86, 1, 'SUPER', 'exam:grade', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(87, 1, 'SUPER', 'exam:makeup', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 考试管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(88, 4, 'TEACHER', 'exam:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(89, 4, 'TEACHER', 'exam:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(90, 4, 'TEACHER', 'exam:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(91, 4, 'TEACHER', 'exam:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(92, 4, 'TEACHER', 'exam:publish', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(93, 4, 'TEACHER', 'exam:grade', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(94, 4, 'TEACHER', 'exam:makeup', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 考试管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(95, 5, 'STUDENT', 'exam:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(96, 5, 'STUDENT', 'exam:take', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(97, 5, 'STUDENT', 'exam:makeup', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 考勤管理权限 (attendance)
-- ========================================
-- 超级管理员 - 考勤管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(98, 1, 'SUPER', 'attendance:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(99, 1, 'SUPER', 'attendance:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(100, 1, 'SUPER', 'attendance:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(101, 1, 'SUPER', 'attendance:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(102, 1, 'SUPER', 'attendance:start', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(103, 1, 'SUPER', 'attendance:record', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(104, 1, 'SUPER', 'attendance:status:modify', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 考勤管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(105, 4, 'TEACHER', 'attendance:add', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(106, 4, 'TEACHER', 'attendance:edit', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(107, 4, 'TEACHER', 'attendance:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(108, 4, 'TEACHER', 'attendance:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(109, 4, 'TEACHER', 'attendance:start', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(110, 4, 'TEACHER', 'attendance:record', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(111, 4, 'TEACHER', 'attendance:status:modify', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 考勤管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(112, 5, 'STUDENT', 'attendance:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(113, 5, 'STUDENT', 'attendance:sign', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 优秀作品权限 (excellent)
-- ========================================
-- 超级管理员 - 优秀作品权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(114, 1, 'SUPER', 'excellent:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(115, 1, 'SUPER', 'excellent:mark', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(116, 1, 'SUPER', 'excellent:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(117, 1, 'SUPER', 'excellent:like', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 优秀作品权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(118, 4, 'TEACHER', 'excellent:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(119, 4, 'TEACHER', 'excellent:mark', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(120, 4, 'TEACHER', 'excellent:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(121, 4, 'TEACHER', 'excellent:like', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 优秀作品权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(122, 5, 'STUDENT', 'excellent:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(123, 5, 'STUDENT', 'excellent:like', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 通知管理权限 (notification)
-- ========================================
-- 超级管理员 - 通知管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(124, 1, 'SUPER', 'notification:send', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(125, 1, 'SUPER', 'notification:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(126, 1, 'SUPER', 'notification:delete', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(127, 1, 'SUPER', 'notification:read', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 老师 - 通知管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(128, 4, 'TEACHER', 'notification:send', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(129, 4, 'TEACHER', 'notification:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(130, 4, 'TEACHER', 'notification:read', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 学生 - 通知管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(131, 5, 'STUDENT', 'notification:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(132, 5, 'STUDENT', 'notification:read', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 充值管理权限 (payment)
-- ========================================
-- 超级管理员 - 充值管理权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(133, 1, 'SUPER', 'payment:package:manage', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(134, 1, 'SUPER', 'payment:order:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(135, 1, 'SUPER', 'payment:recharge', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- 用户通用 - 充值权限(学生、老师)
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(136, 4, 'TEACHER', 'payment:recharge', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(137, 4, 'TEACHER', 'payment:order:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(138, 5, 'STUDENT', 'payment:recharge', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(139, 5, 'STUDENT', 'payment:order:query', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
-- ========================================
-- 个人中心权限 (profile)
-- ========================================
-- 用户通用 - 个人中心权限
INSERT INTO `sys_role_permission` (`permission_id`, `role_id`, `role_code`, `permission_code`, `create_time`, `update_time`) VALUES
(140, 4, 'TEACHER', 'profile:info', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(141, 4, 'TEACHER', 'profile:update', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(142, 4, 'TEACHER', 'profile:password', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(143, 4, 'TEACHER', 'profile:phone', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(144, 4, 'TEACHER', 'profile:consumption', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(145, 5, 'STUDENT', 'profile:info', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(146, 5, 'STUDENT', 'profile:update', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(147, 5, 'STUDENT', 'profile:password', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(148, 5, 'STUDENT', 'profile:phone', '2026-04-30 18:00:00', '2026-04-30 18:00:00'),
(149, 5, 'STUDENT', 'profile:consumption', '2026-04-30 18:00:00', '2026-04-30 18:00:00');
SET FOREIGN_KEY_CHECKS = 1;

View File

@ -0,0 +1,149 @@
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (1, 1, 'SUPER', '系统管理', 'system:user:add', '用户新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (2, 1, 'SUPER', '系统管理', 'system:user:edit', '用户修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (3, 1, 'SUPER', '系统管理', 'system:user:delete', '用户删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (4, 1, 'SUPER', '系统管理', 'system:user:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (5, 1, 'SUPER', '系统管理', 'system:role:add', '角色新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (6, 1, 'SUPER', '系统管理', 'system:role:edit', '角色修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (7, 1, 'SUPER', '系统管理', 'system:role:delete', '角色删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (8, 1, 'SUPER', '系统管理', 'system:role:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (9, 1, 'SUPER', '系统管理', 'system:menu:add', '菜单新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (10, 1, 'SUPER', '系统管理', 'system:menu:edit', '菜单修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (11, 1, 'SUPER', '系统管理', 'system:menu:delete', '菜单删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (12, 1, 'SUPER', '系统管理', 'system:dict:manage', '字典管理', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (13, 1, 'SUPER', '系统管理', 'system:log:query', '日志查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (14, 2, 'SCOOL_ADMIN', '系统管理', 'system:user:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (15, 2, 'SCOOL_ADMIN', '系统管理', 'system:role:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (16, 1, 'SUPER', '用户管理', 'user:student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (17, 1, 'SUPER', '用户管理', 'user:student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (18, 1, 'SUPER', '用户管理', 'user:student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (19, 1, 'SUPER', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (20, 1, 'SUPER', '用户管理', 'user:teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (21, 1, 'SUPER', '用户管理', 'user:teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (22, 1, 'SUPER', '用户管理', 'user:teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (23, 1, 'SUPER', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (24, 1, 'SUPER', '用户管理', 'user:teacher:bind', '教师绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (25, 1, 'SUPER', '用户管理', 'user:student:bind', '学生绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (26, 2, 'SCOOL_ADMIN', '用户管理', 'user:student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (27, 2, 'SCOOL_ADMIN', '用户管理', 'user:student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (28, 2, 'SCOOL_ADMIN', '用户管理', 'user:student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (29, 2, 'SCOOL_ADMIN', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (30, 2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (31, 2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (32, 2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (33, 2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (34, 2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:bind', '教师绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (35, 2, 'SCOOL_ADMIN', '用户管理', 'user:student:bind', '学生绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (36, 3, 'COLLEGE_ADMIN', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (37, 3, 'COLLEGE_ADMIN', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (38, 1, 'SUPER', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (39, 1, 'SUPER', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (40, 1, 'SUPER', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (41, 1, 'SUPER', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (42, 1, 'SUPER', '课程管理', 'course:student:add', '学生选课', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (43, 1, 'SUPER', '课程管理', 'course:student:remove', '移除学生', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (44, 1, 'SUPER', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (45, 1, 'SUPER', '课程管理', 'course:score:export', '成绩导出', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (46, 2, 'SCOOL_ADMIN', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (47, 2, 'SCOOL_ADMIN', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (48, 3, 'COLLEGE_ADMIN', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (49, 3, 'COLLEGE_ADMIN', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (50, 4, 'TEACHER', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (51, 4, 'TEACHER', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (52, 4, 'TEACHER', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (53, 4, 'TEACHER', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (54, 4, 'TEACHER', '课程管理', 'course:student:add', '学生选课', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (55, 4, 'TEACHER', '课程管理', 'course:student:remove', '移除学生', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (56, 4, 'TEACHER', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (57, 4, 'TEACHER', '课程管理', 'course:score:export', '成绩导出', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (58, 5, 'STUDENT', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (59, 5, 'STUDENT', '课程管理', 'course:join', '加入课程', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (60, 5, 'STUDENT', '课程管理', 'course:quit', '退出课程', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (61, 1, 'SUPER', '作业管理', 'homework:add', '作业新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (62, 1, 'SUPER', '作业管理', 'homework:edit', '作业修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (63, 1, 'SUPER', '作业管理', 'homework:delete', '作业删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (64, 1, 'SUPER', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (65, 1, 'SUPER', '作业管理', 'homework:publish', '作业发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (66, 1, 'SUPER', '作业管理', 'homework:grade', '作业批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (67, 1, 'SUPER', '作业管理', 'homework:excellent', '设为优秀', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (68, 1, 'SUPER', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (69, 4, 'TEACHER', '作业管理', 'homework:add', '作业新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (70, 4, 'TEACHER', '作业管理', 'homework:edit', '作业修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (71, 4, 'TEACHER', '作业管理', 'homework:delete', '作业删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (72, 4, 'TEACHER', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (73, 4, 'TEACHER', '作业管理', 'homework:publish', '作业发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (74, 4, 'TEACHER', '作业管理', 'homework:grade', '作业批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (75, 4, 'TEACHER', '作业管理', 'homework:excellent', '设为优秀', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (76, 4, 'TEACHER', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (77, 5, 'STUDENT', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (78, 5, 'STUDENT', '作业管理', 'homework:submit', '提交作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (79, 5, 'STUDENT', '作业管理', 'homework:update', '更新作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (80, 5, 'STUDENT', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (81, 1, 'SUPER', '考试管理', 'exam:add', '考试新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (82, 1, 'SUPER', '考试管理', 'exam:edit', '考试修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (83, 1, 'SUPER', '考试管理', 'exam:delete', '考试删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (84, 1, 'SUPER', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (85, 1, 'SUPER', '考试管理', 'exam:publish', '考试发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (86, 1, 'SUPER', '考试管理', 'exam:grade', '阅卷评分', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (87, 1, 'SUPER', '考试管理', 'exam:makeup', '参加补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (88, 4, 'TEACHER', '考试管理', 'exam:add', '考试新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (89, 4, 'TEACHER', '考试管理', 'exam:edit', '考试修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (90, 4, 'TEACHER', '考试管理', 'exam:delete', '考试删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (91, 4, 'TEACHER', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (92, 4, 'TEACHER', '考试管理', 'exam:publish', '考试发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (93, 4, 'TEACHER', '考试管理', 'exam:grade', '阅卷评分', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (94, 4, 'TEACHER', '考试管理', 'exam:makeup', '参加补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (95, 5, 'STUDENT', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (96, 5, 'STUDENT', '考试管理', 'exam:take', '参加考试', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (97, 5, 'STUDENT', '考试管理', 'exam:makeup', '参加补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (98, 1, 'SUPER', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (99, 1, 'SUPER', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (100, 1, 'SUPER', '考勤管理', 'attendance:delete', '考勤删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (101, 1, 'SUPER', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (102, 1, 'SUPER', '考勤管理', 'attendance:start', '开始考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (103, 1, 'SUPER', '考勤管理', 'attendance:record', '记录考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (104, 1, 'SUPER', '考勤管理', 'attendance:status:modify', '状态修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (105, 4, 'TEACHER', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (106, 4, 'TEACHER', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (107, 4, 'TEACHER', '考勤管理', 'attendance:delete', '考勤删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (108, 4, 'TEACHER', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (109, 4, 'TEACHER', '考勤管理', 'attendance:start', '开始考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (110, 4, 'TEACHER', '考勤管理', 'attendance:record', '记录考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (111, 4, 'TEACHER', '考勤管理', 'attendance:status:modify', '状态修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (112, 5, 'STUDENT', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (113, 5, 'STUDENT', '考勤管理', 'attendance:sign', '签到', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (114, 1, 'SUPER', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (115, 1, 'SUPER', '优秀作品', 'excellent:mark', '作品标记', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (116, 1, 'SUPER', '优秀作品', 'excellent:delete', '作品删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (117, 1, 'SUPER', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (118, 4, 'TEACHER', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (119, 4, 'TEACHER', '优秀作品', 'excellent:mark', '作品标记', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (120, 4, 'TEACHER', '优秀作品', 'excellent:delete', '作品删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (121, 4, 'TEACHER', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (122, 5, 'STUDENT', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (123, 5, 'STUDENT', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (124, 1, 'SUPER', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (125, 1, 'SUPER', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (126, 1, 'SUPER', '通知管理', 'notification:delete', '通知删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (127, 1, 'SUPER', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (128, 4, 'TEACHER', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (129, 4, 'TEACHER', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (130, 4, 'TEACHER', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (131, 5, 'STUDENT', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (132, 5, 'STUDENT', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (133, 1, 'SUPER', '支付管理', 'payment:package:manage', '套餐管理', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (134, 1, 'SUPER', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (135, 1, 'SUPER', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (136, 4, 'TEACHER', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (137, 4, 'TEACHER', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (138, 5, 'STUDENT', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (139, 5, 'STUDENT', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (140, 4, 'TEACHER', '个人中心', 'profile:info', '查看资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (141, 4, 'TEACHER', '个人中心', 'profile:update', '更新资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (142, 4, 'TEACHER', '个人中心', 'profile:password', '修改密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (143, 4, 'TEACHER', '个人中心', 'profile:phone', '修改手机', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (144, 4, 'TEACHER', '个人中心', 'profile:consumption', '消费记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (145, 5, 'STUDENT', '个人中心', 'profile:info', '查看资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (146, 5, 'STUDENT', '个人中心', 'profile:update', '更新资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (147, 5, 'STUDENT', '个人中心', 'profile:password', '修改密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (148, 5, 'STUDENT', '个人中心', 'profile:phone', '修改手机', '2026-04-30 18:00:00', '2026-05-08 16:33:19');
INSERT INTO `kexue_server`.`sys_role_permission` (`permission_id`, `role_id`, `role_code`, `model_name`, `permission_code`, `permission_name`, `create_time`, `update_time`) VALUES (149, 5, 'STUDENT', '个人中心', 'profile:consumption', '消费记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19');

View File

@ -0,0 +1,103 @@
INSERT INTO sys_role_permission (role_id, role_code, model_name, permission_code, permission_name, create_time, update_time) VALUES
-- 系统管理模块
(1, 'SUPER', '系统管理', 'sysUser:add', '用户新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysUser:edit', '用户修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysUser:delete', '用户删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysUser:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysUser:resetPwd', '重置密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysRole:add', '角色新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysRole:edit', '角色修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysRole:delete', '角色删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysRole:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysMenu:add', '菜单新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysMenu:edit', '菜单修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysMenu:delete', '菜单删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDict:manage', '字典管理', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysLog:query', '日志查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:add', '部门新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:edit', '部门修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:delete', '部门删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:query', '部门查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 通知管理模块
(1, 'SUPER', '通知管理', 'notification:add', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:delete', '删除通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:query', '查询通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:edit', '编辑通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 课程管理模块
(1, 'SUPER', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 考勤管理模块
(1, 'SUPER', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:delete', '考勤删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:scan', '扫码签到', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 教师管理模块
(1, 'SUPER', '教师管理', 'teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '教师管理', 'teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '教师管理', 'teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '教师管理', 'teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 学生管理模块
(1, 'SUPER', '学生管理', 'student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '学生管理', 'student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '学生管理', 'student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '学生管理', 'student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 作业管理模块
(1, 'SUPER', '作业管理', 'homework:add', '作业新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:edit', '作业修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:delete', '作业删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:submit', '作业提交', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:grade', '作业批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 考试管理模块
(1, 'SUPER', '考试管理', 'exam:add', '考试新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:edit', '考试修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:delete', '考试删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:submit', '考试提交', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:grade', '考试批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:makeup', '创建补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 优秀作品模块
(1, 'SUPER', '优秀作品', 'excellentWork:add', '作品新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellentWork:delete', '作品删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellentWork:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellentWork:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellentWork:mark', '标记优秀', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 账户管理模块
(1, 'SUPER', '账户管理', 'account:query', '账户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:recharge', '账户充值', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:gift', '赠送金额', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:transaction', '交易记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- SCHOOL_ADMIN 角色权限
(2, 'SCHOOL_ADMIN', '系统管理', 'sysUser:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '系统管理', 'sysRole:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '教师管理', 'teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '教师管理', 'teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '教师管理', 'teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '教师管理', 'teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '学生管理', 'student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '学生管理', 'student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '学生管理', 'student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '学生管理', 'student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCHOOL_ADMIN', '优秀作品', 'excellentWork:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19');

View File

@ -0,0 +1,203 @@
INSERT INTO sys_role_permission (role_id, role_code, model_name, permission_code, permission_name, create_time, update_time) VALUES
-- 系统管理模块
(1, 'SUPER', '系统管理', 'system:user:add', '用户新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:user:edit', '用户修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:user:delete', '用户删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:user:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysUser:resetPwd', '重置密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:role:add', '角色新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:role:edit', '角色修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:role:delete', '角色删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:role:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:menu:add', '菜单新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:menu:edit', '菜单修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:menu:delete', '菜单删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:dict:manage', '字典管理', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'system:log:query', '日志查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:add', '部门新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:edit', '部门修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:delete', '部门删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '系统管理', 'sysDept:query', '部门查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 用户管理模块
(1, 'SUPER', '用户管理', 'user:student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:teacher:bind', '教师绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '用户管理', 'user:student:bind', '学生绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 课程管理模块
(1, 'SUPER', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:student:add', '学生选课', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:student:remove', '移除学生', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '课程管理', 'course:score:export', '成绩导出', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 作业管理模块
(1, 'SUPER', '作业管理', 'homework:add', '作业新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:edit', '作业修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:delete', '作业删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:publish', '作业发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:grade', '作业批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:excellent', '设为优秀', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 考试管理模块
(1, 'SUPER', '考试管理', 'exam:add', '考试新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:edit', '考试修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:delete', '考试删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:publish', '考试发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:grade', '阅卷评分', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考试管理', 'exam:makeup', '创建补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 考勤管理模块
(1, 'SUPER', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:delete', '考勤删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:start', '开始考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:record', '记录考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:status:modify', '状态修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '考勤管理', 'attendance:scan', '扫码签到', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 优秀作品模块
(1, 'SUPER', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellent:mark', '作品标记', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellent:delete', '作品删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 通知管理模块
(1, 'SUPER', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:delete', '通知删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '通知管理', 'notification:edit', '编辑通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 账户管理模块
(1, 'SUPER', '账户管理', 'account:query', '账户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:recharge', '账户充值', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:gift', '赠送金额', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '账户管理', 'account:transaction', '交易记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- 支付管理模块
(1, 'SUPER', '支付管理', 'payment:package:manage', '套餐管理', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(1, 'SUPER', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- SCHOOL_ADMIN 角色权限
(2, 'SCOOL_ADMIN', '系统管理', 'system:user:query', '用户查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '系统管理', 'system:role:query', '角色查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:student:add', '学生新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:student:edit', '学生修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:student:delete', '学生删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:add', '教师新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:edit', '教师修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:delete', '教师删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:teacher:bind', '教师绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '用户管理', 'user:student:bind', '学生绑定', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(2, 'SCOOL_ADMIN', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- COLLEGE_ADMIN 角色权限
(3, 'COLLEGE_ADMIN', '用户管理', 'user:student:query', '学生查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '用户管理', 'user:teacher:query', '教师查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(3, 'COLLEGE_ADMIN', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- TEACHER 角色权限
(4, 'TEACHER', '课程管理', 'course:add', '课程新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:edit', '课程修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:delete', '课程删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:student:add', '学生选课', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:student:remove', '移除学生', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:student:query', '选课查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '课程管理', 'course:score:export', '成绩导出', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:add', '作业新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:edit', '作业修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:delete', '作业删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:publish', '作业发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:grade', '作业批改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:excellent', '设为优秀', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:add', '考试新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:edit', '考试修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:delete', '考试删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:publish', '考试发布', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:grade', '阅卷评分', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考试管理', 'exam:makeup', '参加补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:add', '考勤新增', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:edit', '考勤修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:delete', '考勤删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:start', '开始考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:record', '记录考勤', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '考勤管理', 'attendance:status:modify', '状态修改', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '优秀作品', 'excellent:mark', '作品标记', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '优秀作品', 'excellent:delete', '作品删除', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '通知管理', 'notification:send', '发送通知', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '个人中心', 'profile:info', '查看资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '个人中心', 'profile:update', '更新资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '个人中心', 'profile:password', '修改密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '个人中心', 'profile:phone', '修改手机', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(4, 'TEACHER', '个人中心', 'profile:consumption', '消费记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
-- STUDENT 角色权限
(5, 'STUDENT', '课程管理', 'course:query', '课程查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '课程管理', 'course:join', '加入课程', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '课程管理', 'course:quit', '退出课程', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '作业管理', 'homework:query', '作业查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '作业管理', 'homework:submit', '提交作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '作业管理', 'homework:update', '更新作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '作业管理', 'homework:redo', '重做作业', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '考试管理', 'exam:query', '考试查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '考试管理', 'exam:take', '参加考试', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '考试管理', 'exam:makeup', '参加补考', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '考勤管理', 'attendance:query', '考勤查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '考勤管理', 'attendance:sign', '签到', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '优秀作品', 'excellent:query', '作品查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '优秀作品', 'excellent:like', '作品点赞', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '通知管理', 'notification:query', '通知查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '通知管理', 'notification:read', '标记已读', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '支付管理', 'payment:recharge', '充值功能', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '支付管理', 'payment:order:query', '订单查询', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '个人中心', 'profile:info', '查看资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '个人中心', 'profile:update', '更新资料', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '个人中心', 'profile:password', '修改密码', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '个人中心', 'profile:phone', '修改手机', '2026-04-30 18:00:00', '2026-05-08 16:33:19'),
(5, 'STUDENT', '个人中心', 'profile:consumption', '消费记录', '2026-04-30 18:00:00', '2026-05-08 16:33:19');

159
mvnw.cmd vendored
View File

@ -1,159 +0,0 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM set title of command window
title %0
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "on" ("%HOME%\mavenrc_pre.bat" %*)
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo. goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
@REM ==== END VALIDATION ====
:init
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
if not "%MAVEN_PROJECTBASEDIR%" == "" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
if exist "%WDIR%\.mvn" goto baseDirFound
cd ..
if "%WDIR%" == "%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
)
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
if exist %WRAPPER_JAR% (
if "%MVNW_VERBOSE%" == "true" (
echo Found %WRAPPER_JAR%
)
) else (
if not "%MVNW_REPOURL%" == "" (
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
)
if "%MVNW_VERBOSE%" == "true" (
echo Couldn't find %WRAPPER_JAR%, downloading it ...
echo Downloading from: %DOWNLOAD_URL%
)
powershell -Command "&{$client = new-object System.Net.WebClient; $client.DownloadFile(%DOWNLOAD_URL%, %WRAPPER_JAR%);}"
if "%MVNW_VERBOSE%" == "true" (
echo Finished downloading %WRAPPER_JAR%
)
)
@REM End of extension
@REM Provide a "standardized" way to retrieve the CLI args that will
@REM work with both Windows and non-Windows executions.
set MAVEN_CMD_LINE_ARGS=%*
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* || set ERROR_CODE=1
:end
@REM setlocal
goto mainEnd
:error
set ERROR_CODE=1
:mainEnd
@REM setlocal
@REM Execute a user defined script after this one
if not "%MAVEN_SKIP_RC%" == "on" ("%HOME%\mavenrc_post.bat")
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%

31
pom.xml
View File

@ -2,11 +2,11 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>com.kexue</groupId> <groupId>art.kexue</groupId>
<artifactId>skills</artifactId> <artifactId>kexueServer</artifactId>
<name>agentSkills</name> <name>kexueServer</name>
<version>0.0.1-SNAPSHOT</version> <version>0.0.1-SNAPSHOT</version>
<description>可学AI-skills平台</description> <description>可学AI-实训网站</description>
<properties> <properties>
<java.version>17</java.version> <java.version>17</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@ -264,7 +264,7 @@
<dependency> <dependency>
<groupId>com.github.binarywang</groupId> <groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-pay</artifactId> <artifactId>weixin-java-pay</artifactId>
<version>4.4.0</version> <version>4.7.0</version>
</dependency> </dependency>
<!-- 支付宝SDK --> <!-- 支付宝SDK -->
@ -292,6 +292,23 @@
<version>16.02-2.01</version> <version>16.02-2.01</version>
</dependency> </dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>com.github.binarywang</groupId>
<artifactId>weixin-java-mp</artifactId>
<version>4.7.0</version> <!-- 请检查最新版本 -->
</dependency>
</dependencies> </dependencies>
<dependencyManagement> <dependencyManagement>
<dependencies> <dependencies>
@ -306,7 +323,7 @@
</dependencyManagement> </dependencyManagement>
<build> <build>
<finalName>agentSkills</finalName> <finalName>kexueServer</finalName>
<plugins> <plugins>
<plugin> <plugin>
<groupId>org.apache.maven.plugins</groupId> <groupId>org.apache.maven.plugins</groupId>
@ -337,7 +354,7 @@
<artifactId>spring-boot-maven-plugin</artifactId> <artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version> <version>${spring-boot.version}</version>
<configuration> <configuration>
<mainClass>com.kexue.skills.SkillsApp</mainClass> <mainClass>art.kexue.sxwz.KexueServerApp</mainClass>
<skip>false</skip> <skip>false</skip>
</configuration> </configuration>
<executions> <executions>

View File

@ -1,27 +1,22 @@
package com.kexue.skills; package art.kexue.sxwz;
import org.mybatis.spring.annotation.MapperScan; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.event.ApplicationReadyEvent; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy; import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.InetAddress;
import java.net.UnknownHostException;
@SpringBootApplication @SpringBootApplication
@MapperScan(basePackages = "com.kexue.skills.mapper") @MapperScan(basePackages = "art.kexue.sxwz.mapper")
@ComponentScan(basePackages = "art.kexue.sxwz")
@EnableAspectJAutoProxy @EnableAspectJAutoProxy
@EnableScheduling @EnableScheduling
public class SkillsApp { public class KexueServerApp {
public static void main(String[] args) { public static void main(String[] args) {
SpringApplication.run(SkillsApp.class, args); SpringApplication.run(KexueServerApp.class, args);
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.annotation; package art.kexue.sxwz.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.annotation; package art.kexue.sxwz.annotation;
import java.lang.annotation.*; import java.lang.annotation.*;
@ -32,3 +32,4 @@ public @interface Log {
*/ */
boolean ignore() default false; boolean ignore() default false;
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.annotation; package art.kexue.sxwz.annotation;
/** /**
* @author 维哥 * @author 维哥

View File

@ -1,4 +1,4 @@
package com.kexue.skills.annotation; package art.kexue.sxwz.annotation;
/** /**
* @author 维哥 * @author 维哥

View File

@ -0,0 +1,12 @@
package art.kexue.sxwz.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequirePermission {
String[] value() default {};
}

View File

@ -1,4 +1,4 @@
package com.kexue.skills.annotation; package art.kexue.sxwz.annotation;
import java.lang.annotation.ElementType; import java.lang.annotation.ElementType;
import java.lang.annotation.Retention; import java.lang.annotation.Retention;

View File

@ -1,10 +1,9 @@
package com.kexue.skills.aspect; package art.kexue.sxwz.aspect;
import com.kexue.skills.annotation.RequireAuth; import art.kexue.sxwz.common.ResultCode;
import com.kexue.skills.common.ResultCode; import art.kexue.sxwz.exception.BizException;
import com.kexue.skills.exception.BizException; import art.kexue.sxwz.interceptor.UserContextHolder;
import com.kexue.skills.interceptor.UserContextHolder; import art.kexue.sxwz.service.SysUserService;
import com.kexue.skills.service.SysUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
@ -30,13 +29,13 @@ public class AuthAspect {
private SysUserService sysUserService; private SysUserService sysUserService;
// 处理方法级别注解 // 处理方法级别注解
@Around("@annotation(com.kexue.skills.annotation.RequireAuth)") @Around("@annotation(art.kexue.sxwz.annotation.RequireAuth)")
public Object requireAuthMethod(ProceedingJoinPoint joinPoint) throws Throwable { public Object requireAuthMethod(ProceedingJoinPoint joinPoint) throws Throwable {
return requireAuthImpl(joinPoint); return requireAuthImpl(joinPoint);
} }
// 处理类级别注解 // 处理类级别注解
@Around("@within(com.kexue.skills.annotation.RequireAuth)") @Around("@within(art.kexue.sxwz.annotation.RequireAuth)")
public Object requireAuthClass(ProceedingJoinPoint joinPoint) throws Throwable { public Object requireAuthClass(ProceedingJoinPoint joinPoint) throws Throwable {
return requireAuthImpl(joinPoint); return requireAuthImpl(joinPoint);
} }

View File

@ -0,0 +1,169 @@
package art.kexue.sxwz.aspect;
import art.kexue.sxwz.exception.BizException;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
@Aspect
@Component
@Slf4j
public class EduPermissionAspect {
@Resource
private RedissonClient redissonClient;
@Around("execution(* art.kexue.sxwz.service.impl.Edu*ServiceImpl.*(..))")
public Object checkEduPermission(ProceedingJoinPoint joinPoint) throws Throwable {
try {
cn.dev33.satoken.stp.StpUtil.checkLogin();
Long userId = cn.dev33.satoken.stp.StpUtil.getLoginIdAsLong();
String token = cn.dev33.satoken.stp.StpUtil.getTokenValue();
// SUPER角色拥有所有权限直接放行
if (cn.dev33.satoken.stp.StpUtil.hasRole("SUPER")) {
log.info("用户ID: {} 拥有SUPER角色直接放行访问方法: {}", userId, joinPoint.getSignature().getName());
return joinPoint.proceed();
}
List<String> permissions = getUserPermissions(token);
String requiredPermission = generatePermissionCode(joinPoint);
log.info("用户ID: {}, 访问方法: {}, 需要权限: {}",
userId,
joinPoint.getSignature().getName(),
requiredPermission);
if (permissions == null || permissions.isEmpty()) {
log.warn("用户未配置任何权限");
throw new BizException(403, "没有相应操作权限");
}
if (!permissions.contains(requiredPermission)) {
log.warn("用户缺少权限: {}", requiredPermission);
throw new BizException(403, "没有相应操作权限");
}
log.info("权限验证通过: {}", requiredPermission);
} catch (cn.dev33.satoken.exception.NotLoginException e) {
log.error("未登录:{}", e.getMessage());
throw new BizException(401, "请先登录认证后操作");
} catch (BizException e) {
throw e;
} catch (Exception e) {
log.error("权限验证失败:{}", e.getMessage());
throw new BizException(403, "权限验证失败");
}
return joinPoint.proceed();
}
private List<String> getUserPermissions(String token) {
try {
String loginUserJson = (String) redissonClient.getBucket("loginUser:" + token).get();
if (loginUserJson != null && !loginUserJson.isEmpty()) {
cn.hutool.json.JSONObject jsonObject = cn.hutool.json.JSONUtil.parseObj(loginUserJson);
cn.hutool.json.JSONArray permissionsArray = jsonObject.getJSONArray("permissions");
if (permissionsArray != null) {
return permissionsArray.toList(String.class);
}
}
} catch (Exception e) {
log.error("从Redis获取用户权限失败{}", e.getMessage());
}
return Collections.emptyList();
}
private String generatePermissionCode(ProceedingJoinPoint joinPoint) {
String className = joinPoint.getTarget().getClass().getSimpleName();
String methodName = joinPoint.getSignature().getName();
String module = extractModule(className);
String action = extractAction(methodName);
return String.format("%s:%s", module, action);
}
private String extractModule(String className) {
if (className.startsWith("EduCourse")) {
return "course";
} else if (className.startsWith("EduStudent")) {
return "user:student";
} else if (className.startsWith("EduTeacher")) {
return "user:teacher";
} else if (className.startsWith("EduHomework")) {
return "homework";
} else if (className.startsWith("EduExam")) {
return "exam";
} else if (className.startsWith("EduAttendance")) {
return "attendance";
} else if (className.startsWith("EduExcellentWork")) {
return "excellent";
}else if (className.startsWith("EduSchool")) {
return "school";
} else {
return className.replace("Edu", "").replace("ServiceImpl", "").toLowerCase();
}
}
private String extractAction(String methodName) {
if (methodName.startsWith("save") || methodName.startsWith("create")) {
return "add";
} else if (methodName.startsWith("update") && !methodName.startsWith("updateStatus")) {
return "update"; // 修改update方法返回update而非edit
} else if (methodName.startsWith("updateStatus")) {
return "updateStatus"; // 新增状态变更方法
} else if (methodName.startsWith("edit")) {
return "edit";
} else if (methodName.startsWith("delete") || methodName.startsWith("remove")) {
return "delete";
} else if (methodName.equals("pageList")) {
return "pageList"; // 新增分页查询方法
} else if (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("list")) {
return "query";
} else if (methodName.startsWith("addStudent")) {
return "student:add";
} else if (methodName.startsWith("removeStudent")) {
return "student:remove";
} else if (methodName.startsWith("submit")) {
return "submit";
} else if (methodName.startsWith("grade")) {
return "grade";
} else if (methodName.startsWith("publish")) {
return "publish";
} else if (methodName.startsWith("mark")) {
return "mark";
} else if (methodName.startsWith("addLike")) {
return "like";
} else if (methodName.startsWith("removeLike")) {
return "like:remove";
} else if (methodName.startsWith("countLikes")) {
return "like:count";
} else if (methodName.startsWith("recordAttendance")) {
return "record";
} else if (methodName.startsWith("batchCreate")) {
return "batch:add";
} else if (methodName.startsWith("isStudentIn")) {
return "student:exists";
} else if (methodName.startsWith("sendNotification")) {
return "notification:send";
} else if (methodName.startsWith("markAsRead")) {
return "notification:read";
} else if (methodName.startsWith("createMakeup")) {
return "makeup";
} else {
return methodName.toLowerCase();
}
}
}

View File

@ -1,9 +1,9 @@
package com.kexue.skills.aspect; package art.kexue.sxwz.aspect;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheBuilder;
import com.kexue.skills.annotation.PreventDuplicateSubmission; import art.kexue.sxwz.annotation.PreventDuplicateSubmission;
import com.kexue.skills.exception.BizException; import art.kexue.sxwz.exception.BizException;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Aspect;
@ -28,13 +28,13 @@ public class PreventDuplicateSubmissionAspect {
.build(); .build();
// 处理方法级别注解 // 处理方法级别注解
@Around("@annotation(com.kexue.skills.annotation.PreventDuplicateSubmission)") @Around("@annotation(art.kexue.sxwz.annotation.PreventDuplicateSubmission)")
public Object preventDuplicateSubmissionMethod(ProceedingJoinPoint joinPoint) throws Throwable { public Object preventDuplicateSubmissionMethod(ProceedingJoinPoint joinPoint) throws Throwable {
return preventDuplicateSubmissionImpl(joinPoint); return preventDuplicateSubmissionImpl(joinPoint);
} }
// 处理类级别注解 // 处理类级别注解
@Around("@within(com.kexue.skills.annotation.PreventDuplicateSubmission)") @Around("@within(art.kexue.sxwz.annotation.PreventDuplicateSubmission)")
public Object preventDuplicateSubmissionClass(ProceedingJoinPoint joinPoint) throws Throwable { public Object preventDuplicateSubmissionClass(ProceedingJoinPoint joinPoint) throws Throwable {
return preventDuplicateSubmissionImpl(joinPoint); return preventDuplicateSubmissionImpl(joinPoint);
} }

View File

@ -1,10 +1,10 @@
package com.kexue.skills.aspect; package art.kexue.sxwz.aspect;
import com.kexue.skills.annotation.RequireRole; import art.kexue.sxwz.annotation.RequireRole;
import com.kexue.skills.common.ResultCode; import art.kexue.sxwz.common.ResultCode;
import com.kexue.skills.exception.BizException; import art.kexue.sxwz.exception.BizException;
import com.kexue.skills.interceptor.UserContextHolder; import art.kexue.sxwz.interceptor.UserContextHolder;
import com.kexue.skills.service.SysUserService; import art.kexue.sxwz.service.SysUserService;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Around;
@ -32,13 +32,13 @@ public class RoleAspect {
private SysUserService sysUserService; private SysUserService sysUserService;
// 处理方法级别注解 // 处理方法级别注解
@Around("@annotation(com.kexue.skills.annotation.RequireRole)") @Around("@annotation(art.kexue.sxwz.annotation.RequireRole)")
public Object requireRoleMethod(ProceedingJoinPoint joinPoint) throws Throwable { public Object requireRoleMethod(ProceedingJoinPoint joinPoint) throws Throwable {
return requireRoleImpl(joinPoint); return requireRoleImpl(joinPoint);
} }
// 处理类级别注解 // 处理类级别注解
@Around("@within(com.kexue.skills.annotation.RequireRole)") @Around("@within(art.kexue.sxwz.annotation.RequireRole)")
public Object requireRoleClass(ProceedingJoinPoint joinPoint) throws Throwable { public Object requireRoleClass(ProceedingJoinPoint joinPoint) throws Throwable {
return requireRoleImpl(joinPoint); return requireRoleImpl(joinPoint);
} }
@ -83,6 +83,13 @@ public class RoleAspect {
String.join(",", requireRole.value()), String.join(",", requireRole.value()),
requireRole.getClass().getName()); requireRole.getClass().getName());
// SUPER角色拥有所有权限直接放行
if (cn.dev33.satoken.stp.StpUtil.hasRole("SUPER")) {
log.info("用户{}拥有SUPER角色直接放行", username);
UserContextHolder.setUserName(username);
return joinPoint.proceed();
}
// 获取用户的角色列表 // 获取用户的角色列表
String[] requiredRoles = requireRole.value(); String[] requiredRoles = requireRole.value();
if (requiredRoles != null && requiredRoles.length > 0) { if (requiredRoles != null && requiredRoles.length > 0) {
@ -90,17 +97,17 @@ public class RoleAspect {
List<String> userRoles = cn.dev33.satoken.stp.StpUtil.getRoleList(); List<String> userRoles = cn.dev33.satoken.stp.StpUtil.getRoleList();
log.info("当前用户的角色列表:{}", String.join(",", userRoles)); log.info("当前用户的角色列表:{}", String.join(",", userRoles));
// 检查用户是否拥有所有必需的角色 // 修改为OR逻辑检查用户是否拥有任意一个必需的角色
boolean hasAllRoles = true; boolean hasAnyRole = false;
for (String role : requiredRoles) { for (String role : requiredRoles) {
if (!userRoles.contains(role)) { if (userRoles.contains(role)) {
hasAllRoles = false; hasAnyRole = true;
log.error("用户缺少角色:{}", role); log.info("用户拥有角色:{}", role);
break; break;
} }
} }
if (!hasAllRoles) { if (!hasAnyRole) {
throw new cn.dev33.satoken.exception.NotRoleException(requiredRoles[0]); throw new cn.dev33.satoken.exception.NotRoleException(requiredRoles[0]);
} }
} }

View File

@ -1,6 +1,6 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
import com.kexue.skills.exception.BizException; import art.kexue.sxwz.exception.BizException;
import java.util.Collection; import java.util.Collection;
import java.util.Map; import java.util.Map;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
import com.google.common.cache.Cache; import com.google.common.cache.Cache;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModel;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -134,3 +134,4 @@ public class CommonResult<T> {
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
@ -33,3 +33,4 @@ public interface Const {
Integer ACCOUNT_STATUS_ACCOUNTED = 1;//已扎帐 Integer ACCOUNT_STATUS_ACCOUNTED = 1;//已扎帐
Integer ACCOUNT_STATUS_UNACCOUNTED = 2; //未扎帐 Integer ACCOUNT_STATUS_UNACCOUNTED = 2; //未扎帐
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
/** /**
* 错误代号和信息 * 错误代号和信息
@ -31,3 +31,4 @@ public enum ErrorStatus {
return message; return message;
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
/** /**
* 封装API的错误码 * 封装API的错误码
@ -18,3 +18,4 @@ public interface IErrorCode {
*/ */
String getMessage(); String getMessage();
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
/** /**
* 请求返回结果 * 请求返回结果
@ -108,3 +108,4 @@ public class Result<T> {
this.data = data; this.data = data;
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
/** /**
* 枚举了一些常用API操作码 * 枚举了一些常用API操作码
@ -124,3 +124,4 @@ public enum ResultCode implements IErrorCode {
return message; return message;
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
/** /**
* 返回结果工具类 * 返回结果工具类
@ -46,3 +46,4 @@ public class ResultEntity<T> {
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common; package art.kexue.sxwz.common;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
@ -73,3 +73,4 @@ public class VerifyCode {
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import javax.crypto.*; import javax.crypto.*;
import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.IvParameterSpec;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import java.io.*; import java.io.*;
@ -97,3 +97,4 @@ public class BytesHelper {
return 0; return 0;
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import cn.hutool.core.date.DateUtil; import cn.hutool.core.date.DateUtil;
@ -88,3 +88,4 @@ public class DateConverter {
System.out.println(convertShortTime("12:5")); // 输出12:05:00 System.out.println(convertShortTime("12:5")); // 输出12:05:00
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import java.text.DateFormat; import java.text.DateFormat;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
@ -41,3 +41,4 @@ public class DateUtil {
System.out.println(getDaysBetwwen(7)); System.out.println(getDaysBetwwen(7));
}*/ }*/
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import cn.hutool.core.annotation.AnnotationUtil; import cn.hutool.core.annotation.AnnotationUtil;
import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.bean.BeanUtil;
@ -9,15 +9,14 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil; import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter; import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet; import cn.hutool.poi.excel.StyleSet;
import com.kexue.skills.annotation.Excel; import art.kexue.sxwz.annotation.Excel;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import org.apache.poi.ss.usermodel.*; import org.apache.poi.ss.usermodel.*;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.net.URLEncoder; import java.net.URLEncoder;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -337,3 +337,4 @@ public final class FileHelper
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import io.swagger.annotations.ApiModelProperty; import io.swagger.annotations.ApiModelProperty;
import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.media.Schema;
@ -163,3 +163,4 @@ public class FrontUtils {
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -118,3 +118,4 @@ public class IDUtils {
} }
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -85,3 +85,4 @@ public class ImageUtil {
imageUtil.thumbnailImage("C:\\Users\\ACER\\Pictures\\雷克萨斯\\index-kv-nx-0821-2880x1480.jpg",190,180,DEFAULT_PREVFIX,false); imageUtil.thumbnailImage("C:\\Users\\ACER\\Pictures\\雷克萨斯\\index-kv-nx-0821-2880x1480.jpg",190,180,DEFAULT_PREVFIX,false);
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
@ -137,3 +137,4 @@ public class IpUtil {
return "127.0.0.1"; return "127.0.0.1";
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.math.BigInteger; import java.math.BigInteger;
@ -41,3 +41,4 @@ public class MD5Util {
System.out.println(MD5Util.encode("admin")); System.out.println(MD5Util.encode("admin"));
} }
} }

View File

@ -1,4 +1,4 @@
//package com.kexue.skills.publisher.common.util; //package art.kexue.sxwz.publisher.common.util;
// //
//import org.springframework.security.authentication.AnonymousAuthenticationToken; //import org.springframework.security.authentication.AnonymousAuthenticationToken;
//import org.springframework.security.core.Authentication; //import org.springframework.security.core.Authentication;
@ -17,3 +17,4 @@
// return ""; // return "";
// } // }
//} //}

View File

@ -1,6 +1,6 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import com.kexue.skills.utils.EscapeCharacterUtils; import art.kexue.sxwz.utils.EscapeCharacterUtils;
import net.sf.sevenzipjbinding.IInArchive; import net.sf.sevenzipjbinding.IInArchive;
import net.sf.sevenzipjbinding.SevenZip; import net.sf.sevenzipjbinding.SevenZip;
import net.sf.sevenzipjbinding.SevenZipException; import net.sf.sevenzipjbinding.SevenZipException;
@ -15,7 +15,6 @@ import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime; import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter; import java.time.format.DateTimeFormatter;
import java.util.*; import java.util.*;
import java.util.logging.Logger;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.slf4j.Logger; import org.slf4j.Logger;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.common.util; package art.kexue.sxwz.common.util;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -22,3 +22,4 @@ public class UploadUtils {
return dest.getName(); return dest.getName();
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import lombok.Data; import lombok.Data;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
@ -24,3 +24,4 @@ public class AccountDeductionProperties {
private BigDecimal coefficient; private BigDecimal coefficient;
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -28,3 +28,4 @@ public class CaptchaConfig {
*/ */
private int length = 4; private int length = 4;
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -71,3 +71,4 @@ public class DeepSeekConfig {
this.chat = chat; this.chat = chat;
} }
} }

View File

@ -1,6 +1,6 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import com.kexue.skills.interceptor.CorsFilter; import art.kexue.sxwz.interceptor.CorsFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@ -29,3 +29,4 @@ public class FilterConfig {
return registrationBean; return registrationBean;
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
@ -24,3 +24,4 @@ public class JacksonConfig {
.build(); .build();
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation; import com.alicp.jetcache.anno.config.EnableCreateCacheAnnotation;
import com.alicp.jetcache.anno.config.EnableMethodCache; import com.alicp.jetcache.anno.config.EnableMethodCache;
@ -10,7 +10,8 @@ import org.springframework.context.annotation.Configuration;
*/ */
@Configuration @Configuration
@EnableCreateCacheAnnotation @EnableCreateCacheAnnotation
@EnableMethodCache(basePackages = "com.kexue.skills.service") @EnableMethodCache(basePackages = "art.kexue.sxwz.service")
public class JetCacheConfig { public class JetCacheConfig {
} }

View File

@ -1,7 +1,7 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import com.kexue.skills.interceptor.LogInterceptor; import art.kexue.sxwz.interceptor.LogInterceptor;
import com.kexue.skills.mapper.SysLogMapper; import art.kexue.sxwz.mapper.SysLogMapper;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@ -38,3 +38,4 @@ public class LogConfiguration implements WebMvcConfigurer {
); );
} }
} }

View File

@ -1,6 +1,6 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import com.kexue.skills.service.SysUserService; import art.kexue.sxwz.service.SysUserService;
import cn.dev33.satoken.stp.StpInterface; import cn.dev33.satoken.stp.StpInterface;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -46,3 +46,4 @@ public class MyStpInterfaceImpl implements StpInterface {
return java.util.Collections.emptyList(); return java.util.Collections.emptyList();
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -64,3 +64,4 @@ public class PaymentConfig {
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.redisson.Redisson; import org.redisson.Redisson;
import org.redisson.api.RedissonClient; import org.redisson.api.RedissonClient;
@ -45,3 +45,4 @@ public class RedissonConfig {
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import cn.dev33.satoken.interceptor.SaInterceptor; import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter; import cn.dev33.satoken.router.SaRouter;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import io.swagger.v3.oas.annotations.OpenAPIDefinition; import io.swagger.v3.oas.annotations.OpenAPIDefinition;
import io.swagger.v3.oas.annotations.info.Info; import io.swagger.v3.oas.annotations.info.Info;

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@ -18,3 +18,4 @@ import org.thymeleaf.templatemode.TemplateMode;
@AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class}) @AutoConfigureAfter({WebMvcAutoConfiguration.class, WebFluxAutoConfiguration.class})
public class ThymeleafAutoConfiguration { public class ThymeleafAutoConfiguration {
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
@ -19,3 +19,4 @@ public class ThymeleafProperties {
private Charset encoding; private Charset encoding;
private boolean cache; private boolean cache;
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
@ -46,3 +46,4 @@ public class UploadConfig {
return "/upload/images/"; return "/upload/images/";
} }
} }

View File

@ -1,4 +1,4 @@
package com.kexue.skills.config; package art.kexue.sxwz.config;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter;
@ -77,3 +77,4 @@ public class WebMvcConfig implements WebMvcConfigurer {
// excludePathPatterns("/toRegister","/getVerifyCode", "/api/**","/index","/doLogin","/login","/register", "/addNew", "/static/**","/logout","/upload/"); // excludePathPatterns("/toRegister","/getVerifyCode", "/api/**","/index","/doLogin","/login","/register", "/addNew", "/static/**","/logout","/upload/");
} }
} }

View File

@ -0,0 +1,36 @@
package art.kexue.sxwz.config;
import lombok.Data;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Data
@Configuration
@ConfigurationProperties(prefix = "wechat.login")
public class WechatConfig {
private String appId;
private String appSecret;
private String redirectUri;
private String scope;
private Integer stateExpireMinutes;
@Bean
public WxMpService wxMpService() {
WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
config.setAppId(appId);
config.setSecret(appSecret);
WxMpService service = new WxMpServiceImpl();
service.setWxMpConfigStorage(config);
return service;
}
}

View File

@ -1,23 +1,21 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import art.kexue.sxwz.entity.AccountTransaction;
import cn.dev33.satoken.stp.StpUtil; import cn.dev33.satoken.stp.StpUtil;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.kexue.skills.annotation.Log; import art.kexue.sxwz.annotation.Log;
import com.kexue.skills.annotation.RequireAuth; import art.kexue.sxwz.annotation.RequireAuth;
import com.kexue.skills.annotation.RequireRole; import art.kexue.sxwz.annotation.RequireRole;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.common.Const; import art.kexue.sxwz.entity.Account;
import com.kexue.skills.entity.Account; import art.kexue.sxwz.entity.dto.AccountDto;
import com.kexue.skills.entity.dto.AccountDto; import art.kexue.sxwz.entity.dto.TokenConsumptionDto;
import com.kexue.skills.entity.dto.TokenConsumptionDto; import art.kexue.sxwz.entity.dto.GiftBalanceDto;
import com.kexue.skills.entity.dto.GiftBalanceDto; import art.kexue.sxwz.entity.dto.AccountTransactionDto;
import com.kexue.skills.entity.dto.AccountTransactionDto; import art.kexue.sxwz.entity.dto.ConsumptionGroupedDto;
import com.kexue.skills.entity.dto.ConsumptionGroupedDto; import art.kexue.sxwz.service.AccountService;
import com.kexue.skills.service.AccountService; import art.kexue.sxwz.service.SysUserService;
import com.kexue.skills.service.SysUserService;
import com.kexue.skills.entity.SysUser;
import com.kexue.skills.exception.BizException;
import com.kexue.skills.common.CacheManager;
import java.math.BigDecimal; import java.math.BigDecimal;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
@ -25,7 +23,6 @@ import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource; import javax.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import java.util.List; import java.util.List;
/** /**
@ -163,7 +160,7 @@ public class AccountController {
@Operation(summary = "获取当前登录用户交易记录", description = "获取当前登录用户交易记录") @Operation(summary = "获取当前登录用户交易记录", description = "获取当前登录用户交易记录")
@PostMapping("/getTransactions") @PostMapping("/getTransactions")
@RequireAuth @RequireAuth
public CommonResult<List<com.kexue.skills.entity.AccountTransaction>> getTransactions() { public CommonResult<List<AccountTransaction>> getTransactions() {
Long userId = Long.parseLong(StpUtil.getLoginId().toString()); Long userId = Long.parseLong(StpUtil.getLoginId().toString());
return CommonResult.success(this.accountService.getTransactions(userId)); return CommonResult.success(this.accountService.getTransactions(userId));
} }
@ -177,7 +174,7 @@ public class AccountController {
@Operation(summary = "分页查询充值记录", description = "分页查询所有充值记录,默认根据时间倒序") @Operation(summary = "分页查询充值记录", description = "分页查询所有充值记录,默认根据时间倒序")
@PostMapping("/getRechargePageList") @PostMapping("/getRechargePageList")
@RequireAuth @RequireAuth
public CommonResult<PageInfo<com.kexue.skills.entity.AccountTransaction>> getRechargePageList(@RequestBody AccountTransactionDto queryDto) { public CommonResult<PageInfo<AccountTransaction>> getRechargePageList(@RequestBody AccountTransactionDto queryDto) {
return CommonResult.success(this.accountService.getRechargePageList(queryDto)); return CommonResult.success(this.accountService.getRechargePageList(queryDto));
} }
@ -203,7 +200,7 @@ public class AccountController {
@Operation(summary = "分页查询赠送记录", description = "分页查询所有赠送记录,默认根据时间倒序") @Operation(summary = "分页查询赠送记录", description = "分页查询所有赠送记录,默认根据时间倒序")
@PostMapping("/getGiftPageList") @PostMapping("/getGiftPageList")
@RequireAuth @RequireAuth
public CommonResult<PageInfo<com.kexue.skills.entity.AccountTransaction>> getGiftPageList(@RequestBody AccountTransactionDto queryDto) { public CommonResult<PageInfo<AccountTransaction>> getGiftPageList(@RequestBody AccountTransactionDto queryDto) {
return CommonResult.success(this.accountService.getGiftPageList(queryDto)); return CommonResult.success(this.accountService.getGiftPageList(queryDto));
} }

View File

@ -1,12 +1,11 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.kexue.skills.annotation.Log; import art.kexue.sxwz.annotation.Log;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.AccountFrozen; import art.kexue.sxwz.entity.AccountFrozen;
import com.kexue.skills.entity.dto.AccountFrozenDto; import art.kexue.sxwz.entity.dto.AccountFrozenDto;
import com.kexue.skills.entity.dto.AccountReleaseDto; import art.kexue.sxwz.entity.dto.AccountReleaseDto;
import com.kexue.skills.service.AccountFrozenService; import art.kexue.sxwz.service.AccountFrozenService;
import com.kexue.skills.common.Result;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -71,3 +70,4 @@ public class AccountFrozenController {
} }
} }

View File

@ -1,8 +1,8 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.common.util.IDUtils; import art.kexue.sxwz.common.util.IDUtils;
import com.kexue.skills.config.CaptchaConfig; import art.kexue.sxwz.config.CaptchaConfig;
import com.wf.captcha.SpecCaptcha; import com.wf.captcha.SpecCaptcha;
import com.wf.captcha.base.Captcha; import com.wf.captcha.base.Captcha;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
@ -14,7 +14,6 @@ import javax.annotation.Resource;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.concurrent.TimeUnit;
/** /**
* 验证码控制器 * 验证码控制器

View File

@ -0,0 +1,162 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.ComputeQuota;
import art.kexue.sxwz.entity.dto.ComputeQuotaDto;
import art.kexue.sxwz.service.ComputeQuotaService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/api/computeQuota")
@Tag(name = "算力配额管理", description = "算力配额管理接口")
public class ComputeQuotaController {
@Resource
private ComputeQuotaService computeQuotaService;
@PostMapping
@Operation(summary = "新增配额", description = "创建算力配额记录")
public CommonResult<ComputeQuota> save(@RequestBody ComputeQuota quota) {
return CommonResult.success(computeQuotaService.save(quota));
}
@PutMapping("/{id}")
@Operation(summary = "更新配额", description = "更新算力配额信息")
public CommonResult<ComputeQuota> update(@PathVariable Long id, @RequestBody ComputeQuota quota) {
quota.setId(id);
return CommonResult.success(computeQuotaService.update(quota));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除配额", description = "删除算力配额")
public CommonResult<Void> delete(@PathVariable Long id) {
computeQuotaService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询配额详情", description = "根据ID查询配额详情")
public CommonResult<ComputeQuota> queryById(@PathVariable Long id) {
return CommonResult.success(computeQuotaService.queryById(id));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询配额", description = "分页查询算力配额列表")
public CommonResult<PageInfo<ComputeQuota>> getPageList(@RequestBody ComputeQuotaDto queryDto) {
return CommonResult.success(computeQuotaService.getPageList(queryDto));
}
@GetMapping("/total")
@Operation(summary = "获取总量统计", description = "获取所有算力的总分配、已使用、剩余统计")
public CommonResult<ComputeQuota> getTotalQuota() {
return CommonResult.success(computeQuotaService.getTotalQuota());
}
@GetMapping("/school")
@Operation(summary = "获取学校算力列表", description = "获取所有学校的算力配额列表")
public CommonResult<List<ComputeQuota>> getSchoolQuotaList() {
return CommonResult.success(computeQuotaService.queryBySubjectType(1));
}
@GetMapping("/college")
@Operation(summary = "获取学院算力列表", description = "获取所有学院的算力配额列表")
public CommonResult<List<ComputeQuota>> getCollegeQuotaList() {
return CommonResult.success(computeQuotaService.queryBySubjectType(2));
}
@PostMapping("/allocate")
@Operation(summary = "追加分配算力", description = "为学校或学院追加分配算力小时数(不存在则创建,存在则累加)")
public CommonResult<ComputeQuota> allocateQuota(@RequestBody AllocateRequest request) {
return CommonResult.success(computeQuotaService.allocateQuota(
request.getSubjectType(),
request.getSubjectId(),
request.getSubjectName(),
request.getHours()
));
}
@PostMapping("/deduct")
@Operation(summary = "扣除算力", description = "扣除已使用的算力小时数")
public CommonResult<Boolean> deductQuota(@RequestBody DeductRequest request) {
return CommonResult.success(computeQuotaService.addUsedHours(
request.getSubjectType(),
request.getSubjectId(),
request.getHours()
));
}
public static class AllocateRequest {
private Integer subjectType;
private Long subjectId;
private String subjectName;
private Long hours;
public Integer getSubjectType() {
return subjectType;
}
public void setSubjectType(Integer subjectType) {
this.subjectType = subjectType;
}
public Long getSubjectId() {
return subjectId;
}
public void setSubjectId(Long subjectId) {
this.subjectId = subjectId;
}
public String getSubjectName() {
return subjectName;
}
public void setSubjectName(String subjectName) {
this.subjectName = subjectName;
}
public Long getHours() {
return hours;
}
public void setHours(Long hours) {
this.hours = hours;
}
}
public static class DeductRequest {
private Integer subjectType;
private Long subjectId;
private Long hours;
public Integer getSubjectType() {
return subjectType;
}
public void setSubjectType(Integer subjectType) {
this.subjectType = subjectType;
}
public Long getSubjectId() {
return subjectId;
}
public void setSubjectId(Long subjectId) {
this.subjectId = subjectId;
}
public Long getHours() {
return hours;
}
public void setHours(Long hours) {
this.hours = hours;
}
}
}

View File

@ -0,0 +1,140 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduAttendance;
import art.kexue.sxwz.entity.EduAttendanceRecord;
import art.kexue.sxwz.entity.dto.EduAttendanceDto;
import art.kexue.sxwz.service.EduAttendanceService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/attendance")
@Tag(name = "考勤管理", description = "考勤管理接口")
public class EduAttendanceController {
@Resource
private EduAttendanceService eduAttendanceService;
@PostMapping
@Operation(summary = "新增考勤", description = "创建考勤记录")
public CommonResult<EduAttendance> save(@RequestBody EduAttendance attendance) {
return CommonResult.success(eduAttendanceService.save(attendance));
}
@PutMapping("/{id}")
@Operation(summary = "更新考勤", description = "更新考勤信息")
public CommonResult<EduAttendance> update(@PathVariable Long id, @RequestBody EduAttendance attendance) {
attendance.setId(id);
return CommonResult.success(eduAttendanceService.update(attendance));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除考勤", description = "删除考勤")
public CommonResult<Void> delete(@PathVariable Long id) {
eduAttendanceService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询考勤详情", description = "根据ID查询考勤详情")
public CommonResult<EduAttendance> queryById(@PathVariable Long id) {
return CommonResult.success(eduAttendanceService.queryById(id));
}
@GetMapping("/course/{courseId}")
@Operation(summary = "查询课程考勤列表", description = "根据课程ID查询考勤列表")
public CommonResult<List<EduAttendance>> queryByCourseId(@PathVariable Long courseId) {
return CommonResult.success(eduAttendanceService.queryByCourseId(courseId));
}
@GetMapping("/teacher/{teacherId}")
@Operation(summary = "查询教师考勤列表", description = "根据教师ID查询考勤列表")
public CommonResult<List<EduAttendance>> queryByTeacherId(@PathVariable Long teacherId) {
return CommonResult.success(eduAttendanceService.queryByTeacherId(teacherId));
}
@PostMapping("/{attendanceId}/record/{studentId}")
@Operation(summary = "记录考勤", description = "学生记录考勤")
public CommonResult<EduAttendanceRecord> recordAttendance(@PathVariable Long attendanceId,
@PathVariable Long studentId) {
return CommonResult.success(eduAttendanceService.recordAttendance(attendanceId, studentId));
}
@GetMapping("/record/{recordId}")
@Operation(summary = "查询考勤记录详情", description = "查询考勤记录详情")
public CommonResult<EduAttendanceRecord> queryRecordById(@PathVariable Long recordId) {
return CommonResult.success(eduAttendanceService.queryRecordById(recordId));
}
@GetMapping("/{attendanceId}/records")
@Operation(summary = "查询考勤记录列表", description = "查询考勤的所有记录")
public CommonResult<List<EduAttendanceRecord>> queryRecordsByAttendanceId(@PathVariable Long attendanceId) {
return CommonResult.success(eduAttendanceService.queryRecordsByAttendanceId(attendanceId));
}
@GetMapping("/student/{studentId}/records")
@Operation(summary = "查询学生考勤记录", description = "查询学生的所有考勤记录")
public CommonResult<List<EduAttendanceRecord>> queryRecordsByStudentId(@PathVariable Long studentId) {
return CommonResult.success(eduAttendanceService.queryRecordsByStudentId(studentId));
}
@PostMapping("/{attendanceId}/batch")
@Operation(summary = "批量创建考勤记录", description = "为考勤批量创建学生考勤记录")
public CommonResult<Void> batchCreateRecords(@PathVariable Long attendanceId,
@RequestBody List<Long> studentIds) {
eduAttendanceService.batchCreateRecords(attendanceId, studentIds);
return CommonResult.success(null);
}
@PostMapping("/create")
@Operation(summary = "创建上课签到", description = "创建新的上课签到,自动生成二维码")
public CommonResult<EduAttendance> createAttendance(
@Parameter(description = "学校ID") @RequestParam Long schoolId,
@Parameter(description = "课程ID") @RequestParam Long courseId,
@Parameter(description = "签到时长分钟默认30分钟") @RequestParam(required = false) Integer duration) {
return CommonResult.success(eduAttendanceService.createAttendance(schoolId, courseId, duration));
}
@GetMapping("/{attendanceId}/qrcode")
@Operation(summary = "生成签到二维码", description = "生成考勤签到的二维码图片Base64格式")
public CommonResult<Map<String, String>> generateQRCode(@PathVariable Long attendanceId) {
String qrCodeBase64 = eduAttendanceService.generateQRCode(attendanceId);
Map<String, String> result = new HashMap<>();
result.put("qrCode", qrCodeBase64);
return CommonResult.success(result);
}
@PostMapping("/scan")
@Operation(summary = "扫码签到", description = "学生扫描二维码进行签到")
public CommonResult<EduAttendanceRecord> scanQRCode(
@Parameter(description = "二维码内容") @RequestParam String qrCodeContent,
@Parameter(description = "学生ID") @RequestParam Long studentId) {
EduAttendanceRecord record = eduAttendanceService.scanQRCode(qrCodeContent, studentId);
if (record == null) {
return CommonResult.failed("签到失败,二维码无效或签到已结束");
}
return CommonResult.success(record);
}
@PostMapping("/{attendanceId}/close")
@Operation(summary = "关闭签到", description = "结束当前签到")
public CommonResult<Void> closeAttendance(@PathVariable Long attendanceId) {
eduAttendanceService.closeAttendance(attendanceId);
return CommonResult.success(null);
}
@PostMapping("/pageList")
@Operation(summary = "分页查询考勤", description = "分页查询考勤列表")
public CommonResult<PageInfo<EduAttendance>> getPageList(@RequestBody EduAttendanceDto queryDto) {
return CommonResult.success(eduAttendanceService.getPageList(queryDto));
}
}

View File

@ -0,0 +1,66 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduCollege;
import art.kexue.sxwz.entity.dto.EduCollegeDto;
import art.kexue.sxwz.service.EduCollegeService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/api/college")
@Tag(name = "学院管理", description = "学院信息管理接口")
public class EduCollegeController {
@Resource
private EduCollegeService eduCollegeService;
@PostMapping
@Operation(summary = "新增学院", description = "创建学院信息")
public CommonResult<EduCollege> save(@RequestBody EduCollege college) {
return CommonResult.success(eduCollegeService.save(college));
}
@PutMapping("/{id}")
@Operation(summary = "更新学院", description = "更新学院信息")
public CommonResult<EduCollege> update(@PathVariable Long id, @RequestBody EduCollege college) {
college.setId(id);
return CommonResult.success(eduCollegeService.update(college));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除学院", description = "删除学院(逻辑删除)")
public CommonResult<Void> delete(@PathVariable Long id) {
eduCollegeService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询学院详情", description = "根据ID查询学院详情")
public CommonResult<EduCollege> queryById(@PathVariable Long id) {
return CommonResult.success(eduCollegeService.queryById(id));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询学院", description = "分页查询学院列表")
public CommonResult<PageInfo<EduCollege>> getPageList(@RequestBody EduCollegeDto queryDto) {
return CommonResult.success(eduCollegeService.getPageList(queryDto));
}
@GetMapping("/list")
@Operation(summary = "获取所有学院", description = "获取所有学院列表")
public CommonResult<List<EduCollege>> getAllList() {
return CommonResult.success(eduCollegeService.queryAll());
}
@GetMapping("/name/{name}")
@Operation(summary = "根据名称查询学院", description = "根据学院名称查询学院信息")
public CommonResult<EduCollege> queryByName(@PathVariable String name) {
return CommonResult.success(eduCollegeService.queryByName(name));
}
}

View File

@ -0,0 +1,106 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduCourse;
import art.kexue.sxwz.entity.dto.EduCourseDto;
import art.kexue.sxwz.entity.request.BatchBindResultDto;
import art.kexue.sxwz.service.EduCourseService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.List;
@RestController
@RequestMapping("/api/course")
@Tag(name = "课程管理", description = "课程管理接口")
public class EduCourseController {
@Resource
private EduCourseService eduCourseService;
@PostMapping
@Operation(summary = "新增课程", description = "创建课程")
public CommonResult<EduCourse> save(@RequestBody EduCourse course) {
return CommonResult.success(eduCourseService.save(course));
}
@PutMapping("/{id}")
@Operation(summary = "更新课程", description = "更新课程信息")
public CommonResult<EduCourse> update(@PathVariable Long id, @RequestBody EduCourse course) {
course.setId(id);
return CommonResult.success(eduCourseService.update(course));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除课程", description = "删除课程")
public CommonResult<Void> delete(@PathVariable Long id) {
eduCourseService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询课程详情", description = "根据ID查询课程详情")
public CommonResult<EduCourse> queryById(@PathVariable Long id) {
return CommonResult.success(eduCourseService.queryById(id));
}
@GetMapping("/teacher/{teacherId}")
@Operation(summary = "查询教师课程列表", description = "根据教师ID查询课程列表")
public CommonResult<List<EduCourse>> queryByTeacherId(@PathVariable Long teacherId) {
return CommonResult.success(eduCourseService.queryByTeacherId(teacherId));
}
@GetMapping("/school/{schoolId}")
@Operation(summary = "查询学校课程列表", description = "根据学校ID查询课程列表")
public CommonResult<List<EduCourse>> queryBySchoolId(@PathVariable Long schoolId) {
return CommonResult.success(eduCourseService.queryBySchoolId(schoolId));
}
@GetMapping("/student/{studentId}")
@Operation(summary = "查询学生课程列表", description = "根据学生ID查询已选课程列表")
public CommonResult<List<EduCourse>> queryByStudentId(@PathVariable Long studentId) {
return CommonResult.success(eduCourseService.queryByStudentId(studentId));
}
@PostMapping("/{courseId}/student/{studentId}")
@Operation(summary = "添加学生到课程", description = "将学生添加到课程")
public CommonResult<Void> addStudent(@PathVariable Long courseId, @PathVariable Long studentId) {
eduCourseService.addStudent(courseId, studentId);
return CommonResult.success(null);
}
@DeleteMapping("/{courseId}/student/{studentId}")
@Operation(summary = "移除课程学生", description = "将学生从课程中移除")
public CommonResult<Void> removeStudent(@PathVariable Long courseId, @PathVariable Long studentId) {
eduCourseService.removeStudent(courseId, studentId);
return CommonResult.success(null);
}
@GetMapping("/{courseId}/student/{studentId}/exists")
@Operation(summary = "检查学生是否在课程中", description = "检查学生是否在课程中")
public CommonResult<Boolean> isStudentInCourse(@PathVariable Long courseId, @PathVariable Long studentId) {
return CommonResult.success(eduCourseService.isStudentInCourse(courseId, studentId));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询课程", description = "分页查询课程列表")
public CommonResult<PageInfo<EduCourse>> getPageList(@RequestBody EduCourseDto queryDto) {
return CommonResult.success(eduCourseService.getPageList(queryDto));
}
@PostMapping("/{courseId}/batchBindStudents")
@Operation(summary = "批量绑定学生到课程", description = "通过Excel表格批量绑定学生到课程。Excel格式第一列为学号或姓名从第二行开始为数据。")
public CommonResult<BatchBindResultDto> batchBindStudents(
@PathVariable Long courseId,
@Parameter(description = "Excel文件") @RequestParam("file") MultipartFile file,
@Parameter(description = "是否追加模式true-追加到现有学生false-覆盖现有学生)") @RequestParam(value = "append", defaultValue = "false") boolean append) throws IOException {
byte[] excelBytes = file.getBytes();
return CommonResult.success(eduCourseService.batchBindStudents(courseId, excelBytes, append));
}
}

View File

@ -0,0 +1,108 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduExam;
import art.kexue.sxwz.entity.EduExamPaper;
import art.kexue.sxwz.entity.dto.EduExamDto;
import art.kexue.sxwz.service.EduExamService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/exam")
@Tag(name = "考试管理", description = "考试管理接口")
public class EduExamController {
@Resource
private EduExamService eduExamService;
@PostMapping
@Operation(summary = "新增考试", description = "创建考试")
public CommonResult<EduExam> save(@RequestBody EduExam exam) {
return CommonResult.success(eduExamService.save(exam));
}
@PutMapping("/{id}")
@Operation(summary = "更新考试", description = "更新考试信息")
public CommonResult<EduExam> update(@PathVariable Long id, @RequestBody EduExam exam) {
exam.setId(id);
return CommonResult.success(eduExamService.update(exam));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除考试", description = "删除考试")
public CommonResult<Void> delete(@PathVariable Long id) {
eduExamService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询考试详情", description = "根据ID查询考试详情")
public CommonResult<EduExam> queryById(@PathVariable Long id) {
return CommonResult.success(eduExamService.queryById(id));
}
@GetMapping("/course/{courseId}")
@Operation(summary = "查询课程考试列表", description = "根据课程ID查询考试列表")
public CommonResult<List<EduExam>> queryByCourseId(@PathVariable Long courseId) {
return CommonResult.success(eduExamService.queryByCourseId(courseId));
}
@GetMapping("/teacher/{teacherId}")
@Operation(summary = "查询教师考试列表", description = "根据教师ID查询考试列表")
public CommonResult<List<EduExam>> queryByTeacherId(@PathVariable Long teacherId) {
return CommonResult.success(eduExamService.queryByTeacherId(teacherId));
}
@GetMapping("/student/{studentId}")
@Operation(summary = "查询学生考试列表", description = "根据学生ID查询考试列表")
public CommonResult<List<EduExam>> queryByStudentId(@PathVariable Long studentId) {
return CommonResult.success(eduExamService.queryByStudentId(studentId));
}
@PostMapping("/{parentExamId}/makeup")
@Operation(summary = "创建补考", description = "为指定考试创建补考")
public CommonResult<EduExam> createMakeupExam(@PathVariable Long parentExamId) {
return CommonResult.success(eduExamService.createMakeupExam(parentExamId));
}
@PostMapping("/{examId}/submit/{studentId}")
@Operation(summary = "提交考试", description = "学生提交考试")
public CommonResult<EduExamPaper> submitExam(@PathVariable Long examId,
@PathVariable Long studentId,
@RequestBody Map<String, String> body) {
return CommonResult.success(eduExamService.submitExam(examId, studentId, body.get("answer")));
}
@PutMapping("/paper/{paperId}/grade")
@Operation(summary = "批改考试", description = "批改考试答卷")
public CommonResult<EduExamPaper> gradeExam(@PathVariable Long paperId,
@RequestBody Map<String, Object> body) {
Double score = body.get("score") != null ? ((Number) body.get("score")).doubleValue() : null;
return CommonResult.success(eduExamService.gradeExam(paperId, score));
}
@GetMapping("/paper/{paperId}")
@Operation(summary = "查询答卷详情", description = "查询考试答卷详情")
public CommonResult<EduExamPaper> queryPaperById(@PathVariable Long paperId) {
return CommonResult.success(eduExamService.queryPaperById(paperId));
}
@GetMapping("/{examId}/papers")
@Operation(summary = "查询考试答卷列表", description = "查询考试的所有答卷")
public CommonResult<List<EduExamPaper>> queryPapersByExamId(@PathVariable Long examId) {
return CommonResult.success(eduExamService.queryPapersByExamId(examId));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询考试", description = "分页查询考试列表")
public CommonResult<PageInfo<EduExam>> getPageList(@RequestBody EduExamDto queryDto) {
return CommonResult.success(eduExamService.getPageList(queryDto));
}
}

View File

@ -0,0 +1,96 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduExcellentWork;
import art.kexue.sxwz.entity.dto.EduExcellentWorkDto;
import art.kexue.sxwz.service.EduExcellentWorkService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/excellent-work")
@Tag(name = "优秀作品", description = "优秀作品管理接口")
public class EduExcellentWorkController {
@Resource
private EduExcellentWorkService eduExcellentWorkService;
@PostMapping
@Operation(summary = "新增优秀作品", description = "创建优秀作品记录")
public CommonResult<EduExcellentWork> save(@RequestBody EduExcellentWork work) {
return CommonResult.success(eduExcellentWorkService.save(work));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除优秀作品", description = "删除优秀作品")
public CommonResult<Void> delete(@PathVariable Long id) {
eduExcellentWorkService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询优秀作品详情", description = "根据ID查询优秀作品详情")
public CommonResult<EduExcellentWork> queryById(@PathVariable Long id) {
return CommonResult.success(eduExcellentWorkService.queryById(id));
}
@GetMapping("/school/{schoolId}")
@Operation(summary = "查询学校优秀作品列表", description = "根据学校ID查询优秀作品列表")
public CommonResult<List<EduExcellentWork>> queryBySchoolId(@PathVariable Long schoolId) {
return CommonResult.success(eduExcellentWorkService.queryBySchoolId(schoolId));
}
@GetMapping("/student/{studentId}")
@Operation(summary = "查询学生优秀作品列表", description = "根据学生ID查询优秀作品列表")
public CommonResult<List<EduExcellentWork>> queryByStudentId(@PathVariable Long studentId) {
return CommonResult.success(eduExcellentWorkService.queryByStudentId(studentId));
}
@PostMapping("/{workId}/like/{userId}")
@Operation(summary = "点赞", description = "为优秀作品点赞")
public CommonResult<Void> addLike(@PathVariable Long workId, @PathVariable Long userId) {
eduExcellentWorkService.addLike(workId, userId);
return CommonResult.success(null);
}
@DeleteMapping("/{workId}/like/{userId}")
@Operation(summary = "取消点赞", description = "取消对优秀作品的点赞")
public CommonResult<Void> removeLike(@PathVariable Long workId, @PathVariable Long userId) {
eduExcellentWorkService.removeLike(workId, userId);
return CommonResult.success(null);
}
@GetMapping("/{workId}/like/{userId}/exists")
@Operation(summary = "检查是否已点赞", description = "检查用户是否已点赞")
public CommonResult<Boolean> hasLiked(@PathVariable Long workId, @PathVariable Long userId) {
return CommonResult.success(eduExcellentWorkService.hasLiked(workId, userId));
}
@GetMapping("/{workId}/like-count")
@Operation(summary = "查询点赞数", description = "查询优秀作品的点赞数")
public CommonResult<Integer> countLikes(@PathVariable Long workId) {
return CommonResult.success(eduExcellentWorkService.countLikes(workId));
}
@PostMapping("/mark")
@Operation(summary = "标记为优秀作品", description = "将作业或考试答卷标记为优秀作品")
public CommonResult<EduExcellentWork> markAsExcellent(@RequestBody Map<String, Object> body) {
Long submitId = ((Number) body.get("submitId")).longValue();
Integer workType = ((Number) body.get("workType")).intValue();
Double score = body.get("score") != null ? ((Number) body.get("score")).doubleValue() : null;
String comment = (String) body.get("comment");
return CommonResult.success(eduExcellentWorkService.markAsExcellent(submitId, workType, score, comment));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询优秀作品", description = "分页查询优秀作品列表")
public CommonResult<PageInfo<EduExcellentWork>> getPageList(@RequestBody EduExcellentWorkDto queryDto) {
return CommonResult.success(eduExcellentWorkService.getPageList(queryDto));
}
}

View File

@ -0,0 +1,103 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduHomework;
import art.kexue.sxwz.entity.EduHomeworkSubmit;
import art.kexue.sxwz.entity.dto.EduHomeworkDto;
import art.kexue.sxwz.service.EduHomeworkService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/api/homework")
@Tag(name = "作业管理", description = "作业管理接口")
public class EduHomeworkController {
@Resource
private EduHomeworkService eduHomeworkService;
@PostMapping
@Operation(summary = "新增作业", description = "创建作业")
public CommonResult<EduHomework> save(@RequestBody EduHomework homework) {
return CommonResult.success(eduHomeworkService.save(homework));
}
@PutMapping("/{id}")
@Operation(summary = "更新作业", description = "更新作业信息")
public CommonResult<EduHomework> update(@PathVariable Long id, @RequestBody EduHomework homework) {
homework.setId(id);
return CommonResult.success(eduHomeworkService.update(homework));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除作业", description = "删除作业")
public CommonResult<Boolean> delete(@PathVariable Long id) {
eduHomeworkService.delete(id);
return CommonResult.success(true);
}
@GetMapping("/{id}")
@Operation(summary = "查询作业详情", description = "根据ID查询作业详情")
public CommonResult<EduHomework> queryById(@PathVariable Long id) {
return CommonResult.success(eduHomeworkService.queryById(id));
}
@GetMapping("/course/{courseId}")
@Operation(summary = "查询课程作业列表", description = "根据课程ID查询作业列表")
public CommonResult<List<EduHomework>> queryByCourseId(@PathVariable Long courseId) {
return CommonResult.success(eduHomeworkService.queryByCourseId(courseId));
}
@GetMapping("/teacher/{teacherId}")
@Operation(summary = "查询教师作业列表", description = "根据教师ID查询作业列表")
public CommonResult<List<EduHomework>> queryByTeacherId(@PathVariable Long teacherId) {
return CommonResult.success(eduHomeworkService.queryByTeacherId(teacherId));
}
@GetMapping("/student/{studentId}")
@Operation(summary = "查询学生作业列表", description = "根据学生ID查询作业列表")
public CommonResult<List<EduHomework>> queryByStudentId(@PathVariable Long studentId) {
return CommonResult.success(eduHomeworkService.queryByStudentId(studentId));
}
@PostMapping("/{homeworkId}/submit/{studentId}")
@Operation(summary = "提交作业", description = "学生提交作业")
public CommonResult<EduHomeworkSubmit> submitHomework(@PathVariable Long homeworkId,
@PathVariable Long studentId,
@RequestBody Map<String, String> body) {
return CommonResult.success(eduHomeworkService.submitHomework(homeworkId, studentId, body.get("answer")));
}
@PutMapping("/submit/{submitId}/grade")
@Operation(summary = "批改作业", description = "教师批改作业")
public CommonResult<EduHomeworkSubmit> gradeHomework(@PathVariable Long submitId,
@RequestBody Map<String, Object> body) {
Double score = body.get("score") != null ? ((Number) body.get("score")).doubleValue() : null;
String comment = (String) body.get("comment");
return CommonResult.success(eduHomeworkService.gradeHomework(submitId, score, comment));
}
@GetMapping("/submit/{submitId}")
@Operation(summary = "查询作业提交详情", description = "查询作业提交详情")
public CommonResult<EduHomeworkSubmit> querySubmitById(@PathVariable Long submitId) {
return CommonResult.success(eduHomeworkService.querySubmitById(submitId));
}
@GetMapping("/{homeworkId}/submits")
@Operation(summary = "查询作业提交列表", description = "查询作业的所有提交")
public CommonResult<List<EduHomeworkSubmit>> querySubmitsByHomeworkId(@PathVariable Long homeworkId) {
return CommonResult.success(eduHomeworkService.querySubmitsByHomeworkId(homeworkId));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询作业", description = "分页查询作业列表")
public CommonResult<PageInfo<EduHomework>> getPageList(@RequestBody EduHomeworkDto queryDto) {
return CommonResult.success(eduHomeworkService.getPageList(queryDto));
}
}

View File

@ -0,0 +1,77 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.annotation.RequireRole;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduSchool;
import art.kexue.sxwz.entity.dto.EduSchoolDto;
import art.kexue.sxwz.service.EduSchoolService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/api/school")
@Tag(name = "学校管理", description = "学校信息管理接口")
public class EduSchoolController {
@Resource
private EduSchoolService eduSchoolService;
@PostMapping
@Operation(summary = "新增学校", description = "创建学校信息")
@RequireRole("SUPER1")
public CommonResult<EduSchool> save(@RequestBody EduSchool school) {
return CommonResult.success(eduSchoolService.save(school));
}
@PutMapping("/{id}")
@Operation(summary = "更新学校", description = "更新学校信息")
@RequireRole("SUPER1")
public CommonResult<EduSchool> update(@PathVariable Long id, @RequestBody EduSchool school) {
school.setId(id);
return CommonResult.success(eduSchoolService.update(school));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除学校", description = "删除学校信息")
@RequireRole("SUPER1")
public CommonResult<Void> delete(@PathVariable Long id) {
eduSchoolService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询学校详情", description = "根据ID查询学校信息")
public CommonResult<EduSchool> queryById(@PathVariable Long id) {
return CommonResult.success(eduSchoolService.queryById(id));
}
@GetMapping
@Operation(summary = "查询学校列表", description = "查询所有学校信息")
public CommonResult<List<EduSchool>> queryList() {
return CommonResult.success(eduSchoolService.queryAll());
}
@GetMapping("/status/{status}")
@Operation(summary = "根据状态查询学校", description = "根据状态查询学校列表")
public CommonResult<List<EduSchool>> queryListByStatus(@PathVariable Integer status) {
return CommonResult.success(eduSchoolService.queryListByStatus(status));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询学校", description = "分页查询学校列表")
public CommonResult<PageInfo<EduSchool>> getPageList(@RequestBody EduSchoolDto queryDto) {
return CommonResult.success(eduSchoolService.getPageList(queryDto));
}
@PutMapping("/{id}/status/{status}")
@Operation(summary = "变更学校状态", description = "启用或禁用学校")
@RequireRole("SUPER1")
public CommonResult<EduSchool> updateStatus(@PathVariable Long id, @PathVariable Integer status) {
return CommonResult.success(eduSchoolService.updateStatus(id, status));
}
}

View File

@ -0,0 +1,92 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduStudent;
import art.kexue.sxwz.entity.dto.EduStudentDto;
import art.kexue.sxwz.service.EduStudentService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import cn.dev33.satoken.stp.StpUtil;
import java.util.List;
@RestController
@RequestMapping("/api/student")
@Tag(name = "学生管理", description = "学生扩展信息管理接口")
public class EduStudentController {
@Resource
private EduStudentService eduStudentService;
@PostMapping
@Operation(summary = "新增学生", description = "创建学生扩展信息")
public CommonResult<EduStudent> save(@RequestBody EduStudent student) {
return CommonResult.success(eduStudentService.save(student));
}
@PutMapping("/{id}")
@Operation(summary = "更新学生", description = "更新学生扩展信息")
public CommonResult<EduStudent> update(@PathVariable Long id, @RequestBody EduStudent student) {
student.setId(id);
return CommonResult.success(eduStudentService.update(student));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除学生", description = "删除学生扩展信息")
public CommonResult<Void> delete(@PathVariable Long id) {
eduStudentService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询学生详情", description = "根据ID查询学生扩展信息")
public CommonResult<EduStudent> queryById(@PathVariable Long id) {
return CommonResult.success(eduStudentService.queryById(id));
}
@GetMapping("/user/{userId}")
@Operation(summary = "根据用户ID查询学生", description = "根据用户ID查询学生扩展信息")
public CommonResult<EduStudent> queryByUserId(@PathVariable Long userId) {
return CommonResult.success(eduStudentService.queryByUserId(userId));
}
@GetMapping("/user")
@Operation(summary = "查询当前用户学生信息", description = "查询当前登录用户的学生扩展信息")
public CommonResult<EduStudent> queryCurrentUserStudent() {
Long userId = StpUtil.getLoginIdAsLong();
return CommonResult.success(eduStudentService.queryByUserId(userId));
}
@GetMapping("/school/{schoolId}")
@Operation(summary = "查询学校学生列表", description = "根据学校ID查询学生列表")
public CommonResult<List<EduStudent>> queryListBySchoolId(@PathVariable Long schoolId) {
return CommonResult.success(eduStudentService.queryListBySchoolId(schoolId));
}
@GetMapping("/college/{collegeId}")
@Operation(summary = "查询学院学生列表", description = "根据学院ID查询学生列表")
public CommonResult<List<EduStudent>> queryListByCollegeId(@PathVariable Long collegeId) {
return CommonResult.success(eduStudentService.queryListByCollegeId(collegeId));
}
@GetMapping("/activation/{code}")
@Operation(summary = "根据激活码查询学生", description = "根据激活码查询未绑定的学生信息")
public CommonResult<EduStudent> queryByActivationCode(@PathVariable String code) {
return CommonResult.success(eduStudentService.queryByActivationCode(code));
}
@PostMapping("/{studentId}/bind/{userId}")
@Operation(summary = "绑定用户", description = "将学生信息绑定到用户账号")
public CommonResult<EduStudent> bindUser(@PathVariable Long studentId, @PathVariable Long userId) {
return CommonResult.success(eduStudentService.bindUser(studentId, userId));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询学生", description = "分页查询学生列表")
public CommonResult<PageInfo<EduStudent>> getPageList(@RequestBody EduStudentDto queryDto) {
return CommonResult.success(eduStudentService.getPageList(queryDto));
}
}

View File

@ -0,0 +1,92 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.entity.EduTeacher;
import art.kexue.sxwz.entity.dto.EduTeacherDto;
import art.kexue.sxwz.service.EduTeacherService;
import com.github.pagehelper.PageInfo;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import cn.dev33.satoken.stp.StpUtil;
import java.util.List;
@RestController
@RequestMapping("/api/teacher")
@Tag(name = "教师管理", description = "教师扩展信息管理接口")
public class EduTeacherController {
@Resource
private EduTeacherService eduTeacherService;
@PostMapping
@Operation(summary = "新增教师", description = "创建教师扩展信息")
public CommonResult<EduTeacher> save(@RequestBody EduTeacher teacher) {
return CommonResult.success(eduTeacherService.save(teacher));
}
@PutMapping("/{id}")
@Operation(summary = "更新教师", description = "更新教师扩展信息")
public CommonResult<EduTeacher> update(@PathVariable Long id, @RequestBody EduTeacher teacher) {
teacher.setId(id);
return CommonResult.success(eduTeacherService.update(teacher));
}
@DeleteMapping("/{id}")
@Operation(summary = "删除教师", description = "删除教师扩展信息")
public CommonResult<Void> delete(@PathVariable Long id) {
eduTeacherService.delete(id);
return CommonResult.success(null);
}
@GetMapping("/{id}")
@Operation(summary = "查询教师详情", description = "根据ID查询教师扩展信息")
public CommonResult<EduTeacher> queryById(@PathVariable Long id) {
return CommonResult.success(eduTeacherService.queryById(id));
}
@GetMapping("/user/{userId}")
@Operation(summary = "根据用户ID查询教师", description = "根据用户ID查询教师扩展信息")
public CommonResult<EduTeacher> queryByUserId(@PathVariable Long userId) {
return CommonResult.success(eduTeacherService.queryByUserId(userId));
}
@GetMapping("/user")
@Operation(summary = "查询当前用户教师信息", description = "查询当前登录用户的教师扩展信息")
public CommonResult<EduTeacher> queryCurrentUserTeacher() {
Long userId = StpUtil.getLoginIdAsLong();
return CommonResult.success(eduTeacherService.queryByUserId(userId));
}
@GetMapping("/school/{schoolId}")
@Operation(summary = "查询学校教师列表", description = "根据学校ID查询教师列表")
public CommonResult<List<EduTeacher>> queryListBySchoolId(@PathVariable Long schoolId) {
return CommonResult.success(eduTeacherService.queryListBySchoolId(schoolId));
}
@GetMapping("/college/{collegeId}")
@Operation(summary = "查询学院教师列表", description = "根据学院ID查询教师列表")
public CommonResult<List<EduTeacher>> queryListByCollegeId(@PathVariable Long collegeId) {
return CommonResult.success(eduTeacherService.queryListByCollegeId(collegeId));
}
@GetMapping("/activation/{code}")
@Operation(summary = "根据激活码查询教师", description = "根据激活码查询未绑定的教师信息")
public CommonResult<EduTeacher> queryByActivationCode(@PathVariable String code) {
return CommonResult.success(eduTeacherService.queryByActivationCode(code));
}
@PostMapping("/{teacherId}/bind/{userId}")
@Operation(summary = "绑定用户", description = "将教师信息绑定到用户账号")
public CommonResult<EduTeacher> bindUser(@PathVariable Long teacherId, @PathVariable Long userId) {
return CommonResult.success(eduTeacherService.bindUser(teacherId, userId));
}
@PostMapping("/pageList")
@Operation(summary = "分页查询教师", description = "分页查询教师列表")
public CommonResult<PageInfo<EduTeacher>> getPageList(@RequestBody EduTeacherDto queryDto) {
return CommonResult.success(eduTeacherService.getPageList(queryDto));
}
}

View File

@ -1,13 +1,13 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.kexue.skills.annotation.Log; import art.kexue.sxwz.annotation.Log;
import com.kexue.skills.annotation.PreventDuplicateSubmission; import art.kexue.sxwz.annotation.PreventDuplicateSubmission;
import com.kexue.skills.common.CacheManager; import art.kexue.sxwz.common.CacheManager;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.request.LoginDto; import art.kexue.sxwz.entity.request.LoginDto;
import com.kexue.skills.entity.request.LoginUserDto; import art.kexue.sxwz.entity.request.LoginUserDto;
import com.kexue.skills.entity.request.PhoneLoginDto; import art.kexue.sxwz.entity.request.PhoneLoginDto;
import com.kexue.skills.service.SysUserService; import art.kexue.sxwz.service.SysUserService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -137,3 +137,4 @@ public class LoginController {
} }

View File

@ -1,10 +1,10 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.kexue.skills.entity.ModelPrice; import art.kexue.sxwz.entity.ModelPrice;
import com.kexue.skills.entity.dto.ModelPriceDto; import art.kexue.sxwz.entity.dto.ModelPriceDto;
import com.kexue.skills.service.ModelPriceService; import art.kexue.sxwz.service.ModelPriceService;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -111,3 +111,4 @@ public class ModelPriceController {
} }
} }

View File

@ -1,12 +1,12 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.kexue.skills.annotation.RequireAuth; import art.kexue.sxwz.annotation.RequireAuth;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.PackageConfig; import art.kexue.sxwz.entity.PackageConfig;
import com.kexue.skills.entity.base.IdDto; import art.kexue.sxwz.entity.base.IdDto;
import com.kexue.skills.entity.dto.PackageConfigDto; import art.kexue.sxwz.entity.dto.PackageConfigDto;
import com.kexue.skills.service.PackageConfigService; import art.kexue.sxwz.service.PackageConfigService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -119,3 +119,4 @@ public class PackageConfigController {
} }
} }

View File

@ -1,4 +1,4 @@
//package com.kexue.skills.controller; //package art.kexue.sxwz.controller;
// //
//import lombok.extern.slf4j.Slf4j; //import lombok.extern.slf4j.Slf4j;
//import org.springframework.stereotype.Controller; //import org.springframework.stereotype.Controller;
@ -90,3 +90,4 @@
// } // }
// //
//} //}

View File

@ -1,9 +1,9 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.PaymentOrder; import art.kexue.sxwz.entity.PaymentOrder;
import com.kexue.skills.service.PayService; import art.kexue.sxwz.service.PayService;
import com.kexue.skills.service.PaymentOrderService; import art.kexue.sxwz.service.PaymentOrderService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -12,8 +12,8 @@ import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletRequest;
import com.kexue.skills.entity.dto.OrderStatusDto; import art.kexue.sxwz.entity.dto.OrderStatusDto;
import com.kexue.skills.entity.dto.OrderStatusQueryDto; import art.kexue.sxwz.entity.dto.OrderStatusQueryDto;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -190,3 +190,4 @@ public class PayController {
} }
} }
} }

View File

@ -1,11 +1,11 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.kexue.skills.annotation.RequireAuth; import art.kexue.sxwz.annotation.RequireAuth;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.PaymentOrder; import art.kexue.sxwz.entity.PaymentOrder;
import com.kexue.skills.entity.dto.PaymentOrderDto; import art.kexue.sxwz.entity.dto.PaymentOrderDto;
import com.kexue.skills.service.PaymentOrderService; import art.kexue.sxwz.service.PaymentOrderService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter; import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;

View File

@ -0,0 +1,52 @@
package art.kexue.sxwz.controller;
import art.kexue.sxwz.common.CommonResult;
import art.kexue.sxwz.utils.QRCodeUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@RestController
@RequestMapping("/api/qrcode")
@CrossOrigin(origins = "*")
@Tag(name = "二维码 Api")
public class QRCodeController {
@GetMapping("/generate")
@Operation(summary = "生成二维码图片", description = "生成二维码图片返回PNG格式图片")
public ResponseEntity<byte[]> generateQRCode(
@Parameter(description = "二维码内容文本或URL") @RequestParam("content") String content,
@Parameter(description = "二维码宽度默认300") @RequestParam(value = "width", defaultValue = "300") int width,
@Parameter(description = "二维码高度默认300") @RequestParam(value = "height", defaultValue = "300") int height) {
byte[] qrCodeBytes = QRCodeUtil.generateQRCode(content, width, height);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.IMAGE_PNG);
headers.setContentLength(qrCodeBytes.length);
return ResponseEntity.ok().headers(headers).body(qrCodeBytes);
}
@GetMapping("/generate/base64")
@Operation(summary = "生成二维码Base64", description = "生成二维码并返回Base64编码字符串")
public CommonResult<Map<String, String>> generateQRCodeBase64(
@Parameter(description = "二维码内容文本或URL") @RequestParam("content") String content,
@Parameter(description = "二维码宽度默认300") @RequestParam(value = "width", defaultValue = "300") int width,
@Parameter(description = "二维码高度默认300") @RequestParam(value = "height", defaultValue = "300") int height) {
String base64Image = QRCodeUtil.generateQRCodeBase64(content, width, height);
Map<String, String> result = new HashMap<>();
result.put("qrCodeImage", base64Image);
return CommonResult.success(result);
}
}

View File

@ -1,8 +1,8 @@
package com.kexue.skills.controller; package art.kexue.sxwz.controller;
import com.kexue.skills.common.CommonResult; import art.kexue.sxwz.common.CommonResult;
import com.kexue.skills.entity.dto.SessionDto; import art.kexue.sxwz.entity.dto.SessionDto;
import com.kexue.skills.service.SysUserService; import art.kexue.sxwz.service.SysUserService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
@ -39,3 +39,4 @@ public class SessionController {
return CommonResult.success(sessionDto); return CommonResult.success(sessionDto);
} }
} }

Some files were not shown because too many files have changed in this diff Show More