feat: 创作工作台统一 + AI味检测/白标 + 移动端补全 + 合规发布闭环
- 新增创作工作台 studio.html:合并选题/内容工厂/文章管理为单一 tab 入口(iframe embed 模式) - 新增 AI味检测模块(ai_slop API + 页面,合规软硬问题分级) - 新增白标品牌配置(branding API + 页面 + deploy 私有化交付包) - 发布闭环:publishing 放宽至 editor + records/mark-published 接口 - 移动端响应式补全(admin/calendar/ai-slop 表格卡片兜底) - 修复菜单幂等播种缺陷(按 path 对齐,避免功能页孤立) - 新增短视频脚本 shortvideo.py 与 2026 市场调研简报
This commit is contained in:
@@ -76,6 +76,17 @@ def import_initial_data():
|
||||
for cfg in default_system_configs:
|
||||
if db.query(SystemConfig).filter(SystemConfig.key == cfg["key"]).first() is None:
|
||||
db.add(SystemConfig(**cfg))
|
||||
|
||||
# 白标默认值(私有化部署/卖给他人时可改)
|
||||
default_branding = [
|
||||
{"key": "brand_name", "value": "宇之然内容创作平台", "description": "白标:平台名称"},
|
||||
{"key": "brand_logo", "value": "", "description": "白标:Logo URL(留空用文字)"},
|
||||
{"key": "brand_primary_color", "value": "#2563eb", "description": "白标:主色(导航/按钮)"},
|
||||
{"key": "brand_support_email", "value": "", "description": "白标:支持邮箱"},
|
||||
]
|
||||
for b in default_branding:
|
||||
if db.query(SystemConfig).filter(SystemConfig.key == b["key"]).first() is None:
|
||||
db.add(SystemConfig(**b))
|
||||
if db.query(SystemConfig).filter(SystemConfig.key == "review_llm_id").first() is None:
|
||||
first_llm = db.query(LLMConfig).filter(LLMConfig.is_active == True).first()
|
||||
if first_llm:
|
||||
@@ -294,21 +305,47 @@ def import_initial_data():
|
||||
db.commit()
|
||||
print("✅ 插入默认角色")
|
||||
|
||||
# 初始化默认菜单(与 uni-nav.js 对齐)
|
||||
if db.query(Menu).count() == 0:
|
||||
default_menus = [
|
||||
{"name": "仪表盘", "path": "/", "icon": "IconHome", "sort_order": 0, "roles": ["admin", "editor"]},
|
||||
{"name": "选题", "path": "topics.html", "icon": "IconTopic", "sort_order": 1, "roles": ["admin", "editor"]},
|
||||
{"name": "数据", "path": "metrics.html", "icon": "IconData", "sort_order": 2, "roles": ["admin", "editor"]},
|
||||
{"name": "日历", "path": "calendar.html", "icon": "IconCalendar", "sort_order": 3, "roles": ["admin", "editor"]},
|
||||
{"name": "素材", "path": "assets.html", "icon": "IconFolder", "sort_order": 4, "roles": ["admin", "editor"]},
|
||||
{"name": "任务", "path": "tasks.html", "icon": "IconMenu", "sort_order": 5, "roles": ["admin", "editor"]},
|
||||
{"name": "系统", "path": "admin.html", "icon": "IconSetting", "sort_order": 6, "roles": ["admin"]},
|
||||
]
|
||||
for m in default_menus:
|
||||
db.add(Menu(**m))
|
||||
# 归一化首页菜单路径,避免 index.html 与 /index.html 产生重复入口
|
||||
idx_plain = db.query(Menu).filter(Menu.path == "index.html").first()
|
||||
idx_slash = db.query(Menu).filter(Menu.path == "/index.html").first()
|
||||
if idx_plain and not idx_slash:
|
||||
idx_plain.path = "/index.html"
|
||||
db.commit()
|
||||
print("✅ 插入默认菜单")
|
||||
elif idx_plain and idx_slash:
|
||||
db.delete(idx_plain)
|
||||
db.commit()
|
||||
|
||||
# 初始化默认菜单:幂等按 path 对齐(已有时更新排序/角色,缺失时插入)。
|
||||
# 运行时会用 DB 菜单覆盖 uni-nav.js 的 fallback,因此这里必须保证文章管理/内容工厂/白标设置等入口存在。
|
||||
default_menus = [
|
||||
{"name": "工作台", "path": "/index.html", "icon": "IconHome", "sort_order": 0, "roles": ["admin", "editor"]},
|
||||
{"name": "创作工作台", "path": "studio.html", "icon": "IconEdit", "sort_order": 1, "roles": ["admin", "editor"]},
|
||||
{"name": "数据", "path": "metrics.html", "icon": "IconData", "sort_order": 2, "roles": ["admin", "editor"]},
|
||||
{"name": "日历", "path": "calendar.html", "icon": "IconCalendar", "sort_order": 3, "roles": ["admin", "editor"]},
|
||||
{"name": "素材", "path": "assets.html", "icon": "IconFolder", "sort_order": 4, "roles": ["admin", "editor"]},
|
||||
{"name": "任务", "path": "tasks.html", "icon": "IconMenu", "sort_order": 5, "roles": ["admin", "editor"]},
|
||||
{"name": "外推营销", "path": "campaigns.html", "icon": "IconStar", "sort_order": 6, "roles": ["admin", "editor"]},
|
||||
{"name": "AI味检测", "path": "ai-slop.html", "icon": "IconSearch", "sort_order": 7, "roles": ["admin", "editor"]},
|
||||
{"name": "白标设置", "path": "branding.html", "icon": "IconSetting", "sort_order": 8, "roles": ["admin"]},
|
||||
{"name": "系统", "path": "admin.html", "icon": "IconSetting", "sort_order": 9, "roles": ["admin"]},
|
||||
]
|
||||
for m in default_menus:
|
||||
found = db.query(Menu).filter(Menu.path == m["path"]).first()
|
||||
if found:
|
||||
found.sort_order = m["sort_order"]
|
||||
found.roles = m["roles"]
|
||||
found.icon = m["icon"]
|
||||
found.is_active = True
|
||||
# 保留原名称,避免意外重命名
|
||||
else:
|
||||
db.add(Menu(**m))
|
||||
# 原独立的选题/内容工厂/文章管理已合并进「创作工作台」,从主导航隐藏(页面仍可被 studio 内嵌与直接访问)
|
||||
for legacy in ["topics.html", "factory.html", "articles.html"]:
|
||||
legacy_menu = db.query(Menu).filter(Menu.path == legacy).first()
|
||||
if legacy_menu:
|
||||
legacy_menu.is_active = False
|
||||
db.commit()
|
||||
print("✅ 菜单已对齐(创作工作台合并选题/内容工厂/文章管理)")
|
||||
|
||||
# 同步 PostgreSQL 自增序列
|
||||
if os.getenv('USE_POSTGRES', 'true').lower() == 'true':
|
||||
|
||||
Reference in New Issue
Block a user