"""安装向导 DTO。 定义渠道插件安装向导的不可变值对象,包括向导字段类型、向导字段、向导步骤、 配置补丁与步骤结果。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库, 用于插件安装向导的步骤声明、表单校验与配置聚合。集合字段使用 tuple 以 保证 frozen dataclass 的不可变语义。 """ from __future__ import annotations from dataclasses import dataclass from enum import StrEnum from typing import Any class WizardFieldType(StrEnum): """向导字段类型。 标识安装向导表单字段的渲染与交互类型,用于前端按类型生成对应输入控件。 继承 ``str, Enum`` 以支持 JSON 序列化与字符串比较。 取值: TEXT: 文本输入。 PASSWORD: 密码输入(脱敏显示)。 SELECT: 下拉选择。 OAUTH: OAuth 授权。 WEBHOOK_URL: Webhook URL(带复制按钮)。 CHECKBOX: 复选框。 QR_LOGIN: 扫码登录字段。前端据此渲染 ``QrLoginInline`` 组件 (二维码 + 轮询状态),而非手填输入框;插件以该类型声明 需要走扫码登录流程的字段。 """ TEXT = "text" PASSWORD = "password" SELECT = "select" OAUTH = "oauth" WEBHOOK_URL = "webhook_url" CHECKBOX = "checkbox" QR_LOGIN = "qr_login" @dataclass(frozen=True) class WizardField: """向导字段。 描述安装向导中单个表单字段的元信息,包括名称、类型、展示标签、是否必填、 默认值、占位提示、帮助文案与下拉选项。集合字段使用 tuple 以保证不可变。 字段: name: 字段名称(技术键名,用于配置补丁键)。 field_type: 字段类型。 label: 展示标签(前端渲染用,空时前端回退到 name)。 required: 是否必填(默认 True)。 default: 默认值(可选)。 placeholder: 占位提示文案(可选,前端输入框 placeholder)。 help: 帮助文案(可选,字段下方说明文字)。 options: select 类型的选项列表(默认空 tuple)。 """ name: str field_type: WizardFieldType label: str = "" required: bool = True default: str | None = None placeholder: str = "" help: str = "" options: tuple[str, ...] = () @dataclass(frozen=True) class WizardStep: """向导步骤。 描述安装向导中一个步骤的完整定义,包含步骤 ID、名称、说明文案、字段列表 与是否可跳过。集合字段使用 tuple 以保证不可变。 字段: step_id: 步骤 ID。 step_name: 步骤名称(步骤条标题)。 description: 步骤说明文案(展示在表单上方,可选)。 fields: 字段列表。 skippable: 是否可跳过(默认 False)。 """ step_id: str step_name: str fields: tuple[WizardField, ...] description: str = "" skippable: bool = False @dataclass(frozen=True) class WizardConfigPatch: """向导配置补丁。 描述单个向导步骤校验通过后产出的配置补丁,用于聚合生成最终渠道配置。 字段: step_id: 步骤 ID。 values: 配置键值对。 """ step_id: str values: dict[str, Any] @dataclass(frozen=True) class WizardStepResult: """向导步骤结果。 描述向导步骤的校验结果,携带是否通过、错误信息与可选的配置补丁。集合 字段使用 tuple 以保证不可变。 字段: step_id: 步骤 ID。 valid: 是否校验通过。 errors: 错误信息列表(默认空 tuple)。 config_patch: 配置补丁(校验失败时为 None)。 """ step_id: str valid: bool errors: tuple[str, ...] = () config_patch: WizardConfigPatch | None = None