Files
hair/static/integration.html
T
xsl 218818bdd0 docs: 同步 integration.html / 接口文档.md / test_interface5.html
- 接口5: 补 generate_grow_image 参数说明(接口文档/integration/test_interface5 加控件)
- 接口1/5/6: 补 left_position/right_position 字段(MediaPipe 21/251号点)
- 接口4: features 字段纠正为固定6个英文字段(原误写~42项含中文, 与代码不符)
- 接口7: 完全移除(代码已 deprecated=True 固定返回错误, 文档却当正常接口详述)
- 错误码: 删错误的'1004已废弃'(1004仍用于接口2/5 gender校验), 补 1004 正确描述 + 1009(X-Internal-Token鉴权)
- test_interface5.html: 加 generate_grow_image 复选框
2026-07-24 00:52:14 +08:00

340 lines
23 KiB
HTML
Raw 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>旷视五接口 — 前端接入说明</title>
<style>
* { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: #f8f9fb; color: #1e293b; line-height: 1.6; }
.wrap { max-width: 960px; margin: 0 auto; padding: 32px 24px; }
h1 { font-size: 26px; margin-bottom: 8px; }
.subtitle { color: #64748b; font-size: 14px; margin-bottom: 32px; }
.card { background: #fff; border-radius: 12px; box-shadow: 0 1px 3px rgba(0,0,0,.05); margin-bottom: 24px; overflow: hidden; }
.card h2 { font-size: 16px; padding: 16px 20px; border-bottom: 1px solid #f1f5f9; background: #fafbfc; }
.card-body { padding: 18px 20px; }
table { width: 100%; border-collapse: collapse; font-size: 13px; }
th, td { text-align: left; padding: 10px 12px; border-bottom: 1px solid #f1f5f9; }
th { background: #f8fafc; font-weight: 700; color: #475569; font-size: 11px; text-transform: uppercase; letter-spacing: .5px; }
tr:last-child td { border-bottom: none; }
code { font-family: "SF Mono", "Fira Code", monospace; font-size: 12.5px; background: #f1f5f9; padding: 2px 6px; border-radius: 4px; color: #0f172a; }
pre { background: #1e293b; color: #e2e8f0; padding: 16px 20px; border-radius: 8px; font-family: "SF Mono", "Fira Code", monospace; font-size: 12.5px; line-height: 1.5; overflow-x: auto; }
.badge { display: inline-block; padding: 2px 10px; border-radius: 10px; font-size: 11px; font-weight: 700; }
.badge.post { background: #dbeafe; color: #1e40af; }
.badge.get { background: #d1fae5; color: #065f46; }
.badge.warn { background: #fef3c7; color: #92400e; }
.endpoint { margin-bottom: 20px; }
.endpoint .url { font-size: 15px; font-weight: 700; margin-bottom: 6px; }
.endpoint .desc { color: #64748b; font-size: 13px; margin-bottom: 10px; }
.endpoint .params { font-size: 12px; color: #94a3b8; margin-bottom: 8px; }
.link { color: #2563eb; text-decoration: none; font-size: 13px; }
.link:hover { text-decoration: underline; }
.toc { display: flex; gap: 10px; flex-wrap: wrap; margin-bottom: 24px; }
.toc a { font-size: 13px; color: #2563eb; text-decoration: none; padding: 4px 12px; background: #eff6ff; border-radius: 6px; }
.toc a:hover { background: #dbeafe; }
hr { border: none; border-top: 1px solid #e2e8f0; margin: 20px 0; }
</style>
</head>
<body>
<div class="wrap">
<h1>📡 旷视五接口 — 前端接入说明</h1>
<p class="subtitle">Base URL: <code>https://hair.xiangsilian.com</code> &nbsp;|&nbsp; 在线文档: <a href="/docs" class="link">/docs</a> &nbsp;|&nbsp; 在线测试页见底部</p>
<div class="toc">
<a href="#overview">通用约定</a>
<a href="#if1">接口1</a>
<a href="#if2">接口2</a>
<a href="#if3">接口3</a>
<a href="#if4">接口4</a>
<a href="#if5">接口5</a>
<a href="#if6">接口6</a>
<a href="#errors">错误码</a>
<a href="#test">在线测试</a>
</div>
<!-- ======== 通用约定 ======== -->
<div class="card" id="overview">
<h2>🔧 通用约定</h2>
<div class="card-body">
<table>
<tr><td>协议</td><td>HTTPS</td></tr>
<tr><td>请求方式</td><td>全部 <span class="badge post">POST</span></td></tr>
<tr><td>编码</td><td>UTF-8</td></tr>
<tr><td>Content-Type</td><td><code>multipart/form-data</code></td></tr>
<tr><td>图片参数</td><td>三选一:<code>image_file</code>(文件上传)/ <code>image_url</code>URL/ <code>image_base64</code>base64 + 前缀)</td></tr>
<tr><td>图片格式</td><td>JPG / PNG,单人正面照</td></tr>
</table>
<p style="margin-top:14px;font-size:13px"><strong>统一响应结构</strong></p>
<pre>{
"code": 0, // 0=成功,非0=错误
"message": "success",
"request_id": "...", // 请求追踪 ID
"data": { ... } // 业务数据,各接口不同
}</pre>
</div>
</div>
<!-- ======== 接口1 ======== -->
<div class="card" id="if1">
<h2>1. 四庭七眼测量 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/measure</code></h2>
<div class="card-body">
<p class="desc">上传正面照 → 返回标注好的 PNG(仅标注图层,透明底)+ 四庭七眼厘米数值 + 关键点像素坐标。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file</td><td>file</td><td>三选一</td><td>上传图片文件</td></tr>
<tr><td>image_url</td><td>string</td><td>三选一</td><td>图片 URL</td></tr>
<tr><td>image_base64</td><td>string</td><td>三选一</td><td>base64 字符串,需带 data:image/...;base64, 前缀</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>annotated_image_url</code></td><td>string</td><td>标注 PNG URL(仅标注图层,透明底,叠加到原图上显示)</td></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>全脸高度(cm= 四庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>四庭:top/upper/middle/lower,各含 <code>_cm</code><code>ratios</code></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:<code>eye_width_cm</code>/<code>face_width_cm</code>/<code>inter_eye_distance_cm</code> + <code>ratios</code> + <code>eye1</code>~<code>eye7</code>(从左到右 7 段宽度 cm<code>eye1</code>/<code>eye7</code> 耳朵不可见时为 null</td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>5 个关键点像素坐标:hair_top/hairline/brow_center/nose_bottom/chin_tip</td></tr>
<tr><td><code>hairline_source</code></td><td>string</td><td>发际线来源:<code>"segmentation"</code>(真实分割,可信度高)/ <code>"estimated"</code>(比例估算,可信度低)</td></tr>
<tr><td><code>head_pose</code></td><td>object</td><td>头部姿态角度:<code>{ yaw, pitch, roll }</code>(度),接近 0 表示正面照</td></tr>
<tr><td><code>left_position</code></td><td>object</td><td>MediaPipe 21 号关键点坐标(左脸定位点),原图像素:<code>{ x: number, y: number }</code></td></tr>
<tr><td><code>right_position</code></td><td>object</td><td>MediaPipe 251 号关键点坐标(右脸定位点,与 21 号镜像),原图像素:<code>{ x: number, y: number }</code></td></tr>
</table>
<p style="margin-top:12px;font-size:12px;color:#64748b">💡 前端把标注图叠加到原图上即可呈现测量效果(标注图白色线条 #FFFFFF,透明底)。</p>
<p style="margin-top:8px"><strong>请求示例</strong>fetch):</p>
<pre>const fd = new FormData();
fd.append('image_file', file); // 或 image_url / image_base64
const res = await fetch('https://hair.xiangsilian.com/api/v1/face/measure', {
method: 'POST',
body: fd
});
const { code, data } = await res.json();
// data.annotated_image_url → 标注 PNG
// data.face_total_height_cm → 全脸高度
// data.four_courts.ratios → { top_court: 0.25, ... }
// 前端叠加显示:原图 + annotated_image_urlabsolute 叠加)</pre>
</div>
</div>
<!-- ======== 接口2 ======== -->
<div class="card" id="if2">
<h2>2. C端生发 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hair/grow</code></h2>
<div class="card-body">
<p class="desc">上传正面照 + 性别 + 发型序号 → 返回指定发际线类型的发际线曲线透明 PNG + 生发图。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
<tr><td>gender</td><td>string</td><td>✅ 必填</td><td><code>"male"</code> / <code>"female"</code></td></tr>
<tr><td>hair_style</td><td>int</td><td>✅ 必填</td><td>发型序号。female: 1~5male: 1~4(见下方映射)</td></tr>
</table>
<p style="margin-top:12px"><strong>data.results[] 元素</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>image_url</code></td><td>string</td><td>发际线曲线<strong>透明 PNG</strong>(仅白色曲线,透明底,需叠加原图显示)</td></tr>
<tr><td><code>grown_image_url</code></td><td>string</td><td>生发后效果图(ComfyUI/Flux「植发3个月」完整人像)⚠ 可空</td></tr>
<tr><td><code>hairline_type</code></td><td>string</td><td>发际线类型 key</td></tr>
<tr><td><code>order</code></td><td>int</td><td>排序(1=最佳,当前按贴图顺序)</td></tr>
</table>
<p style="margin-top:12px;font-size:12px;color:#64748b">💡 <code>image_url</code> 是透明底 PNG,前端需用绝对定位叠加到原图上显示(参考 <a href="/static/test_interface2.html">测试页</a><code>.img-stack</code> 叠加结构)。</p>
<p style="margin-top:8px;font-size:12px;color:#64748b">
Female 5 种:ellipse/flower/heart/straight/wave &nbsp;|&nbsp;
Male 4 种:ellipse/m/straight/inverse_arc<br>
⚠ 生发图由本机 ComfyUI 生成,耗时可达数分钟,fetch 超时需放大(≥5min)。
</p>
</div>
</div>
<!-- ======== 接口3 ======== -->
<div class="card" id="if3">
<h2>3. B端生发(医生端)&nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hair/grow-b</code></h2>
<div class="card-body">
<p class="desc">医生用马克笔在用户照片额头画线 → 拍照上传 → 系统生成生发效果图。</p>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>marked_image_file / marked_image_url / marked_image_base64</td><td></td><td>✅ 三选一</td><td>已用马克笔标注发际线的图片</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>hair_growth_image_url</code></td><td>string</td><td>生发后效果图 URL ⚠ 可空</td></tr>
<tr><td><code>hairline_type</code></td><td>string</td><td>固定 <code>"custom"</code>(手绘定制)</td></tr>
</table>
<p style="font-size:12px;color:#64748b">⚠ 划线图未检测到划线(或无人脸)→ code=1001</p>
</div>
</div>
<!-- ======== 接口4 ======== -->
<div class="card" id="if4">
<h2>4. 用户特征分析 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/features</code></h2>
<div class="card-body">
<p class="desc">上传照片 → 火山方舟豆包视觉模型分析 → 返回固定 6 项面部特征(脸型/眉形/面部年龄/动静类型/性别/基因风格)。</p>
<p><strong>入参</strong>image_file / image_url / image_base64 三选一。无其他参数。</p>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>features</code></td><td>string</td><td><strong>JSON 字符串</strong>(不是对象!客户端需 <code>JSON.parse()</code>)。解析后得到<strong>固定 6 个英文字段</strong></td></tr>
</table>
<p style="margin-top:8px"><strong>features 字段</strong>(固定返回 6 个):</p>
<table>
<tr><th>字段</th><th>说明</th><th>字段</th><th>说明</th></tr>
<tr><td>face_shape</td><td>脸型</td><td>eyebrow_shape</td><td>眉形</td></tr>
<tr><td>facial_age</td><td>面部年龄区间</td><td>gender</td><td>性别</td></tr>
<tr><td>dynamic_static_type</td><td>动静类型</td><td>gene_style</td><td>基因风格</td></tr>
</table>
<pre>const res = await fetch('https://hair.xiangsilian.com/api/v1/face/features', {
method: 'POST',
body: fd
});
const { code, data } = await res.json();
const features = JSON.parse(data.features); // ← 注意:data.features 是字符串!
console.log(features.face_shape); // "鹅蛋脸"
console.log(features.gene_style); // "自然型"</pre>
</div>
</div>
<!-- ======== 接口5 ======== -->
<div class="card" id="if5">
<h2>5. 发际线 PNG 生成 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/hairline/generate</code></h2>
<div class="card-body">
<p class="desc">上传正面照 + 性别 + 多选发型 → 每个选中发型 middle/high/low 三档发际线叠图 + 生发图 + 最佳发际线中心点坐标。</p>
<p><strong>入参</strong>(同接口2:先选性别,再多选发型)</p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
<tr><td>gender</td><td>string</td><td>✅ 必填</td><td><code>"male"</code> / <code>"female"</code></td></tr>
<tr><td>hair_style</td><td>string</td><td>✅ 必填</td><td>发型序号,逗号分隔多选(如 <code>1,2,3</code>)。缺失/越界返回 1007</td></tr>
<tr><td>generate_grow_image</td><td>bool</td><td></td><td>是否生成生发效果图(ComfyUI 生发,全流程最耗时),默认 <code>true</code>。传 <code>false</code> 时跳过生发,各发型 <code>grown_image_url</code> 恒为 <code>null</code>,仅返回三档发际线叠图与中心点,大幅降低耗时</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>hairline_images[]</code></td><td>object[]</td><td>选中发型列表,每项含 <code>hairline_type</code><code>image_middle_url</code>/<code>image_high_url</code>/<code>image_low_url</code> 三档<strong>透明 PNG 叠图</strong>(仅曲线,需叠加原图)、<code>grown_image_url</code> 生发图(完整人像,失败或 <code>generate_grow_image=false</code> 时为 null)、<code>order</code></td></tr>
<tr><td><code>best_hairline_center_point</code></td><td>object \| null</td><td>首个选中发型 <strong>middle 档</strong>发际线中心点像素坐标 <code>{ x: number, y: number }</code></td></tr>
<tr><td><code>high_hairline_center_point</code></td><td>object \| null</td><td>同上,<strong>high 档</strong>发际线中点(发际线偏高,y 更小)</td></tr>
<tr><td><code>low_hairline_center_point</code></td><td>object \| null</td><td>同上,<strong>low 档</strong>发际线中点(发际线偏低,y 更大)</td></tr>
<tr><td><code>face_measure</code></td><td>object \| null</td><td>复用<a href="#if1">接口1</a><strong>四庭七眼测量数值</strong>(不含标注图)。独立流程,测量失败时为 <code>null</code>,不影响发际线主结果。结构见下表</td></tr>
</table>
<p style="margin-top:12px"><code>face_measure</code> 字段(与接口1 的 <code>data</code> 同构,<strong>不含</strong> <code>annotated_image_*</code>):</p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>全脸高度(cm= 四庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>四庭:top/upper/middle/lower,各含 <code>_cm</code><code>ratios</code></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:<code>eye_width_cm</code>/<code>face_width_cm</code>/<code>inter_eye_distance_cm</code> + <code>ratios</code> + <code>eye1</code>~<code>eye7</code>(从左到右 7 段宽度 cm<code>eye1</code>/<code>eye7</code> 耳朵不可见时为 null</td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>5 个关键点像素坐标:hair_top/hairline/brow_center/nose_bottom/chin_tip</td></tr>
<tr><td><code>hairline_source</code></td><td>string</td><td>发际线来源:<code>"segmentation"</code>(真实分割)/ <code>"estimated"</code>(比例估算)</td></tr>
<tr><td><code>head_pose</code></td><td>object</td><td>头部姿态角度:<code>{ yaw, pitch, roll }</code>(度)</td></tr>
<tr><td><code>left_position</code></td><td>object</td><td>MediaPipe 21 号关键点坐标(左脸定位点),原图像素:<code>{ x: number, y: number }</code></td></tr>
<tr><td><code>right_position</code></td><td>object</td><td>MediaPipe 251 号关键点坐标(右脸定位点,与 21 号镜像),原图像素:<code>{ x: number, y: number }</code></td></tr>
</table>
<p style="margin-top:12px;font-size:12px;color:#64748b">💡 前端无需额外请求接口1 即可拿到四庭七眼测量数值;<code>face_measure</code><code>null</code> 时(角度过大/无人脸等)仅隐藏测量区块,发际线结果照常展示。</p>
</div>
</div>
<!-- ======== 接口6 ======== -->
<div class="card" id="if6">
<h2>6. 四庭七眼测量 v2 &nbsp;<span class="badge post">POST</span> &nbsp;<code>/api/v1/face/measure-v2</code> &nbsp;<span class="badge warn">v2</span></h2>
<div class="card-body">
<p class="desc">基于<a href="#if1">接口1</a>的变体。上传正面照 → 返回标注 PNG + 三庭七眼数据。与接口1 的差异:</p>
<ul style="font-size:13px;color:#475569;margin:8px 0 12px 18px;line-height:1.8">
<li><strong>去顶庭</strong>:不画头顶横线、不返回顶庭数据,<code>face_total_height_cm</code> = 上+中+下庭</li>
<li><strong>竖线范围</strong>:发际线→下巴尖(接口1 为头顶→下巴尖)</li>
<li><strong>无头部端线</strong>:仅七眼 6 点 5 段标尺(接口1 为 8 点 7 段)</li>
</ul>
<p><strong>入参</strong></p>
<table>
<tr><th>参数</th><th>类型</th><th>必填</th><th>说明</th></tr>
<tr><td>image_file / image_url / image_base64</td><td></td><td>三选一</td><td>用户正面照</td></tr>
</table>
<p style="margin-top:12px"><strong>data 字段</strong></p>
<table>
<tr><th>字段</th><th>类型</th><th>说明</th></tr>
<tr><td><code>annotated_image_url</code></td><td>string</td><td>标注 PNG URL(仅标注图层,透明底)</td></tr>
<tr><td><code>face_total_height_cm</code></td><td>number</td><td>面部总高度(cm= 三庭之和</td></tr>
<tr><td><code>four_courts</code></td><td>object</td><td>三庭:upper/middle/lower,各含 _cm 和 ratios<strong>无 top_court</strong></td></tr>
<tr><td><code>seven_eyes</code></td><td>object</td><td>七眼:<code>eye_width_cm</code>/<code>face_width_cm</code>/<code>inter_eye_distance_cm</code> + <code>ratios</code> + <strong><code>eye2</code>~<code>eye6</code></strong>(左脸颊/左眼/两眼间距/右眼/右脸颊,5 段宽度 cm;<strong>无 eye1/eye7</strong></td></tr>
<tr><td><code>landmarks</code></td><td>object</td><td>4 个关键点:hairline/brow_center/nose_bottom/chin_tip<strong>无 hair_top</strong></td></tr>
<tr><td><code>left_position</code></td><td>object</td><td>MediaPipe 21 号关键点坐标(左脸定位点),原图像素:<code>{ x: number, y: number }</code></td></tr>
<tr><td><code>right_position</code></td><td>object</td><td>MediaPipe 251 号关键点坐标(右脸定位点,与 21 号镜像),原图像素:<code>{ x: number, y: number }</code></td></tr>
</table>
</div>
</div>
<!-- ======== 错误码 ======== -->
<div class="card" id="errors">
<h2>⚠ 错误码</h2>
<div class="card-body">
<table>
<tr><th>code</th><th>message</th><th>说明</th></tr>
<tr><td>1001</td><td>无法识别人像</td><td>未检测到人脸</td></tr>
<tr><td>1003</td><td>角度问题,非正面照</td><td>非正面 / 角度过大</td></tr>
<tr><td>1004</td><td>gender 必填且只能为 male / female</td><td>接口2/5 的 <code>gender</code> 缺失或非法</td></tr>
<tr><td>1005</td><td>检测到多张人脸</td><td>仅支持单人</td></tr>
<tr><td>1007</td><td>图片参数错误 / 后端不可用</td><td>参数传错 / 服务繁忙请稍后重试</td></tr>
<tr><td>1008</td><td>图片格式不支持</td><td>非 JPG/PNG / base64 解码失败</td></tr>
<tr><td>1009</td><td>未授权</td><td>缺少或错误的 <code>X-Internal-Token</code><code>/api/*</code> 路径鉴权)</td></tr>
</table>
<p style="font-size:12px;color:#94a3b8;margin-top:8px">注:1004 仍在使用(接口2/5 的 gender 校验);接口7(grow-v2)已弃用,请改用接口2。</p>
</div>
</div>
<!-- ======== 在线测试页 ======== -->
<div class="card" id="test">
<h2>🧪 在线测试页面</h2>
<div class="card-body">
<table>
<tr><th>接口</th><th>测试页</th><th>功能</th></tr>
<tr><td>1. 四庭七眼</td><td><a href="/static/test_interface1.html" class="link">/static/test_interface1.html</a></td><td>上传照片 → 原图+标注叠加,底图/标注开关,指标卡片</td></tr>
<tr><td>2. C端生发</td><td><a href="/static/test_interface2.html" class="link">/static/test_interface2.html</a></td><td>上传+性别 → 方案一覧(原图/叠加/生发),双图对比</td></tr>
<tr><td>3. B端生发</td><td><a href="/static/test_interface3.html" class="link">/static/test_interface3.html</a></td><td>划线图上传 → 生发效果图</td></tr>
<tr><td>4. 用户特征</td><td><a href="/static/test_interface4.html" class="link">/static/test_interface4.html</a></td><td>上传照片 → 6项面部特征 + 原始JSON</td></tr>
<tr><td>5. 发际线PNG</td><td><a href="/static/test_interface5.html" class="link">/static/test_interface5.html</a></td><td>上传+性别 → 发际线方案+中心点坐标</td></tr>
<tr><td>6. 四庭七眼 v2</td><td><a href="/static/test_interface6.html" class="link">/static/test_interface6.html</a></td><td>同接口1,去顶庭 · 竖线发际线→下巴 · 无头部端线</td></tr>
</table>
<p style="font-size:12px;color:#94a3b8;margin-top:12px">
完整 API 文档:<a href="/docs" class="link">/docs</a>Swagger UI
</p>
</div>
</div>
<p style="text-align:center;font-size:12px;color:#cbd5e1;margin-top:32px">
Base: https://hair.xiangsilian.com &nbsp;|&nbsp; Swagger: /docs &nbsp;|&nbsp; 接入说明: /static/integration.html
</p>
</div>
</body>
</html>