diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..a93ba02
--- /dev/null
+++ b/.gitignore
@@ -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.*
diff --git a/backend/__pycache__/app.cpython-310.pyc b/backend/__pycache__/app.cpython-310.pyc
deleted file mode 100644
index be2f763..0000000
Binary files a/backend/__pycache__/app.cpython-310.pyc and /dev/null differ
diff --git a/backend/__pycache__/config.cpython-310.pyc b/backend/__pycache__/config.cpython-310.pyc
deleted file mode 100644
index c18e5ac..0000000
Binary files a/backend/__pycache__/config.cpython-310.pyc and /dev/null differ
diff --git a/backend/__pycache__/config.cpython-314.pyc b/backend/__pycache__/config.cpython-314.pyc
deleted file mode 100644
index f76a675..0000000
Binary files a/backend/__pycache__/config.cpython-314.pyc and /dev/null differ
diff --git a/backend/app.py b/backend/app.py
index a010909..e533f2d 100644
--- a/backend/app.py
+++ b/backend/app.py
@@ -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)}')
diff --git a/backend/config.py b/backend/config.py
index c8727aa..a7aa71c 100644
--- a/backend/config.py
+++ b/backend/config.py
@@ -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
\ No newline at end of file
+ # 生产环境关闭调试
+ DEBUG = False
\ No newline at end of file
diff --git a/backend/requirements.txt b/backend/requirements.txt
index 485276d..d1c5548 100644
--- a/backend/requirements.txt
+++ b/backend/requirements.txt
@@ -1,3 +1,4 @@
Flask
Flask-CORS
-requests
\ No newline at end of file
+requests
+gunicorn
\ No newline at end of file
diff --git a/docs/API.md b/docs/API.md
index 003164b..efa6ba4 100644
--- a/docs/API.md
+++ b/docs/API.md
@@ -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: 文件
hairstyle_id: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
-| `/api/change-hair-color` | POST | 更换头发颜色 | image: 文件
rgb: 字符串
ratio: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
+| `/hair/api/hairstyles` | GET | 获取发型列表 | 无 | `{ "hairstyles": [...] }` |
+| `/hair/api/change-hair` | POST | 更换发型 | image: 文件
hairstyle_id: 字符串 | `{ "result_image": "data:image/jpeg;base64,..." }` |
+| `/hair/api/change-hair-color` | POST | 更换头发颜色 | image: 文件
rgb: 字符串
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
diff --git a/frontend/api-doc.html b/frontend/api-doc.html
index c779c20..b4cc372 100644
--- a/frontend/api-doc.html
+++ b/frontend/api-doc.html
@@ -229,13 +229,14 @@
6. API变更流程
7. 附录
支持的图片格式
+ 发型预览图链接
发型更换H5项目 API 文档
-
v1.1 · 2026-02-10
+
v1.3 · 2026-08-10
1. 文档说明
@@ -246,17 +247,23 @@
| 版本 | 日期 | 描述 | 作者 |
| v1.0 | 2026-01-18 | 初始版本 | 系统生成 |
| v1.1 | 2026-02-10 | 补充发色更换接口,修正数据格式 | 系统更新 |
+
| v1.2 | 2026-08-10 | 生产域名 /hair 前缀;发型预览图改为本机静态路径 | 系统更新 |
+
| v1.3 | 2026-08-10 | 补充全部发型预览图完整链接;分辨率更新为 634×950 | 系统更新 |
基本信息
- - API基础路径:
/api
- - 服务端口:5000(Flask)
+ - 生产域名:
https://meida.xiangsilian.com
+ - H5 页面:
https://meida.xiangsilian.com/hair/
+ - API基础路径(对外):
/hair/api
+ - 完整 API 前缀:
https://meida.xiangsilian.com/hair/api
+ - 后端内部监听:127.0.0.1:5000(Gunicorn,经 Nginx 反代)
- 响应格式:JSON
- 字符编码:UTF-8
- 认证方式:无需认证
+
接入方请使用对外路径 /hair/api/...。直连本机 5000 端口时可用 /api/...(仅限服务器本机调试)。
@@ -279,17 +286,17 @@
| 接口路径 | 方法 | 功能描述 |
- /api/hairstyles |
+ /hair/api/hairstyles |
GET |
获取发型列表 |
- /api/change-hair |
+ /hair/api/change-hair |
POST |
更换发型 |
- /api/change-hair-color |
+ /hair/api/change-hair-color |
POST |
更换头发颜色 |
@@ -302,11 +309,12 @@
4.1 获取发型列表
GET
- /api/hairstyles
+ /hair/api/hairstyles
请求参数
无
+ 示例:GET https://meida.xiangsilian.com/hair/api/hairstyles
响应示例
{
@@ -316,12 +324,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"
}
]
}
@@ -332,14 +340,15 @@
| 字段名 | 类型 | 描述 |
id | String | 发型唯一标识符(长数字串,来源于 hairId2url.txt) |
name | String | 发型名称(格式:"发型" + ID后4位) |
- image_url | String | 发型图片的阿里云 OSS URL |
+ image_url | String | 发型预览图本机相对路径,完整访问为 https://meida.xiangsilian.com + image_url |
+
图片存放在服务器 frontend/images/hairstyles/,分辨率 634 × 950(原图 60%)。完整链接见 7.2。
4.2 更换发型
POST
- /api/change-hair
+ /hair/api/change-hair
请求参数 multipart/form-data
@@ -375,7 +384,7 @@
4.3 更换头发颜色
POST
- /api/change-hair-color
+ /hair/api/change-hair-color
请求参数 multipart/form-data
@@ -421,16 +430,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 | 处理失败 | 处理图片失败: [错误信息] |
@@ -457,6 +466,80 @@
文件大小限制:16MB
+
7.2 发型预览图完整链接(本机)
+
+
+ - 分辨率:634 × 950(原图 1056 × 1584 的 60%)
+ - 目录:
frontend/images/hairstyles/
+ - URL 规则:
https://meida.xiangsilian.com/hair/images/hairstyles/{id}.jpg
+ - 数量:60
+
+
+
+
+
7.2 开发工具推荐
- 发型更换H5项目 API 文档 · v1.1 · 最后更新 2026-02-10
+ 发型更换H5项目 API 文档 · v1.3 · 最后更新 2026-08-10
diff --git a/frontend/images/hairstyles/1953267161121464322.jpg b/frontend/images/hairstyles/1953267161121464322.jpg
new file mode 100644
index 0000000..1de3025
Binary files /dev/null and b/frontend/images/hairstyles/1953267161121464322.jpg differ
diff --git a/frontend/images/hairstyles/1953267288284372994.jpg b/frontend/images/hairstyles/1953267288284372994.jpg
new file mode 100644
index 0000000..ed9a329
Binary files /dev/null and b/frontend/images/hairstyles/1953267288284372994.jpg differ
diff --git a/frontend/images/hairstyles/1953270523594317826.jpg b/frontend/images/hairstyles/1953270523594317826.jpg
new file mode 100644
index 0000000..d3d833b
Binary files /dev/null and b/frontend/images/hairstyles/1953270523594317826.jpg differ
diff --git a/frontend/images/hairstyles/1953270724765720577.jpg b/frontend/images/hairstyles/1953270724765720577.jpg
new file mode 100644
index 0000000..4df909c
Binary files /dev/null and b/frontend/images/hairstyles/1953270724765720577.jpg differ
diff --git a/frontend/images/hairstyles/1953271922151432194.jpg b/frontend/images/hairstyles/1953271922151432194.jpg
new file mode 100644
index 0000000..e0d8762
Binary files /dev/null and b/frontend/images/hairstyles/1953271922151432194.jpg differ
diff --git a/frontend/images/hairstyles/1953272913265467394.jpg b/frontend/images/hairstyles/1953272913265467394.jpg
new file mode 100644
index 0000000..0d7c114
Binary files /dev/null and b/frontend/images/hairstyles/1953272913265467394.jpg differ
diff --git a/frontend/images/hairstyles/1953288800932503554.jpg b/frontend/images/hairstyles/1953288800932503554.jpg
new file mode 100644
index 0000000..7735c73
Binary files /dev/null and b/frontend/images/hairstyles/1953288800932503554.jpg differ
diff --git a/frontend/images/hairstyles/1954536242109784066.jpg b/frontend/images/hairstyles/1954536242109784066.jpg
new file mode 100644
index 0000000..869e203
Binary files /dev/null and b/frontend/images/hairstyles/1954536242109784066.jpg differ
diff --git a/frontend/images/hairstyles/1954536297776586754.jpg b/frontend/images/hairstyles/1954536297776586754.jpg
new file mode 100644
index 0000000..98b245c
Binary files /dev/null and b/frontend/images/hairstyles/1954536297776586754.jpg differ
diff --git a/frontend/images/hairstyles/1954536402516746241.jpg b/frontend/images/hairstyles/1954536402516746241.jpg
new file mode 100644
index 0000000..19c0fdc
Binary files /dev/null and b/frontend/images/hairstyles/1954536402516746241.jpg differ
diff --git a/frontend/images/hairstyles/1954536893304840194.jpg b/frontend/images/hairstyles/1954536893304840194.jpg
new file mode 100644
index 0000000..15179a9
Binary files /dev/null and b/frontend/images/hairstyles/1954536893304840194.jpg differ
diff --git a/frontend/images/hairstyles/1954536956919848962.jpg b/frontend/images/hairstyles/1954536956919848962.jpg
new file mode 100644
index 0000000..aaf613a
Binary files /dev/null and b/frontend/images/hairstyles/1954536956919848962.jpg differ
diff --git a/frontend/images/hairstyles/1954537022875279362.jpg b/frontend/images/hairstyles/1954537022875279362.jpg
new file mode 100644
index 0000000..578b938
Binary files /dev/null and b/frontend/images/hairstyles/1954537022875279362.jpg differ
diff --git a/frontend/images/hairstyles/1954537085882114050.jpg b/frontend/images/hairstyles/1954537085882114050.jpg
new file mode 100644
index 0000000..335c241
Binary files /dev/null and b/frontend/images/hairstyles/1954537085882114050.jpg differ
diff --git a/frontend/images/hairstyles/1954537191729569793.jpg b/frontend/images/hairstyles/1954537191729569793.jpg
new file mode 100644
index 0000000..81ecac9
Binary files /dev/null and b/frontend/images/hairstyles/1954537191729569793.jpg differ
diff --git a/frontend/images/hairstyles/1954537709436706817.jpg b/frontend/images/hairstyles/1954537709436706817.jpg
new file mode 100644
index 0000000..2aef835
Binary files /dev/null and b/frontend/images/hairstyles/1954537709436706817.jpg differ
diff --git a/frontend/images/hairstyles/1954537743532204034.jpg b/frontend/images/hairstyles/1954537743532204034.jpg
new file mode 100644
index 0000000..0db2049
Binary files /dev/null and b/frontend/images/hairstyles/1954537743532204034.jpg differ
diff --git a/frontend/images/hairstyles/1954537961069780994.jpg b/frontend/images/hairstyles/1954537961069780994.jpg
new file mode 100644
index 0000000..b3f7760
Binary files /dev/null and b/frontend/images/hairstyles/1954537961069780994.jpg differ
diff --git a/frontend/images/hairstyles/1954538119216013313.jpg b/frontend/images/hairstyles/1954538119216013313.jpg
new file mode 100644
index 0000000..b5db958
Binary files /dev/null and b/frontend/images/hairstyles/1954538119216013313.jpg differ
diff --git a/frontend/images/hairstyles/1954538156499181569.jpg b/frontend/images/hairstyles/1954538156499181569.jpg
new file mode 100644
index 0000000..8c88dd9
Binary files /dev/null and b/frontend/images/hairstyles/1954538156499181569.jpg differ
diff --git a/frontend/images/hairstyles/1954538259330932738.jpg b/frontend/images/hairstyles/1954538259330932738.jpg
new file mode 100644
index 0000000..211dcb2
Binary files /dev/null and b/frontend/images/hairstyles/1954538259330932738.jpg differ
diff --git a/frontend/images/hairstyles/1954538335306555393.jpg b/frontend/images/hairstyles/1954538335306555393.jpg
new file mode 100644
index 0000000..972ae8f
Binary files /dev/null and b/frontend/images/hairstyles/1954538335306555393.jpg differ
diff --git a/frontend/images/hairstyles/1980312945301954561.jpg b/frontend/images/hairstyles/1980312945301954561.jpg
new file mode 100644
index 0000000..23dbc37
Binary files /dev/null and b/frontend/images/hairstyles/1980312945301954561.jpg differ
diff --git a/frontend/images/hairstyles/1980313052302843905.jpg b/frontend/images/hairstyles/1980313052302843905.jpg
new file mode 100644
index 0000000..e8b0739
Binary files /dev/null and b/frontend/images/hairstyles/1980313052302843905.jpg differ
diff --git a/frontend/images/hairstyles/1980313166576656385.jpg b/frontend/images/hairstyles/1980313166576656385.jpg
new file mode 100644
index 0000000..02ff6e1
Binary files /dev/null and b/frontend/images/hairstyles/1980313166576656385.jpg differ
diff --git a/frontend/images/hairstyles/1980313210109337601.jpg b/frontend/images/hairstyles/1980313210109337601.jpg
new file mode 100644
index 0000000..50c5e35
Binary files /dev/null and b/frontend/images/hairstyles/1980313210109337601.jpg differ
diff --git a/frontend/images/hairstyles/1980313433502162946.jpg b/frontend/images/hairstyles/1980313433502162946.jpg
new file mode 100644
index 0000000..f1f2648
Binary files /dev/null and b/frontend/images/hairstyles/1980313433502162946.jpg differ
diff --git a/frontend/images/hairstyles/1980313576506957825.jpg b/frontend/images/hairstyles/1980313576506957825.jpg
new file mode 100644
index 0000000..4e2d956
Binary files /dev/null and b/frontend/images/hairstyles/1980313576506957825.jpg differ
diff --git a/frontend/images/hairstyles/1980313740403580930.jpg b/frontend/images/hairstyles/1980313740403580930.jpg
new file mode 100644
index 0000000..288d8a7
Binary files /dev/null and b/frontend/images/hairstyles/1980313740403580930.jpg differ
diff --git a/frontend/images/hairstyles/1980313819915001858.jpg b/frontend/images/hairstyles/1980313819915001858.jpg
new file mode 100644
index 0000000..1a01328
Binary files /dev/null and b/frontend/images/hairstyles/1980313819915001858.jpg differ
diff --git a/frontend/images/hairstyles/1980314032369082369.jpg b/frontend/images/hairstyles/1980314032369082369.jpg
new file mode 100644
index 0000000..ef130c4
Binary files /dev/null and b/frontend/images/hairstyles/1980314032369082369.jpg differ
diff --git a/frontend/images/hairstyles/1980314209322573825.jpg b/frontend/images/hairstyles/1980314209322573825.jpg
new file mode 100644
index 0000000..7e93fc7
Binary files /dev/null and b/frontend/images/hairstyles/1980314209322573825.jpg differ
diff --git a/frontend/images/hairstyles/1980314290419441665.jpg b/frontend/images/hairstyles/1980314290419441665.jpg
new file mode 100644
index 0000000..4f40929
Binary files /dev/null and b/frontend/images/hairstyles/1980314290419441665.jpg differ
diff --git a/frontend/images/hairstyles/1980314381058351106.jpg b/frontend/images/hairstyles/1980314381058351106.jpg
new file mode 100644
index 0000000..1934426
Binary files /dev/null and b/frontend/images/hairstyles/1980314381058351106.jpg differ
diff --git a/frontend/images/hairstyles/1980314477720281090.jpg b/frontend/images/hairstyles/1980314477720281090.jpg
new file mode 100644
index 0000000..352b2f1
Binary files /dev/null and b/frontend/images/hairstyles/1980314477720281090.jpg differ
diff --git a/frontend/images/hairstyles/1980314710101499906.jpg b/frontend/images/hairstyles/1980314710101499906.jpg
new file mode 100644
index 0000000..7797a6f
Binary files /dev/null and b/frontend/images/hairstyles/1980314710101499906.jpg differ
diff --git a/frontend/images/hairstyles/1980314764421931009.jpg b/frontend/images/hairstyles/1980314764421931009.jpg
new file mode 100644
index 0000000..79cc011
Binary files /dev/null and b/frontend/images/hairstyles/1980314764421931009.jpg differ
diff --git a/frontend/images/hairstyles/1980314868713299969.jpg b/frontend/images/hairstyles/1980314868713299969.jpg
new file mode 100644
index 0000000..10e844f
Binary files /dev/null and b/frontend/images/hairstyles/1980314868713299969.jpg differ
diff --git a/frontend/images/hairstyles/1980315179934851074.jpg b/frontend/images/hairstyles/1980315179934851074.jpg
new file mode 100644
index 0000000..057950d
Binary files /dev/null and b/frontend/images/hairstyles/1980315179934851074.jpg differ
diff --git a/frontend/images/hairstyles/1980315238260842497.jpg b/frontend/images/hairstyles/1980315238260842497.jpg
new file mode 100644
index 0000000..c13c599
Binary files /dev/null and b/frontend/images/hairstyles/1980315238260842497.jpg differ
diff --git a/frontend/images/hairstyles/1980361636742209537.jpg b/frontend/images/hairstyles/1980361636742209537.jpg
new file mode 100644
index 0000000..2e23427
Binary files /dev/null and b/frontend/images/hairstyles/1980361636742209537.jpg differ
diff --git a/frontend/images/hairstyles/1980367742952579074.jpg b/frontend/images/hairstyles/1980367742952579074.jpg
new file mode 100644
index 0000000..04f4300
Binary files /dev/null and b/frontend/images/hairstyles/1980367742952579074.jpg differ
diff --git a/frontend/images/hairstyles/1980367781510815746.jpg b/frontend/images/hairstyles/1980367781510815746.jpg
new file mode 100644
index 0000000..8afa1c6
Binary files /dev/null and b/frontend/images/hairstyles/1980367781510815746.jpg differ
diff --git a/frontend/images/hairstyles/1980367800787836929.jpg b/frontend/images/hairstyles/1980367800787836929.jpg
new file mode 100644
index 0000000..84bd0d0
Binary files /dev/null and b/frontend/images/hairstyles/1980367800787836929.jpg differ
diff --git a/frontend/images/hairstyles/1980367852847538177.jpg b/frontend/images/hairstyles/1980367852847538177.jpg
new file mode 100644
index 0000000..fcbd901
Binary files /dev/null and b/frontend/images/hairstyles/1980367852847538177.jpg differ
diff --git a/frontend/images/hairstyles/1980367968627105793.jpg b/frontend/images/hairstyles/1980367968627105793.jpg
new file mode 100644
index 0000000..f183e8e
Binary files /dev/null and b/frontend/images/hairstyles/1980367968627105793.jpg differ
diff --git a/frontend/images/hairstyles/1980368109866098690.jpg b/frontend/images/hairstyles/1980368109866098690.jpg
new file mode 100644
index 0000000..27e4d30
Binary files /dev/null and b/frontend/images/hairstyles/1980368109866098690.jpg differ
diff --git a/frontend/images/hairstyles/1980368205752082434.jpg b/frontend/images/hairstyles/1980368205752082434.jpg
new file mode 100644
index 0000000..c68310f
Binary files /dev/null and b/frontend/images/hairstyles/1980368205752082434.jpg differ
diff --git a/frontend/images/hairstyles/1980368368847593473.jpg b/frontend/images/hairstyles/1980368368847593473.jpg
new file mode 100644
index 0000000..0e25ed8
Binary files /dev/null and b/frontend/images/hairstyles/1980368368847593473.jpg differ
diff --git a/frontend/images/hairstyles/1980368465631158274.jpg b/frontend/images/hairstyles/1980368465631158274.jpg
new file mode 100644
index 0000000..2445a5f
Binary files /dev/null and b/frontend/images/hairstyles/1980368465631158274.jpg differ
diff --git a/frontend/images/hairstyles/1980368588293578754.jpg b/frontend/images/hairstyles/1980368588293578754.jpg
new file mode 100644
index 0000000..564c20c
Binary files /dev/null and b/frontend/images/hairstyles/1980368588293578754.jpg differ
diff --git a/frontend/images/hairstyles/1980413320612847618.jpg b/frontend/images/hairstyles/1980413320612847618.jpg
new file mode 100644
index 0000000..a1eaa37
Binary files /dev/null and b/frontend/images/hairstyles/1980413320612847618.jpg differ
diff --git a/frontend/images/hairstyles/1980415346071609345.jpg b/frontend/images/hairstyles/1980415346071609345.jpg
new file mode 100644
index 0000000..944c1ba
Binary files /dev/null and b/frontend/images/hairstyles/1980415346071609345.jpg differ
diff --git a/frontend/images/hairstyles/1980415897056354306.jpg b/frontend/images/hairstyles/1980415897056354306.jpg
new file mode 100644
index 0000000..1bc59fc
Binary files /dev/null and b/frontend/images/hairstyles/1980415897056354306.jpg differ
diff --git a/frontend/images/hairstyles/1981177324700549122.jpg b/frontend/images/hairstyles/1981177324700549122.jpg
new file mode 100644
index 0000000..2afe69f
Binary files /dev/null and b/frontend/images/hairstyles/1981177324700549122.jpg differ
diff --git a/frontend/images/hairstyles/1981177378714796034.jpg b/frontend/images/hairstyles/1981177378714796034.jpg
new file mode 100644
index 0000000..7b85199
Binary files /dev/null and b/frontend/images/hairstyles/1981177378714796034.jpg differ
diff --git a/frontend/images/hairstyles/1981177477423546370.jpg b/frontend/images/hairstyles/1981177477423546370.jpg
new file mode 100644
index 0000000..3c0c86e
Binary files /dev/null and b/frontend/images/hairstyles/1981177477423546370.jpg differ
diff --git a/frontend/images/hairstyles/1981177594750812162.jpg b/frontend/images/hairstyles/1981177594750812162.jpg
new file mode 100644
index 0000000..5f6a1fb
Binary files /dev/null and b/frontend/images/hairstyles/1981177594750812162.jpg differ
diff --git a/frontend/images/hairstyles/1981177742742634497.jpg b/frontend/images/hairstyles/1981177742742634497.jpg
new file mode 100644
index 0000000..6feb72a
Binary files /dev/null and b/frontend/images/hairstyles/1981177742742634497.jpg differ
diff --git a/frontend/images/hairstyles/1981177931859607554.jpg b/frontend/images/hairstyles/1981177931859607554.jpg
new file mode 100644
index 0000000..f06cff7
Binary files /dev/null and b/frontend/images/hairstyles/1981177931859607554.jpg differ
diff --git a/frontend/js/api.js b/frontend/js/api.js
index 0ebd088..8916c0d 100644
--- a/frontend/js/api.js
+++ b/frontend/js/api.js
@@ -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() {
diff --git a/frontend/js/main.js b/frontend/js/main.js
index 77f6c77..d3c5c89 100644
--- a/frontend/js/main.js
+++ b/frontend/js/main.js
@@ -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 = `
-
+
${hairstyle.name}
`;
diff --git a/hair_change.service b/hair_change.service
new file mode 100644
index 0000000..5b7dfb6
--- /dev/null
+++ b/hair_change.service
@@ -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
diff --git a/start.sh b/start.sh
index f7ee293..b7468ea 100755
--- a/start.sh
+++ b/start.sh
@@ -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
\ No newline at end of file
+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"
diff --git a/stop.sh b/stop.sh
index e0be024..8d31fb8 100755
--- a/stop.sh
+++ b/stop.sh
@@ -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 "项目停止完成!"
\ No newline at end of file
+echo "项目停止完成!"