feat(monitor): 作品标签 —— 词表在设置里维护,作品上贴
和「作品备注」刻意并存,不是一回事:备注是一句话的自由文字,标签是**从一份固定
词表里选的分类**。分类必须封闭,否则「重点 / 重要 / 优先」各写各的,筛就没法用了。
* `monitor_tag`:词表,全局一套(不按平台分)—— 「重点」是给人自己用的心智,不该在
小红书和抖音各定义一遍。颜色存的是**调色板里的名字**,不是色值:Tailwind 的类名是
静态提取的,拼出来的 `text-${color}` 它看不见,线上会静默变无色。
* `monitor_note_tag`:作品↔标签,**多对多**。一条作品可以既是重点又是竞品;只能贴一个
的话人就会跑去备注里写自由文字,这份词表就白建了。全部替换式提交,不是逐个增删。
* 删除标签时**显式删关联**,不靠外键级联 —— 测试跑 SQLite,它默认不开外键约束。
* 组头上的筛选做成平铺开关片,多选是「或」。
顺带:/monitor/notes 现在支持按 tag_id 筛。
This commit is contained in:
@@ -405,6 +405,50 @@ class MonitorNoteAlias(MonitorBase):
|
||||
updated_at: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
||||
|
||||
|
||||
class MonitorTag(MonitorBase):
|
||||
"""作品标签的**词表** —— 在设置里维护,贴标签时从这里选。
|
||||
|
||||
刻意做成一张表而不是一个设置项:设置里那个注册表存的是标量(一个数、一段文字),
|
||||
而这是一组能增能删能改名的条目。
|
||||
|
||||
**全局一套,不按平台分。** 「重点」「竞品」这种分类是给人自己用的心智,不该在小红书
|
||||
和抖音各定义一遍;而且同一个词在两个平台上含义不同的话,反而不好比。
|
||||
"""
|
||||
|
||||
__tablename__ = "monitor_tag"
|
||||
__table_args__ = (UniqueConstraint("name", name="uq_tag_name"),)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
name: Mapped[str] = mapped_column(String(32), nullable=False)
|
||||
# 一个**调色板里的名字**(cyan/pink/green/…),不是颜色值。Tailwind 的类名是静态
|
||||
# 提取的,拼不出 `text-${color}` 那种动态类,所以这里存的是查表用的键。
|
||||
color: Mapped[str] = mapped_column(String(16), nullable=False, default="")
|
||||
sort_order: Mapped[int] = mapped_column(Integer, nullable=False, default=0)
|
||||
created_at: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
||||
|
||||
|
||||
class MonitorNoteTag(MonitorBase):
|
||||
"""作品 ↔ 标签。
|
||||
|
||||
键取 ``(platform, note_id)``,和作品备注同一个口径:作品 id 本身带平台语义,但显式
|
||||
带上 platform 才能和别处用同一套查询形状。
|
||||
|
||||
**多对多**:一条作品可以既是「重点」又是「竞品」—— 标签本来就是可以叠加的分类,
|
||||
一个不够用的话人就会去备注里写自由文字,那这个功能就白做了。
|
||||
"""
|
||||
|
||||
__tablename__ = "monitor_note_tag"
|
||||
__table_args__ = (
|
||||
UniqueConstraint("platform", "note_id", "tag_id", name="uq_note_tag"),
|
||||
)
|
||||
|
||||
id: Mapped[int] = mapped_column(Integer, primary_key=True, autoincrement=True)
|
||||
platform: Mapped[str] = mapped_column(String(16), nullable=False, index=True)
|
||||
note_id: Mapped[str] = mapped_column(String(128), nullable=False, index=True)
|
||||
tag_id: Mapped[int] = mapped_column(Integer, nullable=False, index=True)
|
||||
created_at: Mapped[int] = mapped_column(BigInteger, nullable=False)
|
||||
|
||||
|
||||
class MonitorSetting(MonitorBase):
|
||||
"""Key/value store. Holds the XHS cookie for unattended runs."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user