diff --git a/design/prototype/index.html b/design/prototype/index.html index 3c78cbe..0e4c155 100644 --- a/design/prototype/index.html +++ b/design/prototype/index.html @@ -621,6 +621,12 @@ 未登录 +

分流动作

直连 is-success · 走隧道 is-warning · 拒绝 is-danger
+ 直连 + 走隧道 + 拒绝 +
+

套餐

.pill-accent · .pill.is-neutral
PRO 会员 免费版 diff --git a/design/prototype/screens/routing-rules.html b/design/prototype/screens/routing-rules.html deleted file mode 100644 index da81d85..0000000 --- a/design/prototype/screens/routing-rules.html +++ /dev/null @@ -1,184 +0,0 @@ - - - - - -分流规则 · 可配置代理原型(真 ui-kit) - - - - - - -
-

分流规则 · 可配置代理

-

Task 3 原型(用 v2 真实设计系统重建:全走 atoms.css / tokens.css / icons.js,非独立 mockup)。让用户像 Shadowrocket 那样自定义"直连 / 走隧道 / 拒绝"。规则模型与实现见 配置说明文档

- -

移动端 · 分流规则子屏

-
-
-
9:415G ▮▮▮
- -
- -
代理模式
-
- - - -
- -
内置规则
-
-
国内直连
GeoIP / GeoSite CN
-
局域网 / 私网直连
强制,不可关
🔒
-
私有服务走隧道
服务端下发
🔒
-
- -
我的规则 · 首命中生效
-
-
git.51yanmei.com
域名后缀
直连
-
aliyun.com
域名后缀
直连
-
github.com
域名后缀
走隧道
-
category-ads
GeoSite 规则集
拒绝
-
35.190.0.0/16
IP-CIDR
走隧道
-
- - -
最终(未命中)
-
-
FINAL 兜底
走隧道
-
-
-
- - -
-
9:415G ▮▮▮
- -
-
类型
-
- 域名域名后缀关键字 - IP-CIDRGeoIPGeoSite -
-
-
-
动作
-
- 直连 DIRECT走隧道 PROXY拒绝 REJECT -
-
预览 · 翻译为 sing-box 规则
-
{ "domain_suffix":
-    ["git.51yanmei.com"],
-  "outbound": "direct" }
-
-
-
- -

桌面端 · 设置窗口(表格 + 实时预览)

-
-
Pangolin — 设置 · 分流规则
-
-
-
通用
节点
分流规则
账户
统计
-
-
-
-
分流规则
-
- -
-
-
- - LAN 直连 🔒 - 私有服务走隧道 🔒 -
- - - - - - - -
类型动作说明启用
域名后缀git.51yanmei.com直连CI 源
域名后缀aliyun.com直连镜像
域名后缀github.com走隧道
GeoSitecategory-ads拒绝广告
IP-CIDR35.190.0.0/16走隧道
-
- - - - FINAL:走隧道 -
-
-
-
- -

与现有 Settings 页的衔接

-

现在 Settings 里的「Smart routing」是个二元开关。改为渐进式披露入口:变成「分流规则」设置行(显示当前模式 + chevron),点进去就是上面的分流规则屏。休闲用户不用点,行为等价开关开着。

-
-
-
现在(二元开关)
-
Smart routing
Accelerate abroad, direct at home
-
-
-
改后(入口 → 分流规则屏)
-
分流规则
自定义直连 / 走隧道 / 拒绝
智能分流
-
-
- -

默认规则 vs 自定义规则 · 冲突处理

-

确定性分层 + 顺序,不靠猜:系统强制层永远在最上(用户改不了)→ 用户规则(有序,首命中)→ 智能分流默认 → FINAL。UI 主动标记两类冲突:

-
-
github.com
域名后缀
走隧道
-
github.com/foo
⚠ 已被上面「github.com 走隧道」覆盖,永不命中
直连
-
git.yanmeiai.com
⚠ 该域名由系统强制走隧道(私有服务),此规则不生效
直连
-
- -
-

为什么用 v2 真 ui-kit

本屏所有组件(段选 .segswitch、设置行 .setting-row、开关 .toggle、卡片 .card、胶囊 .pill、按钮 .btn)都来自 v2 设计系统真原子,颜色全走 token,与线上 App 一致——不是独立 mockup。动作语义色(直连绿/走隧道橙/拒绝红)是原型内联,实现时收进 atoms。

-

待你确认(设计层)

①规则粒度够不够 ②要不要分应用代理(per-app,建议后置)③「从文本导入」Phase 1 还是 2 ④档案 per-user 还是 per-device。确认后出 Phase 1 实现计划。

-
-
- - diff --git a/design/prototype/screens/ui-desktop.html b/design/prototype/screens/ui-desktop.html index 44e686b..de4cdde 100644 --- a/design/prototype/screens/ui-desktop.html +++ b/design/prototype/screens/ui-desktop.html @@ -678,9 +678,9 @@
自动连接
启动时自动连接节点
-
-
智能分流
海外应用走加速,国内直连
- +
+
分流规则
自定义直连 / 走隧道 / 拒绝
+ 智能分流
断连保护 Kill Switch
断线时阻断网络,防止数据泄露
@@ -735,6 +735,40 @@ + +
+
+ +
代理模式
+
+ + + +
+
内置规则
+
+
国内直连
GeoIP / GeoSite CN
+
局域网 / 私网直连
强制,不可关
🔒 强制
+
私有服务走隧道
服务端下发
🔒 服务端
+
+
我的规则 · 有序,首命中生效
+
+
git.51yanmei.com
域名后缀 · CI 源
直连
+
aliyun.com
域名后缀 · 镜像
直连
+
github.com
域名后缀
走隧道
+
category-ads
GeoSite 规则集
拒绝
+
git.yanmeiai.com
⚠ 该域名由系统强制走隧道,此规则不生效
直连
+
+
+ + + +
+
最终(未命中任何规则)
+
FINAL 兜底
走隧道
+
+
+

遇到问题?通过以下任一渠道联系我们,通常数分钟内回复。

@@ -1228,6 +1262,8 @@ var I18N = { 'set.autostart':{zh:'开机自启',en:'Launch at startup'}, 'set.autostartSub':{zh:'系统启动时自动运行',en:'Run automatically on system start'}, 'set.autoconnect':{zh:'自动连接',en:'Auto-connect'}, 'set.autoconnectSub':{zh:'启动时自动连接节点',en:'Connect automatically on launch'}, 'set.smart':{zh:'智能分流',en:'Smart routing'}, 'set.smartSub':{zh:'海外应用走加速,国内直连',en:'Accelerate abroad, direct at home'}, + 'nav.routing':{zh:'分流规则',en:'Routing rules'}, + 'set.routing':{zh:'分流规则',en:'Routing rules'}, 'set.routingSub':{zh:'自定义直连 / 走隧道 / 拒绝',en:'Custom direct / proxy / reject'}, 'set.routeModeSmart':{zh:'智能分流',en:'Smart routing'}, 'set.kill':{zh:'断连保护 Kill Switch',en:'Kill Switch'}, 'set.killSub':{zh:'断线时阻断网络,防止数据泄露',en:'Block traffic if the link drops'}, 'set.lang':{zh:'语言',en:'Language'}, 'set.dark':{zh:'深色外观',en:'Dark appearance'}, 'set.protocol':{zh:'协议',en:'Protocol'}, 'set.web':{zh:'网页版用户中心',en:'Web User Center'}, @@ -1859,6 +1895,8 @@ var _accRedeem=document.getElementById('accRedeemRow'); if(_accRedeem) _accRedee var _accInvite=document.getElementById('accInviteRow'); if(_accInvite) _accInvite.addEventListener('click', function(){ setView('invite'); }); var _accDevices=document.getElementById('accDevicesRow'); if(_accDevices) _accDevices.addEventListener('click', function(){ setView('devices'); }); var _dvBack=document.getElementById('dvBack'); if(_dvBack) _dvBack.addEventListener('click', function(){ setView('account'); }); +var _routingRow=document.getElementById('routingRow'); if(_routingRow) _routingRow.addEventListener('click', function(){ setView('routing'); }); +var _rtBack=document.getElementById('rtBack'); if(_rtBack) _rtBack.addEventListener('click', function(){ setView('settings'); }); var _tbBell=document.getElementById('tbBell'); if(_tbBell) _tbBell.addEventListener('click', function(){ if(S.view!=='notifications'){ S.notifFrom=S.view; } setView('notifications'); }); var _ntBack=document.getElementById('ntBack'); if(_ntBack) _ntBack.addEventListener('click', function(){ setView(S.notifFrom||'connect'); }); document.querySelectorAll('.notif-row.is-expandable').forEach(function(row){ diff --git a/design/prototype/screens/ui-mobile.html b/design/prototype/screens/ui-mobile.html index a561ca3..9b301eb 100644 --- a/design/prototype/screens/ui-mobile.html +++ b/design/prototype/screens/ui-mobile.html @@ -856,10 +856,10 @@
自动连接
-
+
-
智能分流
-
+
分流规则
+
智能分流
@@ -916,6 +916,32 @@
+
+
+
代理模式
+
+ + + +
+
内置规则
+
+
国内直连
GeoIP / GeoSite CN
+
局域网 / 私网直连
强制,不可关
🔒
+
私有服务走隧道
服务端下发
🔒
+
+
我的规则 · 首命中生效
+
+
git.51yanmei.com
域名后缀
直连
+
github.com
域名后缀
走隧道
+
category-ads
GeoSite 规则集
拒绝
+
+ +
最终(未命中)
+
FINAL 兜底
走隧道
+
+
+
@@ -1277,7 +1303,7 @@ const I18N = { devRename:'重命名', devForceLogout:'强制退出', devClearLogin:'清除登录信息', devRenamedToast:'已重命名(演示)', devLoggedOutToast:'已强制退出(演示)', devClearedToast:'已清除登录信息(演示)', secPref:'偏好', prefLang:'语言', prefTheme:'深色外观', prefProtocol:'协议', followLight:'跟随浅色', stateOn:'已开启', - secMore:'更多', navDevices:'设备管理', navSettings:'设置', navRedeem:'兑换 & 购买', + secMore:'更多', navDevices:'设备管理', navSettings:'设置', navRouting:'分流规则', navRedeem:'兑换 & 购买', navContact:'联系我们', navWebUC:'网页用户中心', logout:'退出登录', navOrders:'我的订单', ordDetailTitle:'订单详情', ordSecDetail:'明细', kOrderNo:'订单号', kPlan:'套餐', kAmount:'金额', kMethod:'支付方式', kStatus:'状态', @@ -1358,7 +1384,7 @@ const I18N = { devRename:'Rename', devForceLogout:'Force logout', devClearLogin:'Clear login info', devRenamedToast:'Renamed (demo)', devLoggedOutToast:'Force logged out (demo)', devClearedToast:'Login info cleared (demo)', secPref:'Preferences', prefLang:'Language', prefTheme:'Dark appearance', prefProtocol:'Protocol', followLight:'Follow light', stateOn:'On', - secMore:'More', navDevices:'Devices', navSettings:'Settings', navRedeem:'Redeem & Buy', + secMore:'More', navDevices:'Devices', navSettings:'Settings', navRouting:'Routing rules', navRedeem:'Redeem & Buy', navContact:'Contact us', navWebUC:'Web user center', logout:'Sign out', navOrders:'Orders', ordDetailTitle:'Order Detail', ordSecDetail:'Details', kOrderNo:'Order No.', kPlan:'Plan', kAmount:'Amount', kMethod:'Payment', kStatus:'Status', @@ -2019,7 +2045,7 @@ $('#ordBack').addEventListener('click', ()=>{ if(ordOverlay.dataset.screen==='de /* ---------- 通用子屏(顶栏铃铛→通知;账户→设置 / 联系 / 邀请 / 兑换;命名空间 sub) ---------- */ const subOverlay = $('#subOverlay'); let subToastTimer=null; -const SUB_TITLE = { settings:'navSettings', contact:'navContact', notifications:'navNotifications', invite:'inviteTitle', redeem:'navRedeemCode', devices:'devMgmt' }; +const SUB_TITLE = { settings:'navSettings', routing:'navRouting', contact:'navContact', notifications:'navNotifications', invite:'inviteTitle', redeem:'navRedeemCode', devices:'devMgmt' }; function subShow(name){ document.querySelectorAll('#subOverlay .sub-screen').forEach(sc=>sc.classList.toggle('is-active', sc.dataset.sub===name)); subOverlay.dataset.sub=name; @@ -2065,12 +2091,13 @@ document.querySelectorAll('.notif-row.is-expandable').forEach(function(row){ }); // 账户入口 $('#rowSettings').addEventListener('click', ()=>subOpen('settings')); +$('#rowRouting').addEventListener('click', ()=>subOpen('routing')); $('#rowContact').addEventListener('click', ()=>subOpen('contact')); $('#rowInvite').addEventListener('click', ()=>subOpen('invite')); $('#rowRedeem').addEventListener('click', ()=>subOpen('redeem')); $('#rowDevices').addEventListener('click', ()=>subOpen('devices')); // 返回 → 关闭回上一屏 -$('#subBack').addEventListener('click', subClose); +$('#subBack').addEventListener('click', ()=>{ if(subOverlay.dataset.sub==='routing'){ subShow('settings'); } else { subClose(); } }); // 复制反馈 document.querySelectorAll('#subOverlay .sub-copy').forEach(b=>b.addEventListener('click', ()=>subToast(D().toastCopied.replace('{v}', b.dataset.copy)))); // 演示开关(设置·连接组)