- 新增「按钮管理」admin 页(/admin/task-buttons):按业务(rwfx/3qfx/xdfx)配置跳转按钮, 支持改名称/类型(外链·切换业务·目的树弹框)/目标/追加参数名(id·task_id)/任务id·行动id/启停/排序 - 跳转按钮从左侧栏移到工作区底部「快捷跳转」栏:红底白字、靠右、变大;rwfx 历史 4 按钮纳入配置 - 后端新增全局共享 store /api/task-buttons (table task_buttons,admin 整体替换) - xdfx 行动id/任务id:登录暂存原始行动id,按钮可选追加任一;id 参数名可自定义 - rwfx 清除记录移到「新建对话」下、去掉任务操作框;查询任务目的为空时自动发第一次问答 - 目的树面板默认收起;「弹框查看」抽成可复用 TaskPurposeDialog,可作为按钮配置到任意页面 - 文档(根/后端 CLAUDE.md) + 后端测试 tests/test_task_buttons.py Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
31 lines
1.1 KiB
Python
31 lines
1.1 KiB
Python
"""Abstract task-workspace button persistence API.
|
|
|
|
Global / shared store: no ``user_id`` scoping. Reads are open to any caller; the
|
|
router gates writes behind admin. ``updated_by`` is audit-only.
|
|
|
|
The whole button set is treated as one document: the editor computes the full
|
|
desired layout and replaces every row atomically via :meth:`replace_all`, so the
|
|
stored set never drifts out of sync with what the admin sees.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from abc import ABC, abstractmethod
|
|
from typing import Any
|
|
|
|
|
|
class TaskButtonStore(ABC):
|
|
@abstractmethod
|
|
async def list_buttons(self) -> list[dict[str, Any]]:
|
|
"""Return every stored button row (order unspecified)."""
|
|
raise NotImplementedError
|
|
|
|
@abstractmethod
|
|
async def replace_all(self, rows: list[dict[str, Any]], *, updated_by: str | None = None) -> list[dict[str, Any]]:
|
|
"""Atomically replace the entire button set with ``rows``.
|
|
|
|
Each row is ``{id, business, label, link_type, target, append_task_id,
|
|
enabled, sort_order}``. Returns the persisted rows.
|
|
"""
|
|
raise NotImplementedError
|