75 lines
4.5 KiB
Python
75 lines
4.5 KiB
Python
"""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)
|
||
)
|