feat: improve simadmin config list actions

This commit is contained in:
2026-05-15 23:18:55 +08:00
parent b375016239
commit c7a76ac2cd
2 changed files with 179 additions and 22 deletions
+59 -5
View File
@@ -74,11 +74,65 @@ SimAdmin 配置管理(多级菜单)
q. 退出 q. 退出
``` ```
### 实例列表页快捷操作
菜单选择 `1. 查看实例列表` 后,不再只是展示文本,而是进入实例列表操作页:
```text
SimAdmin 实例列表:
1. 主卡 [启用]
http://192.168.68.1:3000 timeout=10s token=未设置
2. 副卡 [禁用]
http://192.168.68.2:3000 timeout=10s token=abc***xyz
列表操作:
输入实例编号:进入该实例操作菜单
a. 新增实例
e <编号>. 编辑实例,例如 e 1
d <编号>. 删除实例,例如 d 1
t <编号>. 测试状态,例如 t 1
on <编号> / off <编号>. 启用或禁用
r. 刷新列表
b. 返回上级菜单
q. 退出配置管理
```
也就是说,查看列表后可以直接继续操作:
```text
1 # 进入 1 号实例操作菜单
e 1 # 直接编辑 1 号实例
d 2 # 直接删除 2 号实例
t 1 # 直接测试 1 号实例
on 2 # 启用 2 号实例
a # 新增实例
```
### 单实例操作菜单
在列表页输入实例编号后,进入该实例的二级操作菜单:
```text
实例操作:【主卡】
主卡 [启用]
http://192.168.68.1:3000 timeout=10s token=未设置
1. 测试状态
2. 编辑实例
3. 删除实例
4. 启用/禁用
5. 复制/新增一个实例
b. 返回实例列表
q. 退出配置管理
```
### 添加实例流程 ### 添加实例流程
可从主菜单选择 `2. 添加实例`,也可在列表页输入 `a`
```text ```text
sim配置 sim配置
2 1
a
请输入实例名称,例如:主卡 请输入实例名称,例如:主卡
主卡 主卡
请输入 SimAdmin 地址,例如:http://192.168.68.1:3000 请输入 SimAdmin 地址,例如:http://192.168.68.1:3000
@@ -95,7 +149,7 @@ yes
### 编辑实例流程 ### 编辑实例流程
菜单选择 `3. 编辑实例` 后,选择实例编号,再进入二级菜单: 可从主菜单选择 `3. 编辑实例`,也可在列表页输入 `e 1`,或输入实例编号后选择 `2. 编辑实例`。编辑二级菜单:
```text ```text
编辑【主卡】 编辑【主卡】
@@ -110,15 +164,15 @@ q. 放弃返回
### 删除实例流程 ### 删除实例流程
菜单选择 `4. 删除实例`选择编号后,需要输入 `yes` 二次确认。 可从主菜单选择 `4. 删除实例`也可在列表页输入 `d 1`,或进入单实例操作菜单选择 `3. 删除实例`。删除前需要输入 `yes` 二次确认。
### 启用/禁用实例 ### 启用/禁用实例
菜单选择 `5. 启用/禁用实例`选择编号后立即切换 可从主菜单选择 `5. 启用/禁用实例`也可在列表页输入 `on 1` / `off 1`,或进入单实例操作菜单选择 `4. 启用/禁用`
### 测试状态查询 ### 测试状态查询
菜单选择 `6. 测试状态查询`选择编号后会调用该实例的状态接口并返回摘要 可从主菜单选择 `6. 测试状态查询`也可在列表页输入 `t 1`,或进入单实例操作菜单选择 `1. 测试状态`
### 导出配置 ### 导出配置
+120 -17
View File
@@ -10,7 +10,7 @@
# [rule: ^sim短信\s+\S+\s+\S+\s+[\s\S]+$] # [rule: ^sim短信\s+\S+\s+\S+\s+[\s\S]+$]
# [platform: qq,wx,tg,tb,fs] # [platform: qq,wx,tg,tb,fs]
# [open_source: true] # [open_source: true]
# [version: 1.1.0] # [version: 1.2.0]
# [public: false] # [public: false]
# [price: 0] # [price: 0]
# [description: 管理员专用:兼容多个 SimAdmin 实例,支持多级菜单配置管理、状态查询和短信发送。配置桶 otto/simadmin_instances。] # [description: 管理员专用:兼容多个 SimAdmin 实例,支持多级菜单配置管理、状态查询和短信发送。配置桶 otto/simadmin_instances。]
@@ -366,11 +366,66 @@ def choose_instance_by_menu(sender, instances, prompt="请选择实例编号"):
def menu_list(sender): def menu_list(sender):
instances = load_instances(include_disabled=True, allow_empty=True) """实例列表页本身就是二级操作页:看完列表后可直接编辑/新增/删除/测试。"""
if not instances: while True:
reply(sender, "当前没有 SimAdmin 实例。") instances = load_instances(include_disabled=True, allow_empty=True)
return lines = ["SimAdmin 实例列表:"]
reply(sender, "SimAdmin 实例列表:\n" + "\n".join(instance_brief(item, idx) for idx, item in enumerate(instances, 1))) if instances:
lines.extend(instance_brief(item, idx) for idx, item in enumerate(instances, 1))
else:
lines.append("当前没有 SimAdmin 实例。")
lines.extend([
"",
"列表操作:",
"输入实例编号:进入该实例操作菜单",
"a. 新增实例",
"e <编号>. 编辑实例,例如 e 1",
"d <编号>. 删除实例,例如 d 1",
"t <编号>. 测试状态,例如 t 1",
"on <编号> / off <编号>. 启用或禁用",
"r. 刷新列表",
"b. 返回上级菜单",
"q. 退出配置管理",
])
choice = listen_text(sender, "\n".join(lines), allow_empty=True, default="r").strip()
lower = choice.lower()
if lower in ("r", "刷新"):
continue
if lower in ("b", "back", "返回"):
return "back"
if lower in ("q", "quit", "exit", "退出"):
return "quit"
if lower in ("a", "add", "新增", "添加"):
menu_add(sender)
continue
if choice.isdigit():
idx = int(choice) - 1
if 0 <= idx < len(instances):
action = instance_action_menu(sender, idx)
if action == "quit":
return "quit"
continue
reply(sender, "编号超出范围")
continue
m = re.match(r"^(e|edit|编辑|d|del|delete|删除|t|test|测试|on|启用|off|禁用)\s+(\d+)$", lower)
if not m:
reply(sender, "无法识别的列表操作,请重新输入")
continue
op, idx_text = m.group(1), m.group(2)
idx = int(idx_text) - 1
if idx < 0 or idx >= len(instances):
reply(sender, "编号超出范围")
continue
if op in ("e", "edit", "编辑"):
menu_edit(sender, idx)
elif op in ("d", "del", "delete", "删除"):
menu_delete(sender, idx)
elif op in ("t", "test", "测试"):
menu_test(sender, idx)
elif op in ("on", "启用"):
menu_set_enabled(sender, idx, True)
elif op in ("off", "禁用"):
menu_set_enabled(sender, idx, False)
def menu_add(sender): def menu_add(sender):
@@ -398,9 +453,10 @@ def menu_add(sender):
reply(sender, "已添加 SimAdmin 实例:" + item["name"]) reply(sender, "已添加 SimAdmin 实例:" + item["name"])
def menu_delete(sender): def menu_delete(sender, idx=None):
instances = load_instances(include_disabled=True, allow_empty=True) instances = load_instances(include_disabled=True, allow_empty=True)
idx = choose_instance_by_menu(sender, instances, "请选择要删除的实例编号") if idx is None:
idx = choose_instance_by_menu(sender, instances, "请选择要删除的实例编号")
item = instances[idx] item = instances[idx]
if not confirm(sender, "确认删除【%s】?输入 yes 确认" % item["name"]): if not confirm(sender, "确认删除【%s】?输入 yes 确认" % item["name"]):
reply(sender, "已取消删除") reply(sender, "已取消删除")
@@ -410,9 +466,10 @@ def menu_delete(sender):
reply(sender, "已删除 SimAdmin 实例:" + removed["name"]) reply(sender, "已删除 SimAdmin 实例:" + removed["name"])
def menu_edit(sender): def menu_edit(sender, idx=None):
instances = load_instances(include_disabled=True, allow_empty=True) instances = load_instances(include_disabled=True, allow_empty=True)
idx = choose_instance_by_menu(sender, instances, "请选择要编辑的实例编号") if idx is None:
idx = choose_instance_by_menu(sender, instances, "请选择要编辑的实例编号")
item = dict(instances[idx]) item = dict(instances[idx])
while True: while True:
reply(sender, "\n".join([ reply(sender, "\n".join([
@@ -451,21 +508,64 @@ def menu_edit(sender):
return return
def menu_toggle(sender): def menu_set_enabled(sender, idx, enabled):
instances = load_instances(include_disabled=True, allow_empty=True) instances = load_instances(include_disabled=True, allow_empty=True)
idx = choose_instance_by_menu(sender, instances, "请选择要启用/禁用的实例编号") instances[idx]["enabled"] = bool(enabled)
instances[idx]["enabled"] = not instances[idx].get("enabled")
save_instances(instances) save_instances(instances)
reply(sender, "已将【%s切换为:%s" % (instances[idx]["name"], "启用" if instances[idx]["enabled"] else "禁用")) reply(sender, "已将【%s设置为:%s" % (instances[idx]["name"], "启用" if instances[idx]["enabled"] else "禁用"))
def menu_test(sender): def menu_toggle(sender, idx=None):
instances = load_instances(include_disabled=True, allow_empty=True) instances = load_instances(include_disabled=True, allow_empty=True)
idx = choose_instance_by_menu(sender, instances, "请选择要测试连通性的实例编号") if idx is None:
idx = choose_instance_by_menu(sender, instances, "请选择要启用/禁用的实例编号")
menu_set_enabled(sender, idx, not instances[idx].get("enabled"))
def menu_test(sender, idx=None):
instances = load_instances(include_disabled=True, allow_empty=True)
if idx is None:
idx = choose_instance_by_menu(sender, instances, "请选择要测试连通性的实例编号")
item = instances[idx] item = instances[idx]
reply(sender, format_instance_status(item)) reply(sender, format_instance_status(item))
def instance_action_menu(sender, idx):
while True:
instances = load_instances(include_disabled=True, allow_empty=True)
if idx < 0 or idx >= len(instances):
reply(sender, "实例已不存在,返回列表")
return "back"
item = instances[idx]
reply(sender, "\n".join([
"实例操作:【%s" % item["name"],
instance_brief(item),
"1. 测试状态",
"2. 编辑实例",
"3. 删除实例",
"4. 启用/禁用",
"5. 复制/新增一个实例",
"b. 返回实例列表",
"q. 退出配置管理",
]))
choice = listen_text(sender, "请输入操作编号")
if choice == "1":
menu_test(sender, idx)
elif choice == "2":
menu_edit(sender, idx)
elif choice == "3":
menu_delete(sender, idx)
return "back"
elif choice == "4":
menu_toggle(sender, idx)
elif choice == "5":
menu_add(sender)
elif choice.lower() in ("b", "back", "返回"):
return "back"
else:
return "quit"
def menu_export(sender): def menu_export(sender):
instances = load_instances(include_disabled=True, allow_empty=True) instances = load_instances(include_disabled=True, allow_empty=True)
reply(sender, "当前配置 JSON\n" + json.dumps(instances, ensure_ascii=False, indent=2)) reply(sender, "当前配置 JSON\n" + json.dumps(instances, ensure_ascii=False, indent=2))
@@ -488,7 +588,10 @@ def handle_config_menu(sender):
])) ]))
choice = listen_text(sender, "请输入菜单编号") choice = listen_text(sender, "请输入菜单编号")
if choice == "1": if choice == "1":
menu_list(sender) action = menu_list(sender)
if action == "quit":
reply(sender, "已退出 SimAdmin 配置管理")
return
elif choice == "2": elif choice == "2":
menu_add(sender) menu_add(sender)
elif choice == "3": elif choice == "3":