File size: 6,052 Bytes
59bd45e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
"""
ModelScope 部署入口文件
使用 Gradio 包装 FastAPI 应用
"""

import os
import sys
from pathlib import Path
import gradio as gr

# 添加项目根目录到 Python 路径
sys.path.insert(0, str(Path(__file__).parent))

# 设置环境变量
os.environ.setdefault("DATA_DIR", "data")
os.environ.setdefault("LOG_LEVEL", "INFO")

# 确保数据目录存在
data_dir = Path("data")
data_dir.mkdir(exist_ok=True)

generated_images_dir = Path("generated_images")
generated_images_dir.mkdir(exist_ok=True)

# 导入 FastAPI 应用
from app.main import app as fastapi_app
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse

# 挂载前端静态文件
frontend_dist = Path(__file__).parent / "frontend" / "dist"
if frontend_dist.exists():
    # 挂载静态资源(CSS, JS)
    assets_dir = frontend_dist / "assets"
    if assets_dir.exists():
        fastapi_app.mount("/assets", StaticFiles(directory=str(assets_dir)), name="assets")
        print(f"✅ 前端资源文件已挂载: {assets_dir}")
    
    print(f"✅ 前端应用已挂载: {frontend_dist}")
else:
    print(f"⚠️ 前端构建目录不存在: {frontend_dist}")

# 重写根路由以服务前端
@fastapi_app.get("/", include_in_schema=False)
async def serve_root():
    """服务前端应用首页"""
    if frontend_dist.exists():
        index_file = frontend_dist / "index.html"
        if index_file.exists():
            return FileResponse(index_file)
    return {
        "service": "SoulMate AI Companion",
        "status": "running",
        "version": "1.0.0",
        "message": "Welcome! Visit /docs for API documentation."
    }

# 添加 catch-all 路由用于 SPA
@fastapi_app.get("/{full_path:path}", include_in_schema=False)
async def serve_spa(full_path: str):
    """服务前端应用(SPA 路由支持)"""
    # 如果是 API 路径,跳过
    if full_path.startswith("api/") or full_path == "docs" or full_path == "openapi.json" or full_path == "health":
        from fastapi import HTTPException
        raise HTTPException(status_code=404, detail="Not found")
    
    # 返回前端 index.html
    if frontend_dist.exists():
        index_file = frontend_dist / "index.html"
        if index_file.exists():
            return FileResponse(index_file)
    
    return {"error": "Frontend not found"}

# 创建 Gradio 界面(用于 ModelScope 的展示)
with gr.Blocks(
    title="治愈系记录助手 - SoulMate AI Companion",
    theme=gr.themes.Soft(
        primary_hue="purple",
        secondary_hue="pink",
    ),
) as demo:
    
    gr.Markdown("""
    # 🌟 治愈系记录助手 - SoulMate AI Companion
    
    一个温暖、治愈的 AI 陪伴应用,帮助你记录心情、捕捉灵感、管理待办。
    
    ### ✨ 核心特性
    - 🎤 **语音/文字快速记录** - 自动分类保存
    - 🤖 **AI 语义解析** - 智能提取情绪、灵感和待办
    - 💬 **AI 对话陪伴(RAG)** - 基于历史记录的个性化对话
    - 🖼️ **AI 形象定制** - 生成专属治愈系角色(720 种组合)
    - 🫧 **物理引擎心情池** - 基于 Matter.js 的动态气泡可视化
    
    ---
    
    ### 🚀 开始使用
    
    **🎯 前端应用地址:** 点击上方的 "App" 标签页访问完整应用
    
    **📚 API 文档:** [FastAPI Swagger Docs →](/docs)
    
    ---
    
    ### 📖 使用说明
    
    1. **首页快速记录**
       - 点击麦克风录音或在输入框输入文字
       - AI 自动分析并分类保存
    
    2. **查看分类数据**
       - 点击顶部心情、灵感、待办图标
       - 查看不同类型的记录
    
    3. **与 AI 对话**
       - 点击 AI 形象显示问候对话框
       - 点击对话框中的聊天图标进入完整对话
       - AI 基于你的历史记录提供个性化回复
    
    4. **定制 AI 形象**
       - 点击右下角 ✨ 按钮
       - 选择颜色、性格、外观、角色
       - 生成专属形象(需要 MiniMax API)
    
    5. **心情气泡池**
       - 点击顶部心情图标
       - 左右滑动查看不同日期的心情卡片
       - 点击卡片展开查看当天的气泡池
       - 可以拖拽气泡,感受物理引擎效果
    
    ---
    
    ### ⚙️ 配置说明
    
    需要在 ModelScope 的环境变量中配置:
    
    **必需:**
    - `ZHIPU_API_KEY` - 智谱 AI API 密钥
      - 获取地址:https://open.bigmodel.cn/
      - 用途:语音识别、语义解析、AI 对话
    
    **可选:**
    - `MINIMAX_API_KEY` - MiniMax API 密钥
    - `MINIMAX_GROUP_ID` - MiniMax Group ID
      - 获取地址:https://platform.minimaxi.com/
      - 用途:AI 形象生成
    
    ---
    
    ### 🔗 相关链接
    - [GitHub 仓库](https://github.com/kernel-14/Nora)
    - [详细文档](https://github.com/kernel-14/Nora/blob/main/README.md)
    - [智谱 AI](https://open.bigmodel.cn/)
    - [MiniMax](https://platform.minimaxi.com/)
    
    ---
    
    ### 📊 API 端点
    
    - `POST /api/process` - 处理文本/语音输入
    - `POST /api/chat` - 与 AI 对话(RAG)
    - `GET /api/records` - 获取所有记录
    - `GET /api/moods` - 获取情绪数据
    - `GET /api/inspirations` - 获取灵感
    - `GET /api/todos` - 获取待办事项
    - `POST /api/character/generate` - 生成角色形象
    - `GET /health` - 健康检查
    - `GET /docs` - API 文档
    """)

# 挂载 FastAPI 到 Gradio
app = gr.mount_gradio_app(fastapi_app, demo, path="/gradio")

# 如果直接运行此文件
if __name__ == "__main__":
    import uvicorn
    print("=" * 50)
    print("🌟 治愈系记录助手 - SoulMate AI Companion")
    print("=" * 50)
    print(f"📍 前端应用: http://0.0.0.0:7860/")
    print(f"📚 Gradio 界面: http://0.0.0.0:7860/gradio")
    print(f"📖 API 文档: http://0.0.0.0:7860/docs")
    print(f"🔍 健康检查: http://0.0.0.0:7860/health")
    print("=" * 50)
    
    uvicorn.run(app, host="0.0.0.0", port=7860)