公开完整前后端的代码

This commit is contained in:
Linus Torvalds
2026-02-26 19:22:38 +08:00
commit 193de8a34f
161 changed files with 17373 additions and 0 deletions

View File

@@ -0,0 +1,116 @@
# 取消工单 API
- **路径**: `/api/v3/cancel_ticket`
- **方法**: `POST`
- **功能**: 用户取消自己提交的报修工单。
## 描述
此接口允许用户取消一个他们自己创建的、尚未完成的工单。取消操作会向该工单添加一条新的追踪记录,并将工单状态更新为 `canceled`
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 任何已激活的用户 (`user` 或更高权限) 都可以取消自己的工单。
- 管理员 (`admin``dev` 权限) 可以取消任何工单。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
### 查询参数
| 参数 | 类型 | 描述 | 是否必须 |
| ---- | ------ | ---------------- | -------- |
| `tid` | string | 要取消的工单 ID。 | 是 |
**请求示例**:
```
POST /api/v3/cancel_ticket?tid=T20251206001
```
## 响应
### 成功响应 (200 OK)
| 字段 | 类型 | 描述 |
| ------- | ------- | -------------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
**响应示例**:
```json
{
"success": true,
"msg": "ticket canceled"
}
```
### 失败响应
#### 400 Bad Request (请求错误)
- `tid` 参数缺失或格式不正确。
- 无法获取工单信息(例如,工单不存在)。
```json
{
"success": false,
"msg": "missing required URL parameter: tid",
"errType": 2
}
```
```json
{
"success": false,
"msg": "invalid ticket ID: ...",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ----------------------- | --------- | ------------------------------------------------------------ |
| `no such ticket` | `logic` | 提供的 `tid` 对应的工单不存在。 |
| `new status is invalid` | `logic` | 工单当前状态不允许被取消 (例如,已经完成或已经取消的工单)。 |
#### 403 Forbidden (权限错误)
- 当用户尝试取消不属于自己的工单时返回。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时返回。
```json
{
"success": false,
"msg": "you can only cancel tickets of your own",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 此操作是不可逆的。一旦工单被取消,通常不能再重新打开。
- 只有工单的创建者或管理员才能取消工单。
- 后台逻辑会检查工单的当前状态,确保只有在特定状态下的工单才能被取消。
- 取消操作实际上是调用了 `AppendTrace` 逻辑,添加了一条备注为“用户取消报修”并更新状态为 `canceled` 的记录。

View File

@@ -0,0 +1,141 @@
# 修改个人信息 API
- **路径**: `/api/v3/change_profile`
- **方法**: `POST`
- **功能**: 更新用户的个人信息。
## 描述
此接口允许用户修改他们的个人资料,如宿舍信息、联系电话、宽带运营商和账号。管理员有权修改任何用户的信息,而普通用户只能修改自己的信息。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 普通用户 (`user` 或更高权限) 只能修改自己的信息。
- 管理员 (`admin` 权限) 可以修改任何用户的信息。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
| 字段 | 类型 | 描述 | 校验规则 |
| --------- | -------- | ------------------------------------------ | ------------ |
| `who` | string | 要修改信息用户的微信 OpenID | `required` |
| `block` | string | 新的宿舍区 | `required` |
| `room` | string | 新的房间号 | `required` |
| `phone` | string | 新的手机号码 | `required` |
| `isp` | string | 新的宽带运营商| `required` |
| `account` | string | 新的宽带账号 | `required` |
**请求示例 (普通用户修改自己信息)**:
```json
{
"who": "user_openid_123",
"block": "15",
"room": "202",
"phone": "13900139000",
"isp": "telecom",
"account": "987654321"
}
```
**请求示例 (管理员修改他人信息)**:
```json
{
"who": "another_user_openid_456",
"block": "9",
"room": "303",
"phone": "13700137000",
"isp": "mobile",
"account": "555555555"
}
```
## 响应
### 成功响应 (200 OK)
| 字段 | 类型 | 描述 |
| ------- | ------- | -------------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
**响应示例**:
```json
{
"success": true,
"msg": "profile change success~"
}
```
### 失败响应
#### 400 Bad Request (请求错误)
请求体绑定失败、格式错误或未通过验证。
```json
{
"success": false,
"msg": "invalid request body: Key: 'ChangeUserProfileRequest.Phone' Error:Field validation for 'Phone' failed on the 'required' tag",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ---------------------------- | --------- | ------------------------ |
| `no such user` | `logic` | 目标用户不存在 |
| `phone number has been used` | `logic` | 该手机号已被其他用户注册 |
#### 403 Forbidden (权限错误)
- 当非管理员用户尝试修改其他用户的信息时返回。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时返回。
```json
{
"success": false,
"msg": "only admins can change other users' profiles",
"errType": 3
}
```
```json
{
"success": false,
"msg": "only active users can access this API",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 普通用户调用时,请求体中的 `who` 字段必须是自己的微信 OpenID该 OpenID 从 JWT 中解析得出。
- 管理员可以指定任意用户的 OpenID 到 `who` 字段来修改其信息。
- 所有字段都是必需的,即使只修改其中一项,也需要提供所有字段的当前值或新值。
- 手机号码在系统中必须是唯一的。

View File

@@ -0,0 +1,9 @@
# 错误的类型
API如果没有成功执行会返回一个错误类型`error_type`整型,它的涵义如下:
- 0:没有错误
- 1:服务器内部错误
- 2:无效请求
- 3:未授权访问
- 4:数据库错误
- 5:业务逻辑错误

View File

@@ -0,0 +1,29 @@
# 返回内容的格式
本项目的API通常返回JSON格式预览如下
```JSON
{
"success":true,
"msg":"API Execution OK"
}
```
```JSON
{
"success":false,
"msg":"API Execution met a problem",
"error_type":2,
"debug":"Can not bind your JSON Request body"
}
```
任何API都会返回`success``msg`字段,错误时还会返回`error_type`字段,如果打开`Debug.APIVerbose`会返回`debug`字段。
关于msg的内容可以看每个API在logic包中的开头注释具体信息位于`logic/errors.go`
另外在回应头里有字段`X-Request-Id`这是我们为每个HTTP请求生成的唯一ID可以用来在日志里查找相应的信息

View File

@@ -0,0 +1,152 @@
# 筛选工单 API
- **路径**: `/api/v3/filter_tickets`
- **方法**: `POST`
- **功能**: 根据多种条件筛选工单列表。
## 描述
此接口是为网维人员设计的强大工具,允许他们根据各种条件(如状态、报修人、时间范围、问题分类等)来查询和筛选工单。管理员拥有更广泛的查询范围。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 必须是网维人员 (`operator` 或更高权限) 才能调用此 API。
- 只有管理员 (`admin`) 才能使用 `scope: "all"` 来查询所有(包括已关闭的)工单。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
| 字段 | 类型 | 描述 | 默认值/规则 |
| ----------- | -------- | -------------------------------------------------------------------- | ------------ |
| `scope` | string | 查询范围: `active` (活动工单) 或 `all` (所有工单, **仅管理员**)。 | `active` |
| `block` | array of strings | 宿舍区 (Block) 列表。 | (可选) |
| `issuer` | string | 报修人学号 (支持模糊匹配)。 | (可选) |
| `category` | string | 问题分类。 | (可选) |
| `isp` | string | 宽带运营商。 | (可选) |
| `status` | string | 工单状态。 | (可选) |
| `newer_than`| string | 时间范围下限 (RFC3339 格式)。 | (可选) |
| `older_than`| string | 时间范围上限 (RFC3339 格式)。 | `time.Now()` |
**请求示例 (查询所有活动中的、特定宿舍区、新装工单)**:
```json
{
"scope": "active",
"block": ["QT", "ZH"],
"category": "first-install"
}
```
**请求示例 (管理员查询2025年11月之后创建的所有已完成工单)**:
```json
{
"scope": "all",
"status": "solved",
"newer_than": "2025-11-01T00:00:00Z"
}
```
## 响应
### 成功响应 (200 OK)
响应体包含一个 `tickets` 数组,其中每个元素都是一个符合条件的工单对象。
| 字段 | 类型 | 描述 |
| --------- | ------- | ---------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `tickets` | array | 工单对象数组 |
`tickets` 数组中每个对象的结构与 `get_ticket` API 返回的工单对象结构相同。
**响应示例**:
```json
{
"success": true,
"msg": "query success",
"tickets": [
// ... 符合条件的工单对象列表 ...
]
}
```
如果找不到匹配的工单,`tickets` 数组将为空。
### 失败响应
#### 400 Bad Request (请求错误)
- 请求体绑定失败、格式错误或未通过验证。
- `scope` 值无效 (不是 "active" 或 "all")。
- `newer_than` 时间晚于 `older_than` 时间。
```json
{
"success": false,
"msg": "invalid scope value",
"errType": 2
}
```
```json
{
"success": false,
"msg": "newerThan cannot be after olderThan",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ----------------- | --------- | ---------------- |
| "无效的片区参数" | `logic` | `block` 参数无效。 |
| "Scope参数无效" | `logic` | `scope` 参数无效。|
#### 403 Forbidden (权限错误)
- 当非网维人员尝试调用此接口时。
- 当非管理员用户尝试使用 `scope: "all"` 时。
```json
{
"success": false,
"msg": "only admin can view all tickets",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库查询错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 这是网维人员和管理员的核心查询功能。
- 普通 `operator` 只能查询 `active` (活动) 工单,而 `admin` 可以查询 `all` (所有) 工单。
- `block` 参数用于按宿舍区进行筛选,可以传入一个包含多个宿舍区代码的数组。
- 所有筛选条件都是可选的,不提供的字段不会作为筛选依据。多个条件之间是 "与" (AND) 关系。
- 时间参数 `older_than` 如果不提供,默认会使用当前时间 (`time.Now()`)。
- `newer_than` 的时间不能晚于 `older_than` 的时间,否则会返回 400 错误。
- 时间范围查询是基于工单的创建时间。

140
back/doc/API/filterUsers.md Normal file
View File

@@ -0,0 +1,140 @@
# 筛选用户 API
- **路径**: `/api/v3/filter_users`
- **方法**: `POST`
- **功能**: 根据指定条件筛选用户列表。
## 描述
此接口仅供管理员使用,用于根据一个或多个筛选条件查询和获取用户列表。可以根据姓名、电话、宿舍区、房间号、运营商和宽带账号进行组合查询。
## 认证
- **需要 JWT**: 是
- **权限要求**: 只有管理员 (`admin`) 权限的用户才能访问此 API。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
所有字段都是可选的,但至少需要提供一个字段进行筛选。
| 字段 | 类型 | 描述 |
| --------- | -------- | ------------------------------------------ |
| `name` | string | 用户姓名 (支持模糊匹配) |
| `phone` | string | 手机号码 (支持模糊匹配) |
| `block` | string | 宿舍区 |
| `room` | string | 房间号 (支持模糊匹配) |
| `isp` | string | 宽带运营商 |
| `account` | string | 宽带账号 (支持模糊匹配) |
**请求示例**:
查询朝晖所有使用中国移动宽带的用户。
```json
{
"block": "ZH",
"isp": "mobile"
}
```
## 响应
### 成功响应 (200 OK)
响应体包含一个 `profiles` 数组,其中每个元素都是一个符合条件的用户信息对象。
| 字段 | 类型 | 描述 |
| ---------- | -------- | ------------------------------------------ |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `profiles` | array | 用户信息对象数组 |
`profiles` 数组中每个对象的结构与 `view_profile` API 返回的 `profile` 对象相同。
**响应示例**:
```json
{
"success": true,
"msg": "query success",
"profiles": [
{
"sid": "20230002002",
"name": "李四",
"block": "QT",
"access": "user",
"room": "101",
"phone": "13800138001",
"isp": "中国移动",
"account": "111222333",
"wx": "user_openid_456"
},
{
"sid": "20230002005",
"name": "王五",
"block": "ZH",
"access": "operator",
"room": "203",
"phone": "13800138004",
"isp": "中国移动",
"account": "444555666",
"wx": "operator_openid_789"
}
]
}
```
如果找不到匹配的用户,`profiles` 数组将为空。
### 失败响应
#### 400 Bad Request (请求错误)
请求体绑定失败或格式错误。
```json
{
"success": false,
"msg": "cannot bind your request body: ...",
"errType": 2
}
```
#### 403 Forbidden (权限错误)
当非管理员用户尝试调用此接口时返回。
```json
{
"success": false,
"msg": "only admin can access this API",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库查询错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 这是一个仅限管理员使用的功能。
- 所有筛选条件都是可选的,不提供的字段不会作为筛选依据。
- 多个筛选条件之间是 "与" (AND) 的关系。

140
back/doc/API/getTicket.md Normal file
View File

@@ -0,0 +1,140 @@
# 获取用户工单列表 API
- **路径**: `/api/v3/get_ticket`
- **方法**: `GET`
- **功能**: 获取指定用户提交的所有工单列表。
## 描述
此接口用于查询某个用户创建的所有报修工单。普通用户只能查询自己的工单,而管理员可以查询任何用户的工单。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 普通用户 (`user` 或更高权限) 可以查看自己的工单。
- 管理员 (`admin` 权限) 可以查看任何用户的工单。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
### 查询参数
| 参数 | 类型 | 描述 | 是否必须 |
| ---- | ------ | ------------------------------------------------------------ | -------- |
| `who` | string | 要查询工单的用户的微信 OpenID。如果留空则默认为当前登录用户的 OpenID。 | 否 |
**请求示例 (查看自己工单)**:
```
GET /api/v3/get_ticket
```
**请求示例 (管理员查看他人所有工单)**:
```
GET /api/v3/get_ticket?who=another_user_openid_456
```
## 响应
### 成功响应 (200 OK)
响应体包含一个 `tickets` 数组,其中每个元素都是一个工单的详细信息。
| 字段 | 类型 | 描述 |
| ----------- | ------- | ------------------------------------------------------------ |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `tickets` | array | 工单对象数组 |
| `ticket.tid` | string | 工单 ID |
| `ticket.submitted_at` | string | 提交时间 |
| `ticket.occur_at` | string | 问题发生时间 |
| `ticket.description` | string | 问题描述 |
| `ticket.appointed_at` | string | 预约上门时间 |
| `ticket.notes` | string | 备注 |
| `ticket.priority` | string | 优先级 |
| `ticket.category` | string | 问题分类 |
| `ticket.status` | string | 当前状态 |
| `ticket.last_updated_at`| string | 最后更新时间 |
| `ticket.issuer` | object | 报修人信息对象 (结构同 `view_profile` API 的 `profile` 对象) |
**响应示例**:
```json
{
"success": true,
"msg": "query success",
"tickets": [
{
"tid": "T20251206001",
"submitted_at": "2025-12-06T10:00:00Z",
"occur_at": "2025-12-06T09:30:00Z",
"description": "宿舍 WIFI 突然无法连接,路由器灯正常。",
"appointed_at": "2025-12-07T00:00:00Z",
"notes": "明天下午都有空。",
"priority": "medium",
"category": "无法连接",
"status": "scheduled",
"last_updated_at": "2025-12-06T10:00:00Z",
"issuer": {
"sid": "20230001001",
"name": "张三",
"block": "A",
"access": "user",
"room": "101",
"phone": "13800138000",
"isp": "中国移动",
"account": "123456789",
"wx": "user_openid_123"
}
}
]
}
```
如果用户没有任何工单,`tickets` 数组将为空。
### 失败响应
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| -------------- | --------- | -------------- |
| `no such user` | `logic` | 目标用户不存在 |
#### 403 Forbidden (权限错误)
- 当非管理员用户尝试查看其他用户的工单时返回。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时返回。
```json
{
"success": false,
"msg": "only admins can view other users' own tickets",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 如果不提供 `who` 查询参数API 将自动查询当前认证用户的所有工单。
- 返回的工单列表包含了每个工单的详细信息以及报修人的完整个人信息。
- 这是一个查询操作,不会修改任何数据。

143
back/doc/API/getTraces.md Normal file
View File

@@ -0,0 +1,143 @@
# 获取工单追踪记录 API
- **路径**: `/api/v3/get_traces`
- **方法**: `GET`
- **功能**: 获取指定工单的所有处理和状态变更记录。
## 描述
此接口用于查询一个特定工单从创建到当前状态的所有追踪记录Traces。用户可以查看自己工单的处理进度网维人员则可以查看所有他们有权访问的工单的完整历史记录。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 工单的创建者 (`user` 权限) 可以查看该工单的追踪记录。
- 网维人员 (`operator` 或更高权限) 可以查看任何工单的追踪记录。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
### 查询参数
| 参数 | 类型 | 描述 | 是否必须 |
| ---- | ------ | ---------------- | -------- |
| `tid` | string | 要查询的工单 ID。 | 是 |
**请求示例**:
```
GET /api/v3/get_traces?tid=123
```
## 响应
### 成功响应 (200 OK)
响应体包含一个 `traces` 数组,其中每个元素都是一条工单处理记录。
| 字段 | 类型 | 描述 |
| ----------- | ------- | ------------------------------------------------------------ |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `traces` | array | 追踪记录对象数组 |
| `trace.opid` | integer | 操作记录的唯一 ID |
| `trace.tid` | integer | 所属工单的 ID |
| `trace.updated_at` | string | 本次记录的更新时间 |
| `trace.op` | string | 操作人员的 ID (如果是用户自己取消,可能为特殊值如 "-1") |
| `trace.op_name` | string | 操作人的姓名 |
| `trace.new_status` | string | 本次操作后工单的新状态 |
| `trace.new_priority` | string | 本次操作后工单的新优先级 |
| `trace.new_appointment`| string | 本次操作后工单的新预约时间 |
| `trace.new_category` | string | 本次操作后工单的类型 |
| `trace.remark` | string | 本次操作的备注信息 |
**响应示例**:
```json
{
"success": true,
"msg": "query success",
"traces": [
{
"opid": 1,
"tid": 123,
"updated_at": "2025-12-06T10:00:00Z",
"op": "-1",
"new_status": "fresh",
"new_priority": "mainline",
"new_appointment": "",
"remark": "工单已创建"
},
{
"opid": 3,
"tid": 123,
"updated_at": "2025-12-06T15:30:00Z",
"op": "W007",
"new_status": "solved",
"new_priority": "",
"new_appointment": "",
"remark": "问题已解决,用户确认网络恢复正常。"
}
]
}
```
如果工单不存在,`traces` 数组将为空(或返回 `ErrNoSuchTicket` 错误)。
### 失败响应
#### 400 Bad Request (请求错误)
- `tid` 参数缺失或格式不正确。
- 无法获取工单信息(例如,工单不存在)。
```json
{
"success": false,
"msg": "missing required URL parameter: tid",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ------------------ | --------- | ----------------------------- |
| "无法找到对应的工单" | `logic` | 提供的 `tid` 对应的工单不存在。 |
#### 403 Forbidden (权限错误)
- 当用户尝试查看不属于自己的工单,并且该用户不是网维人员时返回。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时返回。
```json
{
"success": false,
"msg": "you can only view ticket traces of your own",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库查询错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 此 API 返回的记录是按时间顺序排列的,可以清晰地展示工单的整个生命周期。
- `op` 字段标识了执行该操作的人员。
- 这是一个只读操作,不会对工单或追踪记录进行任何修改。

View File

@@ -0,0 +1,149 @@
# 添加维修记录 (New Repair Trace) API
- **路径**: `/api/v3/new_repair_trace`
- **方法**: `POST`
- **功能**: 网维人员为工单添加处理记录、更新状态或修改其他属性。
## 描述
此接口是网维人员的核心工具,用于记录对报修工单的每一次操作。无论是状态变更(如“改日修”、“已完成”)、优先级调整,还是添加备注,都通过此接口完成。每一次调用都会在工单下生成一条新的追踪记录 (trace)。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 必须是网维人员 (`operator` 或更高权限) 才能调用此 API。
- 只有管理员 (`admin`) 才能修改工单的 `priority` (优先级)。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
| 字段 | 类型 | 描述 | 校验规则 |
| ---------------- | -------- | -------------------------------------------------------------------- | ------------ |
| `tid` | integer | 要更新的工单 ID | `required` |
| `remark` | string | 本次操作的备注信息,例如 | `required` |
| `new_status` | string | 工单的新状态 | (可选) |
| `new_priority` | string | **(仅管理员)** 工单的新优先级 | (可选) |
| `new_appointment`| string | 新的预约上门日期 (RFC3339 日期格式, 例如: "2025-12-08T00:00:00Z") | (可选) |
| `new_category` | string | 新工单类型 | (可选) |
**请求示例 (更新状态和备注)**:
```json
{
"tid": 123,
"remark": "已电话联系用户,指导其重启路由器后网络恢复正常。工单完成。",
"new_status": "solved"
}
```
**请求示例 (重新安排上门时间)**:
```json
{
"tid": 124,
"remark": "用户今天没空,改约明天下午。",
"new_status": "scheduled",
"new_appointment": "2025-12-08T00:00:00Z"
}
```
## 响应
### 成功响应 (200 OK)
| 字段 | 类型 | 描述 |
| ------- | ------- | -------------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
**响应示例**:
```json
{
"success": true,
"msg": "new trace added"
}
```
### 失败响应
#### 400 Bad Request (请求错误)
- 请求体绑定失败、格式错误或未通过验证。
- 当设置了 `new_appointment``new_status` 不是 `scheduled` 时。
```json
{
"success": false,
"msg": "invalid request body: ...",
"errType": 2
}
```
```json
{
"success": false,
"msg": "only appointed status can set appointment time",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ----------------------- | --------- | ------------------------------------------ |
|"无法找到对应的工单" | `logic` | 提供的 `tid` 对应的工单不存在。 |
| "无法找到对应的网维成员" | `logic` | 操作者(网维人员)信息不存在。 |
|"您的工单状态更新请求不符合逻辑"| `logic` | 新状态不符合工单状态流转规则 |
#### 403 Forbidden (权限错误)
- 当非网维人员尝试调用此接口时。
- 当非管理员尝试修改 `new_priority` 时。
```json
{
"success": false,
"msg": "only Network Support staff can access this API",
"errType": 3
}
```
```json
{
"success": false,
"msg": "only admin can change ticket priority",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 这是网维人员更新工单的主要方式。
- `remark` 字段是必填的,用于记录每次操作的内容。
- 只有在 `new_status` 设置为 `scheduled` 时,才能提供 `new_appointment` 字段。
- 工单状态的变更必须遵循预定义的逻辑流程。
- 只有管理员有权限调整工单的优先级。
- 这个 API 的底层实现是 `logic.AppendTrace`,与 `cancelTicket` API 共享部分逻辑。

141
back/doc/API/newTicket.md Normal file
View File

@@ -0,0 +1,141 @@
# 创建新工单 API
- **路径**: `/api/v3/new_ticket`
- **方法**: `POST`
- **功能**: 用户提交新的报修工单。
## 描述
此接口允许已注册用户提交新的网络报修工单。用户需要描述问题、问题发生时间、选择问题分类等。管理员可以为其他用户创建工单,并指定工单的初始状态和优先级。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 任何已激活的用户 (`user` 或更高权限) 都可以为自己创建工单。
- 只有管理员 (`admin`) 可以为其他用户创建工单,或在创建时指定 `status``priority`
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
| 字段 | 类型 | 描述 | 校验规则 |
| ------------- | -------- | -------------------------------------------------------------------- | ------------ |
| `issuer_sid` | string | 报修人的学号 | `required` |
| `description` | string | 问题描述 | `required` |
| `category` | string | 问题分类 | `required` |
| `occur_at` | string | 问题发生时间 (RFC3339 格式, 例如: "2025-12-06T10:00:00Z") | `required` |
| `appointed_at`| string | 预约上门维修日期 (RFC3339 日期格式, 例如: "2025-12-07T00:00:00Z") | (可选) |
| `notes` | string | 备注信息 | (可选) |
| `status` | string | **(仅管理员)** 工单状态) | (可选) |
| `priority` | string | **(仅管理员)** 工单优先级 | (可选) |
**请求示例 (普通用户)**:
```json
{
"issuer_sid": "2025020202022",
"description": "宿舍 WIFI 突然无法连接,路由器灯正常。",
"category": "ip-or-device",
"occur_at": "2025-12-06T09:30:00Z",
"appointed_at": "2025-12-07T00:00:00Z",
"notes": "明天下午都有空。"
}
```
**请求示例 (管理员)**:
```json
{
"issuer_sid": "2025020202022",
"description": "用户反映整个楼层网络波动。",
"category": "网络掉线",
"occur_at": "2025-12-06T08:00:00Z",
"status": "fresh",
"priority": "assigned"
}
```
## 响应
### 成功响应 (201 Created)
| 字段 | 类型 | 描述 |
| ------- | ------- | -------------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `tid` | string | 编号 |
**响应示例**:
```json
{
"success": true,
"msg": "new ticket created",
"tid": 12345
}
```
### 失败响应
#### 400 Bad Request (请求错误)
请求体绑定失败、格式错误或未通过验证。
```json
{
"success": false,
"msg": "invalid request body: ...",
"errType": "request"
}
```
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| ---------------------------------------- | --------- | ------------------------------------------ |
| `no such user` | `logic` | `issuer_sid` 对应的用户不存在 |
| `appointment time is invalid` | `logic` | 预约时间 `appointed_at` 在当前时间之前 |
| `occur time is invalid` | `logic` | 问题发生时间 `occur_at` 在当前时间之后 |
| `you have too many active tickets` | `logic` | 用户有过多例如超过3个未完成的工单 |
#### 403 Forbidden (权限错误)
- 当非管理员用户尝试为他人创建工单时。
- 当非管理员用户在创建工单时尝试设置 `status``priority` 字段时。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时。
```json
{
"success": false,
"msg": "only admins can create tickets for other users",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 普通用户调用时,`issuer_sid` 必须是自己的学号;
- `occur_at` 时间不能晚于当前提交时间。
- `appointed_at` 如果提供,必须是未来的日期。如果提供了 `appointed_at`,工单状态会自动设置为 `scheduled`(除非管理员手动指定了其他状态)。
- 一个用户不能有太多当前限制为3个处于活动状态`canceled``completed`)的工单。
- `status``priority` 字段仅供管理员在创建时设置,普通用户提交的工单将使用系统默认值。

127
back/doc/API/register.md Normal file
View File

@@ -0,0 +1,127 @@
# 注册 API
- **路径**: `/api/v3/register`
- **方法**: `POST`
- **功能**: 为新用户创建账户。
## 描述
此接口用于新用户进行注册。用户需要提供其个人信息和联系方式。服务器将验证所提供信息的有效性,并在数据库中创建一个新的用户记录。
## 认证
- **需要 JWT**: 是
- **权限要求**: 调用此接口的 JWT 负载中,用户的 `access` 级别必须是 `unregistered`。已注册用户无法调用此接口。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ---------------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
| `Content-Type` | string | 必须是 `application/json` |
### 请求体 (JSON)
| 字段 | 类型 | 描述 | 校验规则 |
| --------- | -------- | ------------------------------------------ | ------------ |
| `sid` | string | 用户的学号 | `required` |
| `name` | string | 用户的真实姓名 | `required` |
| `block` | string | 宿舍楼 | `required` ,`wts.block`枚举 |
| `room` | string | 房间号 | `required` |
| `phone` | string | 手机号码 | `required` 必须为有效的中国大陆11为手机号 |
| `isp` | string | 宽带运营商 | `required``wts.isp` |
| `account` | string | 宽带账号 | `required` |
### 命令行参数
如果后端开启跳过JWT模式的话需要提供`op`参数作为OpenID
**请求示例**:
```json
{
"sid": "20230001001",
"name": "哈基米",
"block": "ZH",
"room": "1501",
"phone": "13800138000",
"isp": "mobile",
"account": "12345678901"
}
```
## 响应
### 成功响应 (201 Created)
| 字段 | 类型 | 描述 |
| ------- | ------- | -------------------- |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
**响应示例**:
```json
{
"success": true,
"msg": "register success~"
}
```
### 失败响应
#### 400 Bad Request (请求错误)
请求体绑定失败、格式错误或未通过验证。
```json
{
"success": false,
"msg": "invalid request body: Key: 'RegisterRequest.Sid' Error:Field validation for 'Sid' failed on the 'required' tag",
"errType": 2
}
```
#### 400 Bad Request (业务逻辑错误)
由业务逻辑产生的已知错误。
| `msg` 内容 | `errType` | 描述 |
| ---------------------------- | --------- | ---------------------------------- |
| "抱歉,您输入的姓名或学号有误,如果确信所输入信息没有问题,请联系我们的工作人员。" | `logic` | 提供的学号在学校记录中不存在 |
| "抱歉,您输入的姓名或学号有误,如果确信所输入信息没有问题,请联系我们的工作人员。"| `logic` | 提供的学号与姓名不匹配 |
| "您已经注册了。如果您确信您还没有注册,请联系我们的工作人员。" | `logic` | 该学号已被注册 |
|"抱歉,您所使用的联系电话已经被登记,请换一个不一样的电话号码。" | `logic` | 该手机号已被其他用户注册 |
| "抱歉,您的微信已经注册过了,一个微信只能注册一个账号。" | `logic` | 该微信账号已被其他用户注册 |
#### 403 Forbidden (权限错误)
当一个已经注册的用户尝试调用此接口时返回。
```json
{
"success": false,
"msg": "only unregistered users can access this API",
"errType": 3
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": 1
}
```
## 注意事项
- 在调用此 API 前,用户必须已经通过微信授权流程,并获取了一个包含 `unregistered` 权限的 JWT。
- 提交的学号和姓名必须与学校数据库中的记录完全匹配,否则会注册失败。
- 手机号码和微信 OpenID 在系统中是唯一的,不能重复注册。

View File

@@ -0,0 +1 @@
# 工单概览 API

129
back/doc/API/viewProfile.md Normal file
View File

@@ -0,0 +1,129 @@
# 查看个人信息 API
- **路径**: `/api/v3/view_profile`
- **方法**: `GET`
- **功能**: 获取用户的个人信息。
## 描述
此接口用于查询用户的详细个人资料。普通用户可以查看自己的信息,而管理员可以查看任何用户的信息。
## 认证
- **需要 JWT**: 是
- **权限要求**:
- 普通用户 (`user` 或更高权限) 可以查看自己的信息。
- 管理员 (`admin` 权限) 可以查看任何用户的信息。
## 请求
### 请求头
| Header | 类型 | 描述 |
| --------------- | ------ | ------------------------- |
| `Authorization` | string | `Bearer <your_jwt_token>` |
### 查询参数
| 参数 | 类型 | 描述 | 是否必须 |
| ---- | ------ | ------------------------------------------------------------ | -------- |
| `who` | string | 要查询用户的微信 OpenID。如果留空则默认为当前登录用户的 OpenID。 | 否 |
**请求示例 (查看自己信息)**:
```
GET /api/v3/view_profile
```
**请求示例 (管理员查看他人信息)**:
```
GET /api/v3/view_profile?who=hajimihajimihajimi
```
## 响应
### 成功响应 (200 OK)
响应体包含一个 `profile` 对象,其中有用户的详细信息。
| 字段 | 类型 | 描述 |
| --------- | ------- | ------------------------------------------ |
| `success` | boolean | `true` 表示操作成功 |
| `msg` | string | 成功的提示信息 |
| `profile` | object | 用户信息对象 |
| `profile.sid` | string | 学号 |
| `profile.name` | string | 姓名 |
| `profile.block` | string | 宿舍楼 |
| `profile.access` | string | 用户权限等级 (例如: "user", "admin") |
| `profile.room` | string | 房间号 |
| `profile.phone` | string | 手机号码 |
| `profile.isp` | string | 宽带运营商 |
| `profile.account` | string | 宽带账号 |
| `profile.wx` | string | 微信 OpenID |
**响应示例**:
```json
{
"success": true,
"msg": "user profile",
"profile": {
"sid": "20230001001",
"name": "张三",
"block": "XH",
"access": "user",
"room": "1501",
"phone": "13800138000",
"isp": "mobile",
"account": "12345678901",
"wx": "hajimihajimihajimi"
}
}
```
### 失败响应
#### 400 Bad Request (业务逻辑错误)
| `msg` 内容 | `errType` | 描述 |
| -------------- | --------- | -------------- |
| "无法找到该微信账户所请求的用户" | `logic` | 目标用户不存在 |
#### 403 Forbidden (权限错误)
- 当非管理员用户尝试查看其他用户的信息时返回。
- 当非活跃用户(如 `unregistered`)尝试调用此接口时返回。
```json
{
"success": false,
"msg": "only admins can view other users' profiles",
"errType": "auth"
}
```
```json
{
"success": false,
"msg": "only active users can access this API",
"errType": "auth"
}
```
#### 500 Internal Server Error (服务器内部错误)
当发生未预料到的数据库错误或其他内部错误时返回。
```json
{
"success": false,
"msg": "system met a uncaught error,please view logs.",
"errType": "internal"
}
```
## 注意事项
- 如果不提供 `who` 查询参数API 将自动查询当前通过 JWT 认证的用户的信息。
- 只有管理员权限的用户才能使用 `who` 参数查询其他用户的信息。