save code
This commit is contained in:
@@ -286,3 +286,53 @@ Press CTRL+C to quit
|
||||
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /api/hairstyles HTTP/1.1" 200 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:07:35] "POST /api/change-hair HTTP/1.1" 200 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:08:15] "POST /api/change-hair-color HTTP/1.1" 200 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:20] "GET /api/hairstyles HTTP/1.1" 200 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:42] "GET /api/hairstyles HTTP/1.1" 200 -
|
||||
204.76.203.51 - - [10/Feb/2026 11:06:23] "GET http://azenv.net/ HTTP/1.1" 200 -
|
||||
204.76.203.51 - - [10/Feb/2026 11:06:24] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
|
||||
59.173.110.245 - - [10/Feb/2026 11:10:15] "HEAD http://110.242.68.4/ HTTP/1.1" 200 -
|
||||
42.48.38.44 - - [10/Feb/2026 11:48:17] "CONNECT www.baidu.com:443 HTTP/1.1" 405 -
|
||||
42.48.38.44 - - [10/Feb/2026 11:48:17] "GET http://www.minghui.org/ HTTP/1.1" 200 -
|
||||
42.48.38.44 - - [10/Feb/2026 11:48:17] "CONNECT dnspod.qcloud.com:443 HTTP/1.1" 405 -
|
||||
223.166.22.69 - - [10/Feb/2026 11:48:33] "CONNECT www.so.com:443 HTTP/1.1" 405 -
|
||||
123.178.210.17 - - [10/Feb/2026 13:08:44] "GET / HTTP/1.1" 200 -
|
||||
182.138.158.133 - - [10/Feb/2026 13:09:14] "GET / HTTP/1.1" 200 -
|
||||
1.85.216.80 - - [10/Feb/2026 13:09:17] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
64.62.156.122 - - [10/Feb/2026 13:37:43] "GET / HTTP/1.1" 200 -
|
||||
64.62.156.130 - - [10/Feb/2026 13:38:12] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
204.76.203.51 - - [10/Feb/2026 15:03:23] "GET http://azenv.net/ HTTP/1.1" 200 -
|
||||
93.123.109.160 - - [10/Feb/2026 15:34:05] code 400, message Bad HTTP/0.9 request type ('\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie:')
|
||||
93.123.109.160 - - [10/Feb/2026 15:34:05] "\x03\x00\x00/*à\x00\x00\x00\x00\x00Cookie: mstshash=Administr" HTTPStatus.BAD_REQUEST -
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:16] code 400, message Bad request version ('À\x14À')
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:16] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03é\x13Êó\x16Ý?\x89÷J14\x80VdôÖ\x95\x81\x99kõIïì\x11\x00ty\x97\x1b© \x0bÓ;ðgr\x13û\x80ÜT\x13²\x0f\x1e\x89eM,\x90îö¾\x1aò\x11*õ¯c+\x84\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:19] "GET / HTTP/1.1" 200 -
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:26] code 505, message Invalid HTTP version (2.0)
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:26] "PRI * HTTP/2.0" HTTPStatus.HTTP_VERSION_NOT_SUPPORTED -
|
||||
167.94.138.44 - - [10/Feb/2026 16:03:30] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
167.94.138.44 - - [10/Feb/2026 16:04:26] code 400, message Bad request version ('À\x14À')
|
||||
167.94.138.44 - - [10/Feb/2026 16:04:26] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03·ýkas!Öy\x91$\x9c\x05߯\x17\x13j¯ùCÎ\x8b\x81\x9bkòÀD.\x83Gê ¶7÷\x0f¢\x1d!÷g\x19û\x97©¹NVô\x15\x8f\x81Ð9J©&tµ¿öf1Ã\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
|
||||
167.94.138.44 - - [10/Feb/2026 16:04:29] "GET /.well-known/security.txt HTTP/1.1" 404 -
|
||||
111.33.154.219 - - [10/Feb/2026 16:48:03] "HEAD / HTTP/1.1" 200 -
|
||||
85.217.140.19 - - [10/Feb/2026 16:56:50] code 400, message Bad request version ('À\x14À')
|
||||
85.217.140.19 - - [10/Feb/2026 16:56:50] "\x16\x03\x01\x00î\x01\x00\x00ê\x03\x03LjU¯_ì¼ö\x8fßJÞ\x8c+@\x80¯ cÝ\x96\x88õ&éi\x8e\x97.B¿¤ \x9d<\x9fõGe¼îwÞ²-º\x90¹\x8bJµDn©5-\x88eQF§ßeýÛ\x00&̨̩À/À0À+À,À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
|
||||
45.91.64.7 - - [10/Feb/2026 17:19:27] "GET / HTTP/1.0" 200 -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:46] code 400, message Bad request version ('Ó]Oß')
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:46] "\x16\x03\x01\x05¨\x01\x00\x05¤\x03\x03ÏIóÐÞ6oh)µkäc´;"I$~¿´ó\x8a\x8e½\x90xÅó\x94\x93\x87 V+¢\x94d\x1e¦Kù¹úW÷¾Ë\x9a¥\x1eÓ]Oß" HTTPStatus.BAD_REQUEST -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:46] "GET /aaa9 HTTP/1.1" 404 -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:47] code 400, message Bad request version ('À\x13À')
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:47] "\x16\x03\x01\x05¨\x01\x00\x05¤\x03\x03¾\x80A\x87\\KæJÀÂD\x04Yø×LÛü\x0cqñÙ"´+0ü\x0d\x81ïõ à\x0bgEvÁý)P\x9a.Ãî\x8aO\x98o°\x85;Q+öyA8\x14\x12<»³u\x00\x1aÀ+À/À,À0̨̩À\x09À\x13À" HTTPStatus.BAD_REQUEST -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:47] "GET /aab9 HTTP/1.1" 404 -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:48] "GET / HTTP/1.1" 200 -
|
||||
95.215.0.144 - - [10/Feb/2026 17:19:49] "GET /js/axios.min.js HTTP/1.1" 200 -
|
||||
5.101.64.6 - - [10/Feb/2026 17:19:49] "GET /js/main.js HTTP/1.1" 200 -
|
||||
45.91.64.8 - - [10/Feb/2026 17:20:01] "GET /css/style.css HTTP/1.1" 200 -
|
||||
46.161.50.108 - - [10/Feb/2026 17:20:02] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
45.91.64.6 - - [10/Feb/2026 17:20:04] "GET /api/hairstyles HTTP/1.1" 200 -
|
||||
18.218.118.203 - - [10/Feb/2026 17:34:22] "GET / HTTP/1.1" 200 -
|
||||
18.218.118.203 - - [10/Feb/2026 17:36:14] "GET / HTTP/1.1" 200 -
|
||||
18.218.118.203 - - [10/Feb/2026 17:38:32] code 400, message Bad request syntax ('SSH-2.0-Go')
|
||||
18.218.118.203 - - [10/Feb/2026 17:38:32] "SSH-2.0-Go" HTTPStatus.BAD_REQUEST -
|
||||
18.218.118.203 - - [10/Feb/2026 17:39:47] code 400, message Bad request version ('À\x14À')
|
||||
18.218.118.203 - - [10/Feb/2026 17:39:47] "\x16\x03\x01\x00{\x01\x00\x00w\x03\x03\x9duPið\x7f6lU§£®v*õN-\x8dàd\x990º®øT\x84b\x0cÆ\x0d\x00\x00\x1aÀ/À+À\x11À\x07À\x13À\x09À\x14À" HTTPStatus.BAD_REQUEST -
|
||||
210.12.133.162 - - [10/Feb/2026 18:18:13] "GET /api/hairstyles HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:19:14] "POST /api/change-hair-color HTTP/1.1" 200 -
|
||||
|
||||
+120
-59
@@ -9,25 +9,24 @@
|
||||
| 版本 | 日期 | 描述 | 作者 |
|
||||
|------|------|------|------|
|
||||
| v1.0 | 2026-01-18 | 初始版本 | 系统生成 |
|
||||
| v1.1 | 2026-02-10 | 补充发色更换接口,修正数据格式 | 系统更新 |
|
||||
|
||||
### 1.2 基本信息
|
||||
|
||||
- **API基础路径**: `/api`
|
||||
- **服务端口**: 5000(Flask)
|
||||
- **响应格式**: JSON
|
||||
- **字符编码**: UTF-8
|
||||
- **认证方式**: 无需认证
|
||||
|
||||
## 2. 响应格式
|
||||
|
||||
所有API响应均采用统一的格式:
|
||||
|
||||
### 2.1 成功响应
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {...},
|
||||
"message": ""
|
||||
"data": {...}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -36,7 +35,6 @@
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "错误信息"
|
||||
}
|
||||
```
|
||||
@@ -47,6 +45,7 @@
|
||||
|---------|------|----------|---------|-------------|
|
||||
| `/api/hairstyles` | GET | 获取发型列表 | 无 | `{ "hairstyles": [...] }` |
|
||||
| `/api/change-hair` | POST | 更换发型 | image: 文件<br>hairstyle_id: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
|
||||
| `/api/change-hair-color` | POST | 更换头发颜色 | image: 文件<br>rgb: 字符串<br>ratio: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
|
||||
|
||||
## 4. 详细接口说明
|
||||
|
||||
@@ -67,18 +66,17 @@
|
||||
"data": {
|
||||
"hairstyles": [
|
||||
{
|
||||
"id": "hair_001",
|
||||
"name": "发型1",
|
||||
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267183426772993.jpg"
|
||||
"id": "1953267161121464322",
|
||||
"name": "发型4322",
|
||||
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"
|
||||
},
|
||||
{
|
||||
"id": "hair_002",
|
||||
"name": "发型2",
|
||||
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267306382794754.jpg"
|
||||
"id": "1953267288284372994",
|
||||
"name": "发型2994",
|
||||
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267288284372994.jpg"
|
||||
}
|
||||
]
|
||||
},
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -86,18 +84,22 @@
|
||||
|
||||
| 字段名 | 类型 | 描述 |
|
||||
|-------|------|------|
|
||||
| `id` | 字符串 | 发型唯一标识符 |
|
||||
| `name` | 字符串 | 发型名称 |
|
||||
| `image_url` | 字符串 | 发型图片的OSS URL |
|
||||
| `id` | 字符串 | 发型唯一标识符(长数字串,来源于 hairId2url.txt) |
|
||||
| `name` | 字符串 | 发型名称(格式为 "发型" + ID后4位) |
|
||||
| `image_url` | 字符串 | 发型图片的阿里云 OSS URL |
|
||||
|
||||
### 4.2 更换发型
|
||||
|
||||
#### 4.2.1 请求信息
|
||||
- **路径**: `/api/change-hair`
|
||||
- **方法**: POST
|
||||
- **Content-Type**: `multipart/form-data`
|
||||
- **参数**:
|
||||
- `image`: 文件 (必填) - 用户上传的图片文件
|
||||
- `hairstyle_id`: 字符串 (必填) - 要更换的发型ID
|
||||
|
||||
| 参数名 | 类型 | 必填 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `image` | File | 是 | 用户上传的图片文件(支持 png/jpg/jpeg/gif,最大16MB) |
|
||||
| `hairstyle_id` | String | 是 | 要更换的发型ID |
|
||||
|
||||
#### 4.2.2 响应信息
|
||||
- **状态码**: 200 OK
|
||||
@@ -108,8 +110,7 @@
|
||||
"success": true,
|
||||
"data": {
|
||||
"result_image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
|
||||
},
|
||||
"message": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -117,23 +118,72 @@
|
||||
|
||||
| 字段名 | 类型 | 描述 |
|
||||
|-------|------|------|
|
||||
| `result_image` | 字符串 | 发型更换后的图片,Base64编码格式 |
|
||||
| `result_image` | 字符串 | 发型更换后的图片,Base64 Data URL 格式 |
|
||||
|
||||
#### 4.2.4 备注
|
||||
- 远程AI处理耗时较长,超时时间为120秒
|
||||
- 如果远程API调用失败,会返回原始图片作为降级处理
|
||||
|
||||
### 4.3 更换头发颜色
|
||||
|
||||
#### 4.3.1 请求信息
|
||||
- **路径**: `/api/change-hair-color`
|
||||
- **方法**: POST
|
||||
- **Content-Type**: `multipart/form-data`
|
||||
- **参数**:
|
||||
|
||||
| 参数名 | 类型 | 必填 | 描述 |
|
||||
|-------|------|------|------|
|
||||
| `image` | File | 是 | 用户上传的图片文件(支持 png/jpg/jpeg/gif,最大16MB) |
|
||||
| `rgb` | String | 是 | RGB颜色值,格式为 `"[R, G, B]"`,例如 `"[255, 106, 0]"` |
|
||||
| `ratio` | String | 是 | 颜色替换强度,范围 0.0 ~ 1.0,例如 `"0.9"` |
|
||||
|
||||
#### 4.3.2 响应信息
|
||||
- **状态码**: 200 OK
|
||||
- **响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"result_image": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 4.3.3 字段说明
|
||||
|
||||
| 字段名 | 类型 | 描述 |
|
||||
|-------|------|------|
|
||||
| `result_image` | 字符串 | 发色更换后的图片,Base64 Data URL 格式 |
|
||||
|
||||
#### 4.3.4 备注
|
||||
- 远程AI处理耗时较长,超时时间为120秒
|
||||
- 如果远程API调用失败,会返回原始图片作为降级处理
|
||||
- ratio 值越大,颜色替换效果越明显
|
||||
|
||||
## 5. 错误处理
|
||||
|
||||
### 5.1 常见错误状态码
|
||||
|
||||
| 状态码 | 描述 | 示例消息 |
|
||||
|-------|------|---------|
|
||||
| 400 | 请求参数错误 | "请上传图片"、"请选择发型" |
|
||||
| 500 | 服务器内部错误 | "获取发型列表失败: [错误信息]" |
|
||||
| 状态码 | 接口 | 描述 | 示例消息 |
|
||||
|-------|------|------|---------|
|
||||
| 400 | `/api/change-hair` | 缺少图片 | "请上传图片" |
|
||||
| 400 | `/api/change-hair` | 缺少发型ID | "请选择发型" |
|
||||
| 400 | `/api/change-hair` | 文件类型不合法 | "不支持的文件类型,请上传图片文件" |
|
||||
| 400 | `/api/change-hair-color` | 缺少图片 | "请上传图片" |
|
||||
| 400 | `/api/change-hair-color` | 缺少颜色值 | "请选择颜色" |
|
||||
| 400 | `/api/change-hair-color` | 缺少替换比例 | "请设置更换比例" |
|
||||
| 400 | `/api/change-hair-color` | 文件类型不合法 | "不支持的文件类型,请上传图片文件" |
|
||||
| 500 | `/api/hairstyles` | 服务器内部错误 | "获取发型列表失败: [错误信息]" |
|
||||
| 500 | `/api/change-hair` | 处理失败 | "处理图片失败: [错误信息]" |
|
||||
| 500 | `/api/change-hair-color` | 处理失败 | "处理图片失败: [错误信息]" |
|
||||
|
||||
### 5.2 错误响应示例
|
||||
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"data": null,
|
||||
"message": "请上传图片"
|
||||
}
|
||||
```
|
||||
@@ -146,60 +196,71 @@
|
||||
4. **测试验证**: 测试新API的功能和兼容性
|
||||
5. **部署上线**: 按计划部署变更
|
||||
|
||||
## 7. 版本控制
|
||||
## 7. 附录
|
||||
|
||||
当API需要重大变更时,应采用版本控制机制:
|
||||
### 7.1 数据结构定义
|
||||
|
||||
1. **URL版本控制**: 在API路径中添加版本号,如 `/api/v2/hairstyles`
|
||||
2. **向后兼容**: 保留旧版本API一段时间,确保前端有足够时间迁移
|
||||
3. **弃用通知**: 在响应中添加弃用警告,提示开发者使用新API
|
||||
|
||||
## 8. 最佳实践
|
||||
|
||||
1. **使用标准HTTP方法**: GET用于获取数据,POST用于提交数据
|
||||
2. **保持接口幂等性**: 相同请求应产生相同结果
|
||||
3. **合理设置缓存**: 对频繁访问的数据进行缓存,提高性能
|
||||
4. **限流保护**: 对API调用进行限流,防止滥用
|
||||
5. **日志记录**: 记录API调用日志,便于问题排查
|
||||
|
||||
## 9. 附录
|
||||
|
||||
### 9.1 数据结构定义
|
||||
|
||||
#### 9.1.1 发型对象 (Hairstyle)
|
||||
#### 7.1.1 发型对象 (Hairstyle)
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "string",
|
||||
"name": "string",
|
||||
"image_url": "string"
|
||||
"id": "1953267161121464322",
|
||||
"name": "发型4322",
|
||||
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"
|
||||
}
|
||||
```
|
||||
|
||||
#### 9.1.2 更换发型请求 (ChangeHairRequest)
|
||||
#### 7.1.2 更换发型请求 (ChangeHairRequest)
|
||||
|
||||
```
|
||||
FormData:
|
||||
- image: File
|
||||
- hairstyle_id: string
|
||||
- hairstyle_id: string (例: "1953267161121464322")
|
||||
```
|
||||
|
||||
#### 9.1.3 更换发型响应 (ChangeHairResponse)
|
||||
#### 7.1.3 更换发型响应 (ChangeHairResponse)
|
||||
|
||||
```json
|
||||
{
|
||||
"result_image": "string"
|
||||
"success": true,
|
||||
"data": {
|
||||
"result_image": "data:image/jpeg;base64,..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 9.2 开发工具推荐
|
||||
#### 7.1.4 更换发色请求 (ChangeHairColorRequest)
|
||||
|
||||
```
|
||||
FormData:
|
||||
- image: File
|
||||
- rgb: string (例: "[255, 106, 0]")
|
||||
- ratio: string (例: "0.9")
|
||||
```
|
||||
|
||||
#### 7.1.5 更换发色响应 (ChangeHairColorResponse)
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"result_image": "data:image/jpeg;base64,..."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7.2 支持的图片格式
|
||||
|
||||
| 格式 | MIME类型 |
|
||||
|------|----------|
|
||||
| PNG | image/png |
|
||||
| JPG/JPEG | image/jpeg |
|
||||
| GIF | image/gif |
|
||||
|
||||
文件大小限制:16MB
|
||||
|
||||
### 7.3 开发工具推荐
|
||||
|
||||
- **API测试**: Postman, Insomnia
|
||||
- **文档生成**: Swagger, ReDoc
|
||||
- **代码生成**: OpenAPI Generator
|
||||
|
||||
### 9.3 相关链接
|
||||
|
||||
- [RESTful API设计指南](https://restfulapi.net/)
|
||||
- [OpenAPI规范](https://swagger.io/specification/)
|
||||
- [HTTP状态码](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status)
|
||||
@@ -0,0 +1,475 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>发型更换H5项目 - API文档</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body {
|
||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "PingFang SC", "Microsoft YaHei", sans-serif;
|
||||
background: #f7f8fa;
|
||||
color: #333;
|
||||
line-height: 1.7;
|
||||
}
|
||||
|
||||
/* 侧边栏 */
|
||||
.sidebar {
|
||||
position: fixed;
|
||||
top: 0; left: 0;
|
||||
width: 260px;
|
||||
height: 100vh;
|
||||
background: #fff;
|
||||
border-right: 1px solid #e8e8e8;
|
||||
overflow-y: auto;
|
||||
padding: 24px 0;
|
||||
z-index: 100;
|
||||
}
|
||||
.sidebar-title {
|
||||
padding: 0 20px 16px;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
color: #4A90E2;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
.sidebar a {
|
||||
display: block;
|
||||
padding: 6px 20px;
|
||||
color: #555;
|
||||
text-decoration: none;
|
||||
font-size: 14px;
|
||||
transition: all .2s;
|
||||
}
|
||||
.sidebar a:hover, .sidebar a.active {
|
||||
color: #4A90E2;
|
||||
background: #f0f7ff;
|
||||
}
|
||||
.sidebar a.level-2 { padding-left: 36px; font-size: 13px; color: #888; }
|
||||
|
||||
/* 主内容 */
|
||||
.main {
|
||||
margin-left: 260px;
|
||||
padding: 32px 48px 80px;
|
||||
max-width: 960px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 28px;
|
||||
margin-bottom: 8px;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
.version-badge {
|
||||
display: inline-block;
|
||||
background: #4A90E2;
|
||||
color: #fff;
|
||||
padding: 2px 10px;
|
||||
border-radius: 12px;
|
||||
font-size: 12px;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
h2 {
|
||||
font-size: 22px;
|
||||
margin: 40px 0 16px;
|
||||
padding-bottom: 8px;
|
||||
border-bottom: 2px solid #4A90E2;
|
||||
color: #1a1a1a;
|
||||
}
|
||||
h3 {
|
||||
font-size: 18px;
|
||||
margin: 28px 0 12px;
|
||||
color: #333;
|
||||
}
|
||||
h4 {
|
||||
font-size: 15px;
|
||||
margin: 20px 0 8px;
|
||||
color: #555;
|
||||
}
|
||||
p, li { font-size: 14px; }
|
||||
p { margin-bottom: 10px; }
|
||||
ul { padding-left: 20px; margin-bottom: 12px; }
|
||||
li { margin-bottom: 4px; }
|
||||
|
||||
/* 信息卡片 */
|
||||
.info-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 8px;
|
||||
padding: 16px 20px;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.info-card .label { color: #888; font-size: 13px; }
|
||||
.info-card .value { font-weight: 600; }
|
||||
|
||||
/* 表格 */
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin: 12px 0 20px;
|
||||
font-size: 14px;
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 1px 3px rgba(0,0,0,0.05);
|
||||
}
|
||||
th {
|
||||
background: #f5f7fa;
|
||||
font-weight: 600;
|
||||
text-align: left;
|
||||
padding: 10px 14px;
|
||||
border-bottom: 2px solid #e8e8e8;
|
||||
white-space: nowrap;
|
||||
}
|
||||
td {
|
||||
padding: 10px 14px;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
}
|
||||
tr:last-child td { border-bottom: none; }
|
||||
tr:hover td { background: #fafbfc; }
|
||||
|
||||
/* 代码块 */
|
||||
pre {
|
||||
background: #1e1e2e;
|
||||
color: #cdd6f4;
|
||||
padding: 16px 20px;
|
||||
border-radius: 8px;
|
||||
overflow-x: auto;
|
||||
margin: 10px 0 16px;
|
||||
font-size: 13px;
|
||||
line-height: 1.6;
|
||||
}
|
||||
code {
|
||||
font-family: "JetBrains Mono", "Fira Code", "SF Mono", Menlo, Consolas, monospace;
|
||||
}
|
||||
:not(pre) > code {
|
||||
background: #f0f2f5;
|
||||
padding: 2px 6px;
|
||||
border-radius: 4px;
|
||||
font-size: 13px;
|
||||
color: #d63384;
|
||||
}
|
||||
|
||||
/* JSON 语法高亮 */
|
||||
.json-key { color: #89b4fa; }
|
||||
.json-string { color: #a6e3a1; }
|
||||
.json-bool, .json-null { color: #fab387; }
|
||||
.json-number { color: #f9e2af; }
|
||||
.json-bracket { color: #cdd6f4; }
|
||||
|
||||
/* 方法标签 */
|
||||
.method {
|
||||
display: inline-block;
|
||||
padding: 2px 10px;
|
||||
border-radius: 4px;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
color: #fff;
|
||||
font-family: monospace;
|
||||
}
|
||||
.method-get { background: #22c55e; }
|
||||
.method-post { background: #3b82f6; }
|
||||
|
||||
/* 接口卡片 */
|
||||
.endpoint-card {
|
||||
background: #fff;
|
||||
border: 1px solid #e8e8e8;
|
||||
border-radius: 8px;
|
||||
padding: 20px 24px;
|
||||
margin: 16px 0;
|
||||
}
|
||||
.endpoint-path {
|
||||
font-family: monospace;
|
||||
font-size: 15px;
|
||||
font-weight: 600;
|
||||
color: #1a1a1a;
|
||||
margin-left: 8px;
|
||||
}
|
||||
|
||||
/* 必填标签 */
|
||||
.required {
|
||||
color: #ef4444;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
/* 备注块 */
|
||||
.note {
|
||||
background: #fff7ed;
|
||||
border-left: 4px solid #f59e0b;
|
||||
padding: 12px 16px;
|
||||
border-radius: 0 8px 8px 0;
|
||||
margin: 12px 0;
|
||||
font-size: 13px;
|
||||
}
|
||||
.note-title { font-weight: 700; color: #d97706; margin-bottom: 4px; }
|
||||
|
||||
/* 版本历史表格 */
|
||||
.version-table td:first-child { font-weight: 600; color: #4A90E2; }
|
||||
|
||||
/* 响应式 */
|
||||
@media (max-width: 768px) {
|
||||
.sidebar { display: none; }
|
||||
.main { margin-left: 0; padding: 20px 16px; }
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<!-- 侧边栏导航 -->
|
||||
<nav class="sidebar">
|
||||
<div class="sidebar-title">API 文档导航</div>
|
||||
<a href="#section1">1. 文档说明</a>
|
||||
<a href="#section1-1" class="level-2">基本信息</a>
|
||||
<a href="#section2">2. 响应格式</a>
|
||||
<a href="#section3">3. 接口列表总览</a>
|
||||
<a href="#section4">4. 详细接口说明</a>
|
||||
<a href="#section4-1" class="level-2">4.1 获取发型列表</a>
|
||||
<a href="#section4-2" class="level-2">4.2 更换发型</a>
|
||||
<a href="#section4-3" class="level-2">4.3 更换头发颜色</a>
|
||||
<a href="#section5">5. 错误处理</a>
|
||||
<a href="#section6">6. API变更流程</a>
|
||||
<a href="#section7">7. 附录</a>
|
||||
<a href="#section7-2" class="level-2">支持的图片格式</a>
|
||||
</nav>
|
||||
|
||||
<!-- 主内容 -->
|
||||
<div class="main">
|
||||
|
||||
<h1>发型更换H5项目 API 文档</h1>
|
||||
<span class="version-badge">v1.1 · 2026-02-10</span>
|
||||
|
||||
<!-- 1. 文档说明 -->
|
||||
<h2 id="section1">1. 文档说明</h2>
|
||||
<p>本文档描述了发型更换H5项目的API接口规范,所有前后端交互都应遵循此文档。任何API变更都应先修改此文档,然后再进行代码实现。</p>
|
||||
|
||||
<h4>版本历史</h4>
|
||||
<table class="version-table">
|
||||
<tr><th>版本</th><th>日期</th><th>描述</th><th>作者</th></tr>
|
||||
<tr><td>v1.0</td><td>2026-01-18</td><td>初始版本</td><td>系统生成</td></tr>
|
||||
<tr><td>v1.1</td><td>2026-02-10</td><td>补充发色更换接口,修正数据格式</td><td>系统更新</td></tr>
|
||||
</table>
|
||||
|
||||
<h3 id="section1-1">基本信息</h3>
|
||||
<div class="info-card">
|
||||
<ul>
|
||||
<li><span class="label">API基础路径:</span><code>/api</code></li>
|
||||
<li><span class="label">服务端口:</span><span class="value">5000</span>(Flask)</li>
|
||||
<li><span class="label">响应格式:</span>JSON</li>
|
||||
<li><span class="label">字符编码:</span>UTF-8</li>
|
||||
<li><span class="label">认证方式:</span>无需认证</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 2. 响应格式 -->
|
||||
<h2 id="section2">2. 响应格式</h2>
|
||||
|
||||
<h4>成功响应</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">true</span>,
|
||||
<span class="json-key">"data"</span>: <span class="json-bracket">{ ... }</span>
|
||||
}</code></pre>
|
||||
|
||||
<h4>失败响应</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">false</span>,
|
||||
<span class="json-key">"message"</span>: <span class="json-string">"错误信息"</span>
|
||||
}</code></pre>
|
||||
|
||||
<!-- 3. 接口列表 -->
|
||||
<h2 id="section3">3. 接口列表总览</h2>
|
||||
<table>
|
||||
<tr><th>接口路径</th><th>方法</th><th>功能描述</th></tr>
|
||||
<tr>
|
||||
<td><code>/api/hairstyles</code></td>
|
||||
<td><span class="method method-get">GET</span></td>
|
||||
<td>获取发型列表</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/api/change-hair</code></td>
|
||||
<td><span class="method method-post">POST</span></td>
|
||||
<td>更换发型</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><code>/api/change-hair-color</code></td>
|
||||
<td><span class="method method-post">POST</span></td>
|
||||
<td>更换头发颜色</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
<!-- 4. 详细接口说明 -->
|
||||
<h2 id="section4">4. 详细接口说明</h2>
|
||||
|
||||
<!-- 4.1 获取发型列表 -->
|
||||
<h3 id="section4-1">4.1 获取发型列表</h3>
|
||||
<div class="endpoint-card">
|
||||
<span class="method method-get">GET</span>
|
||||
<span class="endpoint-path">/api/hairstyles</span>
|
||||
</div>
|
||||
|
||||
<h4>请求参数</h4>
|
||||
<p>无</p>
|
||||
|
||||
<h4>响应示例</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">true</span>,
|
||||
<span class="json-key">"data"</span>: {
|
||||
<span class="json-key">"hairstyles"</span>: [
|
||||
{
|
||||
<span class="json-key">"id"</span>: <span class="json-string">"1953267161121464322"</span>,
|
||||
<span class="json-key">"name"</span>: <span class="json-string">"发型4322"</span>,
|
||||
<span class="json-key">"image_url"</span>: <span class="json-string">"https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"</span>
|
||||
},
|
||||
{
|
||||
<span class="json-key">"id"</span>: <span class="json-string">"1953267288284372994"</span>,
|
||||
<span class="json-key">"name"</span>: <span class="json-string">"发型2994"</span>,
|
||||
<span class="json-key">"image_url"</span>: <span class="json-string">"https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267288284372994.jpg"</span>
|
||||
}
|
||||
]
|
||||
}
|
||||
}</code></pre>
|
||||
|
||||
<h4>字段说明</h4>
|
||||
<table>
|
||||
<tr><th>字段名</th><th>类型</th><th>描述</th></tr>
|
||||
<tr><td><code>id</code></td><td>String</td><td>发型唯一标识符(长数字串,来源于 hairId2url.txt)</td></tr>
|
||||
<tr><td><code>name</code></td><td>String</td><td>发型名称(格式:"发型" + ID后4位)</td></tr>
|
||||
<tr><td><code>image_url</code></td><td>String</td><td>发型图片的阿里云 OSS URL</td></tr>
|
||||
</table>
|
||||
|
||||
<!-- 4.2 更换发型 -->
|
||||
<h3 id="section4-2">4.2 更换发型</h3>
|
||||
<div class="endpoint-card">
|
||||
<span class="method method-post">POST</span>
|
||||
<span class="endpoint-path">/api/change-hair</span>
|
||||
</div>
|
||||
|
||||
<h4>请求参数 <code>multipart/form-data</code></h4>
|
||||
<table>
|
||||
<tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr>
|
||||
<tr><td><code>image</code></td><td>File</td><td><span class="required">是</span></td><td>用户上传的图片文件(支持 png/jpg/jpeg/gif,最大 16MB)</td></tr>
|
||||
<tr><td><code>hairstyle_id</code></td><td>String</td><td><span class="required">是</span></td><td>要更换的发型ID</td></tr>
|
||||
</table>
|
||||
|
||||
<h4>响应示例</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">true</span>,
|
||||
<span class="json-key">"data"</span>: {
|
||||
<span class="json-key">"result_image"</span>: <span class="json-string">"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."</span>
|
||||
}
|
||||
}</code></pre>
|
||||
|
||||
<h4>响应字段</h4>
|
||||
<table>
|
||||
<tr><th>字段名</th><th>类型</th><th>描述</th></tr>
|
||||
<tr><td><code>result_image</code></td><td>String</td><td>发型更换后的图片,Base64 Data URL 格式</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="note">
|
||||
<div class="note-title">注意事项</div>
|
||||
<ul>
|
||||
<li>远程 AI 处理耗时较长,超时时间为 <strong>120 秒</strong></li>
|
||||
<li>如果远程 API 调用失败,会返回原始图片作为降级处理</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 4.3 更换头发颜色 -->
|
||||
<h3 id="section4-3">4.3 更换头发颜色</h3>
|
||||
<div class="endpoint-card">
|
||||
<span class="method method-post">POST</span>
|
||||
<span class="endpoint-path">/api/change-hair-color</span>
|
||||
</div>
|
||||
|
||||
<h4>请求参数 <code>multipart/form-data</code></h4>
|
||||
<table>
|
||||
<tr><th>参数名</th><th>类型</th><th>必填</th><th>描述</th></tr>
|
||||
<tr><td><code>image</code></td><td>File</td><td><span class="required">是</span></td><td>用户上传的图片文件(支持 png/jpg/jpeg/gif,最大 16MB)</td></tr>
|
||||
<tr><td><code>rgb</code></td><td>String</td><td><span class="required">是</span></td><td>RGB颜色值,格式为 <code>"[R, G, B]"</code>,例如 <code>"[255, 106, 0]"</code></td></tr>
|
||||
<tr><td><code>ratio</code></td><td>String</td><td><span class="required">是</span></td><td>颜色替换强度,范围 0.0 ~ 1.0,例如 <code>"0.9"</code></td></tr>
|
||||
</table>
|
||||
|
||||
<h4>响应示例</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">true</span>,
|
||||
<span class="json-key">"data"</span>: {
|
||||
<span class="json-key">"result_image"</span>: <span class="json-string">"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAAAQABAAD..."</span>
|
||||
}
|
||||
}</code></pre>
|
||||
|
||||
<h4>响应字段</h4>
|
||||
<table>
|
||||
<tr><th>字段名</th><th>类型</th><th>描述</th></tr>
|
||||
<tr><td><code>result_image</code></td><td>String</td><td>发色更换后的图片,Base64 Data URL 格式</td></tr>
|
||||
</table>
|
||||
|
||||
<div class="note">
|
||||
<div class="note-title">注意事项</div>
|
||||
<ul>
|
||||
<li>远程 AI 处理耗时较长,超时时间为 <strong>120 秒</strong></li>
|
||||
<li>如果远程 API 调用失败,会返回原始图片作为降级处理</li>
|
||||
<li><code>ratio</code> 值越大,颜色替换效果越明显</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- 5. 错误处理 -->
|
||||
<h2 id="section5">5. 错误处理</h2>
|
||||
|
||||
<h4>错误响应格式</h4>
|
||||
<pre><code>{
|
||||
<span class="json-key">"success"</span>: <span class="json-bool">false</span>,
|
||||
<span class="json-key">"message"</span>: <span class="json-string">"请上传图片"</span>
|
||||
}</code></pre>
|
||||
|
||||
<h4>错误状态码列表</h4>
|
||||
<table>
|
||||
<tr><th>状态码</th><th>接口</th><th>触发条件</th><th>错误消息</th></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair</code></td><td>缺少图片</td><td>请上传图片</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair</code></td><td>缺少发型ID</td><td>请选择发型</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair</code></td><td>文件类型不合法</td><td>不支持的文件类型,请上传图片文件</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair-color</code></td><td>缺少图片</td><td>请上传图片</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair-color</code></td><td>缺少颜色值</td><td>请选择颜色</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair-color</code></td><td>缺少替换比例</td><td>请设置更换比例</td></tr>
|
||||
<tr><td>400</td><td><code>/api/change-hair-color</code></td><td>文件类型不合法</td><td>不支持的文件类型,请上传图片文件</td></tr>
|
||||
<tr><td>500</td><td><code>/api/hairstyles</code></td><td>服务器内部错误</td><td>获取发型列表失败: [错误信息]</td></tr>
|
||||
<tr><td>500</td><td><code>/api/change-hair</code></td><td>处理失败</td><td>处理图片失败: [错误信息]</td></tr>
|
||||
<tr><td>500</td><td><code>/api/change-hair-color</code></td><td>处理失败</td><td>处理图片失败: [错误信息]</td></tr>
|
||||
</table>
|
||||
|
||||
<!-- 6. API变更流程 -->
|
||||
<h2 id="section6">6. API 变更流程</h2>
|
||||
<div class="info-card">
|
||||
<ol>
|
||||
<li><strong>文档修改</strong> — 先修改本 API 文档,记录变更内容、原因和影响范围</li>
|
||||
<li><strong>代码实现</strong> — 根据文档修改后端 API 实现</li>
|
||||
<li><strong>前端适配</strong> — 前端根据文档修改进行适配</li>
|
||||
<li><strong>测试验证</strong> — 测试新 API 的功能和兼容性</li>
|
||||
<li><strong>部署上线</strong> — 按计划部署变更</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<!-- 7. 附录 -->
|
||||
<h2 id="section7">7. 附录</h2>
|
||||
|
||||
<h3 id="section7-2">7.1 支持的图片格式</h3>
|
||||
<table>
|
||||
<tr><th>格式</th><th>MIME 类型</th><th>扩展名</th></tr>
|
||||
<tr><td>PNG</td><td>image/png</td><td>.png</td></tr>
|
||||
<tr><td>JPEG</td><td>image/jpeg</td><td>.jpg / .jpeg</td></tr>
|
||||
<tr><td>GIF</td><td>image/gif</td><td>.gif</td></tr>
|
||||
</table>
|
||||
<p>文件大小限制:<strong>16MB</strong></p>
|
||||
|
||||
<h3>7.2 开发工具推荐</h3>
|
||||
<div class="info-card">
|
||||
<ul>
|
||||
<li><strong>API 测试</strong>:Postman、Insomnia</li>
|
||||
<li><strong>文档生成</strong>:Swagger、ReDoc</li>
|
||||
<li><strong>代码生成</strong>:OpenAPI Generator</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div style="margin-top: 60px; padding-top: 20px; border-top: 1px solid #e8e8e8; color: #aaa; font-size: 12px; text-align: center;">
|
||||
发型更换H5项目 API 文档 · v1.1 · 最后更新 2026-02-10
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -68,3 +68,24 @@ nohup: ignoring input
|
||||
1.202.76.38 - - [10/Feb/2026 10:07:15] "GET /js/axios.min.js.map HTTP/1.1" 404 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:07:25] code 404, message File not found
|
||||
1.202.76.38 - - [10/Feb/2026 10:07:25] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:20] "GET / HTTP/1.1" 200 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:20] "GET /css/style.css HTTP/1.1" 200 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:20] "GET /js/axios.min.js HTTP/1.1" 200 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:20] "GET /js/main.js HTTP/1.1" 200 -
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:38] code 404, message File not found
|
||||
111.172.4.198 - - [10/Feb/2026 10:11:38] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:42] "GET / HTTP/1.1" 304 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:42] "GET /js/axios.min.js HTTP/1.1" 304 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:42] "GET /js/main.js HTTP/1.1" 304 -
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:43] code 404, message File not found
|
||||
1.202.76.38 - - [10/Feb/2026 10:24:43] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
118.89.233.55 - - [10/Feb/2026 18:15:52] "HEAD /api-doc.html HTTP/1.1" 200 -
|
||||
1.202.76.38 - - [10/Feb/2026 18:16:19] "GET /api-doc.html HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:17:56] "GET /api-doc.html HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:18:12] "GET / HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:18:13] "GET /css/style.css HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:18:13] "GET /js/axios.min.js HTTP/1.1" 200 -
|
||||
210.12.133.162 - - [10/Feb/2026 18:18:13] "GET /js/main.js HTTP/1.1" 200 -
|
||||
223.104.3.195 - - [10/Feb/2026 18:18:36] "GET /api-doc.html HTTP/1.1" 200 -
|
||||
223.104.3.195 - - [10/Feb/2026 18:18:37] code 404, message File not found
|
||||
223.104.3.195 - - [10/Feb/2026 18:18:37] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
|
||||
Reference in New Issue
Block a user