Break/v2 api restructure - #20
Draft
PrintNow wants to merge 32 commits into
Draft
Conversation
后端: - Provider 模型支持 inline 类型(Payload 字段,JSON 序列化节点列表) - Provider handler 新增节点 CRUD 端点(GET/POST/PUT/DELETE /providers/:id/nodes) - IsCacheStale / FetchAndCache 对 inline provider 直接跳过 HTTP 拉取 - 订阅 YAML 生成:inline provider 直接读 Payload,http provider 走原有缓存逻辑 - 新增统一规则集 API /api/rule-sets(source_type=external/hosted,复用原两张表) - 新增 GET /api/subscriptions/:id/components,从 rules 自动推断引用的规则集 - CustomConfig handler 移除 Proxies 字段,代理节点改由 inline provider 承载 - 新增数据库迁移 002_provider_inline 前端: - 侧边栏重构为分组导航(来源素材/配置编排/发布)+ 底部流程提示卡片 - 路由:/rule-sets 替代原 /rule-providers + /hosted-rule-sets - 新增 RuleSets.tsx(tab 切分 全部/订阅/私有) - Providers.tsx 支持 http/inline 双类型,inline 显示节点预览 + 节点管理 Dialog - 新增 ProxyNodeForm 组件(8 种协议字段动态渲染,支持 YAML 粘贴解析) - CustomConfigDetail 删除"代理节点"tab,新增"YAML 编辑"tab - ProxyGroupDialog use[] 支持 inline provider 并显示紫色标识 - Subscriptions.tsx 新增组成要素展开面板(懒加载) - types、API 客户端、i18n 全面更新
在代理组编辑弹窗右上角新增「YAML 模式/表单模式」切换按钮: - 切换到 YAML 模式:将当前表单状态序列化为 YAML 展示在可编辑 textarea - 切换回表单模式:解析 YAML 并同步回表单各字段 - 保存时:YAML 模式直接解析 YAML 保存,表单模式走原有逻辑
历史数据中 proxies 等字段存储为 null,GORM 读回后为 nil slice, JSON 序列化输出 null,前端调用 .length 报错。 新增 normalizeCustomConfig 辅助函数,在所有读取路径(List/Get/ Create/Clone/Update/Import)返回前将 nil slice 统一转为空切片。
BREAKING CHANGE: 以下 API 和数据结构发生不兼容变更,旧客户端需全量升级。
## API 路由变更
- 删除 GET/POST /api/rule-providers 及 GET/PUT/DELETE /api/rule-providers/:id
- 删除 GET/POST /api/hosted-rule-sets 及 GET/PUT/DELETE /api/hosted-rule-sets/:id
- 新增统一入口 GET/POST /api/rule-sets(source_type=external|hosted)
及 GET/PUT/DELETE /api/rule-sets/:id
## CustomConfig 结构变更
- 删除 CustomConfig 的 proxies 字段(JSON: "proxies")
代理节点改由 inline Provider 承载,通过 /api/providers 管理
- 相应地,创建/更新 CustomConfig 的请求体不再接受 proxies 字段
## Provider 模型变更
- Provider 新增 type 字段("http" | "inline")
- inline 类型新增 payload 字段(JSON 序列化节点列表)
- 新增节点 CRUD 端点:
GET /api/providers/:id/nodes
POST /api/providers/:id/nodes
PUT /api/providers/:id/nodes/:index
DELETE /api/providers/:id/nodes/:index
- 数据库新增迁移 002_provider_inline(provider 表加 type/payload 列)
## 前端路由变更
- /rule-providers 和 /hosted-rule-sets 页面合并为 /rule-sets
- CustomConfigDetail 移除"代理节点"tab,新增"YAML 编辑"tab
- 侧边栏导航结构重组为分组模式(来源素材 / 配置编排 / 发布)
PrintNow
marked this pull request as draft
June 12, 2026 18:39
路由变更(Breaking): - 删除 /api/rule-providers(5 个端点) - 删除 /api/hosted-rule-sets(6 个端点) - /api/rule-sets 补全 GET /:id、新增 POST /reset-hosted-tokens Handler 重构: - 删除 handler/rule_provider.go、handler/hosted_rule_set.go - rule_set.go 合并所有辅助函数,修复 DeleteRuleSet 缺少 source_type 的 bug - ListRuleSets 补回系统预设(is_preset=true)的外部规则集 模型与迁移: - 删除 model.CustomConfig.Proxies 字段(代理节点已由 inline Provider 承载) - 新增迁移 003:删除 custom_configs.proxies 列 死代码清理: - util/yaml.go:删除 customProxies 参数、ExpandCustomProxies、ParseRulesList - util/rules_validate.go:删除 proxies/proxy-groups 校验函数(旧架构遗留) - util/loyalsoldier_ruleset.go:删除从未被调用的工具函数 前端同步: - rule-sets.ts delete() 补传 source_type 查询参数 - types/index.ts 删除 HostedRuleSet、RuleProvider 废弃类型 - types/index.ts 删除 CustomConfig.proxies 字段
包含重构计划文档 IMPLEMENTATION.md、HTML 交互原型 prototype.html 及 UX 设计决策说明 ux-design-doc.md。
- 所有列表页(Providers、RuleSets、RuleProviders、HostedRuleSets、UserAgents、 CustomConfigs、ConfigTemplates、Subscriptions)新增移动端卡片视图, 桌面端保留表格布局(sm 断点切换) - Dashboard 统计卡片改为响应式 grid(移动 2 列 / 桌面 5 列), 日志表格移动端隐藏次要列 - Login / Register 居中卡片布局,移动端全宽,添加品牌底色 - Settings 表单收窄为 max-w-xl,间距紧凑化 - AccessLogs 移动端卡片日志列表 - SubscriptionDetail、ConfigTemplateDetail 紧凑化标题区与操作栏 - CustomConfigDetail 移动端禁用拖拽(PointerSensor distance=Infinity), 拖拽句柄在移动端隐藏(hidden md:flex) - 补充 types/index.ts 中缺失的 RuleProvider、HostedRuleSet 类型定义 - TypeScript 编译零错误,vite build 通过
- 新增 helper.go:HasColumn/HasTable/HasIndex/DropColumnIfExists/ RenameColumnIfExists/CreateIndexIfNotExists/DropIndexIfExists, 全部幂等、双方言兼容(SQLite 用 pragma_table_info,MySQL 用 information_schema) - Migration struct 新增 Description 字段,runner 输出 slog 日志跟踪进度 - SchemaMigration 表新增 description 列(AutoMigrate 自动补列) - 用 helper 重写 003 migration,彻底修复 SQLite DropColumn nil-schema panic - 完善迁移测试:幂等性、helper 函数全覆盖
- api/rule-sets.ts: 新增 get() 和 resetTokens() 方法
- RuleProviders.tsx: 替换 ruleProvidersApi → ruleSetsApi.list('external'),
移除 provider.type 字段引用(统一 API 不返回 type,后端固定 http)
- HostedRuleSets.tsx: 替换 hostedRuleSetsApi → ruleSetsApi,
url 字段改用 hrs_url(统一响应结构变更)
- CustomConfigDetail/index.tsx: 合并两个旧查询为单一 ruleSetsApi.list(),
通过 useMemo 按 source_type 派生 allRuleProviders / allHostedRuleSets
- types/index.ts: 补充 RuleProvider 和 HostedRuleSet 接口定义(供类型兼容)
- 后端路由无 /rule-providers 和 /hosted-rule-sets,统一由 /rule-sets 处理
…ovider 不再在 Subscription 层面存储 enabled_provider_ids JSON 字段,转而在生成 YAML 时从 CustomConfig 代理组的 use: 字段提取被引用的 Provider 名称,按名 查询数据库。同步添加 005 迁移删除该列,并清理 handler/service/domain 层 相关代码。
- RuleProvider 新增 server_cache_enabled / cache_token / cached_content / cache_expires_at 字段,支持将上游规则集内容缓存到本服务 - HostedRuleSet / RuleProvider 均新增 rule_count 字段,创建/更新时自动解析 - 新增公开端点 GET /rule-cache/:token 供 Clash 拉取缓存内容 - 创建/更新外部规则集时若启用缓存,异步触发首次拉取
删除 enabledProviderIds.ts/test.ts,API 层不再对该字段做客户端解析。 types/index.ts 同步移除 enabled_provider_ids,新增 rule_count / server_cache_enabled 字段定义。
AppLayout 接入 breadcrumb store,顶部导航栏展示动态面包屑路径; 补充 server_cache_enabled、rule_count 等新字段的中英文 i18n 词条。
- RuleSets.tsx:创建/编辑外部规则集时新增「服务端缓存」开关 - HostedRuleSets.tsx:列表展示 rule_count,编辑弹窗同步优化 - YamlEditor:弹窗高度同时设置 minHeight + maxHeight,符合规范
- SubscriptionDetail:移除 enabled_provider_ids 相关 UI,Provider 列表改为 只读展示(从 CustomConfig 推导),简化配置表单 - Subscriptions:列表页去除 enabled_provider_ids 展示 - ConfigTemplateDetail:面包屑注册、编辑器高度修复 - CustomConfigDetail:适配新代理组结构,移除冗余字段 - ProxyGroupDialog:移除 enabled_provider_ids 选择器
- inline 类型节点源隐藏刷新按钮和缓存 badge,改为显示「自托管」标识和最后更新时间 - 后端 ProviderStatus 补充 type/updated_at 字段;staleProviderCount 排除 inline 类型 - 访问日志附带订阅名(后端新增 AccessLogEntry.SubscriptionName) - 日志行第一列改为订阅名+IP 双行展示,时间列 hover 弹出完整日期时间供审计
- 时间列改为完整时间(YYYY-MM-DD HH:mm:ss)+ 相对时间双行展示 - dashboard 查询每 60s 自动刷新,tab 切到后台时暂停(refetchIntervalInBackground: false) - 补充 dashboard i18n relativeDaysAgo 词条
- AccessLog model 新增 user_agent 字段(text 类型,AutoMigrate 自动加列) - sub.go 写日志时从请求头读取 User-Agent - dashboard 日志行在地理位置下方展示 UA,截断 + title 属性查看全文
- AccessLog model 新增 user_agent 字段(AutoMigrate 自动建列) - sub.go 写日志时从请求头读取 User-Agent - dashboard 日志行在地理位置下方展示 UA(截断 + title 查看全文) - AccessLogs 页面新增 UA 列、可配置 per_page(10/20/50/100),时间列改为 YYYY-MM-DD HH:mm:ss - 补充 accessLogs i18n:totalCount / perPage / userAgent
- 地址列对私有规则集展示 hrs_url(本服务器访问地址),并附复制按钮 - 地址列对订阅/预设规则集保持展示上游源 URL - 列名由 "URL" 改为 "地址",避免与上游源地址歧义 - 预设规则集(is_preset=true)隐藏编辑与删除按钮,防止触发后端 404 - 移动端卡片同步上述逻辑 - i18n 补充 urlColumn 词条
- 将 emoji → canvas PNG base64 转换改为直接生成 SVG data URL, 存储体积从 ~3-5KB 降至 ~100B,无需"转换"按钮,输入即时预览 - ProxyGroupDialog 成员排序传感器补充移动端检测,与主页面保持一致
- User 模型增加 is_admin 字段,第一个注册用户自动成为管理员 - 新增 SystemSetting 模型与 GetSetting/SetSetting 工具函数 - Register 增加 skipRegistrationCheck 参数,支持注册开关(allow_registration) - 新增 admin handler/middleware,管理员可管理用户和系统设置 - base_url 支持在管理后台配置并从数据库覆盖环境变量,无需重启 - 新建订阅时若未手动设置过期时间,自动应用 default_token_expiry_days 设置 - 前端:Admin 路由、页面(用户列表、系统设置)、Sidebar 管理入口、AdminRoute 守卫 - 迁移:007 admin/settings 建表、008 初始化 base_url 和 token_expiry 种子数据
变更历史: - 新增 ConfigHistory 模型,每次保存自定义配置时异步写入历史快照(最多 50 条) - 新增 GET /:id/history 和 POST /:id/history/:hid/restore 接口 - 前端变更历史 Tab:展示快照列表(代理组/规则数量),支持一键恢复 代理组增强: - 代理组行展示 icon 图标(ProxyGroup.icon 字段) - 新增批量编辑 Sheet:直接粘贴/编辑 YAML 数组格式,应用后自动保存 - 编辑或新增代理组后自动保存(不影响规则草稿,通过 suppressRulesSyncRef 控制) - 有未保存改动时拦截页面 beforeunload - 规则文本切换时有错误行仅过滤错误,保留合法规则(不再阻断操作)
- Providers:inline 节点源新增 YAML 批量编辑抽屉,可直接粘贴整块节点列表保存 - ConfigTemplates:操作改为下拉菜单,支持克隆配置模板;增加更新时间列 - Login/Register:错误提示由 Alert 组件改为轻量 div,减少视觉噪音 - RuleSets:hosted 标签页隐藏"缓存模式"和"刷新间隔"列;预设 Badge 调整至名称前
- 后端:validateMihomoRuleLine 跳过 # 开头的注释行; yaml.go filterEmptyStrings 已过滤注释行,生成的 mihomo 配置纯净 - 前端新增 parseRulesWithComments / serializeRulesWithComments / parseRulesTextFull 三个工具函数,管理注释与规则的并行关联 - index.tsx 新增 ruleComments 并行状态,add/delete/drag/normalize 操作均同步;原文模式与结构化模式双向切换时注释不丢失 - SortableRuleRow 折叠态右侧显示注释文字(点击文字才触发编辑, 点击空白仍展开行);展开态提供注释输入框
点击"查看变更"按钮弹出 Dialog,展示当前版本与上一历史版本的 行级 diff(绿色新增、红色删除),大段未变内容自动折叠。 纯前端按需计算,零后端压力。
支持推送到 GHCR 和 Docker Hub,触发条件包括 Tag、Release、main 分支及 break/release 开发分支,多平台构建 linux/amd64 + linux/arm64。
Alert 和 AlertDescription 已被替换为自定义 div 实现,但 import 语句未清理,导致 TS6192 编译报错使 Docker 构建失败。
- fix(middleware): CurrentUserID 显式检查类型断言,新增 RequireCurrentUserID 防御辅助 - fix(admin): CreateAdminUser 中 is_admin 更新失败时返回 500 而非静默成功 - fix(rule-set): 预设规则集缓存模式仅管理员可修改 - perf(admin): ListAdminUsers/GetAdminUser 用 SQL 聚合消除 3N+1 查询 - fix(config-history): goroutine 内历史写入/清理错误改为 slog 记录
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.