✨ feat(command): 黑白名单开关、自动保存与管理界面重构
- 新增 list_enabled 开关控制是否启用名单过滤 - 表单变更后 800ms 自动保存,去掉手动保存按钮 - Header 显示"未保存"指示器,保存中 toast 提示 - 内容区限制最大宽度 900px,优化宽屏显示 - 侧边栏增加圆角选中态,运行状态带脉冲动画 - 白名单模式灰掉黑名单输入,关闭名单时显示遮罩 - 命令测试结果增加成功/失败颜色反馈 - 回调格式改用等宽字体代码块
This commit is contained in:
14
config.py
14
config.py
@@ -43,6 +43,7 @@ class CommandConfig:
|
|||||||
length_min: int = 2
|
length_min: int = 2
|
||||||
length_max: int = 4
|
length_max: int = 4
|
||||||
scope: str = "all" # all / group / private
|
scope: str = "all" # all / group / private
|
||||||
|
list_enabled: bool = False # 是否启用黑白名单过滤
|
||||||
list_mode: str = "allow" # allow / deny
|
list_mode: str = "allow" # allow / deny
|
||||||
allowed_groups: frozenset[str] = frozenset()
|
allowed_groups: frozenset[str] = frozenset()
|
||||||
denied_groups: frozenset[str] = frozenset()
|
denied_groups: frozenset[str] = frozenset()
|
||||||
@@ -62,6 +63,7 @@ _ENV_DEFAULTS: dict = {
|
|||||||
"length_min": int(os.environ.get("COMMAND_LENGTH_MIN", "2")),
|
"length_min": int(os.environ.get("COMMAND_LENGTH_MIN", "2")),
|
||||||
"length_max": int(os.environ.get("COMMAND_LENGTH_MAX", "4")),
|
"length_max": int(os.environ.get("COMMAND_LENGTH_MAX", "4")),
|
||||||
"scope": os.environ.get("COMMAND_SCOPE", "all"),
|
"scope": os.environ.get("COMMAND_SCOPE", "all"),
|
||||||
|
"list_enabled": os.environ.get("COMMAND_LIST_ENABLED", "false").lower() in ("true", "1", "yes"),
|
||||||
"list_mode": os.environ.get("COMMAND_LIST_MODE", "allow"),
|
"list_mode": os.environ.get("COMMAND_LIST_MODE", "allow"),
|
||||||
"allowed_groups": os.environ.get("COMMAND_ALLOWED_GROUPS", ""),
|
"allowed_groups": os.environ.get("COMMAND_ALLOWED_GROUPS", ""),
|
||||||
"denied_groups": os.environ.get("COMMAND_DENIED_GROUPS", ""),
|
"denied_groups": os.environ.get("COMMAND_DENIED_GROUPS", ""),
|
||||||
@@ -87,6 +89,7 @@ def _yaml_defaults() -> dict:
|
|||||||
"length_min": 2,
|
"length_min": 2,
|
||||||
"length_max": 4,
|
"length_max": 4,
|
||||||
"scope": "all",
|
"scope": "all",
|
||||||
|
"list_enabled": False,
|
||||||
"list_mode": "allow",
|
"list_mode": "allow",
|
||||||
"allowed_groups": [],
|
"allowed_groups": [],
|
||||||
"denied_groups": [],
|
"denied_groups": [],
|
||||||
@@ -127,6 +130,7 @@ def ensure_settings_yaml() -> None:
|
|||||||
"length_max": ("COMMAND_LENGTH_MAX", int),
|
"length_max": ("COMMAND_LENGTH_MAX", int),
|
||||||
"scope": ("COMMAND_SCOPE", str),
|
"scope": ("COMMAND_SCOPE", str),
|
||||||
"list_mode": ("COMMAND_LIST_MODE", str),
|
"list_mode": ("COMMAND_LIST_MODE", str),
|
||||||
|
"list_enabled": ("COMMAND_LIST_ENABLED", "bool"),
|
||||||
"allowed_groups": ("COMMAND_ALLOWED_GROUPS", "csv_list"),
|
"allowed_groups": ("COMMAND_ALLOWED_GROUPS", "csv_list"),
|
||||||
"denied_groups": ("COMMAND_DENIED_GROUPS", "csv_list"),
|
"denied_groups": ("COMMAND_DENIED_GROUPS", "csv_list"),
|
||||||
"allowed_users": ("COMMAND_ALLOWED_USERS", "csv_list"),
|
"allowed_users": ("COMMAND_ALLOWED_USERS", "csv_list"),
|
||||||
@@ -158,6 +162,14 @@ def _apply_yaml_to_command(data: dict) -> None:
|
|||||||
command.length_max = int(cmd_data.get("length_max", _ENV_DEFAULTS["length_max"]))
|
command.length_max = int(cmd_data.get("length_max", _ENV_DEFAULTS["length_max"]))
|
||||||
command.scope = str(cmd_data.get("scope", _ENV_DEFAULTS["scope"]))
|
command.scope = str(cmd_data.get("scope", _ENV_DEFAULTS["scope"]))
|
||||||
command.list_mode = str(cmd_data.get("list_mode", _ENV_DEFAULTS["list_mode"]))
|
command.list_mode = str(cmd_data.get("list_mode", _ENV_DEFAULTS["list_mode"]))
|
||||||
|
|
||||||
|
# list_enabled: YAML bool → Python bool
|
||||||
|
list_enabled_val = cmd_data.get("list_enabled", _ENV_DEFAULTS["list_enabled"])
|
||||||
|
if isinstance(list_enabled_val, str):
|
||||||
|
command.list_enabled = list_enabled_val.lower() in ("true", "1", "yes")
|
||||||
|
else:
|
||||||
|
command.list_enabled = bool(list_enabled_val)
|
||||||
|
|
||||||
command.callback_url = str(cmd_data.get("callback_url", _ENV_DEFAULTS["callback_url"]))
|
command.callback_url = str(cmd_data.get("callback_url", _ENV_DEFAULTS["callback_url"]))
|
||||||
command.callback_timeout = int(cmd_data.get("callback_timeout", _ENV_DEFAULTS["callback_timeout"]))
|
command.callback_timeout = int(cmd_data.get("callback_timeout", _ENV_DEFAULTS["callback_timeout"]))
|
||||||
|
|
||||||
@@ -210,6 +222,7 @@ def get_settings_flat() -> dict[str, str]:
|
|||||||
"command_length_max": str(command.length_max),
|
"command_length_max": str(command.length_max),
|
||||||
"command_scope": command.scope,
|
"command_scope": command.scope,
|
||||||
"command_list_mode": command.list_mode,
|
"command_list_mode": command.list_mode,
|
||||||
|
"command_list_enabled": str(command.list_enabled).lower(),
|
||||||
"command_allowed_groups": ",".join(sorted(command.allowed_groups)),
|
"command_allowed_groups": ",".join(sorted(command.allowed_groups)),
|
||||||
"command_denied_groups": ",".join(sorted(command.denied_groups)),
|
"command_denied_groups": ",".join(sorted(command.denied_groups)),
|
||||||
"command_allowed_users": ",".join(sorted(command.allowed_users)),
|
"command_allowed_users": ",".join(sorted(command.allowed_users)),
|
||||||
@@ -227,6 +240,7 @@ _API_KEY_MAP: dict[str, tuple[str, ...]] = {
|
|||||||
"command_length_max": ("length_max", int),
|
"command_length_max": ("length_max", int),
|
||||||
"command_scope": ("scope", str),
|
"command_scope": ("scope", str),
|
||||||
"command_list_mode": ("list_mode", str),
|
"command_list_mode": ("list_mode", str),
|
||||||
|
"command_list_enabled": ("list_enabled", "bool"),
|
||||||
"command_at_sender": ("at_sender", "bool"),
|
"command_at_sender": ("at_sender", "bool"),
|
||||||
"command_callback_url": ("callback_url", str),
|
"command_callback_url": ("callback_url", str),
|
||||||
"command_callback_timeout": ("callback_timeout", int),
|
"command_callback_timeout": ("callback_timeout", int),
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
28
plugin.py
28
plugin.py
@@ -51,11 +51,12 @@ class WebHookPlugin(NcatBotPlugin):
|
|||||||
"已配置" if os.environ.get("WEBHOOK_API_KEY") else "自动生成",
|
"已配置" if os.environ.get("WEBHOOK_API_KEY") else "自动生成",
|
||||||
)
|
)
|
||||||
self.logger.info(
|
self.logger.info(
|
||||||
"命令监听: 前缀=%s 长度=%d~%d 范围=%s 名单=%s 回调=%s",
|
"命令监听: 前缀=%s 长度=%d~%d 范围=%s 名单=%s(%s) 回调=%s",
|
||||||
command.prefix,
|
command.prefix,
|
||||||
command.length_min,
|
command.length_min,
|
||||||
command.length_max,
|
command.length_max,
|
||||||
command.scope,
|
command.scope,
|
||||||
|
"开" if command.list_enabled else "关",
|
||||||
command.list_mode,
|
command.list_mode,
|
||||||
command.callback_url or "未配置",
|
command.callback_url or "未配置",
|
||||||
)
|
)
|
||||||
@@ -122,20 +123,21 @@ class WebHookPlugin(NcatBotPlugin):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
# 黑白名单过滤
|
# 黑白名单过滤
|
||||||
if command.list_mode == "allow":
|
if command.list_enabled:
|
||||||
# 白名单模式:在名单内才放行
|
if command.list_mode == "allow":
|
||||||
if command.allowed_groups and is_group:
|
# 白名单模式:在名单内才放行
|
||||||
if event.data.group_id not in command.allowed_groups:
|
if command.allowed_groups and is_group:
|
||||||
|
if event.data.group_id not in command.allowed_groups:
|
||||||
|
continue
|
||||||
|
if command.allowed_users and event.data.user_id not in command.allowed_users:
|
||||||
continue
|
continue
|
||||||
if command.allowed_users and event.data.user_id not in command.allowed_users:
|
elif command.list_mode == "deny":
|
||||||
continue
|
# 黑名单模式:在名单内则拒绝
|
||||||
elif command.list_mode == "deny":
|
if command.denied_groups and is_group:
|
||||||
# 黑名单模式:在名单内则拒绝
|
if event.data.group_id in command.denied_groups:
|
||||||
if command.denied_groups and is_group:
|
continue
|
||||||
if event.data.group_id in command.denied_groups:
|
if command.denied_users and event.data.user_id in command.denied_users:
|
||||||
continue
|
continue
|
||||||
if command.denied_users and event.data.user_id in command.denied_users:
|
|
||||||
continue
|
|
||||||
|
|
||||||
# 构建回调数据
|
# 构建回调数据
|
||||||
data = {
|
data = {
|
||||||
|
|||||||
Reference in New Issue
Block a user