deerflow-code/offline-backend-20260512/backend/packages/harness/deerflow/persistence/task_buttons/model.py
2026-09-07 18:24:55 +08:00

75 lines
4.5 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""ORM model for task-workspace configurable jump buttons (按钮管理).
Global / shared — there is no ``user_id`` scoping; every account sees the same
buttons. The task deep-link workspaces (rwfx / 3qfx / xdfx, see
``TaskFxWorkspace``) render the enabled buttons for their ``business`` in the
left task panel. Each row is one button:
- ``business`` — which workspace the button belongs to (``rwfx`` / ``3qfx`` /
``xdfx``).
- ``label`` — display name.
- ``link_type`` — ``url`` (external / in-app route), ``business``
(internal switch to another deep-link business), ``purpose`` (task-purpose
dialog), or ``host`` (iframe ``postMessage`` ``HOST_NAVIGATE`` to the
embedding host).
- ``target`` — the full URL (``url``) or the target business code (``business``).
- ``append_task_id`` — for ``url`` buttons, whether to append ``?id={taskId}``.
- ``enabled`` — 停用 parks a button without deleting it.
- ``sort_order`` — position among the business's buttons.
When the whole table is empty (fresh deployment, never saved) the frontend
falls back to code-defined seed defaults built from the live task-deeplink
config; once saved, this table is the source of truth. ``updated_by`` is
audit-only.
"""
from __future__ import annotations
from datetime import UTC, datetime
from sqlalchemy import Boolean, Integer, String
from sqlalchemy.orm import Mapped, mapped_column
from deerflow.persistence.base import Base
from deerflow.persistence.types import BeijingDateTime, PortableJSON
class TaskButtonRow(Base):
__tablename__ = "task_buttons"
id: Mapped[str] = mapped_column(String(128), primary_key=True)
business: Mapped[str] = mapped_column(String(32), index=True)
label: Mapped[str] = mapped_column(String(255), default="")
link_type: Mapped[str] = mapped_column(String(16), default="url")
target: Mapped[str] = mapped_column(String(1024), default="")
append_task_id: Mapped[bool] = mapped_column(Boolean, default=True)
# 追加的查询参数名(如 ``id`` / ``task_id``)。可空,读时归一化为 ``id``。
id_param: Mapped[str | None] = mapped_column(String(64), default="id")
# 追加的 id 取哪种:``task``=任务id(默认)/ ``action``=行动id(仅 xdfx 二者不同:深链原始
# ?taskId= 实为行动id,任务id 由 action 接口解析)。可空,读时归一化为 ``task``。
id_kind: Mapped[str | None] = mapped_column(String(16), default="task")
# ``url`` 外链打开方式:``blank``=新窗口(默认)/ ``self``=当前窗口。可空,读时归一化为 ``blank``。
open_mode: Mapped[str | None] = mapped_column(String(16), default="blank")
# ``url`` 外链追加的登录参数(与应用管理一致):在拼好的地址后再依次追加
# ``?{key}={value}``,``value`` 由前端运行时从 ``userInfo`` 按 ``source`` 解析
# (``other`` 时取 ``custom_value`` 字面值)。每项 ``{key, source, custom_value}``。
# 旧行 / NULL 读时归一化为 ``[]``。必须 ``nullable=True``:否则在已存在
# ``task_buttons`` 表的旧库上,启动期 ``_ensure_orm_columns_sync`` 会跳过
# 「NOT NULL 且无 server_default」的列(见 engine.py),该列永远补不上。
login_params_json: Mapped[list | None] = mapped_column(PortableJSON(), default=list, nullable=True)
# ``url`` 跳转是否追加登录态(token 登录的上游 token + 登录用户名),供外链所在的外部系统
# 校验当前登录用户。仅 token 登录(前端存有 token1)时实际拼上;非 token 登录自动跳过。
# ``server_default`` 必须显式声明:否则在已存在 ``task_buttons`` 表的旧库上,
# 启动期自动补列 ``_ensure_orm_columns_sync`` 会跳过「NOT NULL 且无 server_default」
# 的列(见 engine.py),导致该列永远补不上 → GET 查询报 Unknown column → 500。
append_auth: Mapped[bool] = mapped_column(Boolean, default=False, server_default="0")
# 追加 token / 用户名的查询参数名。可空,读时归一化为 ``token`` / ``username``。
auth_token_param: Mapped[str | None] = mapped_column(String(64), default="token")
auth_name_param: Mapped[str | None] = mapped_column(String(64), default="username")
enabled: Mapped[bool] = mapped_column(Boolean, default=True)
sort_order: Mapped[int] = mapped_column(Integer, default=0)
updated_by: Mapped[str | None] = mapped_column(String(64))
updated_at: Mapped[datetime] = mapped_column(
BeijingDateTime(), default=lambda: datetime.now(UTC), onupdate=lambda: datetime.now(UTC)
)