Files
pangolin/client/lib/l10n/strings_zh.dart
T
wangjia 2080062d8c feat: 数据面故障韧性 — 节点健康上报(控制面) + 客户端连通看门狗
盲区:节点 status 只看 agent 的 gRPC 在线,sing-box 数据面坏了(崩/配置坏/数据口不通)
而 agent 仍在线时,节点仍显示 up、connect 放行、客户端「已连接」但流量全失败,且不自愈。

控制面:
- agent 每心跳探 sing-box clash_api /version(2s 超时,连续 2 次失败才报不健康,防抖),
  经新增 HeartbeatRequest.data_plane_healthy 上报(手写 agentv1 契约 + proto 同步;JSON codec)。
- NodeLoad 加 DataPlaneHealthy(随 load 写 Redis;字段缺失默认 healthy 防滚动期误杀)。
- effectiveNodeStatus 扩为 (dbStatus, agentOnline, dataPlaneHealthy);ListNodes 与 ConnectNode
  统一改用它 → 数据面坏的节点列表置灰 + connect 返回 404 拦截。

客户端(connection_provider 连通看门狗):
- 连上后每 15s 经隧道 HTTP 探海外 generate_204(可注入),连续 3 次失败判当前节点不可用。
- 智能选择 → 自动切到其他最优可用节点重连;手动选定 → 断开并提示「节点异常」(尊重用户选择)。
- 新增 nodeUnhealthySwitched/nodeUnhealthyError 文案。

测试:agent 健康探测防抖、effectiveNodeStatus 真值表、dataPlaneHealthy 助手、看门狗
智能切/手动断/健康不触发;go test ./... 与 flutter test 全绿。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-29 13:19:22 +08:00

312 lines
9.0 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// strings_zh.dart — 中文文案资源(单显)
//
// 红线词禁用:VPN / 翻墙 / 科学上网 / 突破封锁 / 自由穿越 / Go anywhere。
// 脱敏口径:网络加速 / 体验优化 + 隐私保护。套餐数字以 design/CLAUDE.md §7 为准。
import 'app_text.dart';
class StringsZh extends AppText {
const StringsZh();
@override
AppLang get lang => AppLang.zh;
@override
String get brand => '穿山甲';
@override
String get online => '● 在线';
@override
String get offline => '○ 离线';
@override
String get capOff => '未连接 · 轻点连接';
@override
String get capConnecting => '连接中…';
@override
String get capOn => '已连接 · 网络已加密';
@override
String get connectNow => '点击连接';
@override
String get secure => '已加密';
@override
String get tabConnect => '连接';
@override
String get tabServers => '节点';
@override
String get tabStats => '统计';
@override
String get tabMe => '我的';
@override
String get currentNode => '当前节点';
@override
String get download => '下载';
@override
String get upload => '上传';
@override
String get latency => '延迟';
@override
String get quotaToday => '今日剩余';
@override
String get minutes => '分钟';
@override
String get quotaFree => '免费版 · 每日 10 分钟';
@override
String get watchAd => '看广告开始使用';
@override
String get adUnlocked => '已解锁 · 今日可用';
@override
String get chooseNode => '选择节点';
@override
String get searchPh => '搜索国家 / 城市';
@override
String get smartSelect => '智能选择';
@override
String nodeSwitchTitle(String name) => '切换到「$name」?';
@override
String get nodeSwitchBody => '当前连接将断开并重连到该节点。';
@override
String get nodeSwitchConfirm => '切换';
@override
String get nodeUnhealthySwitched => '当前节点异常,已自动切换';
@override
String get nodeUnhealthyError => '当前节点异常,请重连或更换节点';
@override
String get smartSub => '根据当前网络环境,自动选择最优节点';
@override
String get recommended => '推荐';
@override
String get statsTitle => '使用统计';
@override
String get trafficMonth => '本月流量';
@override
String get avgPing => '平均延迟';
@override
String get durMonth => '本月时长';
@override
String get weekTraffic => '本周流量 (GB)';
@override
List<String> get days7 => const ['', '', '', '', '', '', ''];
@override
String get byDevice => '设备明细';
@override
String get noDeviceUsage => '暂无设备用量';
@override
String get periodMonth => '本月';
@override
String get periodWeek => '本周';
@override
String get periodToday => '今日';
@override
String get statDown => '下行';
@override
String get statUp => '上行';
@override
String get statDuration => '使用时长';
@override
String get chartTwoWeeks => '最近两周流量';
@override
String get allDevices => '全部设备';
@override
String get meTitle => '我的';
@override
String get proMember => 'PRO 会员';
@override
String get freePlanName => '免费版';
@override
String get expires => '有效期至';
@override
String get upgradeBtn => '续费 / 升级';
@override
String get accInfoTitle => '账户信息';
@override
String get accEmail => '邮箱';
@override
String get accPassword => '密码';
@override
String get accChange => '修改';
@override
String get myDevices => '我的设备';
@override
String get devicesSub => 'PRO 套餐最多 5 台设备同时在线';
@override
String get thisDevice => '本机';
@override
String get remove => '移除';
@override
String get devOnline => '在线';
@override
String get devOffline => '离线';
@override
String get devLastLogin => '最后登录';
@override
String get devNeverLogin => '从未登录';
@override
String get devForceLogout => '强制退出';
@override
String get devClearLogin => '清除登录信息';
@override
String get devRename => '重命名';
@override
String get devRenameHint => '设备名称';
@override
String get devSave => '保存';
@override
String get devForceLogoutConfirm => '将吊销该设备的登录会话,它会被踢下线、需重新登录。设备仍保留在列表中。';
@override
String get devClearLoginConfirm => '将从设备列表彻底移除此设备,并吊销其登录会话与数据面凭证。该设备需重新登录才能再次使用。';
@override
String get devCancel => '取消';
@override
String get redeemEntry => '兑换 & 购买';
@override
String get contactEntry => '联系我们';
@override
String get signOut => '退出登录';
@override
String get language => '语言';
@override
String get darkAppearance => '深色外观';
@override
String get stateOn => '已开启';
@override
String get followLight => '跟随浅色';
@override
String get protocol => '协议';
@override
String get settingsTitle => '设置';
@override
String get autostart => '开机自启';
@override
String get autostartSub => '系统启动时自动运行';
@override
String get smartRoute => '智能分流';
@override
String get smartRouteSub => '海外应用走加速,国内直连';
@override
String get killSwitch => 'Kill Switch';
@override
String get killSwitchSub => '断线时阻断网络,防止泄露';
@override
String get checkUpdate => '检查更新';
@override
String get choosePlan => '选择套餐';
@override
String get freePlan => '免费版';
@override
String get proPlan => '专业版';
@override
String get teamPlan => '团队版';
@override
String get perMonth => '/月';
@override
String get current => '当前';
@override
String get upgrade => '立即升级';
@override
String get choose => '选择';
@override
String get mostPopular => '最受欢迎';
@override
List<String> get featsFree =>
const ['仅 1 个基础节点', '每日 10 分钟时长', '使用前观看广告', '注册享 7 天免费试用'];
@override
List<String> get featsPro =>
const ['80+ 全球节点', '无限流量 · 极速', '5 台设备同时在线', '流媒体优化'];
@override
List<String> get featsTeam =>
const ['专业版全部功能', '10 个成员席位', '集中计费与管理', '优先客服'];
@override
String get redeemTitle => '兑换 & 购买';
@override
String get redeemCodeTitle => '兑换激活码';
@override
String get redeemPh => '输入激活码';
@override
String get redeemBtn => '激活';
@override
String get redeemOk => '激活成功 · PRO 已开通';
@override
String get buyTitle => '购买渠道';
@override
String get buySub => 'App 内不支持直接支付。请通过以下渠道获取激活码:';
@override
String get chStore => '自助发卡商店';
@override
String get chEmail => '邮箱客服';
@override
String get contactTitle => '联系我们';
@override
String get contactIntro => '遇到问题?通过以下任一渠道联系我们,通常数分钟内回复。';
@override
String get contactEmail => '邮箱客服';
@override
String get contactStore => '自助发卡商店';
@override
String get contactHoursTitle => '服务时间';
@override
String get contactHours => '每日 9:00 24:00 (GMT+8)';
@override
String get authTagline => '极速 · 稳定 · 省心';
@override
String get tabLogin => '登录';
@override
String get tabRegister => '注册';
@override
String get emailLabel => '邮箱';
@override
String get emailPh => '你的邮箱地址';
@override
String get pwLabel => '密码';
@override
String get pwPh => '输入密码';
@override
String get setPwPh => '设置登录密码(用于多端登录)';
@override
String get codeLabel => '邮箱验证码';
@override
String codeSentTo(String email) => '验证码已发送至 $email';
@override
String get sendCode => '发送验证码';
@override
String get resend => '重新发送';
@override
String get doLogin => '登录';
@override
String get doNext => '下一步';
@override
String get doCreate => '创建账户';
@override
String get forgotPw => '忘记密码?';
@override
String get tos => '继续即代表同意《服务条款》与《隐私政策》';
@override
String get obSkip => '跳过';
@override
String get obNext => '下一步';
@override
String get obAllow => '允许并继续';
@override
String get obStart => '开始使用';
@override
String get ob1Title => '一键连接全球';
@override
String get ob1Sub => '80+ 节点,智能选择最快线路,稳定不掉线。';
@override
String get ob2Title => '授权网络配置';
@override
String get ob2Sub => '系统会请求添加一个网络配置,用于建立加密隧道。';
@override
String get ob3Title => '安全 · 无日志';
@override
String get ob3Sub => '端到端加密,我们不记录你的任何浏览数据。';
}