优化注册功能

This commit is contained in:
赵杰 Jie Zhao (雄狮汽车科技)
2025-11-03 12:29:32 +08:00
parent f50d37259e
commit 7ab87e8f15
10 changed files with 829 additions and 83 deletions

View File

@@ -44,4 +44,6 @@ HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:5000/health')" || exit 1 CMD python -c "import requests; requests.get('http://localhost:5000/health')" || exit 1
# 使用gunicorn启动应用生产环境 # 使用gunicorn启动应用生产环境
# 注意默认配置使用2个worker适合1GB+内存的机器
# 如果机器内存较小512MB-1GB建议修改为 "--workers", "1"
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--timeout", "120", "--access-logfile", "-", "--error-logfile", "-", "web_app:app"] CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "2", "--timeout", "120", "--access-logfile", "-", "--error-logfile", "-", "web_app:app"]

63
Dockerfile.low-mem Normal file
View File

@@ -0,0 +1,63 @@
# -*- coding: utf-8 -*-
# 小内存优化版 Dockerfile适用于 512MB-1GB 内存的 Linux 机器)
FROM python:3-slim
# 设置工作目录
WORKDIR /app
# 设置环境变量(优化内存使用)
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
FLASK_APP=web_app.py \
FLASK_ENV=production \
PYTHONHASHSEED=0 \
MALLOC_ARENA_MAX=2
# 安装系统依赖(最小化安装)
RUN apt-get update && apt-get install -y --no-install-recommends \
tesseract-ocr \
tesseract-ocr-chi-sim \
tesseract-ocr-eng \
&& rm -rf /var/lib/apt/lists/* \
&& apt-get clean
# 复制requirements文件
COPY requirements.txt .
# 创建最小化的 requirements.txt移除GUI相关依赖
RUN echo "scikit-learn>=1.3.0" > requirements-minimal.txt && \
echo "pandas>=2.0.0" >> requirements-minimal.txt && \
echo "numpy>=1.24.0" >> requirements-minimal.txt && \
echo "joblib>=1.3.0" >> requirements-minimal.txt && \
echo "requests>=2.31.0" >> requirements-minimal.txt && \
echo "python-dotenv>=1.0.0" >> requirements-minimal.txt && \
echo "python-dateutil>=2.8.0" >> requirements-minimal.txt && \
echo "Pillow>=10.0.0" >> requirements-minimal.txt && \
echo "pytesseract>=0.3.10" >> requirements-minimal.txt && \
echo "opencv-python-headless>=4.8.0" >> requirements-minimal.txt && \
echo "Flask>=3.0.0" >> requirements-minimal.txt && \
echo "Werkzeug>=3.0.0" >> requirements-minimal.txt && \
echo "gunicorn" >> requirements-minimal.txt
# 安装Python依赖使用最小化依赖opencv使用headless版本
RUN pip install --no-cache-dir -r requirements-minimal.txt
# 复制应用代码
COPY . .
# 创建必要的目录
RUN mkdir -p templates static/css static/js logs data models
# 设置权限
RUN chmod +x start_web.py
# 暴露端口
EXPOSE 5000
# 健康检查(不使用 requests直接用 Python
HEALTHCHECK --interval=30s --timeout=10s --start-period=10s --retries=3 \
CMD python -c "import urllib.request; urllib.request.urlopen('http://localhost:5000/health').read()" || exit 1
# 使用gunicorn启动应用小内存配置单worker减少内存占用
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "1", "--threads", "2", "--timeout", "120", "--worker-class", "sync", "--max-requests", "1000", "--max-requests-jitter", "100", "--preload", "--access-logfile", "-", "--error-logfile", "-", "web_app:app"]

View File

@@ -186,12 +186,72 @@ server {
} }
``` ```
## 💾 小内存机器配置512MB-1GB
如果你的 Linux 机器内存较小,可以使用专门优化的小内存版本:
```bash
# 使用小内存优化的 Dockerfile 和配置
docker-compose -f docker-compose.low-mem.yml up -d
# 查看日志
docker-compose -f docker-compose.low-mem.yml logs -f
# 停止容器
docker-compose -f docker-compose.low-mem.yml down
```
### 小内存优化措施
1. **单 Worker 配置**Gunicorn 使用 1 个 worker + 2 个线程,减少内存占用
2. **最小化依赖**:移除 GUI 相关依赖CustomTkinter、Kivy等
3. **OpenCV Headless**:使用 `opencv-python-headless`,不包含 GUI 组件
4. **内存限制**:容器内存限制为 512MB最大保留 256MB
5. **环境变量优化**:设置 `MALLOC_ARENA_MAX=2``PYTHONHASHSEED=0` 减少内存碎片
### 内存需求对比
| 配置 | 内存需求 | 适用场景 |
|------|---------|---------|
| 标准版Dockerfile | 1GB+ | 服务器、开发环境 |
| 小内存版Dockerfile.low-mem | 512MB-1GB | 树莓派、小型 VPS、低配服务器 |
### 手动调整内存限制
如果使用标准版,可以通过修改 `docker-compose.yml` 来限制内存:
```yaml
services:
web:
deploy:
resources:
limits:
memory: 512M # 限制最大内存
reservations:
memory: 256M # 保留内存
```
## 📝 注意事项 ## 📝 注意事项
1. **OCR功能**Docker镜像已包含Tesseract OCR支持 1. **OCR功能**
2. **内存限制**建议至少分配1GB内存给容器 - Docker镜像已包含 Tesseract OCR 支持(轻量级)
3. **文件权限**:确保挂载的目录有适当的读写权限 - **未包含** PaddleOCR 和 EasyOCR内存占用大需要手动安装
4. **时区设置**如需修改时区在Dockerfile中添加 - 默认只使用 Tesseract OCR内存占用很小
2. **内存限制**
- 标准版:建议至少分配 **1GB 内存**给容器
- 小内存版:可以在 **512MB 内存**的机器上运行
3. **Worker 数量调整**
- 标准版默认 2 个 worker适合 1GB+ 内存)
- 小内存机器可以在 `Dockerfile` 中修改为 1 个 worker
```dockerfile
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "--workers", "1", ...]
```
4. **文件权限**:确保挂载的目录有适当的读写权限
5. **时区设置**如需修改时区在Dockerfile中添加
```dockerfile ```dockerfile
ENV TZ=Asia/Shanghai ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

182
README_GIT_PUSH.md Normal file
View File

@@ -0,0 +1,182 @@
# Git 自动上传脚本使用指南
本目录提供了三个版本的 Git 自动上传脚本,适用于不同操作系统。
## 📋 脚本说明
### 1. `git_push.sh` - Linux/Mac Bash 脚本
适用于 Linux 和 MacOS 系统。
**使用方法:**
```bash
# 给脚本添加执行权限(首次使用)
chmod +x git_push.sh
# 基本使用(交互式输入提交信息)
./git_push.sh
# 直接指定提交信息
./git_push.sh "feat: 添加新功能"
```
### 2. `git_push.bat` - Windows 批处理脚本
适用于 Windows 系统。
**使用方法:**
```cmd
# 基本使用(交互式输入提交信息)
git_push.bat
# 直接指定提交信息
git_push.bat "feat: 添加新功能"
```
### 3. `git_push.py` - Python 跨平台脚本(推荐)
适用于所有操作系统Windows、Linux、Mac需要 Python 3.6+。
**使用方法:**
```bash
# 基本使用(交互式输入提交信息)
python git_push.py
# 直接指定提交信息
python git_push.py "feat: 添加新功能"
# 多个单词的提交信息
python git_push.py "feat: 添加新功能和修复bug"
```
## 🚀 功能特性
所有脚本都包含以下功能:
1. **自动检测 Git 仓库**:检查当前目录是否为 Git 仓库
2. **显示更改状态**:显示将要提交的文件
3. **交互式确认**:在提交前确认操作
4. **智能提交信息**
- 可以直接通过命令行参数指定
- 也可以交互式输入
- 默认提供带时间戳的提交信息
5. **自动添加文件**:自动添加所有更改的文件
6. **错误处理**:友好的错误提示和处理
7. **颜色输出**支持彩色输出Python 版本)
## 📝 使用示例
### 示例 1基本使用
```bash
# Linux/Mac
./git_push.sh
# Windows
git_push.bat
# Python跨平台
python git_push.py
```
脚本会:
1. 显示当前更改的文件
2. 询问是否继续
3. 请求输入提交信息(或使用默认)
4. 自动添加、提交并推送
### 示例 2指定提交信息
```bash
# Linux/Mac
./git_push.sh "fix: 修复用户注册bug"
# Windows
git_push.bat "fix: 修复用户注册bug"
# Python
python git_push.py "fix: 修复用户注册bug"
```
### 示例 3提交多个文件的更改
```bash
# 脚本会自动检测所有更改的文件
./git_push.sh "feat: 添加Docker支持和优化内存配置"
```
## ⚙️ 配置说明
### 默认分支
脚本会自动检测当前分支并使用该分支进行推送。
### 远程仓库
确保已配置远程仓库:
```bash
# 查看远程仓库
git remote -v
# 如果未配置,添加远程仓库
git remote add origin <your-repo-url>
```
### 身份验证
如果推送时遇到身份验证问题:
1. **HTTPS 方式**
- 需要输入用户名和密码(或访问令牌)
- 可以配置凭证助手避免每次输入:
```bash
git config --global credential.helper store
```
2. **SSH 方式**
- 配置 SSH 密钥更安全
- 将远程 URL 改为 SSH 格式:
```bash
git remote set-url origin git@github.com:username/repo.git
```
## 🔧 故障排除
### 问题 1权限不足Linux/Mac
```bash
# 解决方案:添加执行权限
chmod +x git_push.sh
```
### 问题 2Python 脚本无法运行
```bash
# 检查 Python 版本
python --version # 需要 Python 3.6+
# 如果系统中有多个 Python 版本
python3 git_push.py
```
### 问题 3推送失败认证问题
- 检查远程仓库地址是否正确
- 确认已配置 SSH 密钥或访问令牌
- 可以手动执行 `git push origin <branch>` 测试
### 问题 4没有需要提交的更改
- 脚本会检测是否有未提交的更改
- 如果没有更改,可以选择拉取远程更新
## 💡 建议
1. **推荐使用 Python 版本**`git_push.py`
- 跨平台兼容性最好
- 错误处理更完善
- 支持彩色输出
2. **提交信息规范**
- 使用规范的提交信息格式,例如:
- `feat: 添加新功能`
- `fix: 修复bug`
- `docs: 更新文档`
- `chore: 更新配置`
- `refactor: 代码重构`
3. **定期提交**
- 建议频繁提交小的更改
- 避免一次性提交大量更改
## 📚 相关文档
- [Git 官方文档](https://git-scm.com/doc)
- [提交信息规范](https://www.conventionalcommits.org/)

View File

@@ -135,6 +135,50 @@ class DataManager:
) )
''') ''')
# 餐食记录表
cursor.execute('''
CREATE TABLE IF NOT EXISTS meal_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
date TEXT,
meal_type TEXT,
foods TEXT,
quantities TEXT,
calories REAL,
satisfaction_score INTEGER,
food_items TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (user_id)
)
''')
# 反馈记录表
cursor.execute('''
CREATE TABLE IF NOT EXISTS feedback_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
date TEXT,
recommended_foods TEXT,
user_choice TEXT,
feedback_type TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (user_id)
)
''')
# 问卷记录表
cursor.execute('''
CREATE TABLE IF NOT EXISTS questionnaire_records (
id INTEGER PRIMARY KEY AUTOINCREMENT,
user_id TEXT,
questionnaire_type TEXT,
answers TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (user_id) REFERENCES users (user_id),
UNIQUE(user_id, questionnaire_type)
)
''')
# 分析结果表 # 分析结果表
cursor.execute(''' cursor.execute('''
CREATE TABLE IF NOT EXISTS analysis_results ( CREATE TABLE IF NOT EXISTS analysis_results (
@@ -195,9 +239,16 @@ class DataManager:
return None return None
# 解析用户基本信息 # 解析用户基本信息
try:
data_dict = json.loads(result[0]) data_dict = json.loads(result[0])
except json.JSONDecodeError as e:
logger.error(f"解析用户数据JSON失败: user_id={user_id}, error={e}")
conn.close()
return None
# 获取餐食记录 # 获取餐食记录(如果表存在)
meals = []
try:
cursor.execute(''' cursor.execute('''
SELECT date, meal_type, foods, quantities, calories, satisfaction_score, food_items SELECT date, meal_type, foods, quantities, calories, satisfaction_score, food_items
FROM meal_records FROM meal_records
@@ -206,8 +257,8 @@ class DataManager:
''', (user_id,)) ''', (user_id,))
meal_rows = cursor.fetchall() meal_rows = cursor.fetchall()
meals = []
for row in meal_rows: for row in meal_rows:
try:
meal = { meal = {
'date': row[0], 'date': row[0],
'meal_type': row[1], 'meal_type': row[1],
@@ -218,8 +269,16 @@ class DataManager:
'food_items': json.loads(row[6]) if row[6] else [] 'food_items': json.loads(row[6]) if row[6] else []
} }
meals.append(meal) meals.append(meal)
except (json.JSONDecodeError, IndexError) as e:
logger.warning(f"解析餐食记录失败: {e}")
continue
except sqlite3.OperationalError as e:
# 表不存在,跳过
logger.warning(f"meal_records表不存在跳过: {e}")
# 获取反馈记录 # 获取反馈记录(如果表存在)
feedback = []
try:
cursor.execute(''' cursor.execute('''
SELECT date, recommended_foods, user_choice, feedback_type SELECT date, recommended_foods, user_choice, feedback_type
FROM feedback_records FROM feedback_records
@@ -228,8 +287,8 @@ class DataManager:
''', (user_id,)) ''', (user_id,))
feedback_rows = cursor.fetchall() feedback_rows = cursor.fetchall()
feedback = []
for row in feedback_rows: for row in feedback_rows:
try:
fb = { fb = {
'date': row[0], 'date': row[0],
'recommended_foods': json.loads(row[1]) if row[1] else [], 'recommended_foods': json.loads(row[1]) if row[1] else [],
@@ -237,8 +296,16 @@ class DataManager:
'feedback_type': row[3] 'feedback_type': row[3]
} }
feedback.append(fb) feedback.append(fb)
except (json.JSONDecodeError, IndexError) as e:
logger.warning(f"解析反馈记录失败: {e}")
continue
except sqlite3.OperationalError as e:
# 表不存在,跳过
logger.warning(f"feedback_records表不存在跳过: {e}")
# 获取问卷数据 # 获取问卷数据(如果表存在)
preferences = {}
try:
cursor.execute(''' cursor.execute('''
SELECT questionnaire_type, answers SELECT questionnaire_type, answers
FROM questionnaire_records FROM questionnaire_records
@@ -246,15 +313,21 @@ class DataManager:
''', (user_id,)) ''', (user_id,))
questionnaire_rows = cursor.fetchall() questionnaire_rows = cursor.fetchall()
preferences = {}
for row in questionnaire_rows: for row in questionnaire_rows:
try:
preferences[row[0]] = json.loads(row[1]) if row[1] else {} preferences[row[0]] = json.loads(row[1]) if row[1] else {}
except (json.JSONDecodeError, IndexError) as e:
logger.warning(f"解析问卷记录失败: {e}")
continue
except sqlite3.OperationalError as e:
# 表不存在,跳过
logger.warning(f"questionnaire_records表不存在跳过: {e}")
conn.close() conn.close()
# 构建完整的用户数据 # 构建完整的用户数据
user_data = UserData( user_data = UserData(
user_id=data_dict['user_id'], user_id=data_dict.get('user_id', user_id),
profile=data_dict.get('profile', {}), profile=data_dict.get('profile', {}),
meals=meals, meals=meals,
feedback=feedback, feedback=feedback,
@@ -266,7 +339,7 @@ class DataManager:
return user_data return user_data
except Exception as e: except Exception as e:
logger.error(f"获取用户数据失败: {e}") logger.error(f"获取用户数据失败: user_id={user_id}, error={e}", exc_info=True)
return None return None
def save_analysis_result(self, result: AnalysisResult) -> bool: def save_analysis_result(self, result: AnalysisResult) -> bool:

View File

@@ -0,0 +1,41 @@
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile.low-mem
container_name: diet_recommendation_app_low_mem
ports:
- "5000:5000"
environment:
- FLASK_ENV=production
- PYTHONUNBUFFERED=1
- PYTHONHASHSEED=0
- MALLOC_ARENA_MAX=2
volumes:
# 持久化数据目录
- ./data:/app/data
- ./logs:/app/logs
- ./models:/app/models
restart: unless-stopped
# 内存限制(小内存机器配置)
deploy:
resources:
limits:
memory: 512M
reservations:
memory: 256M
networks:
- app-network
healthcheck:
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:5000/health').read()"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
networks:
app-network:
driver: bridge

86
git_push.bat Normal file
View File

@@ -0,0 +1,86 @@
@echo off
REM -*- coding: utf-8 -*-
REM Git 自动上传脚本Windows
chcp 65001 >nul
setlocal enabledelayedexpansion
echo === Git 自动上传脚本 ===
REM 检查是否在 git 仓库中
if not exist .git (
echo 错误: 当前目录不是 git 仓库
exit /b 1
)
REM 获取当前分支
for /f "tokens=2" %%i in ('git branch --show-current 2^>nul') do set CURRENT_BRANCH=%%i
if "!CURRENT_BRANCH!"=="" (
for /f "delims=" %%i in ('git rev-parse --abbrev-ref HEAD 2^>nul') do set CURRENT_BRANCH=%%i
)
echo 当前分支: !CURRENT_BRANCH!
REM 检查是否有未提交的更改
git status --porcelain >nul 2>&1
if errorlevel 1 (
echo 没有需要提交的更改
set /p CONTINUE="是否继续检查远程更新? (y/n) "
if /i "!CONTINUE!"=="y" (
echo 拉取远程更新...
git pull origin !CURRENT_BRANCH! 2>nul || echo 拉取失败,可能没有远程分支
)
exit /b 0
)
REM 显示当前状态
echo 当前更改状态:
git status --short
REM 询问是否继续
set /p CONTINUE="是否继续提交并推送? (y/n) "
if /i not "!CONTINUE!"=="y" (
echo 操作已取消
exit /b 0
)
REM 获取提交信息
if "%1"=="" (
set /p COMMIT_MSG="请输入提交信息(或直接按回车使用默认信息): "
if "!COMMIT_MSG!"=="" (
for /f "tokens=1-3 delims=/- " %%a in ('date /t') do set DATE_STR=%%a-%%b-%%c
for /f "tokens=1-2 delims=: " %%a in ('time /t') do set TIME_STR=%%a:%%b
set COMMIT_MSG=chore: update code !DATE_STR! !TIME_STR!
)
) else (
set COMMIT_MSG=%1
)
REM 添加所有更改
echo 添加文件到暂存区...
git add -A
if errorlevel 1 (
echo 添加文件失败
exit /b 1
)
REM 提交更改
echo 提交更改...
git commit -m "!COMMIT_MSG!"
if errorlevel 1 (
echo 提交失败
exit /b 1
)
echo 提交成功!
REM 推送到远程
echo 推送到远程仓库...
git push origin !CURRENT_BRANCH!
if errorlevel 1 (
echo 推送失败,可能需要设置远程仓库或认证
echo 提示: 可以手动执行 'git push origin !CURRENT_BRANCH!'
exit /b 1
)
echo ✓ 推送成功!
echo === 完成 ===

138
git_push.py Normal file
View File

@@ -0,0 +1,138 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Git 自动上传脚本(跨平台)
支持 Windows、Linux、Mac
"""
import os
import sys
import subprocess
import platform
from datetime import datetime
# 颜色输出Windows 10+ 支持 ANSI
def print_color(text, color="white"):
colors = {
"red": "\033[0;31m",
"green": "\033[0;32m",
"yellow": "\033[1;33m",
"blue": "\033[0;34m",
"reset": "\033[0m"
}
if platform.system() == "Windows":
# Windows 10+ 支持 ANSI需要启用
try:
import ctypes
kernel32 = ctypes.windll.kernel32
kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7)
except:
pass
color_code = colors.get(color.lower(), colors["reset"])
reset = colors["reset"]
print(f"{color_code}{text}{reset}")
def run_command(cmd, check=True):
"""执行命令并返回结果"""
try:
result = subprocess.run(
cmd,
shell=True,
check=check,
capture_output=True,
text=True,
encoding='utf-8'
)
return result.returncode == 0, result.stdout.strip(), result.stderr.strip()
except subprocess.CalledProcessError as e:
return False, e.stdout.strip() if hasattr(e, 'stdout') else "", e.stderr.strip() if hasattr(e, 'stderr') else ""
def main():
print_color("=== Git 自动上传脚本 ===", "green")
# 检查是否在 git 仓库中
if not os.path.exists(".git"):
print_color("错误: 当前目录不是 git 仓库", "red")
sys.exit(1)
# 获取当前分支
success, branch, _ = run_command("git branch --show-current", check=False)
if not success:
success, branch, _ = run_command("git rev-parse --abbrev-ref HEAD", check=False)
if not branch:
print_color("错误: 无法获取当前分支", "red")
sys.exit(1)
print_color(f"当前分支: {branch}", "yellow")
# 检查是否有未提交的更改
success, status, _ = run_command("git status --porcelain", check=False)
if not status:
print_color("没有需要提交的更改", "yellow")
response = input("是否继续检查远程更新? (y/n) ").strip().lower()
if response == 'y':
print_color("拉取远程更新...", "green")
run_command(f"git pull origin {branch}", check=False)
sys.exit(0)
# 显示当前状态
print_color("当前更改状态:", "yellow")
success, status_output, _ = run_command("git status --short", check=False)
print(status_output)
# 询问是否继续
response = input("是否继续提交并推送? (y/n) ").strip().lower()
if response != 'y':
print_color("操作已取消", "yellow")
sys.exit(0)
# 获取提交信息
if len(sys.argv) > 1:
commit_msg = " ".join(sys.argv[1:])
else:
default_msg = f"chore: update code {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}"
user_msg = input(f"请输入提交信息(或直接按回车使用默认信息): ").strip()
commit_msg = user_msg if user_msg else default_msg
# 添加所有更改
print_color("添加文件到暂存区...", "green")
success, _, error = run_command("git add -A")
if not success:
print_color(f"添加文件失败: {error}", "red")
sys.exit(1)
# 提交更改
print_color("提交更改...", "green")
success, _, error = run_command(f'git commit -m "{commit_msg}"')
if not success:
if "nothing to commit" in error.lower():
print_color("没有需要提交的更改", "yellow")
sys.exit(0)
print_color(f"提交失败: {error}", "red")
sys.exit(1)
print_color("提交成功!", "green")
# 推送到远程
print_color("推送到远程仓库...", "green")
success, _, error = run_command(f"git push origin {branch}")
if not success:
print_color(f"推送失败: {error}", "red")
print_color(f"提示: 可以手动执行 'git push origin {branch}'", "yellow")
print_color("可能需要设置远程仓库地址或进行身份验证", "yellow")
sys.exit(1)
print_color("✓ 推送成功!", "green")
print_color("=== 完成 ===", "green")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print_color("\n操作已取消", "yellow")
sys.exit(0)
except Exception as e:
print_color(f"发生错误: {e}", "red")
sys.exit(1)

84
git_push.sh Normal file
View File

@@ -0,0 +1,84 @@
#!/bin/bash
# -*- coding: utf-8 -*-
# Git 自动上传脚本Linux/Mac
set -e # 遇到错误立即退出
# 颜色输出
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo -e "${GREEN}=== Git 自动上传脚本 ===${NC}"
# 检查是否在 git 仓库中
if [ ! -d .git ]; then
echo -e "${RED}错误: 当前目录不是 git 仓库${NC}"
exit 1
fi
# 获取当前分支
CURRENT_BRANCH=$(git branch --show-current)
echo -e "${YELLOW}当前分支: ${CURRENT_BRANCH}${NC}"
# 检查是否有未提交的更改
if [ -z "$(git status --porcelain)" ]; then
echo -e "${YELLOW}没有需要提交的更改${NC}"
read -p "是否继续检查远程更新? (y/n) " -n 1 -r
echo
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo -e "${GREEN}拉取远程更新...${NC}"
git pull origin "$CURRENT_BRANCH" || echo -e "${YELLOW}拉取失败,可能没有远程分支${NC}"
fi
exit 0
fi
# 显示当前状态
echo -e "${YELLOW}当前更改状态:${NC}"
git status --short
# 询问是否继续
read -p "是否继续提交并推送? (y/n) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
echo -e "${YELLOW}操作已取消${NC}"
exit 0
fi
# 获取提交信息
if [ -z "$1" ]; then
echo -e "${YELLOW}请输入提交信息(或直接按回车使用默认信息):${NC}"
read -r COMMIT_MSG
if [ -z "$COMMIT_MSG" ]; then
COMMIT_MSG="chore: update code $(date '+%Y-%m-%d %H:%M:%S')"
fi
else
COMMIT_MSG="$1"
fi
# 添加所有更改
echo -e "${GREEN}添加文件到暂存区...${NC}"
git add -A
# 提交更改
echo -e "${GREEN}提交更改...${NC}"
if git commit -m "$COMMIT_MSG"; then
echo -e "${GREEN}提交成功!${NC}"
else
echo -e "${RED}提交失败${NC}"
exit 1
fi
# 推送到远程
echo -e "${GREEN}推送到远程仓库...${NC}"
if git push origin "$CURRENT_BRANCH"; then
echo -e "${GREEN}✓ 推送成功!${NC}"
else
echo -e "${RED}推送失败,可能需要设置远程仓库或认证${NC}"
echo -e "${YELLOW}提示: 可以手动执行 'git push origin $CURRENT_BRANCH'${NC}"
exit 1
fi
echo -e "${GREEN}=== 完成 ===${NC}"

View File

@@ -411,40 +411,57 @@ def user_register():
# 如果用户不存在,创建新用户 # 如果用户不存在,创建新用户
if not user_data: if not user_data:
initial_data = { from core.base import UserData
'profile': { # 直接创建UserData对象并保存
initial_profile = {
'name': name, 'name': name,
'age': 25, 'age': 25,
'gender': '未知', 'gender': '未知',
'height': 170, 'height': 170,
'weight': 60, 'weight': 60,
'activity_level': 'moderate' 'activity_level': 'moderate'
},
'preferences': {}
} }
if core.create_user(user_id, initial_data): user_data = UserData(
user_data = core.get_user_data(user_id) user_id=user_id,
else: profile=initial_profile,
preferences={}
)
# 保存用户数据
if not core.data_manager.save_user_data(user_data):
logger.error(f"保存用户数据失败: user_id={user_id}")
return jsonify({ return jsonify({
'success': False, 'success': False,
'message': '创建用户失败' 'message': '创建用户失败:数据保存失败'
}), 500 }), 500
# 更新用户基本信息 # 验证保存是否成功(重新获取一次)
if user_data: saved_user_data = core.get_user_data(user_id)
if not saved_user_data:
logger.error(f"用户数据保存后无法获取: user_id={user_id}")
return jsonify({
'success': False,
'message': '创建用户失败:数据验证失败'
}), 500
user_data = saved_user_data
else:
# 用户已存在,更新姓名
user_data.profile['name'] = name user_data.profile['name'] = name
core.data_manager.save_user_data(user_data) if not core.data_manager.save_user_data(user_data):
logger.error(f"更新用户数据失败: user_id={user_id}")
return jsonify({
'success': False,
'message': '更新用户信息失败'
}), 500
# 设置会话
session['user_id'] = user_id session['user_id'] = user_id
return jsonify({ return jsonify({
'success': True, 'success': True,
'user_id': user_id, 'user_id': user_id,
'name': name 'name': user_data.profile.get('name', name)
}) })
else:
return jsonify({
'success': False,
'message': '用户数据获取失败'
}), 500
except Exception as e: except Exception as e:
logger.error(f"用户注册失败: {e}", exc_info=True) logger.error(f"用户注册失败: {e}", exc_info=True)