v0.2.14 前端代码优化
parent
260a85d8f3
commit
6522a9cf05
|
|
@ -0,0 +1,20 @@
|
|||
# SAMS系统文档
|
||||
|
||||
本目录包含SAMS系统的相关文档。
|
||||
|
||||
## 文档结构
|
||||
|
||||
- `api.md`: API接口文档,包含所有后端接口的详细说明
|
||||
- 认证接口
|
||||
- 系统管理接口
|
||||
- 活动管理接口
|
||||
- 社团管理接口
|
||||
- 通用说明
|
||||
|
||||
## 文档更新
|
||||
|
||||
本文档会随着系统开发持续更新。如果您发现文档中的任何问题或有改进建议,请及时反馈。
|
||||
|
||||
## 文档格式
|
||||
|
||||
所有文档均使用Markdown格式编写,可以使用任何支持Markdown的编辑器或查看器阅读。
|
||||
|
|
@ -0,0 +1,961 @@
|
|||
# SAMS系统接口文档
|
||||
|
||||
## 1. 认证接口 (AuthController)
|
||||
|
||||
### 1.1 用户登录
|
||||
- **接口路径**: `/login`
|
||||
- **请求方式**: POST
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"username": "string", // 用户名/学号/邮箱
|
||||
"password": "string" // 密码
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "登录成功",
|
||||
"data": "JWT令牌"
|
||||
}
|
||||
```
|
||||
|
||||
## 2. 系统管理接口 (sys)
|
||||
|
||||
### 2.1 用户管理 (UserController)
|
||||
- **接口路径**: `/api/user`
|
||||
- **功能**: 普通用户管理相关接口
|
||||
|
||||
#### 2.1.1 修改密码
|
||||
- **接口路径**: `/api/user/change-password`
|
||||
- **请求方式**: PUT
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"userId": "number", // 用户ID
|
||||
"oldPassword": "string", // 旧密码
|
||||
"newPassword": "string" // 新密码
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "密码修改成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.2 更新个人信息
|
||||
- **接口路径**: `/api/user/profile`
|
||||
- **请求方式**: PUT
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"userId": "number", // 用户ID
|
||||
"nickname": "string", // 昵称
|
||||
"email": "string", // 邮箱
|
||||
"avatar": "string" // 头像URL
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "个人信息更新成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.3 获取用户详情
|
||||
- **接口路径**: `/api/user/{userId}`
|
||||
- **请求方式**: GET
|
||||
- **路径参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"userId": "number",
|
||||
"username": "string",
|
||||
"nickname": "string",
|
||||
"email": "string",
|
||||
"avatar": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.1.4 上传头像
|
||||
- **接口路径**: `/api/user/avatar`
|
||||
- **请求方式**: POST
|
||||
- **请求参数**:
|
||||
- file: 头像文件(MultipartFile)
|
||||
- **响应结果**: 返回上传后的头像URL字符串
|
||||
|
||||
### 2.2 管理员用户管理 (AdminUserController)
|
||||
- **接口路径**: `/api/admin/user`
|
||||
- **功能**: 管理员用户管理相关接口
|
||||
|
||||
#### 2.2.1 批量导入用户
|
||||
- **接口路径**: `/api/admin/user/import`
|
||||
- **请求方式**: POST
|
||||
- **请求参数**:
|
||||
```json
|
||||
[
|
||||
{
|
||||
"username": "string",
|
||||
"password": "string",
|
||||
"email": "string",
|
||||
"role": "string"
|
||||
}
|
||||
]
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "用户导入成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.2 查询用户列表
|
||||
- **接口路径**: `/api/admin/user/list`
|
||||
- **请求方式**: GET
|
||||
- **请求参数**:
|
||||
- keyword: 关键字(可选,用于搜索用户名、学号、邮箱)
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"userId": "number",
|
||||
"username": "string",
|
||||
"email": "string",
|
||||
"role": "string",
|
||||
"status": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.3 更新用户信息
|
||||
- **接口路径**: `/api/admin/user/update`
|
||||
- **请求方式**: PUT
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"userId": "number",
|
||||
"role": "string",
|
||||
"status": "string",
|
||||
"password": "string"
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "用户信息更新成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.4 重置用户密码
|
||||
- **接口路径**: `/api/admin/user/reset-password/{userId}`
|
||||
- **请求方式**: PUT
|
||||
- **路径参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "密码已重置为 123456",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.5 封禁用户
|
||||
- **接口路径**: `/api/admin/user/ban/{userId}`
|
||||
- **请求方式**: PUT
|
||||
- **路径参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "用户已封禁",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 2.2.6 删除用户
|
||||
- **接口路径**: `/api/admin/user/{userId}`
|
||||
- **请求方式**: DELETE
|
||||
- **路径参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "用户已删除",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 2.3 文件管理 (FileController)
|
||||
- **接口路径**: `/api/file`
|
||||
- **功能**: 文件上传下载相关接口
|
||||
- **说明**: 该模块目前为空,待实现
|
||||
|
||||
## 3. 活动管理接口 (ams)
|
||||
|
||||
### 3.1 活动管理 (ActivityController)
|
||||
- **接口路径**: `/api/admin/activity`
|
||||
- **功能**: 活动创建、修改、查询等
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 3.1.1 创建活动
|
||||
- **接口路径**: `/api/admin/activity/create`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: USER, CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"title": "string", // 活动标题
|
||||
"description": "string", // 活动描述
|
||||
"startTime": "string", // 开始时间
|
||||
"endTime": "string", // 结束时间
|
||||
"location": "string", // 活动地点
|
||||
"maxParticipants": "number", // 最大参与人数
|
||||
"clubId": "number" // 主办社团ID
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "活动创建成功,等待审批",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.1.2 取消活动
|
||||
- **接口路径**: `/api/admin/activity/cancel`
|
||||
- **请求方式**: PUT
|
||||
- **权限要求**: CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "活动已取消",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 审批管理 (ApprovalController)
|
||||
- **接口路径**: `/api/admin/approval`
|
||||
- **功能**: 活动审批相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 3.2.1 审批通过
|
||||
- **接口路径**: `/api/admin/approval/approve`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: CLUB_ADMIN, DEPARTMENT_ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
- apprId: 审批ID
|
||||
- approverId: 审批人ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "审批已通过",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.2.2 审批拒绝
|
||||
- **接口路径**: `/api/admin/approval/reject`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: CLUB_ADMIN, DEPARTMENT_ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
- apprId: 审批ID
|
||||
- reason: 拒绝原因
|
||||
- approverId: 审批人ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "审批已拒绝",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 评论管理 (CommentController)
|
||||
- **接口路径**: `/api/comment`
|
||||
- **功能**: 活动评论相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 3.3.1 发表评论
|
||||
- **接口路径**: `/api/comment/add`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- userId: 用户ID
|
||||
- actId: 活动ID
|
||||
- content: 评论内容
|
||||
- parentCommentId: 父评论ID(可选,用于回复)
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "评论成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3.2 删除评论
|
||||
- **接口路径**: `/api/comment/delete`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: USER, ADMIN
|
||||
- **请求参数**:
|
||||
- commentId: 评论ID
|
||||
- userId: 用户ID
|
||||
- isAdmin: 是否为管理员
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "评论已删除",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3.3 获取活动评论列表
|
||||
- **接口路径**: `/api/comment/list`
|
||||
- **请求方式**: GET
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"commentId": "number",
|
||||
"userId": "number",
|
||||
"content": "string",
|
||||
"createTime": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.3.4 获取评论回复
|
||||
- **接口路径**: `/api/comment/replies`
|
||||
- **请求方式**: GET
|
||||
- **请求参数**:
|
||||
- parentCommentId: 父评论ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"commentId": "number",
|
||||
"userId": "number",
|
||||
"content": "string",
|
||||
"createTime": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.4 反应管理 (ReactionController)
|
||||
- **接口路径**: `/api/reaction`
|
||||
- **功能**: 活动反应(点赞等)相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 3.4.1 添加反应
|
||||
- **接口路径**: `/api/reaction/add`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- userId: 用户ID
|
||||
- reactionType: 反应类型(LIKE/DISLIKE)
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.4.2 取消反应
|
||||
- **接口路径**: `/api/reaction/remove`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "已取消点赞/点踩",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.4.3 获取反应统计
|
||||
- **接口路径**: `/api/reaction/stats`
|
||||
- **请求方式**: GET
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"likes": "number",
|
||||
"dislikes": "number"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.4.4 获取活动反应列表
|
||||
- **接口路径**: `/api/reaction/list`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"reactionId": "number",
|
||||
"userId": "number",
|
||||
"reactionType": "string",
|
||||
"createTime": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.5 报名管理 (RegistrationController)
|
||||
- **接口路径**: `/api/registration`
|
||||
- **功能**: 活动报名相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 3.5.1 报名活动
|
||||
- **接口路径**: `/api/registration/register`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "报名成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.5.2 取消报名
|
||||
- **接口路径**: `/api/registration/cancel`
|
||||
- **请求方式**: PUT
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "报名已取消",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.5.3 活动签到
|
||||
- **接口路径**: `/api/registration/attend`
|
||||
- **请求方式**: PUT
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "签到成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.5.4 获取我的报名列表
|
||||
- **接口路径**: `/api/registration/my-registrations`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: USER
|
||||
- **请求参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"registrationId": "number",
|
||||
"actId": "number",
|
||||
"userId": "number",
|
||||
"status": "string",
|
||||
"createTime": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 3.5.5 获取活动报名列表
|
||||
- **接口路径**: `/api/registration/list`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **请求参数**:
|
||||
- actId: 活动ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"registrationId": "number",
|
||||
"actId": "number",
|
||||
"userId": "number",
|
||||
"status": "string",
|
||||
"createTime": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 社团管理接口 (sms)
|
||||
|
||||
### 4.1 社团管理 (ClubController)
|
||||
- **接口路径**: `/api/admin/club`
|
||||
- **功能**: 社团基本信息管理
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 4.1.1 添加社团
|
||||
- **接口路径**: `/api/admin/club/add`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "string", // 社团名称
|
||||
"description": "string", // 社团描述
|
||||
"collegeId": "number", // 所属学院ID
|
||||
"type": "string" // 社团类型
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "社团添加成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.2 更新社团信息
|
||||
- **接口路径**: `/api/admin/club/update`
|
||||
- **请求方式**: PUT
|
||||
- **权限要求**: ADMIN, CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"clubId": "number", // 社团ID
|
||||
"name": "string", // 社团名称
|
||||
"description": "string", // 社团描述
|
||||
"type": "string" // 社团类型
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "社团信息更新成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.3 删除社团
|
||||
- **接口路径**: `/api/admin/club/delete/{clubId}`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **路径参数**:
|
||||
- clubId: 社团ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "社团删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.4 获取社团详情
|
||||
- **接口路径**: `/api/admin/club/{clubId}`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN, CLUB_ADMIN
|
||||
- **路径参数**:
|
||||
- clubId: 社团ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"clubId": "number",
|
||||
"name": "string",
|
||||
"description": "string",
|
||||
"collegeId": "number",
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.1.5 查询社团列表
|
||||
- **接口路径**: `/api/admin/club/list`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN, CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
- keyword: 关键字(可选,用于搜索)
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"clubId": "number",
|
||||
"name": "string",
|
||||
"description": "string",
|
||||
"collegeId": "number",
|
||||
"type": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4.2 社团成员管理 (ClubUserController)
|
||||
- **接口路径**: `/api/admin/club/user`
|
||||
- **功能**: 社团成员管理相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 4.2.1 添加社团成员
|
||||
- **接口路径**: `/api/admin/club/user/add`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
- clubId: 社团ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "成员已加入社团",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.2 移除社团成员
|
||||
- **接口路径**: `/api/admin/club/user/remove`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: CLUB_ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
- clubId: 社团ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "成员已移除",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.3 查询社团成员列表
|
||||
- **接口路径**: `/api/admin/club/user/list`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **请求参数**:
|
||||
- clubId: 社团ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"userId": "number",
|
||||
"username": "string",
|
||||
"role": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.2.4 查看我的社团成员
|
||||
- **接口路径**: `/api/admin/club/user/my-club-members`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: CLUB_ADMIN
|
||||
- **请求参数**:
|
||||
- clubId: 社团ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"userId": "number",
|
||||
"username": "string",
|
||||
"role": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4.3 学院管理 (CollegeController)
|
||||
- **接口路径**: `/api/admin/college`
|
||||
- **功能**: 学院信息管理相关接口
|
||||
- **权限要求**: 需要相应角色权限
|
||||
|
||||
#### 4.3.1 添加学院
|
||||
- **接口路径**: `/api/admin/college/add`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"name": "string", // 学院名称
|
||||
"description": "string", // 学院描述
|
||||
"code": "string" // 学院代码
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "学院添加成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.2 更新学院信息
|
||||
- **接口路径**: `/api/admin/college/update`
|
||||
- **请求方式**: PUT
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
```json
|
||||
{
|
||||
"collegeId": "number", // 学院ID
|
||||
"name": "string", // 学院名称
|
||||
"description": "string", // 学院描述
|
||||
"code": "string" // 学院代码
|
||||
}
|
||||
```
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "学院更新成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.3 删除学院
|
||||
- **接口路径**: `/api/admin/college/delete/{collegeId}`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **路径参数**:
|
||||
- collegeId: 学院ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "学院删除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.4 获取学院详情
|
||||
- **接口路径**: `/api/admin/college/{collegeId}`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **路径参数**:
|
||||
- collegeId: 学院ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"collegeId": "number",
|
||||
"name": "string",
|
||||
"description": "string",
|
||||
"code": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.5 获取我的学院信息
|
||||
- **接口路径**: `/api/admin/college/my-college`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: DEPARTMENT_ADMIN
|
||||
- **请求参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"collegeId": "number",
|
||||
"name": "string",
|
||||
"description": "string",
|
||||
"code": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.6 查询学院列表
|
||||
- **接口路径**: `/api/admin/college/list`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **请求参数**:
|
||||
- keyword: 关键字(可选,用于搜索)
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": [
|
||||
{
|
||||
"collegeId": "number",
|
||||
"name": "string",
|
||||
"description": "string",
|
||||
"code": "string"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.7 指派学院负责人
|
||||
- **接口路径**: `/api/admin/college/assign`
|
||||
- **请求方式**: POST
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
- collegeId: 学院ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "负责人指派成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.8 移除学院负责人
|
||||
- **接口路径**: `/api/admin/college/remove`
|
||||
- **请求方式**: DELETE
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN
|
||||
- **请求参数**:
|
||||
- collegeId: 学院ID
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "负责人移除成功",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.9 获取学院负责人
|
||||
- **接口路径**: `/api/admin/college/getleader/{collegeId}`
|
||||
- **请求方式**: GET
|
||||
- **权限要求**: ADMIN, COLLEGE_ADMIN, DEPARTMENT_ADMIN
|
||||
- **路径参数**:
|
||||
- collegeId: 学院ID
|
||||
- **请求参数**:
|
||||
- userId: 用户ID
|
||||
- **响应结果**:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "success",
|
||||
"data": {
|
||||
"userId": "number",
|
||||
"username": "string",
|
||||
"role": "string"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 通用说明
|
||||
|
||||
1. **认证方式**:
|
||||
- 除登录接口外,所有接口都需要在请求头中携带 JWT Token
|
||||
- Token 格式:`Authorization: Bearer <token>`
|
||||
|
||||
2. **响应格式**:
|
||||
- 所有接口统一使用 `AjaxResult` 封装响应
|
||||
- 成功响应示例:
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"msg": "操作成功",
|
||||
"data": {}
|
||||
}
|
||||
```
|
||||
- 失败响应示例:
|
||||
```json
|
||||
{
|
||||
"code": 500,
|
||||
"msg": "操作失败",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
3. **请求方式**:
|
||||
- 查询类接口使用 GET
|
||||
- 创建类接口使用 POST
|
||||
- 更新类接口使用 PUT
|
||||
- 删除类接口使用 DELETE
|
||||
|
||||
4. **数据格式**:
|
||||
- 请求和响应均使用 JSON 格式
|
||||
- 日期时间格式统一使用 ISO 8601 标准
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 创建活动
|
||||
export function createActivity(data) {
|
||||
return request({
|
||||
url: '/api/admin/activity/create',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 取消活动
|
||||
export function cancelActivity(data) {
|
||||
return request({
|
||||
url: '/api/admin/activity/cancel',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取活动列表
|
||||
export function getActivityList(params) {
|
||||
return request({
|
||||
url: '/api/admin/activity/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取活动详情
|
||||
export function getActivityDetail(actId) {
|
||||
return request({
|
||||
url: `/api/admin/activity/${actId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 更新活动信息
|
||||
export function updateActivity(data) {
|
||||
return request({
|
||||
url: '/api/admin/activity/update',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除活动
|
||||
export function deleteActivity(actId) {
|
||||
return request({
|
||||
url: `/api/admin/activity/delete/${actId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 添加社团
|
||||
export function addClub(data) {
|
||||
return request({
|
||||
url: '/api/admin/club/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新社团信息
|
||||
export function updateClub(data) {
|
||||
return request({
|
||||
url: '/api/admin/club/update',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 删除社团
|
||||
export function deleteClub(clubId) {
|
||||
return request({
|
||||
url: `/api/admin/club/delete/${clubId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取社团详情
|
||||
export function getClubDetail(clubId) {
|
||||
return request({
|
||||
url: `/api/admin/club/${clubId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 获取社团列表
|
||||
export function getClubList(params) {
|
||||
return request({
|
||||
url: '/api/admin/club/list',
|
||||
method: 'get',
|
||||
params
|
||||
})
|
||||
}
|
||||
|
||||
// 获取社团成员列表
|
||||
export function getClubMembers(clubId) {
|
||||
return request({
|
||||
url: `/api/admin/club/${clubId}/members`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 添加社团成员
|
||||
export function addClubMember(data) {
|
||||
return request({
|
||||
url: '/api/admin/club/member/add',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 移除社团成员
|
||||
export function removeClubMember(clubId, userId) {
|
||||
return request({
|
||||
url: `/api/admin/club/${clubId}/member/${userId}`,
|
||||
method: 'delete'
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
import request from '@/utils/request'
|
||||
|
||||
// 用户登录
|
||||
export function login(data) {
|
||||
return request({
|
||||
url: '/api/login',
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 获取用户信息
|
||||
export function getUserInfo(userId) {
|
||||
return request({
|
||||
url: `/api/user/${userId}`,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
|
||||
// 修改密码
|
||||
export function changePassword(data) {
|
||||
return request({
|
||||
url: '/api/user/change-password',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 更新用户信息
|
||||
export function updateProfile(data) {
|
||||
return request({
|
||||
url: '/api/user/profile',
|
||||
method: 'put',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
// 上传头像
|
||||
export function uploadAvatar(data) {
|
||||
return request({
|
||||
url: '/api/user/avatar',
|
||||
method: 'post',
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data'
|
||||
},
|
||||
data
|
||||
})
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
export default {
|
||||
development: {
|
||||
baseUrl: 'http://localhost:8080',
|
||||
uploadUrl: 'http://localhost:8080/api/file/upload'
|
||||
},
|
||||
production: {
|
||||
baseUrl: 'http://your-production-domain',
|
||||
uploadUrl: 'http://your-production-domain/api/file/upload'
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
import env from './env'
|
||||
import settings from './settings'
|
||||
|
||||
const config = {
|
||||
...env[process.env.NODE_ENV || 'development'],
|
||||
...settings
|
||||
}
|
||||
|
||||
export default config
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
export default {
|
||||
/**
|
||||
* 系统标题
|
||||
*/
|
||||
title: 'SAMS学生社团管理系统',
|
||||
|
||||
/**
|
||||
* 系统logo
|
||||
*/
|
||||
logo: '/logo.png',
|
||||
|
||||
/**
|
||||
* 是否显示设置右面板
|
||||
*/
|
||||
showSettings: true,
|
||||
|
||||
/**
|
||||
* 是否显示标签视图
|
||||
*/
|
||||
tagsView: true,
|
||||
|
||||
/**
|
||||
* 是否固定头部
|
||||
*/
|
||||
fixedHeader: true,
|
||||
|
||||
/**
|
||||
* 是否显示侧边栏Logo
|
||||
*/
|
||||
sidebarLogo: true,
|
||||
|
||||
/**
|
||||
* 是否显示动态标题
|
||||
*/
|
||||
dynamicTitle: true,
|
||||
|
||||
/**
|
||||
* 主题色
|
||||
*/
|
||||
theme: '#409EFF',
|
||||
|
||||
/**
|
||||
* 导航模式 vertical / horizontal
|
||||
*/
|
||||
navMode: 'vertical',
|
||||
|
||||
/**
|
||||
* 内容区域宽度 fluid / fixed
|
||||
*/
|
||||
contentWidth: 'fluid',
|
||||
|
||||
/**
|
||||
* 侧边栏主题 dark / light
|
||||
*/
|
||||
sidebarTheme: 'dark',
|
||||
|
||||
/**
|
||||
* 侧边栏折叠
|
||||
*/
|
||||
sidebarCollapse: false,
|
||||
|
||||
/**
|
||||
* 布局模式
|
||||
* default / classic / transverse / columns
|
||||
*/
|
||||
layout: 'default',
|
||||
|
||||
/**
|
||||
* 是否开启水印
|
||||
*/
|
||||
watermark: false,
|
||||
|
||||
/**
|
||||
* 水印配置
|
||||
*/
|
||||
watermarkConfig: {
|
||||
text: 'SAMS',
|
||||
fontColor: '#333',
|
||||
fontSize: 16,
|
||||
rotate: -30,
|
||||
zIndex: 1000
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
const TokenKey = 'Admin-Token'
|
||||
|
||||
export function getToken() {
|
||||
return localStorage.getItem(TokenKey)
|
||||
}
|
||||
|
||||
export function setToken(token) {
|
||||
return localStorage.setItem(TokenKey, token)
|
||||
}
|
||||
|
||||
export function removeToken() {
|
||||
return localStorage.removeItem(TokenKey)
|
||||
}
|
||||
|
||||
export function getUserInfo() {
|
||||
const userInfo = localStorage.getItem('userInfo')
|
||||
return userInfo ? JSON.parse(userInfo) : null
|
||||
}
|
||||
|
||||
export function setUserInfo(userInfo) {
|
||||
return localStorage.setItem('userInfo', JSON.stringify(userInfo))
|
||||
}
|
||||
|
||||
export function removeUserInfo() {
|
||||
return localStorage.removeItem('userInfo')
|
||||
}
|
||||
|
|
@ -1,31 +1,62 @@
|
|||
import axios from 'axios'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getToken } from '@/utils/auth'
|
||||
import config from '@/config'
|
||||
|
||||
// 创建axios实例
|
||||
const service = axios.create({
|
||||
baseURL: '/api',
|
||||
timeout: 5000
|
||||
baseURL: config.baseUrl,
|
||||
timeout: 10000
|
||||
})
|
||||
|
||||
service.interceptors.request.use(config => {
|
||||
const token = localStorage.getItem('token')
|
||||
|
||||
// 只给非登录接口加 token
|
||||
if (token && config.url !== '/login') {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
|
||||
return config
|
||||
})
|
||||
|
||||
|
||||
service.interceptors.response.use(
|
||||
res => {
|
||||
if (res.data.code === 200) return res.data
|
||||
ElMessage.error(res.data.message || '请求出错')
|
||||
return Promise.reject(new Error(res.data.message || 'Error'))
|
||||
// 请求拦截器
|
||||
service.interceptors.request.use(
|
||||
config => {
|
||||
const token = getToken()
|
||||
if (token && config.url !== '/login') {
|
||||
config.headers.Authorization = `Bearer ${token}`
|
||||
}
|
||||
return config
|
||||
},
|
||||
error => {
|
||||
ElMessage.error(error.response?.data?.message || '服务器异常')
|
||||
console.log(error)
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
||||
// 响应拦截器
|
||||
service.interceptors.response.use(
|
||||
response => {
|
||||
const res = response.data
|
||||
if (res.code !== 200) {
|
||||
ElMessage({
|
||||
message: res.message || '系统错误',
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
|
||||
// 401: 未登录或token过期
|
||||
if (res.code === 401) {
|
||||
ElMessageBox.confirm('登录状态已过期,请重新登录', '系统提示', {
|
||||
confirmButtonText: '重新登录',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}
|
||||
return Promise.reject(new Error(res.message || '系统错误'))
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
},
|
||||
error => {
|
||||
console.log('err' + error)
|
||||
ElMessage({
|
||||
message: error.message,
|
||||
type: 'error',
|
||||
duration: 5 * 1000
|
||||
})
|
||||
return Promise.reject(error)
|
||||
}
|
||||
)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,277 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>活动列表</span>
|
||||
<el-button type="primary" @click="handleAdd">新增活动</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
|
||||
<el-form-item label="活动名称">
|
||||
<el-input v-model="queryParams.title" placeholder="请输入活动名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="活动状态">
|
||||
<el-select v-model="queryParams.status" placeholder="请选择活动状态" clearable>
|
||||
<el-option label="进行中" value="ACTIVE" />
|
||||
<el-option label="已结束" value="ENDED" />
|
||||
<el-option label="已取消" value="CANCELLED" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||
<el-button @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="activityList" style="width: 100%">
|
||||
<el-table-column prop="title" label="活动名称" />
|
||||
<el-table-column prop="description" label="活动描述" show-overflow-tooltip />
|
||||
<el-table-column prop="startTime" label="开始时间" width="180" />
|
||||
<el-table-column prop="endTime" label="结束时间" width="180" />
|
||||
<el-table-column prop="location" label="活动地点" width="150" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="getStatusType(scope.row.status)">
|
||||
{{ getStatusText(scope.row.status) }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column label="操作" width="200" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="primary" link @click="handleView(scope.row)">查看</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
v-model:current-page="queryParams.page"
|
||||
v-model:page-size="queryParams.size"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改活动对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="activityFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="活动名称" prop="title">
|
||||
<el-input v-model="form.title" placeholder="请输入活动名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="活动描述" prop="description">
|
||||
<el-input v-model="form.description" type="textarea" placeholder="请输入活动描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="开始时间" prop="startTime">
|
||||
<el-date-picker
|
||||
v-model="form.startTime"
|
||||
type="datetime"
|
||||
placeholder="选择开始时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="结束时间" prop="endTime">
|
||||
<el-date-picker
|
||||
v-model="form.endTime"
|
||||
type="datetime"
|
||||
placeholder="选择结束时间"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
/>
|
||||
</el-form-item>
|
||||
<el-form-item label="活动地点" prop="location">
|
||||
<el-input v-model="form.location" placeholder="请输入活动地点" />
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getActivityList, createActivity, updateActivity, deleteActivity } from '@/api/activity/activity'
|
||||
|
||||
const loading = ref(false)
|
||||
const activityList = ref([])
|
||||
const total = ref(0)
|
||||
|
||||
const queryParams = ref({
|
||||
page: 1,
|
||||
size: 10,
|
||||
title: '',
|
||||
status: ''
|
||||
})
|
||||
|
||||
const dialog = ref({
|
||||
visible: false,
|
||||
title: ''
|
||||
})
|
||||
|
||||
const form = ref({
|
||||
id: undefined,
|
||||
title: '',
|
||||
description: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
location: ''
|
||||
})
|
||||
|
||||
const rules = {
|
||||
title: [{ required: true, message: '请输入活动名称', trigger: 'blur' }],
|
||||
description: [{ required: true, message: '请输入活动描述', trigger: 'blur' }],
|
||||
startTime: [{ required: true, message: '请选择开始时间', trigger: 'change' }],
|
||||
endTime: [{ required: true, message: '请选择结束时间', trigger: 'change' }],
|
||||
location: [{ required: true, message: '请输入活动地点', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
const getStatusType = (status) => {
|
||||
const statusMap = {
|
||||
ACTIVE: 'success',
|
||||
ENDED: 'info',
|
||||
CANCELLED: 'danger'
|
||||
}
|
||||
return statusMap[status] || 'info'
|
||||
}
|
||||
|
||||
const getStatusText = (status) => {
|
||||
const statusMap = {
|
||||
ACTIVE: '进行中',
|
||||
ENDED: '已结束',
|
||||
CANCELLED: '已取消'
|
||||
}
|
||||
return statusMap[status] || '未知'
|
||||
}
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getActivityList(queryParams.value)
|
||||
activityList.value = res.data.records
|
||||
total.value = res.data.total
|
||||
} catch (error) {
|
||||
console.error('获取活动列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.value.page = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.value = {
|
||||
page: 1,
|
||||
size: 10,
|
||||
title: '',
|
||||
status: ''
|
||||
}
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
queryParams.value.size = val
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
queryParams.value.page = val
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dialog.value = {
|
||||
visible: true,
|
||||
title: '添加活动'
|
||||
}
|
||||
form.value = {
|
||||
id: undefined,
|
||||
title: '',
|
||||
description: '',
|
||||
startTime: '',
|
||||
endTime: '',
|
||||
location: ''
|
||||
}
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
dialog.value = {
|
||||
visible: true,
|
||||
title: '修改活动'
|
||||
}
|
||||
form.value = { ...row }
|
||||
}
|
||||
|
||||
const handleView = (row) => {
|
||||
// TODO: 实现查看详情功能
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确认要删除该活动吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteActivity(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('删除活动失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
try {
|
||||
if (form.value.id) {
|
||||
await updateActivity(form.value)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await createActivity(form.value)
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
dialog.value.visible = false
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('提交表单失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
dialog.value.visible = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,310 @@
|
|||
<template>
|
||||
<div class="app-container">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>社团列表</span>
|
||||
<el-button type="primary" @click="handleAdd">新增社团</el-button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<el-form :inline="true" :model="queryParams" class="demo-form-inline">
|
||||
<el-form-item label="社团名称">
|
||||
<el-input v-model="queryParams.name" placeholder="请输入社团名称" clearable />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属学院">
|
||||
<el-select v-model="queryParams.collegeId" placeholder="请选择学院" clearable>
|
||||
<el-option
|
||||
v-for="item in collegeOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleQuery">查询</el-button>
|
||||
<el-button @click="resetQuery">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
<el-table v-loading="loading" :data="clubList" style="width: 100%">
|
||||
<el-table-column prop="name" label="社团名称" />
|
||||
<el-table-column prop="description" label="社团描述" show-overflow-tooltip />
|
||||
<el-table-column prop="collegeName" label="所属学院" width="150" />
|
||||
<el-table-column prop="memberCount" label="成员数" width="100" />
|
||||
<el-table-column prop="activityCount" label="活动数" width="100" />
|
||||
<el-table-column prop="createTime" label="创建时间" width="180" />
|
||||
<el-table-column label="操作" width="250" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="primary" link @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button type="primary" link @click="handleView(scope.row)">查看</el-button>
|
||||
<el-button type="primary" link @click="handleMembers(scope.row)">成员管理</el-button>
|
||||
<el-button type="danger" link @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<div class="pagination-container">
|
||||
<el-pagination
|
||||
v-model:current-page="queryParams.page"
|
||||
v-model:page-size="queryParams.size"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="total"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</el-card>
|
||||
|
||||
<!-- 添加或修改社团对话框 -->
|
||||
<el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body>
|
||||
<el-form ref="clubFormRef" :model="form" :rules="rules" label-width="80px">
|
||||
<el-form-item label="社团名称" prop="name">
|
||||
<el-input v-model="form.name" placeholder="请输入社团名称" />
|
||||
</el-form-item>
|
||||
<el-form-item label="社团描述" prop="description">
|
||||
<el-input v-model="form.description" type="textarea" placeholder="请输入社团描述" />
|
||||
</el-form-item>
|
||||
<el-form-item label="所属学院" prop="collegeId">
|
||||
<el-select v-model="form.collegeId" placeholder="请选择学院">
|
||||
<el-option
|
||||
v-for="item in collegeOptions"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="submitForm">确 定</el-button>
|
||||
<el-button @click="cancel">取 消</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
|
||||
<!-- 成员管理对话框 -->
|
||||
<el-dialog title="成员管理" v-model="memberDialog.visible" width="800px" append-to-body>
|
||||
<el-table :data="memberDialog.members" style="width: 100%">
|
||||
<el-table-column prop="username" label="用户名" />
|
||||
<el-table-column prop="realName" label="姓名" />
|
||||
<el-table-column prop="role" label="角色" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.role === 'ADMIN' ? 'danger' : 'info'">
|
||||
{{ scope.row.role === 'ADMIN' ? '管理员' : '普通成员' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column prop="joinTime" label="加入时间" width="180" />
|
||||
<el-table-column label="操作" width="150" fixed="right">
|
||||
<template #default="scope">
|
||||
<el-button type="danger" link @click="handleRemoveMember(scope.row)">移除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
<template #footer>
|
||||
<div class="dialog-footer">
|
||||
<el-button type="primary" @click="handleAddMember">添加成员</el-button>
|
||||
<el-button @click="memberDialog.visible = false">关 闭</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { ElMessage, ElMessageBox } from 'element-plus'
|
||||
import { getClubList, addClub, updateClub, deleteClub, getClubMembers, removeClubMember } from '@/api/club/club'
|
||||
|
||||
const loading = ref(false)
|
||||
const clubList = ref([])
|
||||
const total = ref(0)
|
||||
const collegeOptions = ref([])
|
||||
|
||||
const queryParams = ref({
|
||||
page: 1,
|
||||
size: 10,
|
||||
name: '',
|
||||
collegeId: undefined
|
||||
})
|
||||
|
||||
const dialog = ref({
|
||||
visible: false,
|
||||
title: ''
|
||||
})
|
||||
|
||||
const memberDialog = ref({
|
||||
visible: false,
|
||||
clubId: undefined,
|
||||
members: []
|
||||
})
|
||||
|
||||
const form = ref({
|
||||
id: undefined,
|
||||
name: '',
|
||||
description: '',
|
||||
collegeId: undefined
|
||||
})
|
||||
|
||||
const rules = {
|
||||
name: [{ required: true, message: '请输入社团名称', trigger: 'blur' }],
|
||||
description: [{ required: true, message: '请输入社团描述', trigger: 'blur' }],
|
||||
collegeId: [{ required: true, message: '请选择所属学院', trigger: 'change' }]
|
||||
}
|
||||
|
||||
const getList = async () => {
|
||||
loading.value = true
|
||||
try {
|
||||
const res = await getClubList(queryParams.value)
|
||||
clubList.value = res.data.records
|
||||
total.value = res.data.total
|
||||
} catch (error) {
|
||||
console.error('获取社团列表失败:', error)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const handleQuery = () => {
|
||||
queryParams.value.page = 1
|
||||
getList()
|
||||
}
|
||||
|
||||
const resetQuery = () => {
|
||||
queryParams.value = {
|
||||
page: 1,
|
||||
size: 10,
|
||||
name: '',
|
||||
collegeId: undefined
|
||||
}
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleSizeChange = (val) => {
|
||||
queryParams.value.size = val
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleCurrentChange = (val) => {
|
||||
queryParams.value.page = val
|
||||
getList()
|
||||
}
|
||||
|
||||
const handleAdd = () => {
|
||||
dialog.value = {
|
||||
visible: true,
|
||||
title: '添加社团'
|
||||
}
|
||||
form.value = {
|
||||
id: undefined,
|
||||
name: '',
|
||||
description: '',
|
||||
collegeId: undefined
|
||||
}
|
||||
}
|
||||
|
||||
const handleEdit = (row) => {
|
||||
dialog.value = {
|
||||
visible: true,
|
||||
title: '修改社团'
|
||||
}
|
||||
form.value = { ...row }
|
||||
}
|
||||
|
||||
const handleView = (row) => {
|
||||
// TODO: 实现查看详情功能
|
||||
}
|
||||
|
||||
const handleDelete = (row) => {
|
||||
ElMessageBox.confirm('确认要删除该社团吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await deleteClub(row.id)
|
||||
ElMessage.success('删除成功')
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('删除社团失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const handleMembers = async (row) => {
|
||||
memberDialog.value = {
|
||||
visible: true,
|
||||
clubId: row.id,
|
||||
members: []
|
||||
}
|
||||
try {
|
||||
const res = await getClubMembers(row.id)
|
||||
memberDialog.value.members = res.data
|
||||
} catch (error) {
|
||||
console.error('获取社团成员失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const handleAddMember = () => {
|
||||
// TODO: 实现添加成员功能
|
||||
}
|
||||
|
||||
const handleRemoveMember = (row) => {
|
||||
ElMessageBox.confirm('确认要移除该成员吗?', '警告', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(async () => {
|
||||
try {
|
||||
await removeClubMember(memberDialog.value.clubId, row.id)
|
||||
ElMessage.success('移除成功')
|
||||
handleMembers({ id: memberDialog.value.clubId })
|
||||
} catch (error) {
|
||||
console.error('移除成员失败:', error)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const submitForm = async () => {
|
||||
try {
|
||||
if (form.value.id) {
|
||||
await updateClub(form.value)
|
||||
ElMessage.success('修改成功')
|
||||
} else {
|
||||
await addClub(form.value)
|
||||
ElMessage.success('新增成功')
|
||||
}
|
||||
dialog.value.visible = false
|
||||
getList()
|
||||
} catch (error) {
|
||||
console.error('提交表单失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
const cancel = () => {
|
||||
dialog.value.visible = false
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
getList()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.app-container {
|
||||
padding: 20px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.pagination-container {
|
||||
margin-top: 20px;
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
<template>
|
||||
<div class="home-container">
|
||||
<el-row :gutter="20">
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>社团总数</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-body">
|
||||
<div class="number">{{ statistics.clubCount }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>活动总数</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-body">
|
||||
<div class="number">{{ statistics.activityCount }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>成员总数</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-body">
|
||||
<div class="number">{{ statistics.memberCount }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="6">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>今日活动</span>
|
||||
</div>
|
||||
</template>
|
||||
<div class="card-body">
|
||||
<div class="number">{{ statistics.todayActivityCount }}</div>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
|
||||
<el-row :gutter="20" class="mt-20">
|
||||
<el-col :span="12">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>最近活动</span>
|
||||
<el-button type="text" @click="$router.push('/activity/list')">查看更多</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="activity-list">
|
||||
<el-table :data="recentActivities" style="width: 100%">
|
||||
<el-table-column prop="title" label="活动名称" />
|
||||
<el-table-column prop="startTime" label="开始时间" width="180" />
|
||||
<el-table-column prop="status" label="状态" width="100">
|
||||
<template #default="scope">
|
||||
<el-tag :type="scope.row.status === 'ACTIVE' ? 'success' : 'info'">
|
||||
{{ scope.row.status === 'ACTIVE' ? '进行中' : '已结束' }}
|
||||
</el-tag>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
<el-col :span="12">
|
||||
<el-card class="box-card">
|
||||
<template #header>
|
||||
<div class="card-header">
|
||||
<span>热门社团</span>
|
||||
<el-button type="text" @click="$router.push('/club/list')">查看更多</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<div class="club-list">
|
||||
<el-table :data="popularClubs" style="width: 100%">
|
||||
<el-table-column prop="name" label="社团名称" />
|
||||
<el-table-column prop="memberCount" label="成员数" width="100" />
|
||||
<el-table-column prop="activityCount" label="活动数" width="100" />
|
||||
</el-table>
|
||||
</div>
|
||||
</el-card>
|
||||
</el-col>
|
||||
</el-row>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { getActivityList } from '@/api/activity/activity'
|
||||
import { getClubList } from '@/api/club/club'
|
||||
|
||||
const statistics = ref({
|
||||
clubCount: 0,
|
||||
activityCount: 0,
|
||||
memberCount: 0,
|
||||
todayActivityCount: 0
|
||||
})
|
||||
|
||||
const recentActivities = ref([])
|
||||
const popularClubs = ref([])
|
||||
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
// 获取活动列表
|
||||
const activityRes = await getActivityList({ page: 1, size: 5 })
|
||||
recentActivities.value = activityRes.data.records
|
||||
|
||||
// 获取社团列表
|
||||
const clubRes = await getClubList({ page: 1, size: 5 })
|
||||
popularClubs.value = clubRes.data.records
|
||||
|
||||
// 更新统计数据
|
||||
statistics.value = {
|
||||
clubCount: clubRes.data.total,
|
||||
activityCount: activityRes.data.total,
|
||||
memberCount: clubRes.data.records.reduce((sum, club) => sum + club.memberCount, 0),
|
||||
todayActivityCount: activityRes.data.records.filter(activity => {
|
||||
const today = new Date().toISOString().split('T')[0]
|
||||
return activity.startTime.startsWith(today)
|
||||
}).length
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取数据失败:', error)
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
fetchData()
|
||||
})
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.home-container {
|
||||
padding: 20px;
|
||||
}
|
||||
.mt-20 {
|
||||
margin-top: 20px;
|
||||
}
|
||||
.card-header {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
}
|
||||
.card-body {
|
||||
text-align: center;
|
||||
padding: 20px 0;
|
||||
}
|
||||
.number {
|
||||
font-size: 36px;
|
||||
font-weight: bold;
|
||||
color: #409EFF;
|
||||
}
|
||||
.activity-list,
|
||||
.club-list {
|
||||
margin-top: 10px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -2,10 +2,10 @@
|
|||
<div class="login-page">
|
||||
<div class="login-left">
|
||||
<div class="login-box">
|
||||
<h2 class="title">欢迎登录</h2>
|
||||
<h2 class="title">SAMS学生社团管理系统</h2>
|
||||
<el-form :model="loginForm" :rules="loginRules" ref="loginRef" label-position="top" size="large">
|
||||
<el-form-item label="账号登录" prop="account">
|
||||
<el-input v-model="loginForm.account" placeholder="请输入用户名 / 学号 / 邮箱" />
|
||||
<el-form-item label="账号登录" prop="username">
|
||||
<el-input v-model="loginForm.username" placeholder="请输入用户名 / 学号 / 邮箱" />
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item label="密码" prop="password">
|
||||
|
|
@ -32,20 +32,21 @@
|
|||
import { ref } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { login } from '@/api/auth'
|
||||
import { login } from '@/api/system/user'
|
||||
import { setToken, setUserInfo } from '@/utils/auth'
|
||||
|
||||
const router = useRouter()
|
||||
const loginRef = ref(null)
|
||||
const loading = ref(false)
|
||||
|
||||
const loginForm = ref({
|
||||
account: '',
|
||||
username: '',
|
||||
password: '',
|
||||
remember: false
|
||||
})
|
||||
|
||||
const loginRules = {
|
||||
account: [{ required: true, message: '请输入用户名/学号/邮箱', trigger: 'blur' }],
|
||||
username: [{ required: true, message: '请输入用户名/学号/邮箱', trigger: 'blur' }],
|
||||
password: [{ required: true, message: '请输入密码', trigger: 'blur' }]
|
||||
}
|
||||
|
||||
|
|
@ -54,22 +55,13 @@ const submitLogin = () => {
|
|||
if (!valid) return
|
||||
loading.value = true
|
||||
try {
|
||||
const token = await login(loginForm.value)
|
||||
localStorage.setItem('token', token)
|
||||
const res = await login(loginForm.value)
|
||||
setToken(res.data.token)
|
||||
setUserInfo(res.data.userInfo)
|
||||
ElMessage.success('登录成功')
|
||||
// 登录成功后
|
||||
const payload = jwtDecode(token)
|
||||
const roles = Array.isArray(payload.role) ? payload.role : [payload.role]
|
||||
|
||||
if (roles.includes('PARTICIPANT')) {
|
||||
router.push('/user/home')
|
||||
} else if (roles.includes('COLLEGE_ADMIN') ||roles.includes('DEPARTMENT_ADMIN') ||roles.includes('CLUB_ADMIN') ) {
|
||||
router.push('/admin/home')
|
||||
} else {
|
||||
router.push('/403') // 无匹配权限
|
||||
}
|
||||
} catch (e) {
|
||||
ElMessage.error(e.message || '登录失败')
|
||||
router.push('/')
|
||||
} catch (error) {
|
||||
ElMessage.error(error.message || '登录失败')
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
|
|
@ -97,6 +89,7 @@ const submitLogin = () => {
|
|||
font-weight: bold;
|
||||
margin-bottom: 32px;
|
||||
text-align: center;
|
||||
color: #409EFF;
|
||||
}
|
||||
.login-btn {
|
||||
width: 100%;
|
||||
|
|
|
|||
Loading…
Reference in New Issue