feat: v0.9.0 新增记录日志、设备更换记录及IMC服务集成
- 新增 RecordsLog.vue 操作记录日志页面 - 新增 ReplacementRecords.vue 设备更换记录页面 - 新增 imc_service.py IMC网管系统集成服务 - 新增 datetime.js 前端日期时间工具函数 - 新增 OLT时间同步.md 文档 - 扩展 devices.py API:设备更换记录、批量操作等 - 扩展 ssh_service.py:OLT时间同步功能 - 扩展 olt.py:新增时间同步相关接口 - 更新 DeviceList.vue:增强设备列表功能 - 更新路由和导航菜单 - 将 .claude/ 和 .mcp.json 加入 .gitignore Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -348,6 +348,85 @@ class SSHService:
|
||||
send_and_wait("quit", ">", timeout=5)
|
||||
return True
|
||||
|
||||
def sync_ntp(self, old_server: str, new_server: str) -> bool:
|
||||
"""同步 NTP 时间服务器配置
|
||||
流程: system-view -> undo ntp old -> ntp new -> clock timezone -> quit -> save force
|
||||
old_server 若不存在会报错,直接忽略继续执行。
|
||||
"""
|
||||
if not self.shell:
|
||||
raise Exception("SSH 未连接")
|
||||
|
||||
def send_and_wait(cmd: str, expect: str, timeout: int = 15) -> str:
|
||||
self.shell.send(cmd + "\n")
|
||||
buf = ""
|
||||
deadline = time.time() + timeout
|
||||
while time.time() < deadline:
|
||||
if self.shell.recv_ready():
|
||||
buf += self.shell.recv(4096).decode('utf-8', errors='ignore')
|
||||
if expect in buf:
|
||||
return buf
|
||||
else:
|
||||
time.sleep(0.2)
|
||||
return buf
|
||||
|
||||
out = send_and_wait("system-view", "]")
|
||||
if "]" not in out:
|
||||
raise Exception("进入 system-view 失败")
|
||||
|
||||
# 删除旧 NTP 服务器(若不存在会报错,忽略即可)
|
||||
send_and_wait(f"undo ntp-service unicast-server {old_server}", "]")
|
||||
|
||||
# 添加新 NTP 服务器
|
||||
out = send_and_wait(f"ntp-service unicast-server {new_server}", "]")
|
||||
if "]" not in out:
|
||||
raise Exception(f"配置 NTP 服务器 {new_server} 失败")
|
||||
|
||||
# 设置时区为北京时间
|
||||
out = send_and_wait("clock timezone Beijing add 08:00:00", "]")
|
||||
if "]" not in out:
|
||||
raise Exception("配置时区失败")
|
||||
|
||||
# 退出系统视图
|
||||
send_and_wait("quit", ">")
|
||||
|
||||
# 强制保存配置
|
||||
send_and_wait("save force", ">", timeout=30)
|
||||
|
||||
return True
|
||||
|
||||
def get_onu_events(self, port_id: str) -> list:
|
||||
"""
|
||||
查询 ONU 上下线事件记录
|
||||
命令: display epon onu-event interface Onu{port_id}
|
||||
返回: [{'date', 'time', 'event', 'status', 'datetime_str'}, ...]
|
||||
时间按倒序(最新在前)返回
|
||||
"""
|
||||
output = self.execute_command(
|
||||
f"display epon onu-event interface Onu{port_id}"
|
||||
)
|
||||
output = self._clean_output(output)
|
||||
events = []
|
||||
for line in output.splitlines():
|
||||
line = line.strip()
|
||||
m = re.match(r'(\d{4}/\d{2}/\d{2})\s+(\d{2}:\d{2}:\d{2})\s+(.+)', line)
|
||||
if not m:
|
||||
continue
|
||||
date_str, time_str, rest = m.group(1), m.group(2), m.group(3).strip()
|
||||
# 最后一个单词是 ONU Status(Up/Offline),前面整体是 Event 名称
|
||||
parts = rest.rsplit(None, 1)
|
||||
if len(parts) == 2:
|
||||
event, status = parts[0].strip(), parts[1].strip()
|
||||
else:
|
||||
event, status = rest, ''
|
||||
events.append({
|
||||
'date': date_str,
|
||||
'time': time_str,
|
||||
'event': event,
|
||||
'status': status,
|
||||
'datetime_str': f"{date_str} {time_str}",
|
||||
})
|
||||
return events
|
||||
|
||||
def close(self):
|
||||
"""关闭 SSH 连接"""
|
||||
if self.client:
|
||||
|
||||
Reference in New Issue
Block a user