- 新增 articles.commentary_meituan{_status,_model,_error} 4 列 + commentary_engine
- LlmSetting 加 meituan_api_key/base_url/chat_model/interval_sec/enabled/commentary_prompt
- 新 app/services/llm/providers.py 工厂,支持多 provider 客户端
- enrichment 流程改为 commentary_angel + commentary_meituan 并行(asyncio.gather),
任一 provider 失败不影响另一个
- enrichment_loop 状态判定:任一 provider 状态不是 ok 都视为待 enrich
- alembic 0004_dual_commentary 迁移
- 前端 Feed 卡片 + ArticleDetail 详情页各加一条'美团评论'卡
- AdminLlmSettings 加美团 provider 配置卡(独立 api_key 编辑器,不回显明文)
- LlmSettingOut.meituan_api_key_set (bool) 替代直接回传 key
- 默认 URL https://api.longcat.chat/openai/v1 / 默认模型 LongCat-2.0-Preview
129 lines
3.4 KiB
Python
129 lines
3.4 KiB
Python
"""双 provider 评论:加美团评论列 + commentary_engine 标识
|
|
|
|
- commentary_engine 区分"实际写入的 provider 名称"(angel / meituan / "angel,meituan")
|
|
- commentary_meituan{_status,_model,_error,_} 4 列
|
|
|
|
Revision ID: 0004
|
|
Revises: 0003
|
|
Create Date: 2026-06-12
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from typing import Sequence, Union
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision: str = "0004"
|
|
down_revision: Union[str, None] = "0003"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
# === articles:加 5 列(4 个 status/model/error + 1 个 content)===
|
|
op.add_column(
|
|
"articles",
|
|
sa.Column("commentary_engine", sa.String(32), nullable=True),
|
|
)
|
|
op.add_column(
|
|
"articles",
|
|
sa.Column(
|
|
"commentary_meituan",
|
|
sa.Text,
|
|
nullable=True,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"articles",
|
|
sa.Column(
|
|
"commentary_meituan_status",
|
|
sa.String(16),
|
|
nullable=False,
|
|
server_default="n/a",
|
|
),
|
|
)
|
|
op.add_column(
|
|
"articles",
|
|
sa.Column(
|
|
"commentary_meituan_model",
|
|
sa.String(64),
|
|
nullable=True,
|
|
),
|
|
)
|
|
op.add_column(
|
|
"articles",
|
|
sa.Column(
|
|
"commentary_meituan_error",
|
|
sa.Text,
|
|
nullable=True,
|
|
),
|
|
)
|
|
# 旧存量:commentary_status=ok 的文章 → 标记 commentary_engine=angel
|
|
op.execute(
|
|
"UPDATE articles SET commentary_engine = 'angel' "
|
|
"WHERE commentary_status = 'ok' AND commentary_engine IS NULL"
|
|
)
|
|
|
|
# === llm_settings:加 6 列(美团 provider 配置)===
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column("meituan_api_key", sa.Text, nullable=False, server_default=""),
|
|
)
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column(
|
|
"meituan_base_url",
|
|
sa.String(255),
|
|
nullable=False,
|
|
server_default="https://api.longcat.chat/openai/v1",
|
|
),
|
|
)
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column(
|
|
"meituan_chat_model",
|
|
sa.String(64),
|
|
nullable=False,
|
|
server_default="LongCat-2.0-Preview",
|
|
),
|
|
)
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column(
|
|
"meituan_interval_sec",
|
|
sa.Float,
|
|
nullable=False,
|
|
server_default="2.0",
|
|
),
|
|
)
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column(
|
|
"meituan_enabled",
|
|
sa.Boolean,
|
|
nullable=False,
|
|
server_default=sa.true(),
|
|
),
|
|
)
|
|
op.add_column(
|
|
"llm_settings",
|
|
sa.Column("meituan_commentary_prompt", sa.Text, nullable=True),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
# 反向顺序很重要(后加的先删)
|
|
op.drop_column("llm_settings", "meituan_commentary_prompt")
|
|
op.drop_column("llm_settings", "meituan_enabled")
|
|
op.drop_column("llm_settings", "meituan_interval_sec")
|
|
op.drop_column("llm_settings", "meituan_chat_model")
|
|
op.drop_column("llm_settings", "meituan_base_url")
|
|
op.drop_column("llm_settings", "meituan_api_key")
|
|
|
|
op.drop_column("articles", "commentary_meituan_error")
|
|
op.drop_column("articles", "commentary_meituan_model")
|
|
op.drop_column("articles", "commentary_meituan_status")
|
|
op.drop_column("articles", "commentary_meituan")
|
|
op.drop_column("articles", "commentary_engine")
|