This commit is contained in:
Ubuntu
2026-08-10 22:38:12 +08:00
parent 624be459a3
commit b6e25b8a9c
74 changed files with 255 additions and 104 deletions
+25
View File
@@ -0,0 +1,25 @@
# Python
.venv/
venv/
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
# Logs / runtime
logs/
*.log
backend/nohup.out
frontend/frontend.log
backend/app.log
# Local / IDE
.idea/
.vscode/
*.swp
.DS_Store
# Env / secrets
.env
.env.*
Binary file not shown.
Binary file not shown.
Binary file not shown.
+13 -6
View File
@@ -13,11 +13,15 @@ app = Flask(__name__)
app.config.from_object(Config)
CORS(app) # 启用CORS,允许跨域请求
# 发型预览图本地目录(相对 frontend,经 Nginx /hair 对外提供)
HAIRSTYLE_IMAGE_DIR = os.path.join(os.path.dirname(__file__), '../frontend/images/hairstyles')
HAIRSTYLE_IMAGE_URL_PREFIX = '/hair/images/hairstyles'
# 加载发型数据
def load_hairstyles_from_file():
"""
从hairId2url.txt文件加载发型数据
解析文件中的发型ID和URL对应关系
图片改为本机静态资源路径,不再直接返回 OSS URL
"""
hairstyles = []
try:
@@ -25,30 +29,33 @@ def load_hairstyles_from_file():
with open('../hairId2url.txt', 'r', encoding='utf-8') as f:
lines = f.readlines()
# 解析文件内容,提取发型ID和URL
# 解析文件内容,提取发型ID
for line in lines:
line = line.strip()
# 查找包含 -> 分隔符的行,这些是发型ID和URL的映射
if '->' in line and '.jpg' in line:
# 分割行获取文件名和URL
# 分割行获取文件名
parts = line.split('->')
if len(parts) == 2:
filename = parts[0].strip()
url = parts[1].strip()
# 提取发型ID(去掉.jpg后缀)
if filename.endswith('.jpg'):
hair_id = filename[:-4]
local_path = os.path.join(HAIRSTYLE_IMAGE_DIR, filename)
if not os.path.isfile(local_path):
print(f'警告: 本地发型图片不存在: {local_path}')
continue
# 生成发型名称
hairstyle_name = f'发型{hair_id[-4:]}'
# 添加到发型列表
# 添加到发型列表(本服务器静态路径)
hairstyles.append({
'id': hair_id,
'name': hairstyle_name,
'image_url': url
'image_url': f'{HAIRSTYLE_IMAGE_URL_PREFIX}/{filename}'
})
except Exception as e:
print(f'加载发型数据失败: {str(e)}')
+4 -4
View File
@@ -3,9 +3,9 @@ class Config:
# 应用名称
APP_NAME = "Hair Change Color"
REMOTE_API_URL = "http://xiangsilian.com:18801/api/swapHair/v1"
REMOTE_API_URL = "http://xiangsilian.com:38801/api/swapHair/v1"
REMOTE_HAIR_COLOR_API_URL = "http://xiangsilian.com:18801/hairColor/v2"
REMOTE_HAIR_COLOR_API_URL = "http://xiangsilian.com:38801/hairColor/v2"
# 远程发型更换API地址
# REMOTE_API_URL = "http://117.50.160.71:8801/api/swapHair/v1"
@@ -20,5 +20,5 @@ class Config:
MAX_CONTENT_LENGTH = 16 * 1024 * 1024 # 16MB
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
# 开发环境配置
DEBUG = True
# 生产环境关闭调试
DEBUG = False
+2 -1
View File
@@ -1,3 +1,4 @@
Flask
Flask-CORS
requests
requests
gunicorn
+52 -23
View File
@@ -10,15 +10,23 @@
|------|------|------|------|
| v1.0 | 2026-01-18 | 初始版本 | 系统生成 |
| v1.1 | 2026-02-10 | 补充发色更换接口,修正数据格式 | 系统更新 |
| v1.2 | 2026-08-10 | 生产域名 `/hair` 前缀;发型预览图改为本机静态路径 | 系统更新 |
| v1.3 | 2026-08-10 | 补充全部发型预览图完整链接;分辨率更新为 634×950 | 系统更新 |
### 1.2 基本信息
- **API基础路径**: `/api`
- **服务端口**: 5000(Flask)
- **生产域名**: `https://meida.xiangsilian.com`
- **H5 页面**: `https://meida.xiangsilian.com/hair/`
- **在线 API 文档**: `https://meida.xiangsilian.com/hair/api-doc.html`
- **API基础路径(对外)**: `/hair/api`
- **完整 API 前缀**: `https://meida.xiangsilian.com/hair/api`
- **后端内部监听**: `127.0.0.1:5000`(Gunicorn,经 Nginx 反代;应用内路由仍为 `/api/...`)
- **响应格式**: JSON
- **字符编码**: UTF-8
- **认证方式**: 无需认证
> 接入方请使用对外路径 `/hair/api/...`。直连本机 `5000` 端口时可用 `/api/...`(仅限服务器本机调试)。
## 2. 响应格式
### 2.1 成功响应
@@ -43,18 +51,19 @@
| 接口路径 | 方法 | 功能描述 | 请求参数 | 成功响应数据 |
|---------|------|----------|---------|-------------|
| `/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,..." }` |
| `/hair/api/hairstyles` | GET | 获取发型列表 | 无 | `{ "hairstyles": [...] }` |
| `/hair/api/change-hair` | POST | 更换发型 | image: 文件<br>hairstyle_id: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
| `/hair/api/change-hair-color` | POST | 更换头发颜色 | image: 文件<br>rgb: 字符串<br>ratio: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
## 4. 详细接口说明
### 4.1 获取发型列表
#### 4.1.1 请求信息
- **路径**: `/api/hairstyles`
- **路径**: `/hair/api/hairstyles`
- **方法**: GET
- **参数**: 无
- **示例**: `GET https://meida.xiangsilian.com/hair/api/hairstyles`
#### 4.1.2 响应信息
- **状态码**: 200 OK
@@ -68,12 +77,12 @@
{
"id": "1953267161121464322",
"name": "发型4322",
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"
"image_url": "/hair/images/hairstyles/1953267161121464322.jpg"
},
{
"id": "1953267288284372994",
"name": "发型2994",
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267288284372994.jpg"
"image_url": "/hair/images/hairstyles/1953267288284372994.jpg"
}
]
}
@@ -86,12 +95,14 @@
|-------|------|------|
| `id` | 字符串 | 发型唯一标识符(长数字串,来源于 hairId2url.txt) |
| `name` | 字符串 | 发型名称(格式为 "发型" + ID后4位) |
| `image_url` | 字符串 | 发型图片的阿里云 OSS URL |
| `image_url` | 字符串 | 发型预览图本机相对路径,完整访问为 `https://meida.xiangsilian.com` + `image_url` |
图片文件存放在服务器 `frontend/images/hairstyles/`,分辨率 **634 × 950**(原图 60%),完整链接列表见 [7.3](#73-发型预览图完整链接本机)。
### 4.2 更换发型
#### 4.2.1 请求信息
- **路径**: `/api/change-hair`
- **路径**: `/hair/api/change-hair`
- **方法**: POST
- **Content-Type**: `multipart/form-data`
- **参数**:
@@ -127,7 +138,7 @@
### 4.3 更换头发颜色
#### 4.3.1 请求信息
- **路径**: `/api/change-hair-color`
- **路径**: `/hair/api/change-hair-color`
- **方法**: POST
- **Content-Type**: `multipart/form-data`
- **参数**:
@@ -168,16 +179,16 @@
| 状态码 | 接口 | 描述 | 示例消息 |
|-------|------|------|---------|
| 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` | 处理失败 | "处理图片失败: [错误信息]" |
| 400 | `/hair/api/change-hair` | 缺少图片 | "请上传图片" |
| 400 | `/hair/api/change-hair` | 缺少发型ID | "请选择发型" |
| 400 | `/hair/api/change-hair` | 文件类型不合法 | "不支持的文件类型,请上传图片文件" |
| 400 | `/hair/api/change-hair-color` | 缺少图片 | "请上传图片" |
| 400 | `/hair/api/change-hair-color` | 缺少颜色值 | "请选择颜色" |
| 400 | `/hair/api/change-hair-color` | 缺少替换比例 | "请设置更换比例" |
| 400 | `/hair/api/change-hair-color` | 文件类型不合法 | "不支持的文件类型,请上传图片文件" |
| 500 | `/hair/api/hairstyles` | 服务器内部错误 | "获取发型列表失败: [错误信息]" |
| 500 | `/hair/api/change-hair` | 处理失败 | "处理图片失败: [错误信息]" |
| 500 | `/hair/api/change-hair-color` | 处理失败 | "处理图片失败: [错误信息]" |
### 5.2 错误响应示例
@@ -206,7 +217,7 @@
{
"id": "1953267161121464322",
"name": "发型4322",
"image_url": "https://xiangsilian.oss-cn-beijing.aliyuncs.com/hair_images/1953267161121464322.jpg"
"image_url": "/hair/images/hairstyles/1953267161121464322.jpg"
}
```
@@ -259,7 +270,25 @@ FormData:
文件大小限制:16MB
### 7.3 开发工具推荐
### 7.3 接入示例(curl)
```bash
# 发型列表
curl -s https://meida.xiangsilian.com/hair/api/hairstyles
# 更换发型
curl -s -X POST https://meida.xiangsilian.com/hair/api/change-hair \
-F "image=@/path/to/face.jpg" \
-F "hairstyle_id=1953267161121464322"
# 更换发色
curl -s -X POST https://meida.xiangsilian.com/hair/api/change-hair-color \
-F "image=@/path/to/face.jpg" \
-F 'rgb=[255, 106, 0]' \
-F "ratio=0.9"
```
### 7.4 开发工具推荐
- **API测试**: Postman, Insomnia
- **文档生成**: Swagger, ReDoc
+106 -23
View File
@@ -229,13 +229,14 @@
<a href="#section6">6. API变更流程</a>
<a href="#section7">7. 附录</a>
<a href="#section7-2" class="level-2">支持的图片格式</a>
<a href="#section7-images" class="level-2">发型预览图链接</a>
</nav>
<!-- 主内容 -->
<div class="main">
<h1>发型更换H5项目 API 文档</h1>
<span class="version-badge">v1.1 · 2026-02-10</span>
<span class="version-badge">v1.3 · 2026-08-10</span>
<!-- 1. 文档说明 -->
<h2 id="section1">1. 文档说明</h2>
@@ -246,17 +247,23 @@
<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>
<tr><td>v1.2</td><td>2026-08-10</td><td>生产域名 /hair 前缀;发型预览图改为本机静态路径</td><td>系统更新</td></tr>
<tr><td>v1.3</td><td>2026-08-10</td><td>补充全部发型预览图完整链接;分辨率更新为 634×950</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><code>https://meida.xiangsilian.com</code></li>
<li><span class="label">H5 页面:</span><code>https://meida.xiangsilian.com/hair/</code></li>
<li><span class="label">API基础路径(对外):</span><code>/hair/api</code></li>
<li><span class="label">完整 API 前缀:</span><code>https://meida.xiangsilian.com/hair/api</code></li>
<li><span class="label">后端内部监听:</span><span class="value">127.0.0.1:5000</span>(Gunicorn,经 Nginx 反代)</li>
<li><span class="label">响应格式:</span>JSON</li>
<li><span class="label">字符编码:</span>UTF-8</li>
<li><span class="label">认证方式:</span>无需认证</li>
</ul>
<p style="margin-top:12px;font-size:13px;color:#666;">接入方请使用对外路径 <code>/hair/api/...</code>。直连本机 5000 端口时可用 <code>/api/...</code>(仅限服务器本机调试)。</p>
</div>
<!-- 2. 响应格式 -->
@@ -279,17 +286,17 @@
<table>
<tr><th>接口路径</th><th>方法</th><th>功能描述</th></tr>
<tr>
<td><code>/api/hairstyles</code></td>
<td><code>/hair/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><code>/hair/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><code>/hair/api/change-hair-color</code></td>
<td><span class="method method-post">POST</span></td>
<td>更换头发颜色</td>
</tr>
@@ -302,11 +309,12 @@
<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>
<span class="endpoint-path">/hair/api/hairstyles</span>
</div>
<h4>请求参数</h4>
<p>无</p>
<p>示例:<code>GET https://meida.xiangsilian.com/hair/api/hairstyles</code></p>
<h4>响应示例</h4>
<pre><code>{
@@ -316,12 +324,12 @@
{
<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">"image_url"</span>: <span class="json-string">"/hair/images/hairstyles/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>
<span class="json-key">"image_url"</span>: <span class="json-string">"/hair/images/hairstyles/1953267288284372994.jpg"</span>
}
]
}
@@ -332,14 +340,15 @@
<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>
<tr><td><code>image_url</code></td><td>String</td><td>发型预览图本机相对路径,完整访问为 <code>https://meida.xiangsilian.com</code> + <code>image_url</code></td></tr>
</table>
<p>图片存放在服务器 <code>frontend/images/hairstyles/</code>,分辨率 <strong>634 × 950</strong>(原图 60%)。完整链接见 <a href="#section7-images">7.2</a>。</p>
<!-- 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>
<span class="endpoint-path">/hair/api/change-hair</span>
</div>
<h4>请求参数 <code>multipart/form-data</code></h4>
@@ -375,7 +384,7 @@
<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>
<span class="endpoint-path">/hair/api/change-hair-color</span>
</div>
<h4>请求参数 <code>multipart/form-data</code></h4>
@@ -421,16 +430,16 @@
<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>
<tr><td>400</td><td><code>/hair/api/change-hair</code></td><td>缺少图片</td><td>请上传图片</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair</code></td><td>缺少发型ID</td><td>请选择发型</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair</code></td><td>文件类型不合法</td><td>不支持的文件类型,请上传图片文件</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair-color</code></td><td>缺少图片</td><td>请上传图片</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair-color</code></td><td>缺少颜色值</td><td>请选择颜色</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair-color</code></td><td>缺少替换比例</td><td>请设置更换比例</td></tr>
<tr><td>400</td><td><code>/hair/api/change-hair-color</code></td><td>文件类型不合法</td><td>不支持的文件类型,请上传图片文件</td></tr>
<tr><td>500</td><td><code>/hair/api/hairstyles</code></td><td>服务器内部错误</td><td>获取发型列表失败: [错误信息]</td></tr>
<tr><td>500</td><td><code>/hair/api/change-hair</code></td><td>处理失败</td><td>处理图片失败: [错误信息]</td></tr>
<tr><td>500</td><td><code>/hair/api/change-hair-color</code></td><td>处理失败</td><td>处理图片失败: [错误信息]</td></tr>
</table>
<!-- 6. API变更流程 -->
@@ -457,6 +466,80 @@
</table>
<p>文件大小限制:<strong>16MB</strong></p>
<h3 id="section7-images">7.2 发型预览图完整链接(本机)</h3>
<div class="info-card">
<ul>
<li><span class="label">分辨率:</span><span class="value">634 × 950</span>(原图 1056 × 1584 的 60%)</li>
<li><span class="label">目录:</span><code>frontend/images/hairstyles/</code></li>
<li><span class="label">URL 规则:</span><code>https://meida.xiangsilian.com/hair/images/hairstyles/{id}.jpg</code></li>
<li><span class="label">数量:</span><span class="value">60</span></li>
</ul>
</div>
<table>
<tr><th>发型 ID</th><th>名称</th><th>完整链接</th></tr>
<tr><td><code>1953267161121464322</code></td><td>发型4322</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953267161121464322.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953267161121464322.jpg</a></td></tr>
<tr><td><code>1953267288284372994</code></td><td>发型2994</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953267288284372994.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953267288284372994.jpg</a></td></tr>
<tr><td><code>1953270523594317826</code></td><td>发型7826</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953270523594317826.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953270523594317826.jpg</a></td></tr>
<tr><td><code>1953270724765720577</code></td><td>发型0577</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953270724765720577.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953270724765720577.jpg</a></td></tr>
<tr><td><code>1953271922151432194</code></td><td>发型2194</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953271922151432194.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953271922151432194.jpg</a></td></tr>
<tr><td><code>1953272913265467394</code></td><td>发型7394</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953272913265467394.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953272913265467394.jpg</a></td></tr>
<tr><td><code>1953288800932503554</code></td><td>发型3554</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1953288800932503554.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1953288800932503554.jpg</a></td></tr>
<tr><td><code>1954536242109784066</code></td><td>发型4066</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954536242109784066.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954536242109784066.jpg</a></td></tr>
<tr><td><code>1954536297776586754</code></td><td>发型6754</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954536297776586754.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954536297776586754.jpg</a></td></tr>
<tr><td><code>1954536402516746241</code></td><td>发型6241</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954536402516746241.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954536402516746241.jpg</a></td></tr>
<tr><td><code>1954536893304840194</code></td><td>发型0194</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954536893304840194.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954536893304840194.jpg</a></td></tr>
<tr><td><code>1954536956919848962</code></td><td>发型8962</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954536956919848962.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954536956919848962.jpg</a></td></tr>
<tr><td><code>1954537022875279362</code></td><td>发型9362</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537022875279362.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537022875279362.jpg</a></td></tr>
<tr><td><code>1954537085882114050</code></td><td>发型4050</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537085882114050.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537085882114050.jpg</a></td></tr>
<tr><td><code>1954537191729569793</code></td><td>发型9793</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537191729569793.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537191729569793.jpg</a></td></tr>
<tr><td><code>1954537709436706817</code></td><td>发型6817</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537709436706817.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537709436706817.jpg</a></td></tr>
<tr><td><code>1954537743532204034</code></td><td>发型4034</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537743532204034.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537743532204034.jpg</a></td></tr>
<tr><td><code>1954537961069780994</code></td><td>发型0994</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954537961069780994.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954537961069780994.jpg</a></td></tr>
<tr><td><code>1954538119216013313</code></td><td>发型3313</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954538119216013313.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954538119216013313.jpg</a></td></tr>
<tr><td><code>1954538156499181569</code></td><td>发型1569</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954538156499181569.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954538156499181569.jpg</a></td></tr>
<tr><td><code>1954538259330932738</code></td><td>发型2738</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954538259330932738.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954538259330932738.jpg</a></td></tr>
<tr><td><code>1954538335306555393</code></td><td>发型5393</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1954538335306555393.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1954538335306555393.jpg</a></td></tr>
<tr><td><code>1980312945301954561</code></td><td>发型4561</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980312945301954561.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980312945301954561.jpg</a></td></tr>
<tr><td><code>1980313052302843905</code></td><td>发型3905</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313052302843905.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313052302843905.jpg</a></td></tr>
<tr><td><code>1980313166576656385</code></td><td>发型6385</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313166576656385.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313166576656385.jpg</a></td></tr>
<tr><td><code>1980313210109337601</code></td><td>发型7601</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313210109337601.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313210109337601.jpg</a></td></tr>
<tr><td><code>1980313433502162946</code></td><td>发型2946</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313433502162946.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313433502162946.jpg</a></td></tr>
<tr><td><code>1980313576506957825</code></td><td>发型7825</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313576506957825.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313576506957825.jpg</a></td></tr>
<tr><td><code>1980313740403580930</code></td><td>发型0930</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313740403580930.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313740403580930.jpg</a></td></tr>
<tr><td><code>1980313819915001858</code></td><td>发型1858</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980313819915001858.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980313819915001858.jpg</a></td></tr>
<tr><td><code>1980314032369082369</code></td><td>发型2369</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314032369082369.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314032369082369.jpg</a></td></tr>
<tr><td><code>1980314209322573825</code></td><td>发型3825</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314209322573825.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314209322573825.jpg</a></td></tr>
<tr><td><code>1980314290419441665</code></td><td>发型1665</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314290419441665.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314290419441665.jpg</a></td></tr>
<tr><td><code>1980314381058351106</code></td><td>发型1106</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314381058351106.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314381058351106.jpg</a></td></tr>
<tr><td><code>1980314477720281090</code></td><td>发型1090</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314477720281090.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314477720281090.jpg</a></td></tr>
<tr><td><code>1980314710101499906</code></td><td>发型9906</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314710101499906.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314710101499906.jpg</a></td></tr>
<tr><td><code>1980314764421931009</code></td><td>发型1009</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314764421931009.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314764421931009.jpg</a></td></tr>
<tr><td><code>1980314868713299969</code></td><td>发型9969</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980314868713299969.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980314868713299969.jpg</a></td></tr>
<tr><td><code>1980315179934851074</code></td><td>发型1074</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980315179934851074.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980315179934851074.jpg</a></td></tr>
<tr><td><code>1980315238260842497</code></td><td>发型2497</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980315238260842497.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980315238260842497.jpg</a></td></tr>
<tr><td><code>1980361636742209537</code></td><td>发型9537</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980361636742209537.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980361636742209537.jpg</a></td></tr>
<tr><td><code>1980367742952579074</code></td><td>发型9074</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980367742952579074.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980367742952579074.jpg</a></td></tr>
<tr><td><code>1980367781510815746</code></td><td>发型5746</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980367781510815746.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980367781510815746.jpg</a></td></tr>
<tr><td><code>1980367800787836929</code></td><td>发型6929</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980367800787836929.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980367800787836929.jpg</a></td></tr>
<tr><td><code>1980367852847538177</code></td><td>发型8177</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980367852847538177.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980367852847538177.jpg</a></td></tr>
<tr><td><code>1980367968627105793</code></td><td>发型5793</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980367968627105793.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980367968627105793.jpg</a></td></tr>
<tr><td><code>1980368109866098690</code></td><td>发型8690</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980368109866098690.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980368109866098690.jpg</a></td></tr>
<tr><td><code>1980368205752082434</code></td><td>发型2434</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980368205752082434.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980368205752082434.jpg</a></td></tr>
<tr><td><code>1980368368847593473</code></td><td>发型3473</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980368368847593473.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980368368847593473.jpg</a></td></tr>
<tr><td><code>1980368465631158274</code></td><td>发型8274</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980368465631158274.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980368465631158274.jpg</a></td></tr>
<tr><td><code>1980368588293578754</code></td><td>发型8754</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980368588293578754.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980368588293578754.jpg</a></td></tr>
<tr><td><code>1980413320612847618</code></td><td>发型7618</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980413320612847618.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980413320612847618.jpg</a></td></tr>
<tr><td><code>1980415346071609345</code></td><td>发型9345</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980415346071609345.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980415346071609345.jpg</a></td></tr>
<tr><td><code>1980415897056354306</code></td><td>发型4306</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1980415897056354306.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1980415897056354306.jpg</a></td></tr>
<tr><td><code>1981177324700549122</code></td><td>发型9122</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177324700549122.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177324700549122.jpg</a></td></tr>
<tr><td><code>1981177378714796034</code></td><td>发型6034</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177378714796034.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177378714796034.jpg</a></td></tr>
<tr><td><code>1981177477423546370</code></td><td>发型6370</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177477423546370.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177477423546370.jpg</a></td></tr>
<tr><td><code>1981177594750812162</code></td><td>发型2162</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177594750812162.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177594750812162.jpg</a></td></tr>
<tr><td><code>1981177742742634497</code></td><td>发型4497</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177742742634497.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177742742634497.jpg</a></td></tr>
<tr><td><code>1981177931859607554</code></td><td>发型7554</td><td><a href="https://meida.xiangsilian.com/hair/images/hairstyles/1981177931859607554.jpg" target="_blank" rel="noopener">https://meida.xiangsilian.com/hair/images/hairstyles/1981177931859607554.jpg</a></td></tr>
</table>
<h3>7.2 开发工具推荐</h3>
<div class="info-card">
<ul>
@@ -467,7 +550,7 @@
</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
发型更换H5项目 API 文档 · v1.3 · 最后更新 2026-08-10
</div>
</div>
Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 60 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 46 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 52 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 51 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

+2 -2
View File
@@ -1,5 +1,5 @@
// API调用封装
const API_BASE_URL = 'http://localhost:5000/api';
// API调用封装(经 Nginx 挂载在 /hair 下,使用同源相对路径)
const API_BASE_URL = '/hair/api';
// 获取发型列表
export async function getHairstyles() {
+8 -3
View File
@@ -1,5 +1,5 @@
// API基础URL
const API_BASE_URL = 'http://xiangsilian.com:5000/api';
// API基础URL(经 Nginx 挂载在 /hair 下,使用同源相对路径)
const API_BASE_URL = '/hair/api';
// API调用函数
async function getHairstyles() {
@@ -199,9 +199,14 @@ function renderHairstyles() {
const hairstyleItem = document.createElement('div');
hairstyleItem.className = 'hairstyle-item';
hairstyleItem.dataset.id = hairstyle.id;
// 本服务器静态图路径;若接口仍返回 OSS 绝对地址则强制改成本地
const imageSrc = hairstyle.image_url && !hairstyle.image_url.startsWith('http')
? hairstyle.image_url
: `/hair/images/hairstyles/${hairstyle.id}.jpg`;
hairstyleItem.innerHTML = `
<img src="${hairstyle.image_url}" alt="${hairstyle.name}">
<img src="${imageSrc}" alt="${hairstyle.name}" loading="lazy">
<p>${hairstyle.name}</p>
`;
+22
View File
@@ -0,0 +1,22 @@
[Unit]
Description=Hair change color Flask service (meida.xiangsilian.com/hair)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=ubuntu
Group=ubuntu
WorkingDirectory=/home/ubuntu/hair_change_color/backend
ExecStart=/home/ubuntu/hair_change_color/.venv/bin/gunicorn \
-w 2 \
-b 127.0.0.1:5000 \
--timeout 180 \
--access-logfile /home/ubuntu/log/hair_access.log \
--error-logfile /home/ubuntu/log/hair_error.log \
app:app
Restart=on-failure
RestartSec=5
[Install]
WantedBy=multi-user.target
+15 -27
View File
@@ -1,31 +1,19 @@
#!/bin/bash
# 启动发型更换服务(systemd: hair_change.service)
# 启动脚本:start.sh
# 用于启动发型更换项目的后端和前端服务
set -e
ROOT="/home/ubuntu/hair_change_color"
VENV_PY="${ROOT}/.venv/bin/python"
echo "启动发型更换项目..."
if [ ! -x "$VENV_PY" ]; then
echo "错误: 虚拟环境不存在,请先执行:"
echo " python3 -m venv ${ROOT}/.venv && ${ROOT}/.venv/bin/pip install -r ${ROOT}/backend/requirements.txt"
exit 1
fi
# 进入项目根目录
cd /home/ubuntu/hair_change_color
# 启动后端服务 (Flask应用)
echo "启动后端服务..."
cd backend
nohup python3 app.py > ../logs/backend.log 2>&1 &
BACKEND_PID=$!
echo "后端服务已启动,PID: $BACKEND_PID"
# 启动前端服务 (HTTP服务器)
echo "启动前端服务..."
cd ../frontend
nohup python3 -m http.server 48080 > ../logs/frontend.log 2>&1 &
FRONTEND_PID=$!
echo "前端服务已启动,PID: $FRONTEND_PID"
echo "项目启动完成!"
echo "后端访问地址: http://127.0.0.1:5000"
echo "前端访问地址: http://127.0.0.1:48080"
# 保存PID到文件,用于停止脚本
echo $BACKEND_PID > /tmp/hair_backend.pid
echo $FRONTEND_PID > /tmp/hair_frontend.pid
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 重启 hair_change.service ..."
sudo systemctl restart hair_change.service
sleep 1
sudo systemctl --no-pager --full status hair_change.service || true
echo "访问地址: https://meida.xiangsilian.com/hair/"
echo "日志: /home/ubuntu/log/hair_error.log /home/ubuntu/log/hair_access.log"
+6 -15
View File
@@ -1,19 +1,10 @@
#!/bin/bash
# 停止脚本:stop.sh
# 用于停止发型更换项目的后端和前端服务
# 停止发型更换服务
echo "停止发型更换项目..."
# 停止后端服务
echo "停止后端服务..."
ps aux | grep "app.py" | grep -v grep | awk '{print $2}' | xargs -r kill -9 2>/dev/null || echo "后端服务可能已经停止"
# 停止前端服务
echo "停止前端服务..."
ps aux | grep "http.server 48080" | grep -v grep | awk '{print $2}' | xargs -r kill -9 2>/dev/null || echo "前端服务可能已经停止"
# 清理PID文件(如果存在)
sudo systemctl stop hair_change.service 2>/dev/null || true
# 兼容旧启动方式
pkill -f "hair_change_color/backend/app.py" 2>/dev/null || true
pkill -f "http.server 48080" 2>/dev/null || true
rm -f /tmp/hair_backend.pid /tmp/hair_frontend.pid
echo "项目停止完成!"
echo "项目停止完成!"