691 lines
19 KiB
Markdown
691 lines
19 KiB
Markdown
# API 文档
|
||
|
||
Base URL:`http://localhost:8080/api`
|
||
|
||
## 通用约定
|
||
|
||
所有接口均返回统一 JSON 结构:
|
||
|
||
```typescript
|
||
class Response<T> {
|
||
"code": number;
|
||
"message": string;
|
||
"data": T | null;
|
||
}
|
||
```
|
||
|
||
- `code === 200` 表示成功;**`code !== 200` 时 `data` 恒为 `null`**
|
||
- 除特别标注(公开)外,接口需在请求头携带 `Authorization: Bearer <token>`
|
||
- 下文路径均省略 `/api` 前缀,`data` 仅给出 `T` 的声明
|
||
- 部分 `/test` 接口的返回值不遵循上述格式
|
||
- 前端类示例使用 **TypeScript** 类定义
|
||
|
||
## 接口总览
|
||
|
||
| 分组 | 路径前缀 | 说明 |
|
||
|--------------|--------------------|-------------------------------------------|
|
||
| 测试 | `/test` | 连通性测试 |
|
||
| 认证 | `/v1/auth` | 登录 / 注册 / 验证码 / Token 管理 |
|
||
| 物品管理 | `/v1/items` | 物品 / 类别 / 图片 CRUD、借还、上下架查询 |
|
||
| 使用记录 | `/v1/usages` | 使用记录 CRUD、图片、当前/按用户查询 |
|
||
| 财务管理 | `/v1/finance` | 财务记录 / 分类 CRUD、凭证图片上传 |
|
||
| 财务凭证图片 | `/v1/proof-images` | 财务凭证图片 CRUD |
|
||
| 邮件通知 | `/v1/email` | 通知设置、收件邮箱启用状态 |
|
||
|
||
---
|
||
|
||
## 分组:测试 `/test`
|
||
|
||
### GET /hello
|
||
|
||
需要认证。
|
||
|
||
**响应**
|
||
|
||
```typescript
|
||
"Hello Kotlin WebFlux!"
|
||
```
|
||
|
||
---
|
||
|
||
## 分组:认证 `/v1/auth`
|
||
|
||
| 方法 | 路径 | 认证 | 说明 |
|
||
|--------|---------------------------|------|--------------------------|
|
||
| POST | `/login` | 公开 | 登录,获取 Token |
|
||
| GET | `/logout` | 需要 | 注销,Token 加入黑名单 |
|
||
| GET | `/ask-code` | 公开 | 发送邮箱验证码 |
|
||
| POST | `/register` | 公开 | 邮箱注册 |
|
||
| POST | `/reset` | 公开 | 重置密码 |
|
||
| GET | `/relogin` | 需要 | 用旧 Token 换取新 Token |
|
||
|
||
### POST /login
|
||
|
||
以 `application/x-www-form-urlencoded` 表单提交。
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|----------|--------|----------|
|
||
| username | string | 用户名 |
|
||
| password | string | 密码 |
|
||
|
||
**响应 data**
|
||
|
||
```typescript
|
||
class data {
|
||
"username": string;
|
||
"role": string;
|
||
"token": string;
|
||
"expire": Date;
|
||
}
|
||
```
|
||
|
||
### GET /logout
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**:`null`
|
||
|
||
### GET /ask-code
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|-------|-----------------------------|------------------------------------|
|
||
| email | string | 接收验证码的邮箱 |
|
||
| type | `register` \| `reset` | 验证码用途(注册 / 重置密码) |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /register
|
||
|
||
**请求体字段**:`email`、`code`、`username`、`password`
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /reset
|
||
|
||
**请求体字段**:`email`、`code`、`password`
|
||
|
||
**响应 data**:`null`
|
||
|
||
### GET /relogin
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**
|
||
|
||
```typescript
|
||
class data {
|
||
"token": string;
|
||
"expire": Date;
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 分组:物品管理 `/v1/items`
|
||
|
||
| 方法 | 路径 | 认证 | 说明 |
|
||
|--------|---------------------------------|------|----------------------------------------|
|
||
| GET | `/items` | 需要 | 分页查询物品 |
|
||
| POST | `/items` | 需要 | 创建物品 |
|
||
| PUT | `/items` | 需要 | 更新物品 |
|
||
| DELETE | `/items` | 需要 | 删除物品(同时清理其图片) |
|
||
| POST | `/items/{id}/upload_images` | 需要 | 上传物品图片(multipart) |
|
||
| POST | `/items/{id}/set_primary_image` | 需要 | 设置物品主图 |
|
||
| POST | `/items/{id}/borrow` | 需要 | 借用物品(扣减可用库存) |
|
||
| POST | `/items/{id}/return_item` | 需要 | 归还物品(恢复可用库存) |
|
||
| GET | `/items/available` | 需要 | 获取可用物品列表 |
|
||
| GET | `/items/in_use` | 需要 | 获取使用中物品列表 |
|
||
| GET | `/items/categories` | 需要 | 查询物品类别列表 |
|
||
| POST | `/items/categories` | 需要 | 创建物品类别 |
|
||
| PUT | `/items/categories` | 需要 | 更新物品类别 |
|
||
| DELETE | `/items/categories` | 需要 | 删除物品类别 |
|
||
| GET | `/items/images` | 需要 | 查询物品图片列表 |
|
||
| POST | `/items/images` | 需要 | 创建物品图片 |
|
||
| PUT | `/items/images` | 需要 | 更新物品图片 |
|
||
| DELETE | `/items/images` | 需要 | 删除物品图片(同时删除物理文件) |
|
||
|
||
### 实体定义
|
||
|
||
```typescript
|
||
class Item {
|
||
"id": number | null;
|
||
"code": string; // 物品编号 / 资产编号
|
||
"name": string;
|
||
"categoryId": number | null;
|
||
"model": string | null;
|
||
"brand": string | null;
|
||
"location": string | null;
|
||
"totalQuantity": number;
|
||
"availableQuantity": number;
|
||
"unit": string; // 默认 "件"
|
||
"price": number | null;
|
||
"purchaseDate": string | null;
|
||
"supplier": string | null;
|
||
"status": string; // normal / disabled / lost / repair
|
||
"description": string | null;
|
||
"imagePath": string | null;
|
||
"createdBy": number | null;
|
||
"createdAt": string | null;
|
||
"updatedAt": string | null;
|
||
}
|
||
```
|
||
|
||
```typescript
|
||
class Category {
|
||
"id": number | null;
|
||
"name": string;
|
||
"parentId": number | null;
|
||
"description": string | null;
|
||
"createdAt": string | null;
|
||
"updatedAt": string | null;
|
||
}
|
||
```
|
||
|
||
```typescript
|
||
class Attachment {
|
||
"id": number | null;
|
||
"relatedTable": string | null; // 关联表名,如 "items"
|
||
"relatedId": number | null; // 关联记录 ID
|
||
"fileName": string | null;
|
||
"filePath": string | null;
|
||
"fileSize": number | null;
|
||
"contentType": string | null;
|
||
"uploadedBy": number | null;
|
||
"uploadedAt": string | null;
|
||
}
|
||
```
|
||
|
||
```typescript
|
||
class Page<T> {
|
||
"records": T[];
|
||
"total": number;
|
||
"size": number;
|
||
"current": number;
|
||
"pages": number;
|
||
}
|
||
```
|
||
|
||
### GET /items
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|----------|---------|-----------------------------------|
|
||
| pageNum | number | 页码,默认 `1` |
|
||
| pageSize | number | 每页条数,默认 `10` |
|
||
| keyword | string? | 按名称 / 编号模糊搜索 |
|
||
| status | string? | 按状态过滤,如 `normal` |
|
||
|
||
**响应 data**:`Page<Item>`
|
||
|
||
### POST /items
|
||
|
||
**请求体**:`Item`(`id` / `createdAt` / `updatedAt` 由服务端填充)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### PUT /items
|
||
|
||
**请求体**:`Item`(须包含 `id`)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### DELETE /items
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|--------|---------|
|
||
| id | number | 物品 ID |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /items/{id}/upload_images
|
||
|
||
**请求**:`multipart/form-data`,字段名 `files`,可传多个图片文件
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /items/{id}/set_primary_image
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---------|--------|------------------------------------------|
|
||
| imageId | number | 附件 ID,须属于该物品 |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /items/{id}/borrow
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|----------|--------|--------------------|
|
||
| quantity | number | 借用数量,默认 `1` |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### POST /items/{id}/return_item
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|----------|--------|--------------------|
|
||
| quantity | number | 归还数量,默认 `1` |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### GET /items/available
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**:`Item[]`
|
||
|
||
### GET /items/in_use
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**:`Item[]`
|
||
|
||
### GET /items/categories
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**:`Category[]`
|
||
|
||
### POST /items/categories
|
||
|
||
**请求体**:`Category`(`id` / `createdAt` / `updatedAt` 由服务端填充)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### PUT /items/categories
|
||
|
||
**请求体**:`Category`(须包含 `id`)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### DELETE /items/categories
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|--------|----------|
|
||
| id | number | 类别 ID |
|
||
|
||
**响应 data**:`null`
|
||
|
||
### GET /items/images
|
||
|
||
**请求参数**:无
|
||
|
||
**响应 data**:`Attachment[]`(`relatedTable` 为 `"items"` 的图片)
|
||
|
||
### POST /items/images
|
||
|
||
**请求体**:`Attachment`(`id` / `uploadedAt` 由服务端填充)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### PUT /items/images
|
||
|
||
**请求体**:`Attachment`(须包含 `id`)
|
||
|
||
**响应 data**:`null`
|
||
|
||
### DELETE /items/images
|
||
|
||
**请求参数**
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|--------|----------|
|
||
| id | number | 图片 ID |
|
||
|
||
**响应 data**:`null`
|
||
|
||
---
|
||
|
||
## 分组:使用记录 `/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
|
||
|
||
`ws://localhost:8080/ws` — 目前不支持
|