Files
2026-02-10 18:22:21 +08:00

476 lines
18 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!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>