feat: improve simadmin config list actions
This commit is contained in:
@@ -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. 测试状态`。
|
||||||
|
|
||||||
### 导出配置
|
### 导出配置
|
||||||
|
|
||||||
|
|||||||
@@ -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":
|
||||||
|
|||||||
Reference in New Issue
Block a user