fix: 修复环路检测失败 + 多项UX增强
修复: - 环路检测正则 \s+(Onu\S+)\s+ → \s+(Onu\S+) (splitlines移除换行后尾随\s无法匹配) - 权限中间件 Header(...) → Header(None) 避免缺失Auth头返回422而非401 - 环路检测请求超时30s→120s (SSH连接30+台OLT实测需58秒) 重构 (ssh_service.py): - 提取 _send_and_wait 为私有方法,消除3处重复内部函数 - 添加 __enter__/__exit__ 上下文管理器支持 - 加固 execute_command prompt检测 (按行匹配<DEVICE_NAME>) - 移除未使用的settings import - olt.py/devices.py 调用方改用 with 语法 新功能: - 侧边栏退出登录上方显示当前用户名和角色 - 版本号从VERSION文件自动读取 (后端/health返回,前端动态显示) - 基于广西南宁经纬度计算日落时间,自动切换深色/浅色主题 - /api/olt/loopback-detection 响应增加raw字段便于排查 基础设施: - CLAUDE.md 加入 .gitignore - 新增 .claude/rules/07-remote-operations.md (远程部署操作) - 新增 .claude/rules/08-frp-notes.md (frp隧道注意事项) - 新增 VERSION 文件 (版本号 0.10.0) - 新增环路检测解析测试用例 (5个) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* 广西(南宁)日落时间计算
|
||||
* 纬度 22.82°N, 经度 108.37°E, 时区 UTC+8
|
||||
*/
|
||||
|
||||
const LAT = 22.82 // 南宁纬度
|
||||
const LON = 108.37 // 南宁经度
|
||||
|
||||
function toRad(deg) { return deg * Math.PI / 180 }
|
||||
function toDeg(rad) { return rad * 180 / Math.PI }
|
||||
|
||||
/**
|
||||
* 计算指定日期的日落时间(北京时间)
|
||||
* @param {Date} date
|
||||
* @returns {{ hour: number, minute: number }} 日落时分
|
||||
*/
|
||||
export function getSunsetTime(date = new Date()) {
|
||||
const dayOfYear = Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 86400000)
|
||||
|
||||
// 太阳赤纬 (solar declination)
|
||||
const declination = 23.45 * Math.sin(toRad(360 / 365 * (284 + dayOfYear)))
|
||||
|
||||
// 日落时角 cos(ω) = -tan(lat)*tan(δ)
|
||||
const cosOmega = -Math.tan(toRad(LAT)) * Math.tan(toRad(declination))
|
||||
const omega = Math.acos(Math.max(-1, Math.min(1, cosOmega))) // 弧度
|
||||
|
||||
// 日落地方太阳时(小时)
|
||||
const solarHour = 12 + toDeg(omega) / 15
|
||||
|
||||
// 修正:时区经度(120°E)与本地经度差
|
||||
const correction = (120 - LON) / 15 * 60 // 分钟
|
||||
const totalMinutes = solarHour * 60 + correction
|
||||
|
||||
const hour = Math.floor(totalMinutes / 60) % 24
|
||||
const minute = Math.round(totalMinutes % 60)
|
||||
|
||||
return { hour, minute }
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前是否在日落之后(应使用深色模式)
|
||||
*/
|
||||
export function isAfterSunset() {
|
||||
const now = new Date()
|
||||
const sunset = getSunsetTime(now)
|
||||
const currentMinutes = now.getHours() * 60 + now.getMinutes()
|
||||
const sunsetMinutes = sunset.hour * 60 + sunset.minute
|
||||
// 日出约为 12 - (sunset - 12) = 24 - sunset(粗略估算)
|
||||
const sunriseMinutes = (24 * 60 - sunsetMinutes) % (24 * 60)
|
||||
// 深色时间:日落之后 到 日出之前
|
||||
return currentMinutes >= sunsetMinutes || currentMinutes < sunriseMinutes
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取距离下次切换的毫秒数
|
||||
* 用于设置定时器在日落/日出时自动切换
|
||||
*/
|
||||
export function getMsUntilNextSwitch() {
|
||||
const now = new Date()
|
||||
const sunset = getSunsetTime(now)
|
||||
const sunsetMin = sunset.hour * 60 + sunset.minute
|
||||
const sunriseMin = (24 * 60 - sunsetMin) % (24 * 60)
|
||||
const currentMin = now.getHours() * 60 + now.getMinutes()
|
||||
|
||||
let targetMin
|
||||
if (currentMin >= sunsetMin || currentMin < sunriseMin) {
|
||||
// 当前是深色时间,下次切换是日出
|
||||
targetMin = sunriseMin
|
||||
} else {
|
||||
// 当前是浅色时间,下次切换是日落
|
||||
targetMin = sunsetMin
|
||||
}
|
||||
|
||||
const diffMin = (targetMin - currentMin + 24 * 60) % (24 * 60)
|
||||
return diffMin * 60 * 1000
|
||||
}
|
||||
Reference in New Issue
Block a user