feat: first version of backend API

This commit is contained in:
SOR
2026-08-09 20:51:28 +08:00
parent 905f1d897d
commit 8262b3469f
14 changed files with 1380 additions and 217 deletions
+346 -7
View File
@@ -22,11 +22,15 @@ class Response<T> {
## 接口总览
| 分组 | 路径前缀 | 说明 |
|----------|-------------|-------------------------------------------|
| 测试 | `/test` | 连通性测试 |
| 认证 | `/v1/auth` | 登录 / 注册 / 验证码 / Token 管理 |
| 物品管理 | `/v1/items` | 物品 / 类别 / 图片 CRUD、借还、上下架查询 |
| 分组 | 路径前缀 | 说明 |
|--------------|--------------------|-------------------------------------------|
| 测试 | `/test` | 连通性测试 |
| 认证 | `/v1/auth` | 登录 / 注册 / 验证码 / Token 管理 |
| 物品管理 | `/v1/items` | 物品 / 类别 / 图片 CRUD、借还、上下架查询 |
| 使用记录 | `/v1/usages` | 使用记录 CRUD、图片、当前/按用户查询 |
| 财务管理 | `/v1/finance` | 财务记录 / 分类 CRUD、凭证图片上传 |
| 财务凭证图片 | `/v1/proof-images` | 财务凭证图片 CRUD |
| 邮件通知 | `/v1/email` | 通知设置、收件邮箱启用状态 |
---
@@ -34,7 +38,7 @@ class Response<T> {
### GET /hello
公开接口。
需要认证。
**响应**
@@ -57,6 +61,8 @@ class Response<T> {
### POST /login
以 `application/x-www-form-urlencoded` 表单提交。
**请求参数**
| 字段 | 类型 | 说明 |
@@ -113,7 +119,7 @@ class data {
```typescript
class data {
"token": string;
"expire": time;
"expire": Date;
}
```
@@ -344,6 +350,339 @@ class Page<T> {
---
## 分组:使用记录 `/v1/usages`
| 方法 | 路径 | 认证 | 说明 |
|--------|------------------------------|------|--------------------------------------|
| GET | `/usages` | 需要 | 分页查询使用记录 |
| POST | `/usages` | 需要 | 创建使用记录 |
| PUT | `/usages` | 需要 | 更新使用记录 |
| DELETE | `/usages` | 需要 | 删除使用记录 |
| POST | `/usages/{id}/upload_images` | 需要 | 上传使用记录图片(multipart) |
| GET | `/usages/current` | 需要 | 获取当前使用中的记录 |
| GET | `/usages/by_user` | 需要 | 根据用户姓名获取使用记录 |
| GET | `/usages/images` | 需要 | 查询使用记录图片列表 |
| POST | `/usages/images` | 需要 | 创建使用记录图片 |
| PUT | `/usages/images` | 需要 | 更新使用记录图片 |
| DELETE | `/usages/images` | 需要 | 删除使用记录图片(同时删除物理文件) |
### 实体定义
```typescript
class BorrowRecord {
"id": number | null;
"itemId": number;
"borrower": string;
"quantity": number;
"borrowDate": string | null;
"dueDate": string | null;
"returnDate": string | null;
"status": string; // BORROWED / RETURNED / OVERDUE / CANCELED
"approver": string | null;
"note": string | null;
"createdAt": string | null;
"updatedAt": string | null;
}
```
### GET /usages
**请求参数**
| 字段 | 类型 | 说明 |
|----------|---------|---------------------|
| pageNum | number | 页码,默认 `1` |
| pageSize | number | 每页条数,默认 `10` |
| keyword | string? | 按借入人模糊搜索 |
| status | string? | 按状态过滤 |
**响应 data**:`Page<BorrowRecord>`
### POST /usages
**请求体**:`BorrowRecord`(`id` / `createdAt` / `updatedAt` 由服务端填充)
**响应 data**:`null`
### PUT /usages
**请求体**:`BorrowRecord`(须包含 `id`)
**响应 data**:`null`
### DELETE /usages
**请求参数**
| 字段 | 类型 | 说明 |
|------|--------|---------|
| id | number | 记录 ID |
**响应 data**:`null`
### POST /usages/{id}/upload_images
**请求**:`multipart/form-data`,字段名 `files`,可传多个图片文件
**响应 data**:`null`
### GET /usages/current
**请求参数**:无
**响应 data**:`BorrowRecord[]`(当前 `BORROWED` 与 `OVERDUE` 记录)
### GET /usages/by_user
**请求参数**
| 字段 | 类型 | 说明 |
|------|---------|------------|
| name | string? | 借入人姓名 |
**响应 data**:`BorrowRecord[]`
### GET /usages/images
**请求参数**:无
**响应 data**:`Attachment[]`(`relatedTable` 为 `"borrow_records"` 的图片)
### POST /usages/images
**请求体**:`Attachment`(`id` / `uploadedAt` 由服务端填充)
**响应 data**:`null`
### PUT /usages/images
**请求体**:`Attachment`(须包含 `id`)
**响应 data**:`null`
### DELETE /usages/images
**请求参数**
| 字段 | 类型 | 说明 |
|------|--------|----------|
| id | number | 图片 ID |
**响应 data**:`null`
---
## 分组:财务管理 `/v1/finance`
| 方法 | 路径 | 认证 | 说明 |
|--------|-------------------------------|------|---------------------------------------|
| GET | `/finance` | 需要 | 分页查询财务记录 |
| POST | `/finance` | 需要 | 创建财务记录 |
| PUT | `/finance` | 需要 | 更新财务记录 |
| DELETE | `/finance` | 需要 | 删除财务记录 |
| POST | `/finance/{id}/upload_images` | 需要 | 上传财务凭证图片(multipart) |
| DELETE | `/finance/{id}` | 需要 | 删除财务记录(发送邮件通知) |
| GET | `/finance/categories` | 需要 | 查询财务分类列表 |
| POST | `/finance/categories` | 需要 | 创建财务分类 |
| PUT | `/finance/categories` | 需要 | 更新财务分类 |
| DELETE | `/finance/categories` | 需要 | 删除财务分类 |
### 实体定义
```typescript
class FinanceRecord {
"id": number | null;
"recordNo": string | null;
"type": string; // PURCHASE / REFUND / REPAIR / DEPRECIATION / OTHER
"relatedItemId": number | null;
"amount": number; // BigDecimal
"currency": string; // 默认 "CNY"
"vendor": string | null;
"occurredAt": string | null;
"recordedBy": number | null;
"note": string | null;
"createdAt": string | null;
}
```
### GET /finance
**请求参数**
| 字段 | 类型 | 说明 |
|----------|---------|--------------------------------|
| pageNum | number | 页码,默认 `1` |
| pageSize | number | 每页条数,默认 `10` |
| keyword | string? | 按单号 / 供应商 / 备注模糊搜索 |
| type | string? | 按类型过滤 |
| start | string? | 发生时间起点 |
| end | string? | 发生时间终点 |
| vendor | string? | 按供应商过滤 |
| itemId | number? | 按关联物品 ID 过滤 |
**响应 data**:`Page<FinanceRecord>`
### POST /finance
**请求体**:`FinanceRecord`(`id` / `createdAt` 由服务端填充)
**响应 data**:`null`
### PUT /finance
**请求体**:`FinanceRecord`(须包含 `id`)
**响应 data**:`null`
### DELETE /finance
**请求参数**
| 字段 | 类型 | 说明 |
|------|--------|---------|
| id | number | 记录 ID |
**响应 data**:`null`
### POST /finance/{id}/upload_images
**请求**:`multipart/form-data`,字段名 `files`,可传多个图片文件
**响应 data**:`null`
### DELETE /finance/{id}
删除财务记录,并向 `recordedBy` 对应账号的邮箱发送删除通知。
**响应 data**:`null`
### GET /finance/categories
**请求参数**:无
**响应 data**:`Category[]`
### POST /finance/categories
**请求体**:`Category`(`id` / `createdAt` / `updatedAt` 由服务端填充)
**响应 data**:`null`
### PUT /finance/categories
**请求体**:`Category`(须包含 `id`)
**响应 data**:`null`
### DELETE /finance/categories
**请求参数**
| 字段 | 类型 | 说明 |
|------|--------|----------|
| id | number | 分类 ID |
**响应 data**:`null`
---
## 分组:财务凭证图片 `/v1/proof-images`
| 方法 | 路径 | 认证 | 说明 |
|--------|------------------------|------|-----------------------------------|
| GET | `/proof-images` | 需要 | 查询财务凭证图片列表 |
| POST | `/proof-images` | 需要 | 创建财务凭证图片 |
| PUT | `/proof-images` | 需要 | 更新财务凭证图片 |
| DELETE | `/proof-images` | 需要 | 删除财务凭证图片 |
| DELETE | `/proof-images/{id}` | 需要 | 删除凭证图片(同时删除物理文件) |
凭证图片为 `relatedTable` 为 `"finance_records"` 的 `Attachment`,与 `/items/images` 共用 `Attachment` 实体。
### GET /proof-images
**请求参数**:无
**响应 data**:`Attachment[]`
### POST /proof-images
**请求体**:`Attachment`(`id` / `uploadedAt` 由服务端填充)
**响应 data**:`null`
### PUT /proof-images
**请求体**:`Attachment`(须包含 `id`)
**响应 data**:`null`
### DELETE /proof-images
**请求参数**
| 字段 | 类型 | 说明 |
|------|--------|----------|
| id | number | 图片 ID |
**响应 data**:`null`
### DELETE /proof-images/{id}
删除图片并清理物理文件。
**响应 data**:`null`
---
## 分组:邮件通知 `/v1/email`
| 方法 | 路径 | 认证 | 说明 |
|--------|--------------------------|------|-------------------------|
| GET | `/notification-settings` | 需要 | 获取通知设置和邮箱列表 |
| POST | `/notification-settings` | 需要 | 创建 / 更新通知设置 |
| POST | `/toggle-email-status` | 需要 | 切换邮箱启用 / 禁用状态 |
### 实体定义
```typescript
class EmailNotice {
"id": number | null;
"name": string | null;
"targetEmails": string | null;
"subject": string | null;
"body": string | null;
"enabled": boolean; // 默认 true
"scheduleCron": string | null;
"lastSentAt": string | null;
"createdAt": string | null;
"updatedAt": string | null;
}
```
### GET /notification-settings
**请求参数**:无
**响应 data**:`EmailNotice[]`
### POST /notification-settings
**请求体**:`EmailNotice`。`id` 为 `null` 时创建新记录,否则更新已有记录。
**响应 data**:`null`
### POST /toggle-email-status
**请求参数**
| 字段 | 类型 | 说明 |
|------|---------|----------|
| id | number? | 通知 ID |
**响应 data**:`null`
---
## 其他
### WebSocket