style:1.组织管理页面支持组织列表滚动 2.优化一些页面的标题和图标显示

This commit is contained in:
xiamuceer
2025-12-29 12:08:01 +08:00
parent 907a6550ee
commit 7714a22479
19 changed files with 404 additions and 214 deletions
+12 -14
View File
@@ -8,7 +8,7 @@
# 应用配置
# ==========================================
APP_NAME=MuMuAINovel
APP_VERSION=1.1.4
APP_VERSION=1.2.2
APP_HOST=0.0.0.0
APP_PORT=8000
DEBUG=false
@@ -25,7 +25,7 @@ POSTGRES_PASSWORD=123456
POSTGRES_PORT=5432
# 数据库连接 URL(Docker 部署时自动生成)
DATABASE_URL=postgresql+asyncpg://mumuai:123456@localhost:5432/mumuai_novel
# DATABASE_URL=postgresql+asyncpg://mumuai:123456@localhost:5432/mumuai_novel
# ==========================================
# SQLite 数据库配置
@@ -33,13 +33,6 @@ DATABASE_URL=postgresql+asyncpg://mumuai:123456@localhost:5432/mumuai_novel
# DATABASE_URL=sqlite+aiosqlite:///data/ai_story.db
# ==========================================
# 代理配置(可选)
# ==========================================
# HTTP_PROXY=http://your-proxy:port
# HTTPS_PROXY=http://your-proxy:port
# NO_PROXY=localhost,127.0.0.1
# ==========================================
# 日志配置
# ==========================================
@@ -54,6 +47,13 @@ LOG_BACKUP_COUNT=30
# ==========================================
CORS_ORIGINS=["http://localhost:8000","http://127.0.0.1:8000"]
# ==========================================
# 代理配置(可选)
# ==========================================
# HTTP_PROXY=http://your-proxy:port
# HTTPS_PROXY=http://your-proxy:port
# NO_PROXY=localhost,127.0.0.1
# ==========================================
# AI 服务配置(至少配置一个)
# ==========================================
@@ -71,11 +71,9 @@ DEFAULT_MAX_TOKENS=32000
# ==========================================
# LinuxDO OAuth 配置(可选)
# ==========================================
# LINUXDO_CLIENT_ID=your_client_id_here
# LINUXDO_CLIENT_SECRET=your_client_secret_here
# LINUXDO_REDIRECT_URI=http://localhost:8000/api/auth/callback
# 前端 URL(OAuth 回调后重定向)
LINUXDO_CLIENT_ID=11111
LINUXDO_CLIENT_SECRET=11111
LINUXDO_REDIRECT_URI=http://localhost:8000/api/auth/callback
FRONTEND_URL=http://localhost:8000
# 初始管理员(LinuxDO user_id
+5 -5
View File
@@ -497,7 +497,7 @@ async def generate_organization_stream(
- 其他要求:{gen_request.requirements or ''}
"""
yield await SSEResponse.send_progress("构建AI提示词...", 20)
yield await SSEResponse.send_progress("构建AI提示词...", 5)
# 获取自定义提示词模板
template = await PromptService.get_template("SINGLE_ORGANIZATION_GENERATION", user_id, db)
@@ -508,7 +508,7 @@ async def generate_organization_stream(
user_input=user_input
)
yield await SSEResponse.send_progress("调用AI服务生成组织...", 30)
yield await SSEResponse.send_progress("调用AI服务生成组织...", 10)
logger.info(f"🎯 开始为项目 {gen_request.project_id} 生成组织(SSE流式)")
try:
@@ -525,7 +525,7 @@ async def generate_organization_stream(
# 定期更新字数(5-95%,AI生成占90%)
if chunk_count % 5 == 0:
progress = min(5 + (chunk_count // 5), 95)
progress = min(10 + (chunk_count // 5), 95)
yield await SSEResponse.send_progress(
f"AI生成组织中... ({len(ai_content)}字符)",
progress
@@ -544,7 +544,7 @@ async def generate_organization_stream(
yield await SSEResponse.send_error("AI服务返回空响应")
return
yield await SSEResponse.send_progress("解析AI响应...", 96)
yield await SSEResponse.send_progress("解析AI响应...", 90)
# ✅ 使用统一的 JSON 清洗方法
try:
@@ -557,7 +557,7 @@ async def generate_organization_stream(
yield await SSEResponse.send_error(f"AI返回的内容无法解析为JSON{str(e)}")
return
yield await SSEResponse.send_progress("创建组织记录...", 97)
yield await SSEResponse.send_progress("创建组织记录...", 95)
# 创建角色记录(组织也是角色的一种)
character = Character(
+13 -13
View File
@@ -134,10 +134,10 @@ async def world_building_generator(
请结合上述资料,生成符合历史/现实的世界观设定。"""
final_prompt = enhanced_prompt
yield await SSEResponse.send_progress("💡 已整合参考资料,开始生成世界观...", 30)
yield await SSEResponse.send_progress("💡 已整合参考资料,开始生成世界观...", 10)
else:
final_prompt = base_prompt
yield await SSEResponse.send_progress("正在调用AI生成...", 30)
yield await SSEResponse.send_progress("正在调用AI生成...", 10)
# ===== 流式生成世界观(带重试机制) =====
MAX_WORLD_RETRIES = 3 # 最多重试3次
@@ -148,7 +148,7 @@ async def world_building_generator(
while world_retry_count < MAX_WORLD_RETRIES and not world_generation_success:
try:
retry_suffix = f" (重试{world_retry_count}/{MAX_WORLD_RETRIES})" if world_retry_count > 0 else ""
yield await SSEResponse.send_progress(f"生成世界观{retry_suffix}...", 30 + world_retry_count * 5)
yield await SSEResponse.send_progress(f"生成世界观{retry_suffix}...", 10 + world_retry_count * 5)
# 流式生成世界观
accumulated_text = ""
@@ -181,7 +181,7 @@ async def world_building_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ AI返回为空,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
@@ -221,7 +221,7 @@ async def world_building_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ JSON解析失败,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
@@ -241,7 +241,7 @@ async def world_building_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ 生成异常,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
@@ -1599,10 +1599,10 @@ async def world_building_regenerate_generator(
请结合上述资料,生成符合历史/现实的世界观设定。"""
final_prompt = enhanced_prompt
yield await SSEResponse.send_progress("💡 已整合参考资料,开始生成世界观...", 30)
yield await SSEResponse.send_progress("💡 已整合参考资料,开始生成世界观...", 10)
else:
final_prompt = base_prompt
yield await SSEResponse.send_progress("正在调用AI生成...", 30)
yield await SSEResponse.send_progress("正在调用AI生成...", 10)
# ===== 流式生成世界观(带重试机制) =====
MAX_WORLD_RETRIES = 3 # 最多重试3次
@@ -1613,7 +1613,7 @@ async def world_building_regenerate_generator(
while world_retry_count < MAX_WORLD_RETRIES and not world_generation_success:
try:
retry_suffix = f" (重试{world_retry_count}/{MAX_WORLD_RETRIES})" if world_retry_count > 0 else ""
yield await SSEResponse.send_progress(f"重新生成世界观{retry_suffix}...", 30 + world_retry_count * 5)
yield await SSEResponse.send_progress(f"重新生成世界观{retry_suffix}...", 10 + world_retry_count * 5)
# 流式生成世界观
accumulated_text = ""
@@ -1630,7 +1630,7 @@ async def world_building_regenerate_generator(
yield await SSEResponse.send_chunk(chunk)
if chunk_count % 5 == 0:
progress = min(30 + (chunk_count // 5), 85)
progress = min(10 + (chunk_count // 5), 85)
yield await SSEResponse.send_progress(f"生成中... ({len(accumulated_text)}字符)", progress)
if chunk_count % 20 == 0:
@@ -1643,7 +1643,7 @@ async def world_building_regenerate_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ AI返回为空,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
@@ -1679,7 +1679,7 @@ async def world_building_regenerate_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ JSON解析失败,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
@@ -1699,7 +1699,7 @@ async def world_building_regenerate_generator(
if world_retry_count < MAX_WORLD_RETRIES:
yield await SSEResponse.send_progress(
f"⚠️ 生成异常,准备重试...",
30 + world_retry_count * 5,
10 + world_retry_count * 5,
"warning"
)
continue
+6
View File
@@ -4,8 +4,14 @@
set -e # 遇到错误立即退出
# 获取版本信息(从config.py中提取)
APP_VERSION=$(grep -oP "app_version:\s*str\s*=\s*\"\K[^\"]*" /app/app/config.py || echo "unknown")
BUILD_TIME=$(date '+%Y-%m-%d %H:%M:%S')
echo "================================================"
echo "🚀 MuMuAINovel 启动中..."
echo "📦 版本: v${APP_VERSION}"
echo "🕐 启动时间: ${BUILD_TIME}"
echo "================================================"
# 数据库配置(从环境变量读取)