700 Commits

Author SHA1 Message Date
yinjianm 77140864ef feat(ui): 为工单对话页新增用户与订单跳转入口
在工单工作台对话页为当前工单用户增加“查看用户”
和“用户订单”入口,支持直接跳转到用户管理与订单管理

用户管理页新增 `user_id/user_email` 路由作用域,
进入后按用户 ID 精准筛选,并支持在重置筛选时清除
该作用域

同步更新 admin-frontend 模块文档、变更归档与测试环境
compose 配置
2026-05-01 19:07:31 +08:00
yinjianm f70dbe4378 fix(config): 将前端访问开关限制为仅控制首页
移除用户前端开关对订阅入口、用户 API 与访客接口的拦截,
关闭 `frontend_enable` 时仅让用户首页 `/` 返回空 404。

同时更新后台配置文案、测试用例与模块文档,明确 API、
订阅和节点接口保持原有访问边界。
2026-04-29 16:49:11 +08:00
yinjianm 7a1cba4553 feat(config): 新增用户前端访问开关
新增 `frontend_enable` 配置并接入后台站点设置,
用于控制用户首页、订阅入口及用户侧 API 是否对外开放。

开关关闭时相关用户入口统一返回空 404,
同时保留节点 API、管理后台与外部回调接口可访问。

补充特性测试覆盖默认开启、关闭隐藏与节点接口白名单场景
2026-04-29 16:31:33 +08:00
yinjianm e847252e12 fix(api): 修复节点流量限额共享统计与父子显隐联动
统一节点流量统计与限额展示口径,节点详情新增昨日流量,
并让今日、昨日和本月使用清晰的半开时间窗口聚合

同 machine_id 或同 host 的节点现在共享当前账期已用流量,
管理端优先使用后端 traffic_limit_snapshot 展示月额度状态,
mi-node 下发的 current_used 也改为共享账期统计

新增 parent_auto_hidden 标记与父节点显隐联动服务,父节点
因自动上线或流量限额变为不可展示时会隐藏当前显示的子节点,
恢复时只恢复这批自动隐藏的子节点,避免覆盖手动操作
2026-04-29 02:24:57 +08:00
yinjianm 922e86070d feat(api): 新增节点月流量限额强制下线
新增节点级月流量限额配置、重置调度和运行状态持久化
下发 traffic_limit 给 mi-node,并在超额后停止内核、到期后恢复
管理端支持编辑限额参数并展示额度进度、状态和下次重置
手动与定时重置会同步清理限额状态并通知节点刷新配置
2026-04-29 00:46:12 +08:00
yinjianm 52529d1f58 fix(config): 跳过 laravel/reverb 的自动发现
在 Composer 配置中将 laravel/reverb 加入 dont-discover,
避免旧锁文件触发 package discovery 时在 Docker 构建阶段失败。

项目未启用 Reverb,此变更用于稳定后端构建流程。
2026-04-28 17:26:23 +08:00
yinjianm 16b22bc8a7 perf(api): 优化节点统计查询与 Docker 构建缓存
节点流量累计统计改为统一从 v2_stat_server 聚合,
避免节点当前累计字段重置后出现月统计大于累计的错误。

Docker 构建改为先复制 composer 清单并缓存依赖安装,
同时移除 composer.lock 的忽略规则以提升缓存命中率。
2026-04-28 17:13:06 +08:00
yinjianm 1739f7a2f9 feat(api): 新增节点流量悬浮详情与即时自动上线同步
为 server/manage/getNodes 返回节点级今日、本月与累计流量统计,
并在节点管理页名称悬浮层展示上行、下行和合计流量。

同时为自动上线补齐单节点同步入口,在管理端保存、
批量更新以及 REST/WS 心跳后立即同步 show 状态,
避免复制节点后开启自动上线仍需等待定时任务。

另优化管理端前端 Docker 发布流程,默认仅构建 amd64,
并收敛 BuildKit 缓存导出以缩短发布时间
2026-04-28 16:51:35 +08:00
yinjianm a62a124710 fix(api): 修复自动墙检父节点筛选与启用语义
统一自动墙检查询逻辑,兼容 parent_id 为 null 或 0 的父节点
将 gfw_check_enabled 的空值视为开启,避免页面显示已启用却未入队

同时调整管理端自动墙检统计仅计算父节点
并更新 CI 配置以忽略 .helloagents 变更触发后端发布
2026-04-28 14:53:19 +08:00
yinjianm 4c66d1fbe0 feat(ui): 新增自动墙检倒计时提示
精简节点管理页批量操作与工作台说明文案,
并在表格底部新增基于 30 分钟调度节奏估算的
下次自动墙检倒计时提示,便于用户了解任务状态
2026-04-28 14:28:57 +08:00
yinjianm c24a1495ff fix(deploy): 调整 xboard 更新脚本执行流程
更新脚本改为先拉取镜像,再通过一次性 web 容器执行
xboard:update,最后重新启动服务

移除 --migrate 参数并补充非交互终端下的执行说明,
同时更新 README、部署模块文档并新增测试 compose 配置
2026-04-28 13:41:04 +08:00
yinjianm a4e78b864a fix(api): 修复邮件队列超时并补齐调度进程
延长 SendEmailJob 超时并改为超时直接失败,补充重试退避、
失败日志与收件人脱敏,避免 send_email 队列批量超时重试。

新增 MAIL_TIMEOUT 与 QUEUE_RETRY_AFTER 配置,并抽出邮件运行时
配置与 HTML 内容服务,确保 Horizon 常驻进程使用最新邮件配置。

为 Docker、supervisor 与 compose 样例补齐 scheduler 进程,并在
节点管理端开启墙检测托管时立即触发一次检测,保证定时任务持续生效。
2026-04-28 13:32:58 +08:00
yinjianm 329d52f89f fix(api): 修复墙检测任务超时占用与状态展示
为超过 5 分钟未领取或未上报的 pending/checking
任务自动标记失败,避免长期占用 active 状态并阻塞新检测

同时区分前端“等待节点领取”和“检测中”展示,
补充跳过原因提示,并更新相关测试与文档
2026-04-28 01:44:07 +08:00
yinjianm ff50030364 feat(api): 新增节点墙检测自动托管与显隐
新增定时墙检测命令与节点托管字段,自动为开启托管的父
节点创建检测任务,并在 blocked 时自动隐藏节点、normal
时仅恢复由墙检测自动隐藏的节点

更新自动上线服务以尊重 blocked 与自动隐藏状态,避免疑
似被墙节点被重新发布;同时补齐管理端墙检测托管开关、
刷新入口、批量设置与相关测试和知识库同步
2026-04-28 00:51:49 +08:00
yinjianm 73b1696b0a feat(admin-frontend): 新增节点自动上线托管能力
为节点新增 auto_online 字段与后台同步任务,
仅对开启托管的节点按在线状态自动同步前台显示。

管理端补齐单节点与批量开关、列表标识与统计,
并在自动上线启用时禁用手动显隐切换。

后端新增定时命令、保存校验、批量更新支持、
数据库迁移与单元测试,保证托管逻辑可落地。
2026-04-28 00:08:12 +08:00
yinjianm 9af9dd0df7 feat(api): 新增节点墙状态检测闭环
新增父节点墙状态检测任务、结果上报与节点列表状态装饰,
支持子节点继承父节点检测结果并通过 WS/REST 双链路执行

管理端补充墙状态筛选、搜索、单行与批量检测入口,
同时更新知识库归档并新增后续自动上线方案包
2026-04-27 23:45:44 +08:00
yinjianm b3a8d504d1 feat(admin-frontend): 补齐工单回复图片拖拽与粘贴上传
统一工单工作台回复区的图片上传链路,支持按钮选择、
拖拽放下和剪贴板粘贴三种入口,并复用现有图片校验、
上传接口与 Markdown 图片插入逻辑。

同时将回复区样式拆分为独立 SCSS 文件,补充拖拽激活、
上传中提示与发送禁用状态,并同步更新知识库归档信息。
2026-04-27 23:22:21 +08:00
yinjianm 30c2f655e7 fix(admin-frontend): 修复节点权限组保存与协议默认值
统一将节点编辑和批量修改的 group_ids、route_ids
序列化为字符串 ID,避免保存权限组后订阅侧无法命中节点

后端新增 whereGroupId 兼容历史字符串与数字 JSON 值,
并补齐 TUIC 版本、ALPN 选项及 AnyTLS 默认 Padding 配置

docs: 新增 HelloAGENTS 通用与工作流避坑指南
2026-04-27 23:03:57 +08:00
yinjianm c64badfc23 feat(admin-frontend): 补齐活跃筛选与支付快照能力
新增用户管理“活跃状态”高级筛选,并在后端支持
activity_status 复合规则,支持按活跃与非活跃筛选用户。

补齐订单支付成功快照落库与后台展示,保存支付渠道、
支付方法、实付金额和支付 IP,并在订单详情中优先展示。

同时增强节点页在线/离线筛选与批量删除、仪表盘快捷入口,
并修复已关闭工单再次回复后自动重开的统一语义。

附带同步测试、迁移、CI 工作流命名及知识库记录
2026-04-25 00:59:08 +08:00
yinjianm 2218457237 fix(admin-frontend): 补齐独立前端容器的 api 代理
为 Caddy 增加 /api 到后端 web 服务的反向代理,
避免独立静态前端容器无法直连 Laravel API。

同时同步知识库上下文,记录 compose 分支使用
XBOARD_BACKEND_UPSTREAM=http://web:7001 的默认约定。
2026-04-24 23:31:36 +08:00
yinjianm d4168720ac feat(admin-frontend): 补齐用户节点与订单运营工作台
新增用户高级筛选、批量操作与更多行级动作,支持邮件、
CSV、封禁恢复、订单分配、邀请查看、流量记录与重置流量

增强节点管理页的分页、父子筛选、跨页勾选、批量修改与
单节点置顶,并补齐后端批量更新 host、group_ids、rate

修复订单佣金状态误判问题,新增真实佣金筛选与行级确认,
同时优化仪表盘排行悬浮详情展示

补充 admin-frontend 独立 Dockerfile、Caddy 配置与 GHCR
发布工作流,支持通过独立镜像部署管理前端
2026-04-24 23:15:48 +08:00
yinjianm e393b11b61 feat(admin-frontend): 完成节点与礼品卡管理工作台
补齐节点管理真实新增、编辑与排序流程,接入权限组与路由组
维护页,并支持 11 种协议的动态配置表单

开放礼品卡管理入口,交付模板、兑换码、使用记录与统计四页签
工作台,接入 gift-card 相关后台接口

将知识库、权限组与路由管理从占位页升级为真实页面,并修复侧边栏
低高度裁切问题

修复仪表盘 24h 流量排行涨跌始终为 0 的问题,改为对比昨天整日统
计并补充单元测试
2026-04-24 21:58:16 +08:00
yinjianm f7cef30b9c feat(admin-frontend): 完成订阅与系统管理真实工作台
补齐订单、优惠券、主题、插件、公告与支付管理页面,
接入对应后台接口、路由入口与工具层类型定义。
同时修复套餐页开关初始化误写问题,避免浏览即触发写操作。

在订阅协议侧为 Stash 导出增加 AnyTLS 版本守卫,
未知版本或低于 3.3.0 时不再导出该协议,并补充回归测试与知识记录。
2026-04-24 16:52:41 +08:00
yinjianm 16203b14f6 feat(admin-frontend): 新增系统与订阅管理后台页面
扩展管理端侧边栏与路由,新增系统配置真实页面、订阅套餐
管理页、节点管理页及多个结构化占位页

补齐前端 API、类型与工具层,并增强仪表盘刷新、趋势切换、
失败作业详情与流量排行 limit 联动能力

同步后端 traffic rank limit 支持与知识库归档、设计约束、
验证配置及视觉验收产物
2026-04-24 15:32:09 +08:00
yinjianm 9ce345eb76 merge: sync upstream/master preserving local changes 2026-04-23 22:27:18 +08:00
xboard ec1efb4482 refactor(middleware): split V2 server middleware to drop node_type 2026-04-23 19:24:34 +08:00
xboard 5462b7036a docs(upgrade): note pre-2026-04-19 compose upgrade command 2026-04-23 12:23:08 +08:00
xboard ac6d8f01ba fix(caddy): preserve X-Forwarded-For chain so Laravel TrustProxies resolves real client IP 2026-04-23 11:39:58 +08:00
xboard 2efef9e8ee fix(security): prevent payment gateway credentials leakage via OrderResource 2026-04-23 10:26:35 +08:00
yinjianm 60b5c99e74 feat(admin): 补齐工单工作台与流量日志
---
 feat(admin): add ticket workspace and traffic logs
2026-04-21 23:13:00 +08:00
yinjianm 97cf167090 feat(admin-frontend): 新增用户管理页面和导航 2026-04-21 05:19:07 +08:00
yinjianm f68ba190a8 feat(admin-frontend): 重做登录回跳与仪表盘样式
重构管理端登录、主布局和仪表盘,统一为 Apple 风格
并移除高成本装饰层以提升页面流畅度。

补充仪表盘统计、趋势、排行和系统状态接口封装,
同时完善受保护路由的 redirect 回跳逻辑。
2026-04-21 04:23:23 +08:00
yinjianm 4cfda0fbf1 feat(admin-frontend): 初始化管理端登录功能 2026-04-21 03:28:04 +08:00
xboard df77cbfb47 fix(docker): re-apply www ownership to /www at entrypoint 2026-04-20 01:39:24 +08:00
xboard 26210ed8d4 chore(docker): all-in-one redis no longer listens on TCP 2026-04-20 01:14:52 +08:00
xboard 9e2a66f1d5 fix: backfill utls for legacy vless reality nodes 2026-04-20 00:08:00 +08:00
Xboard 1fbf5d160a Update installation instructions for aapanel-docker 2026-04-19 23:33:32 +08:00
xboard cb8c1743dc fix(deploy): make install/update redis-independent and clean stale octane state
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-19 23:23:27 +08:00
xboard dc8fbd1839 docs: update readme 2026-04-19 21:57:56 +08:00
xboard e01620689b refactor: all-in-one docker deployment with auto-tuned resources and per-mode compose templates 2026-04-19 21:18:15 +08:00
xboard c36054b970 fix: restore stripped protocol_settings fields for tuic/mieru/vmess 2026-04-19 00:45:47 +08:00
xboard c0b6ee1763 refactor: core plugins to plugins-core 2026-04-18 23:31:59 +08:00
xboard fe62542b7c fix: unify Trojan server_name/allow_insecure to tls_settings across all protocols 2026-04-18 21:00:21 +08:00
xboard bdd7820a69 feat(admin): batch node-machine binding & frontend update 2026-04-18 19:38:31 +08:00
xboard 1603359120 fix: commit composer.lock for reproducible Docker builds 2026-04-18 16:56:41 +08:00
xboard 360684245e fix: ticket reply_status semantics, N+1 query, and admin reply auto-reopen 2026-04-18 16:40:21 +08:00
xboard da8b5018ea fix: Shadowrocket Trojan whitelist bug and xhttp support 2026-04-18 16:07:22 +08:00
xboard 9ba946621e feat: email template management with DB override, modern mail redesign 2026-04-18 15:41:23 +08:00
xboard e689699f44 fix: batchUpdate use model instance to trigger observer 2026-04-18 04:26:25 +08:00
xboard 521d4e3ac5 fix: dedup device IPs, reset stale online_count on disconnect and scheduled cleanup (#886) 2026-04-18 02:57:55 +08:00
xboard 1708b6564b feat: add xhttp subscriptions, network monitoring, chart legend toggle and ticket sender labels 2026-04-18 02:02:06 +08:00
yinjianm 994819e8a0 fix(clashmeta): handle associative arrays in block yaml export 2026-04-18 01:50:45 +08:00
yinjianm 4a5091825c t2 2026-04-18 01:30:24 +08:00
yinjianm 1282e802b5 t 2026-04-18 01:23:46 +08:00
yinjianm 9ca92430ee fix(clashmeta): render block-style yaml for subscription export 2026-04-18 01:11:11 +08:00
yinjianm 964d055021 chore(ci): optimize docker publish workflow 2026-04-18 00:45:00 +08:00
yinjianm cd5e00bbfb Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	public/assets/admin
2026-04-18 00:35:04 +08:00
yinjianm ecf0a268d3 fix(clashmeta): keep nested proxy objects in block style 2026-04-18 00:31:25 +08:00
xboard d9833fab47 fix(plugin): improve plugin install and uninstall migration handling 2026-04-17 23:11:03 +08:00
xboard f84afc7903 fix: support both GET and POST for handshake endpoint (backward compatibility) 2026-04-17 20:59:48 +08:00
Xboard fea7d97aa3 Update installer URL to use 'dev' branch 2026-04-17 12:54:22 +08:00
xboard a74cc2f19d feat: show install command on machine creation 2026-04-17 06:47:05 +08:00
xboard e297b5fe9f feat: machine mode, ECH subscriptions, batch ops & security hardening 2026-04-17 03:02:53 +08:00
yootus edbd8de356 QuantumultX下发Anytls节点 (#880)
QuantumultX最新版本支持Anytls了,做适配
2026-04-16 19:31:24 +08:00
yinjianm cbb46aca69 chore(helloagents): archive merge workflow proposals and tasks 2026-04-16 17:29:40 +08:00
yinjianm abd64ed20c Merge remote-tracking branch 'upstream/master'
# Conflicts:
#	app/Services/UserOnlineService.php
#	public/assets/admin
2026-04-16 16:59:21 +08:00
xboard 13756956a6 fix: reset traffic stats when copying server nodes 2026-04-11 20:24:43 +08:00
Valentin Lobstein 121511523f Fix: CVE-2026-39912 - Magic link token leak in loginWithMailLink (#873)
The loginWithMailLink endpoint returns the magic login link in the
HTTP response body, allowing unauthenticated account takeover.

The fix returns true instead of the link. The email delivery is
the authentication factor.

Bug inherited from V2Board commit bdb10bed (2022-06-27).
2026-04-10 02:44:20 +08:00
xboard 1fe6531924 fix(update): avoid duplicate safe.directory entries for repo and admin submodule 2026-04-09 20:31:19 +08:00
xboard 38ea7d0067 docs: add donation section 2026-04-09 00:21:28 +08:00
xboard 58ef46f754 fix: stop sending VLESS decryption when encryption is disabled 2026-04-08 11:05:55 +08:00
yootus ec49ba3fd1 Loon和Surfboard适配anytls (#854)
* Loon适配anytls

* Surfboard适配anytls

Surfboard适配anytls
2026-04-02 15:47:41 +08:00
NFamou b7c8b31a91 Merge pull request #856 from NFamou/master
支持Surfboard下发SS2022
2026-04-02 15:46:55 +08:00
xboard f3fd40008b updata admin asset 2026-04-02 05:51:16 +08:00
Xboard 94fc5f6942 Merge pull request #841 from cedar2025/revert-755-feat/server-id-stat-user
Revert "feat: Track user traffic per node (server_id)"
2026-03-30 18:18:35 +08:00
Xboard c5a8c836c0 Revert "feat: Track user traffic per node (server_id)" 2026-03-30 18:17:27 +08:00
xboard 048530a893 Remove duplicate doc files 2026-03-30 18:04:41 +08:00
xboard 7ed5fc8fd3 fix: remove 2026_03_28_050000_lowercase_existing_emails.php 2026-03-30 17:59:39 +08:00
xboard 5f1afe4bdc feat: add Vless Encryption support 2026-03-30 17:03:37 +08:00
Xboard 0cd20d12dd Merge pull request #755 from socksprox/feat/server-id-stat-user
feat: Track user traffic per node (server_id)
2026-03-30 13:55:11 +08:00
Xboard b4a94d1605 Merge pull request #689 from socksprox/fix-user-generation-multiple-prefix
Fix user generation with email_prefix to support multiple users
2026-03-30 13:32:46 +08:00
Xboard 7879a9ef85 Merge pull request #786 from lithromantic/master
Add sha256salt hashing option in password verification
2026-03-30 13:05:39 +08:00
xboard d6a3614d98 update 2026_03_28_161536_add_traffic_fields_to_servers.php 2026-03-30 02:58:09 +08:00
xboard a58d66d72e feat: node traffic limit & batch operations
- Traffic monitoring with transfer_enable limit
- Batch delete nodes
- Reset traffic (single/batch)
2026-03-30 02:50:56 +08:00
xboard daf3055b42 fix: escape Telegram Markdown special characters 2026-03-30 01:46:56 +08:00
xboard 3744ebcd5a Revert "fix: escape Telegram Markdown special characters (fix #450)"
This reverts commit 23294c1f93.
2026-03-29 17:48:49 +08:00
lithromantic 6cac241144 Merge branch 'cedar2025:master' into master 2026-03-29 00:00:34 +01:00
Xboard 76a800ddbb Merge pull request #832 from Dlphine/fix/raw-array-access-data-get
fix: replace raw array access with data_get() to prevent Undefined array key
2026-03-28 17:38:44 +08:00
xboard bbc96a18bc fix: use getHost() for proper host comparison in safe mode 2026-03-28 15:52:25 +08:00
xboard 23294c1f93 fix: escape Telegram Markdown special characters (fix #450) 2026-03-28 09:10:54 +08:00
xboard 130f7c82a8 feat: revoke other sessions when changing password (fix #414) 2026-03-28 08:31:24 +08:00
xboard 0ab67c7a9b fix: add ru-RU.json 2026-03-28 07:44:43 +08:00
xboard 5512841ba2 fix: iOS Safari autofill not filling email field (Fixes #330) 2026-03-28 07:41:57 +08:00
xboard 7fbd1bb92d feat: implement email case-insensitive queries (fix #318) 2026-03-28 07:09:21 +08:00
Dlphine 5dd4cd4bc9 fix: replace raw array access with data_get() to prevent Undefined array key
- Migrate $protocol_settings['key'] to data_get($protocol_settings, 'key') across General, SingBox, Shadowrocket, Surfboard, QuantumultX
- Prevents PHP 8 Undefined array key fatal errors when optional protocol_settings fields are missing
- Same class of bug that caused #735
2026-03-27 13:51:28 +08:00
xboard a6c37bb112 feat: add Russian language support and remove v2board theme 2026-03-26 23:35:30 +08:00
xboard 3c3639613e fix: use ServerService::getServer() for node lookup in WebSocket 2026-03-26 03:51:58 +08:00
xboard 74b5ef0b27 fix: resolve device sync issues and refactor WebSocket server 2026-03-26 03:33:01 +08:00
xboard 420521d90a refactor: restructure device limit system 2026-03-25 17:50:16 +08:00
xboard 73a37a07dd feat: ws notify nodes when user traffic is exhausted 2026-03-25 01:44:55 +08:00
xboard 7dacb69275 feat: Trojan Reality support and protocol distribution optimizations 2026-03-23 14:56:41 +08:00
xboard a712be7cd4 update admin assets submodule 2026-03-23 11:00:31 +08:00
xboard 08d68cbcae fix: intval u/d to avoid bigint overflow (#821) 2026-03-22 19:13:07 +08:00
Xboard b779bd4fd5 Merge pull request #789 from socksprox/feat/or-filter-logic
feat: Add OR logic support to user fetch API filters
2026-03-21 07:49:03 +08:00
yinjianm c3b2b4d4d0 restore admin traffic record details 2026-03-21 01:01:49 +08:00
yinjianm 1b3d022969 feat(payment): add TokenPay payment plugin
Register a new TokenPay payment plugin with configurable API
credentials, payment URL generation, and signed callback
verification.

Also improve admin config fetching to support single-group
lookups and add backwards-compatible subscribe template loading
from legacy settings and bundled files when the database table
is unavailable.
2026-03-19 22:32:28 +08:00
yinjianm ae8a913f9b merge: sync upstream/master from cedar2025/Xboard
合并上游 cedar2025/Xboard 的 master,并按交互决策保留本地改动。
2026-03-19 21:04:27 +08:00
yinjianm 421844895e fix(payment): validate and filter unavailable methods
Filter user-visible payment methods to only include supported
providers and fail fast when a payment record or plugin cannot be
resolved.

This prevents invalid payment options from being returned by the
API and avoids constructing an undefined fallback payment class.
2026-03-19 20:29:26 +08:00
xboard 64e6d8148e feat: Add admin bulk-mail placeholder variables and template rendering 2026-03-19 05:02:16 +08:00
xboard 47983dec40 fix(runtime): force app_url/force_https per-request via middlewar 2026-03-19 04:22:17 +08:00
xboard 139b34ca19 fix(compose): use named volume for redis socket 2026-03-17 22:50:29 +08:00
xboard 9ef61e317c fix(admin): fix giftcard form validation and template creation issues 2026-03-17 18:35:21 +08:00
xboard fe0f1760bd fix(admin): fix node manage tooltip error 2026-03-17 14:13:48 +08:00
Xboard 4a2fbd4d3d Add port mapping for 1panel service 2026-03-17 13:16:43 +08:00
xboard ee55d7fa72 fix: fix brutal-opts configure for clashMeta 2026-03-17 12:26:10 +08:00
xboard e06cd279cf fix(admin): resolve translation key issues 2026-03-17 11:44:17 +08:00
xboard 6eecbb0e4b fix:Fix DynamicForm default value sync, payment unit conversion, advanced config tabs, AnyTLS translation, and UI overlap issues. Fixed #807 2026-03-17 03:21:27 +08:00
Xboard 2ff561e185 Add ws-server service configuration to 1panel.md 2026-03-17 02:36:21 +08:00
xboard dd96e37116 fix(admin): fix order assign 2026-03-17 00:54:26 +08:00
xboard b55091a066 feat: Refactor uTLS & Multiplex Support, Node Status Push Optimization
- Server/ServerSave/Server.php: Unified utls and multiplex schema, validation, and defaults for vmess/vless/trojan/mieru protocols, enabling more flexible protocol configuration.
- Protocols (SingBox/ClashMeta/Shadowrocket/Stash/General): All protocol generators now support utls (client-fingerprint/fp) and multiplex options. Removed getRandFingerprint, replaced with getTlsFingerprint supporting random/custom fingerprints.
- Helper.php: Refactored TLS fingerprint utility to support object/string/random input.
- ServerService: Abstracted updateMetrics method to unify HTTP/WS node status caching logic.
- NodeWebSocketServer: Improved node connection, status push, and full sync logic; adjusted log levels; clarified push logic.
- ServerController: Reused ServerService for node metrics handling, reducing code duplication.
- Docs: Improved aapanel installation docs, added fix for empty admin dashboard.
2026-03-16 23:09:56 +08:00
Xboard 65363ea918 Fix environment variable declaration in Dockerfile. #806 2026-03-16 20:28:18 +08:00
xboard c24e09f0c7 fix: correct node_sync queue assignment in horizon 2026-03-16 02:28:28 +08:00
xboard c45fee2a26 update admin assets 2026-03-15 15:46:44 +08:00
xboard d4f2fcdeb7 fix(admin): fix 2026-03-15 14:10:05 +08:00
xboard 3d082853d7 feat(ClashMeta): enhance Shadowsocks plugin support 2026-03-15 11:36:43 +08:00
xboard 199c146672 refactor: rename ws-server command and update configuration 2026-03-15 10:57:21 +08:00
xboard 98a4964c7c fix(ws): enabel unix socket support for redis connection 2026-03-15 10:47:31 +08:00
xboard 50b75165bd ci: remove image signing 2026-03-15 10:28:49 +08:00
xboard ccdbe9d607 fix: missing ws-server core and update routine 2026-03-15 10:20:42 +08:00
xboard 010275b09e feat: introduce WebSocket sync for XBoard nodes
- Implement Workerman-based `xboard:ws-server` for real-time node synchronization.
- Support custom routes, outbounds, and certificate configurations via JSON.
- Optimize scheduled tasks with `lazyById` to minimize memory footprint.
- Enhance reactivity using Observers for `Plan`, `Server`, and `ServerRoute`.
- Expand protocol support for `httpupgrade`, `h2`, and `mieru`.
2026-03-15 09:49:11 +08:00
xboard 1864223c9b refactor: rewrite default clash rules with KEYWORD-based routing 2026-03-12 13:11:04 +08:00
xboard 0c6ec87ce5 refactor: rewrite restoreProtectedPlugins to use file copy instead of git
- Dockerfile: backup plugins/ to /opt/default-plugins/ at build time
- Replace exec/git-based restore with pure PHP File::copyDirectory()
- Only restore plugins defined in Plugin::PROTECTED_PLUGINS
- Delete target directory before copy to prevent stale files
- Remove function_exists('exec') guard (no longer needed)
2026-03-11 08:30:12 +08:00
xboard 1e069587fe fix: configure SQLite WAL mode and busy_timeout to prevent database locked errors
- Enable WAL journal mode for concurrent read/write support
- Set busy_timeout to 30s to wait on locks instead of failing immediately
- Set synchronous to normal for better write performance

Fixes #770
2026-03-11 07:56:27 +08:00
xboard 8bb4682e98 feat: add configurable ticket_must_wait_reply setting 2026-03-11 07:31:09 +08:00
xboard 2d538c15de perf: fix getTrafficRank slow query with index and batch loading 2026-03-11 07:01:19 +08:00
xboard ec20847f31 refactor: replace database logging with file logging and admin audit log 2026-03-11 06:50:07 +08:00
xboard 6efedcebd4 refactor: move subscribe templates to dedicated database table 2026-03-11 05:47:29 +08:00
xboard 448ddecb56 Use submodule for admin assets 2026-03-11 04:52:06 +08:00
xboard b340652b4d feat(config): support custom telegram webhook url 2026-03-11 02:50:33 +08:00
xboard 562064712d fix(register): handle invalid invite code as API error (#792) 2026-03-11 02:09:25 +08:00
xboard 90f84455d3 feat(surge): add SS2022, SOCKS5, HTTP support 2026-03-09 07:32:51 +08:00
xboard 01bcf43ae8 fix: apply device_limit from plan when assigning via gift card (#630) 2026-03-09 06:51:10 +08:00
xboard 2e0b10e643 fix: return dynamic rate instead of base rate in user server list (#709) 2026-03-09 06:47:30 +08:00
xboard 15a7ef4015 fix: always set uTLS fingerprint for TLS connections in General protocol (#673) 2026-03-09 06:45:28 +08:00
xboard fad6441f4c fix: validate random_int parameters in Helper::randomPort to prevent min > max error 2026-03-09 06:32:10 +08:00
xboard 96cb398315 fix(stash): correct TCP/HTTP network type handling in node generation 2026-03-09 05:39:51 +08:00
Xboard a90c5c41ea Merge pull request #681 from superabbite1/master
Update General.php v2rayN新增tuic协议订阅,vless+ws+tls协议新增fingerprint指纹参数
2026-03-09 05:04:50 +08:00
Xboard 7f5bd7e42b Merge pull request #703 from kuizw9/master
Fix General.php for support AnyTLS and Shadowrocket.php for support Socks Node Name Display
2026-03-09 05:02:07 +08:00
Xboard b00b4358e0 Merge pull request #655 from JxQg/jxq_dev
Feat: Support VLESS node output for Loon protocol, improve buildVless method template
2026-03-09 04:59:20 +08:00
Xboard cf552f6e5d Merge pull request #734 from kelly5454/master
fix: Type error when redeeming gift card
2026-03-09 04:56:14 +08:00
xboard fb266f08da chore: optimize default.clash.yaml template 2026-03-09 03:51:54 +08:00
xboard 9c682af44a feat: add AnyTLS protocol support for Surge 2026-03-09 02:37:32 +08:00
yinjianm dbffb0a7bd 后端流量记录排序改为更精确时间优先(避免只按 record_at 导致排序/分钟不准)
StatController.php (E:/code/php/Xboard-new/app/Http/Controllers/V1/User/StatController.php:22)
     StatController.php (E:/code/php/Xboard-new/app/Http/Controllers/V2/Admin/StatController.php:242)
  2. 流量资源新增 display_at(优先 updated_at,回退 created_at/record_at)
     TrafficLogResource.php (E:/code/php/Xboard-new/app/Http/Resources/TrafficLogResource.php:19)
     TrafficLogResource.php (E:/code/php/Xboard-new/app/Http/Resources/TrafficLogResource.php:43)
  3. 管理端前端(打包产物)流量列改为:时间/上行/下行/倍率/节点/设备/总计,时间显示 YYYY/MM/DD HH:mm
     index.js (E:/code/php/Xboard-new/public/assets/admin/assets/index.js:16)
2026-02-26 05:55:02 +08:00
yinjianm 4f84034814 • 你这个现象我已经定位并修了,核心原因是节点匹配和设备映射都有歧义。
已修改:

  - 节点识别优先用 id,只有找不到才回退 code,避免子节点被匹配成父节点
    ServerService.php (/E:/code/php/Xboard-new/app/Services/ServerService.php#L101)
  - 在线设备解析补全 node_key/node_id,并按真实节点键归类
    UserOnlineService.php (/E:/code/php/Xboard-new/app/Services/UserOnlineService.php#L43)
  - 用户端流量日志设备映射改为按 node_key 精确匹配
    StatController.php (/E:/code/php/Xboard-new/app/Http/Controllers/V1/User/StatController.php#L43)
  - 管理端同样改为按 node_key 映射
    StatController.php (/E:/code/php/Xboard-new/app/Http/Controllers/V2/Admin/StatController.php#L270)

  说明:

  - 这次不涉及数据库结构变更,不需要 migrate。
  - 对管理后台现有统计接口兼容,不会破坏原有 u/d/record_at/server_rate 显示。
  - 旧的历史日志如果之前已经按父节点入库,不会自动改名;新流量会按修复后的逻辑记录。
2026-02-26 05:13:19 +08:00
yinjianm 1e291f8408 fix stat_user unique key with record_type and deduplicate before index 2026-02-26 04:39:42 +08:00
yinjianm 87e547d2f1 修复1 2026-02-26 04:21:30 +08:00
yinjianm 529953d98d 处理jc流量显示的问题 2026-02-26 04:06:28 +08:00
yinjianm 2d14e22322 翻译文档 2026-02-22 04:13:42 +08:00
yinjianm 267aeec5ba 修改文档 2026-02-22 03:58:02 +08:00
yinjianm 809860b8db 修改仓库地址 2026-02-22 03:57:06 +08:00
yinjianm 5370b21ef9 chore: support local docker build deployment 2026-02-22 03:23:33 +08:00
yinjianm 17a7c63aec 修改邮件部分 2026-02-22 03:22:14 +08:00
yinjianm 7a3e245887 添加开发文档 2026-02-22 02:52:32 +08:00
socksprox 3b3fc618d6 Make querying users better with "or" statements 2026-01-28 01:27:21 +01:00
lithromantic f6abc362fd Add sha256salt hashing option in password verification 2026-01-18 00:04:00 +01:00
xboard 601955e60d fix: read plugin enabled from DB for consistency 2026-01-02 18:30:21 +08:00
xboard 6f7181db2f fix(admin): guard unknown order status 2025-12-18 00:57:59 +08:00
socksprox c327fecb49 do not return strings, but int 2025-11-29 17:05:07 +01:00
socksprox 0446f88e9e again: update api combining times 2025-11-29 17:05:07 +01:00
socksprox a01151130e Revert "Combine data with node_id in api output, so its all still "one day", and fits vanilla xboard behaviour"
This reverts commit de39230cbe111bbf793f11bcf5046ef717c67f87.

The api change caused issues
2025-11-29 17:05:07 +01:00
socksprox 9ca8da045c Combine data with node_id in api output, so its all still "one day", and fits vanilla xboard behaviour 2025-11-29 14:07:10 +01:00
socksprox 1ebf86b510 fix: do not merge traffic from different nodes 2025-11-29 13:47:21 +01:00
socksprox 9e35d16fa6 User traffic can now be viewed by node 2025-11-29 13:47:15 +01:00
kuizw9 315b06d103 Merge branch 'cedar2025:master' into master 2025-11-23 14:55:14 +08:00
xboard 95e8e7bca7 feat: add v2node support 2025-11-22 20:33:38 +08:00
xboard 8d0e33ba23 fix: preserve theme config when upgrading theme 2025-11-07 19:25:40 +08:00
kelly5454 3754f7da0d fix: exchange gift card type error 2025-10-30 21:08:39 +08:00
xboard 213aff3993 feat(admin): add Custom ID/Original ID display with copy actions 2025-10-20 21:46:26 +08:00
xboard e3c746d314 feat(plugin): auto-decode JSON config values by type in PluginManager 2025-10-20 18:56:44 +08:00
xboard 7377460ba0 fix(telegram): correct traffic usage description in notification 2025-10-08 10:26:26 +08:00
KuizW9 2d8ed35096 Update General.php
Add AnyTLS to General Client
2025-10-05 22:34:36 +08:00
KuizW9 8941c6b065 Merge branch 'cedar2025:master' into master 2025-10-05 22:32:48 +08:00
xboard 0798b371b6 feat(telegram plugin): improve Telegram notification formatting 2025-09-27 16:53:17 +08:00
KuizW9 ea6bd6fabe Merge branch 'cedar2025:master' into master 2025-09-27 08:52:25 +08:00
xboard f83bdfc9ad fix: avoid getCurrentCommit on cache hit 2025-09-26 19:04:17 +08:00
xboard c5ac76823d allow free plans 2025-09-24 22:19:04 +08:00
KuizW9 35a9e02b8c Update Shadowrocket.php 2025-09-24 19:14:34 +08:00
xboard ccd65f26d4 fix(jobs): resolve PostgreSQL issue in StatServerJob and StatUserJob 2025-09-23 18:57:44 +08:00
xboard bf1234a9c2 fix(plugin): remove stale plugin records when files missing; adjust logging 2025-09-23 14:59:22 +08:00
xboard 92c448e2e1 fix: remove smogate 2025-09-22 22:52:11 +08:00
xboard 2808f40737 Remove Smogate plugin 2025-09-22 18:47:25 +08:00
xboard 61a44483d4 feat(knowledge): add KnowledgeResource with plugin hooks
- Add KnowledgeResource with user.knowledge.resource hook
- Unify processKnowledgeContent for both single and list items
- Remove isListItem parameter for cleaner architecture
2025-09-20 13:36:10 +08:00
xboard 8ae3de511b feat(plugin): add user.subscribe.response hook 2025-09-17 00:02:59 +08:00
xboard 58a374bde9 fix 2025-09-16 18:44:44 +08:00
socksprox 051813d39d Make that user batch generation works again 2025-09-15 15:43:43 +02:00
xboard 843c5af4c2 refactor(online-status): consolidate updates and add cleanup command 2025-09-15 20:32:22 +08:00
xboard cd8a8ecf58 feat(middleware): Add transaction state guard for Octane 2025-09-15 16:15:39 +08:00
xboard 2ac126dd42 refactor(Jobs): Optimize traffic statistics jobs with upsert 2025-09-15 09:56:36 +08:00
xboard 1fd4f923ad fix(server): Correct node_info retrieval method 2025-09-15 09:21:20 +08:00
xboard f289f68898 fix: resolve vmess http-opts headers null issue in subscription generation 2025-09-12 10:45:31 +08:00
superabbite1 fa4a84b3e2 Update Shadowrocket.php
新增Vless+ws+tls协议 Fingerprint指纹参数
2025-09-09 16:43:42 +08:00
superabbite1 3406448475 Update ClashMeta.php
新增vless+ws+tls协议Fingerprint指纹参数
2025-09-09 16:42:11 +08:00
superabbite1 cb07146657 Update General.php
vless+ws+tls协议新增fingerprint指纹参数;v2rayN新增tuic协议订阅
2025-09-09 11:35:44 +08:00
xboard b14477098d fix(epay): allow custom payment types via string input
- Replace select dropdown with string input for `type`
2025-09-05 16:16:30 +08:00
xboard 3238a83d4e feat(shadowrocket): support VLESS transports httpupgrade/xhttp/kcp
- Add parsing for httpupgrade, xhttp, and kcp in Shadowrocket VLESS builder
- Ensure correct obfs/path/host/mode mapping for Shadowrocket compatibility
2025-09-05 15:22:46 +08:00
xboard fe94d7ebc6 fix: remove dependency on job_batches table for batch email sending 2025-09-02 23:54:21 +08:00
xboard 181075ad19 fix: prevent null pointer exception in knowledge fetch 2025-09-01 21:15:40 +08:00
xboard 50562db4ef feat: add force traffic reset to update script 2025-08-31 20:50:34 +08:00
xboard 29a87ba93e feat: add force option to reset traffic command 2025-08-31 20:38:09 +08:00
xboard abf541df72 fix: improve date calculation for month-end reset schedules 2025-08-31 20:30:02 +08:00
Xboard cf10e108ef Merge pull request #658 from xcxnig/patch-2
fix(order): correct renewal handling for onetime plan
2025-08-30 03:15:06 +08:00
Miku a8e2452dcc fix(order): correct renewal handling for onetime plan
fixes onetime plan renewal logic
2025-08-29 23:24:48 +08:00
xboard 5f74093660 fix: correct getAvailableUsers call to use (Server) 2025-08-29 20:50:55 +08:00
xboard 8e0384c833 feat: optimize server.user.get hook definition 2025-08-29 19:21:49 +08:00
Xboard 02c9bca336 Rename docker-compose.yml to compose.yaml 2025-08-29 01:55:34 +08:00
JxQggg 777bbb5ae3 feat(protocols): support VLESS node output, improve buildVless method template
- Added Server::TYPE_VLESS to Loon::$allowedProtocols
- handle() method now supports VLESS node output
- buildVless() method supports all mainstream VLESS parameter templates, including reality/xtls-rprx-vision
2025-08-26 12:27:38 +08:00
xboard 60f1fea356 fix(subscribe): fix vmess+tcp+http subscription in general and singbox 2025-08-24 18:39:00 +08:00
xboard 84d5a4f005 fix(subscribe): fix vmess+tcp+http subscription in Clash and Clash Meta 2025-08-24 18:07:36 +08:00
xboard 9bdd7b8a58 fix(payment): add AlipayF2F libraty file 2025-08-24 17:04:16 +08:00
xboard 23135c6f39 fix: handle disable exec funtion in install script 2025-08-23 19:32:32 +08:00
xboard 724dd54822 fix: support resources/views directory for plugin views 2025-08-23 15:26:09 +08:00
xboard bdbbec3d97 feat(admin): add user details dialog and fix editor resize bug 2025-08-23 15:12:30 +08:00
Xboard 97bea2163c Merge pull request #603 from OfficialKatana/patch-3
Add missing extension
2025-08-23 11:28:46 +08:00
xboard af747c61cc refactor(singbox): use data_get for array access 2025-08-23 11:19:37 +08:00
xboard a907ef523c docs: add plugin development document 2025-08-23 00:25:09 +08:00
xboard 8f3cdf0dde fix: optimize batch email performance and fix gift card issues
- Add chunking and batching for admin email sending
- Fix gift card pagination and add per_page limits
- Update frontend prompts and complete language packs
2025-08-23 00:11:45 +08:00
xboard 53ca5d062c fix(tickets): prevent ApiException logging in ticket creation API 2025-08-21 19:13:14 +08:00
xboard a666557781 fix(auth): handle null redirect in quick login url 2025-08-21 18:57:19 +08:00
Xboard 7386ac26f5 Merge pull request #595 from swcoffee/master
fix: missing field 'version' when distributing tuic protocol in stash
2025-08-21 18:10:04 +08:00
Xboard d4cd3d4bb6 Merge pull request #638 from zytakeshi/fix/singbox-sni-domain-issue
fix: correct SNI domain configuration paths in SingBox protocol
2025-08-21 18:07:53 +08:00
xboard 1808e994ae fix: fix return type in transferToGB method 2025-08-20 04:13:52 +08:00
zytakeshi 4828a00602 Update SingBox.php
fix Vmess
2025-08-16 03:21:17 +09:00
Takeshi Matsumoto c38fd1b7b7 fix: correct VMess TCP transport configuration in SingBox protocol
- Only add HTTP transport when network_settings.header.type is not 'none'
- Use pure TCP (null transport) when header type is 'none' or unset
- Align with General protocol implementation and VMess specification

This prevents unnecessary HTTP transport layer when using pure TCP.
2025-08-16 03:08:56 +09:00
Takeshi Matsumoto f86dd89cdd fix: correct SNI domain configuration paths in SingBox protocol
- Fix Trojan protocol to use 'server_name' instead of 'tls_settings.server_name'
- Fix Hysteria protocol to use 'tls.server_name' instead of 'tls_settings.server_name'
- Align with Server model configuration and General protocol implementation
- Resolves missing SNI domains in sing-box configuration generation

This fixes the inconsistency where SNI domains were missing for certain
protocols while working correctly in General protocol handler.
2025-08-16 02:44:17 +09:00
xboard 877a508f01 fix: fix Alipay face-to-face payment form display issues 2025-08-08 03:17:05 +08:00
xboard 930e2052a4 fix: fix user expiration date display and update issues
- Fix 1970 year display for unlimited validity users
- Resolve SQL error in user update endpoint
- Closes #625
2025-08-08 03:04:44 +08:00
xboard f82a19f591 fix: resolve Telegram ticket notification issue 2025-08-08 02:53:44 +08:00
Xboard 9f9db03cc3 Merge pull request #612 from xcxnig/patch-1
fix(stash): fix Flow network and SNI issues
2025-08-08 02:44:58 +08:00
Miku ca05b65638 fix(stash): fix Flow network and SNI issues 2025-08-02 02:07:29 +08:00
Katana 0971805caa Add missing extension
Fix: Call to undefined function Illuminate\Support\mb_split()
2025-07-30 16:52:01 +08:00
xboard 1405cb0b99 fix: change user default_at to 0 2025-07-27 08:11:42 +08:00
xboard c4dc9669f3 fix: correct errors in database migration file 2025-07-27 08:00:49 +08:00
xboard 78e7be8766 feat: add plugin migrations and fix plan management bugs
- Plugin database migration support
- Fix empty prices error in plan management
- Plugin update functionality
- Custom shadowsocks encryption algorithms
2025-07-27 00:19:14 +08:00
xboard 58868268dd feat: enhance plugin management
- Add command support for plugin management
- Optimize plugin management page layout
- Add email copy functionality for users
- Convert payment methods and Telegram Bot to plugin system
2025-07-26 18:49:58 +08:00
swcoffee 738b433041 fix: missing field 'version' when distributing tuic protocol in stash
stash下发tuic协议时缺少version字段,会导致订阅无法使用
2025-07-26 13:46:54 +08:00
xboard 02d853d46a update composer.yaml 2025-07-23 16:47:48 +08:00
xboard 97f84286d8 fix: announcement sorting issue 2025-07-22 04:28:39 +08:00
xboard 7adfd160cc fix: make subscribe url cofig changes take effect immediately under octane 2025-07-22 03:25:13 +08:00
xboard cd5f444b24 fix(theme): qx import issue and long title display 2025-07-22 02:01:46 +08:00
xboard 920b5b12ec fix: sub link types not working 2025-07-22 01:33:59 +08:00
xboard 06cbe0e478 fix: correct return_url generation for payment in frontend-backend separated deployment 2025-07-21 23:54:00 +08:00
xboard 6649924d10 fix: align user action buttons, add json/yaml support for plugin config, improve formatTrafficSize, show processed commission
- Aligned user action buttons in dropdown for consistent UI.
- Added JSON and YAML support in plugin config form with Monaco Editor and resizable height.
- Improved formatTrafficSize to handle large numbers and prevent undefined units.
- Order detail now shows commission info when commission_status is 1 or 2.
2025-07-21 23:52:07 +08:00
xboard c9bab8fb02 feat: add multiple hooks, pligun schedule support ,add hook:list artisan command 2025-07-21 13:29:17 +08:00
xboard 768e14bdb9 fix: gift card redemption limits validation 2025-07-21 09:28:00 +08:00
xboard 61773a13b4 fix: resolve issue where dynamic rate cannot be disabled 2025-07-21 08:29:14 +08:00
xboard 90360cfeb5 fix: resolve theme refresh issue after updates 2025-07-21 08:27:41 +08:00
xboard bcfda44730 fix: resolve traffic reset time generation and refactor reset logic
- Add fix-null mode to ResetTraffic command
- Refactor reset logic for better separation of concerns
- Update migration to reuse fix functionality
2025-07-19 14:22:01 +08:00
xboard 063a10f6bb refactor: rename hook form traffic.before_process to traffic.process.before 2025-07-18 23:39:19 +08:00
xboard 508caebdcd refactor: refactor subscription delivery logic, change payment return_url to origin_url concatenation
- Unify protocol filter configuration to client.type.field (dot-path, three-segment) format, support strict whitelist mode
- Refactor AbstractProtocol and all protocol classes for more flexible and maintainable subscription delivery
- Change payment callback logic: use origin_url concatenation instead of return_url for more accurate redirects
2025-07-18 15:42:58 +08:00
xboard e2d7b6a5e0 feat(hook): add order.create.after, order.open.before, order.open.after, and protocol.servers.filtered hooks 2025-07-17 12:34:31 +08:00
xboard 10ff5d7b27 feat: consider remaining traffic in surplus calculation when resetting traffic on plan change 2025-07-17 12:13:03 +08:00
xboard 4a7eef8ad6 refactor: optimize surplus value calculation for plan deduction 2025-07-17 11:32:34 +08:00
xboard c4834255c0 style(theme): announcement carousel content and set full-width background 2025-07-16 11:03:07 +08:00
xboard 6fdb083809 feat(plugin hook): add client.subscribe.unavailable hook 2025-07-16 00:08:30 +08:00
xboard ac08199580 fix: fix Redis RDB snapshot permission error 2025-07-15 23:09:38 +08:00
xboard ba2f305f33 fix: theme switch service 2025-07-15 20:50:04 +08:00
Xboard acf05c6107 Merge pull request #558 from Hei-XiaoHu/update-memory-limit
Increase Horizon memory_limit to prevent container memory exhaustion
2025-07-15 03:23:55 +08:00
xboard d30e9cb30b chore: code style and type declaration improvements 2025-07-15 02:55:58 +08:00
xboard b55a56d6a7 feat: improve traffic reset precision and admin features
- Increase traffic reset granularity to seconds
- Add next reset time display in admin pane
2025-07-15 02:18:33 +08:00
xboard 706ba5a7a9 feat: support theme update and various improvements
- Add support for updating themes if a newer version is uploaded
- Hide config button for plugins without configuration items
- Auto refresh theme cache after panel update
- Fix issue where user used traffic cannot be set as a decimal
- Fix subscription issue for shadowrocket in v2board theme
2025-07-15 01:26:14 +08:00
xboard f6cf6706c7 fix(admin): handle null rate_time_ranges when editing server nodes to prevent 500 error 2025-07-14 10:19:08 +08:00
xboard 0311a93252 fix(i18n): correct traffic unit display for gift card template rewards 2025-07-14 00:39:54 +08:00
xboard a838a43ae5 feat: multiple improvements and bug fixes
- Add gift card redemption feature
- Resolve custom range selection issue in overview
- Allow log page size to be modified
- Add subscription path change notification
- Improve dynamic node rate feature
- Support markdown documentation display for plugins
- Reduce power reset service logging
- Fix backend version number not updating after update
2025-07-14 00:33:04 +08:00
xboard a01b94f131 fix(register): handle invalid invite code gracefully
Fix an issue where entering a non-existent invite code during registration would result in an unclear HTTP code 0 error. Now, the system properly validates the invite code and returns a clear error response if the code does not exist.
2025-07-13 21:19:33 +08:00
xboard 18de0e8a43 feat: add plugin update support + fix bugs 2025-07-13 08:53:00 +08:00
xboard 328461b093 fix(plugin): auto-remove plugin record if class file is missing 2025-07-12 21:54:12 +08:00
xboard 1bb1e032d6 remove redundant and unused payment methods 2025-07-12 03:43:39 +08:00
xboard 97788e3c8f feat: Add client.subscribe.servers hook for plugin-based server extension
- Add HookManager::filter('client.subscribe.servers') hook in ClientController::subscribe()
- Allow plugins to inject custom servers into subscription responses
- Update protocol classes to support extended server configurations
- Enable dynamic server list modification before protocol processing
2025-07-11 21:19:23 +08:00
xboard 1e59bc8ca1 fix(subscribe): Disable anytls protocol for Stash client 2025-07-11 08:48:02 +08:00
xboard 59263da76e feat: update plugin/config api 2025-07-09 18:07:38 +08:00
xboard 103b5ddbd6 fix: Subscription filter not working when using types=all parameter 2025-07-07 03:14:21 +08:00
xboard d799c8df8b Fix: Handle raw DB expressions in user filter
A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.Fix: Handle raw DB expressions in user filter

A TypeError occurred when filtering the user list by the `total_used` computed attribute. The `applyQueryCondition` method expected a string for the field name, but received an `Illuminate\Database\Query\Expression` object from `DB::raw`.

This commit updates the `buildFilterQuery` method to check if the query field is an `Expression` instance. If so, it now uses `whereRaw` to apply the filter, preventing the type error and enabling filtering on computed fields. For standard string fields, it continues to use the original `applyQueryCondition` logic.
2025-07-05 12:35:12 +08:00
xboard a3c4cb1aea fix(setting): Resolve admin_setting helper incompatibility with Octane
Updated the `admin_setting` and `admin_settings_batch` helpers to retrieve the `Setting` instance from the service container. This fixes a fatal error and ensures correct behavior in a Laravel Octane environment by preventing the use of stale, shared static instances.
2025-07-04 22:16:19 +08:00
Xiaohu Hei fc8caee0c3 Increase Horizon memory_limit configuration from 32MB to 64MB to support higher workload 2025-07-02 02:12:47 +08:00
xboard 05afe870e7 feat: add tags to plans, refactor order service, adn fix ticket lock 2025-07-01 11:14:18 +08:00
xboard 349c1710fe feat: add PostgreSQL support and refactor database configuration in install command 2025-07-01 03:09:53 +08:00
xboard 690832e3eb feat: add socks protocol support for shadowrocket client 2025-07-01 00:49:55 +08:00
xboard 5b295dbec3 feat: plugin controller config system with guest_comm_config hook integration
- Add HasPluginConfig trait and PluginController base class
- Integrate guest_comm_config hook in CommController for plugin frontend config injection
- Add user creation functionality to UserService and fix null value handling
- Enhance AbstractPlugin.getConfig() with key parameter support
- Multiple service layer optimizations and architecture improvements
2025-06-29 01:42:48 +08:00
xboard b96700ab30 docs: update issue template 2025-06-28 18:16:10 +08:00
xboard 6d85736eea eat: add reCAPTCHA v3 and Cloudflare Turnstile verification support
- Implement reCAPTCHA v3 with score-based validation
- Add Cloudflare Turnstile as captcha alternative
- Create reusable CaptchaService for unified validation
- Support switching between recaptcha, recaptcha-v3, and turnstile
- Maintain backward compatibility with existing configurations
2025-06-28 18:01:59 +08:00
xboard f1d1dd5684 docs: update docs 2025-06-28 15:54:44 +08:00
xboard f974a8c846 fix: admin export subscription link issue 2025-06-24 22:55:34 +08:00
xboard 1dcd2fcdf6 remove: disable traffic package stacking feature 2025-06-24 02:00:12 +08:00
xboard eff2b1f8ba feat(admin): enhance i18n support
Fix system monitor button i18n syntax, complete coupon form i18n
2025-06-23 11:55:17 +08:00
xboard 7efc16990e feat(admin): optimize user traffic management features
- Improve traffic reset dialog interactions
- Enhance traffic reset logs display
2025-06-22 18:04:29 +08:00
xboard 44d92ac1c6 fix: resolve known issues and improve code standards
- Fix known bugs in user, plan, and server modules
- Standardize code formatting and structure
- Optimize database queries and model relationships
- Improve request validation and error handling
- Update admin controllers for better consistency
2025-06-22 17:38:17 +08:00
Xboard 733cc7e9a5 Update README.md 2025-06-22 01:22:04 +08:00
xboard 4fe2f35183 feat: enhance plan validation, traffic system and email verification
- feat: add plan price validation
- feat: make traffic packages stackable
- feat: add commission and invite info to admin order details
- feat: apply email whitelist to verification code API
- fix: subscription link copy compatibility for non-HTTPS
- fix: resolve route editing 500 error in certain cases
- refactor: restructure traffic reset logic
2025-06-22 01:18:38 +08:00
Xboard 7bab761db6 Merge pull request #427 from OfficialKatana/patch-1
更换可用的DoH服务器
2025-06-22 00:05:52 +08:00
xboard d7fb26d527 fix: getSystemStatus api 2025-06-21 16:01:51 +08:00
xboard 42258626b0 feat: enhance plan user statistics with active user count display 2025-06-21 13:20:57 +08:00
xboard 272dbd2107 feat: optimize settings management and admin functionality
- Add system log cleanup functionality with batch processing
- Optimize v2_settings table performance by unifying value storage
- Add comprehensive client support list for one-click subscription
- Fix QR code subscription links for specific node types
- Fix route addition issues in admin management panel
- Enhance admin system controller with log management APIs
2025-06-21 12:11:27 +08:00
xboard 895a870dfc fix(admin): fix shadowsocks plugin issue - save empty string instead of 'none' when plugin is set to none 2025-05-25 08:43:00 +08:00
xboard 6332d96131 fix(clash-meta): support custom SNI configuration for anytls protocol 2025-05-25 00:20:13 +08:00
xboard c90e3d6424 fix(admin): optimize mail encryption selector and null value handling 2025-05-24 22:58:46 +08:00
xboard fadeacf6f8 refactor: comment out update-check routes and refactor findUserByBearerToken, calcResetDayByMonthFirstDay, calcResetDayByExpireDay 2025-05-24 20:47:27 +08:00
xboard 7c86193215 fix: add missing files from previous commit 2025-05-24 20:19:54 +08:00
xboard 4e84cbd953 refactor: optimize mail reminder system - fix memory overflow, improve performance 20-30x, streamline code 2025-05-24 20:08:21 +08:00
Xboard 38f640c6d9 Update composer.json 2025-05-24 18:11:11 +08:00
xboard 78fc0ada98 feat: upgrade Laravel framework from 11.x to 12.15.0 with enhanced dependencies and performance optimizations 2025-05-24 16:28:49 +08:00
Xboard 2ad71017f9 Update 1panel.md 2025-05-24 14:17:22 +08:00
xboard 05f94aeadb fix: restrict anytls delivery to compatible stash client versions 2025-05-24 14:13:44 +08:00
xboard fdb5b222b9 refactor: use request attributes instead of merge for middleware data transfer
- Replace request->merge() with request->attributes->set() in Server middleware to avoid polluting user input
- Add getNodeInfo() helper method in UniProxyController for cleaner node info access
- Update all node_info references to use the new attribute-based approach
2025-05-24 13:54:57 +08:00
xboard bf3a9112f2 fix: improve node filtering by client base_version, set subscription content-type, and add hop_interval support for hysteria2
- Refactor node filtering logic to correctly handle client base_version requirements.
- Set appropriate Content-Type header for subscription responses.
- Add support for hop_interval configuration in hysteria2 node delivery.
2025-05-24 13:45:32 +08:00
xboard a3700ad685 feat: Add node load submission and display functionality
- Implemented node load status submission in UniProxyController with dynamic cache expiration based on server push interval.
- Added log filtering capability in the admin panel for better log management and analysis.
2025-05-24 12:31:18 +08:00
xboard 61300fbcc3 fix: resolve AnyTLS padding scheme modification issue 2025-05-23 20:47:17 +08:00
xboard fc5a957ddd feat: add AnyTLS support and improve system functionality
- Add AnyTLS protocol support
- Add system logs viewing in admin panel
- Refactor client subscription delivery code
- Refactor hook mechanism
- Add plugin support for Shadowsocks protocol
- Add CSV export option for batch user creation
- Fix mobile admin login page width display issue
2025-05-22 17:58:22 +08:00
Xboard 2580475f78 Merge pull request #504 from Fearless743/master
add anytls support
2025-05-21 10:13:28 +08:00
Fearless 711151c7d6 add anytls support 2025-05-19 09:25:52 +08:00
xboard f839e8b3f0 fix: correct obfs host parameter in subscription delivery for clash/clash-meta/shadowsocks/stash 2025-05-18 03:58:14 +08:00
xboard 24d9533dca fix: add missing i18n fields in admin and fix Surge template issue 2025-05-16 23:18:30 +08:00
xboard 0d1588f58a chore: update docker-publish.yaml and Dockerfile 2025-05-16 22:43:00 +08:00
xboard e49f88d311 feat(protocols): add support for ss obfs, ss2022, and vless reality
- Clash and Clash Meta: Added support for Shadowsocks (SS) with obfs.
- Loon: Added support for SS2022 and obfs.
- Stash: Added support for SS2022, obfs, and VLESS Reality.
2025-05-16 06:43:58 +08:00
xboard bbeede8dbc fix(admin): remove one-click update feature and fix fuzzy order search in user management
- Removed the one-click update functionality from the admin panel.
- Fixed the issue where order search in user management used fuzzy matching; now uses precise matching.
2025-05-16 05:48:37 +08:00
xboard 434055f86c chore(redis): disable persistence configuration 2025-05-16 05:16:23 +08:00
xboard 417590e99c feat(admin): optimize subscription template configuration and add Surfboard subscription template
- Improved the code structure for subscription template configuration.
- Added a new feature in the admin panel to configure Surfboard subscription templates.
2025-05-16 05:13:49 +08:00
Xboard f5c3d5c56b Merge pull request #497 from ztbh/master
Fix the bug of sub-node ss password mismatch
2025-05-16 00:18:00 +08:00
xboard faedab24bf fix(admin): correct language pack errors in admin panel 2025-05-15 22:19:25 +08:00
ztb 6c4c296071 Fix the bug of sub-node ss password mismatch 2025-05-13 21:55:18 +08:00
xboard f3cdc2e765 fix(admin): correct ticket message bubble alignment in admin panel 2025-05-11 17:44:18 +08:00
xboard 8377962836 fix(singbox): resolve port type casting and add port hopping support 2025-05-10 17:10:41 +08:00
xboard 73226f6820 fix(node): resolve port type validation error 2025-05-09 19:53:59 +08:00
xboard b614117bd2 fix(admin): Fix order assignment issue in admin panel 2025-05-08 22:14:56 +08:00
xboard 1db1e885c2 fix(stash): resolve incorrect ports deployment 2025-05-08 21:30:47 +08:00
Xboard e443cec064 Merge pull request #484 from cedar2025/new-dev
fix: resolve PHPStan static analysis warnings
2025-05-08 17:17:41 +08:00
xboard 97e7ffccae fix: resolve PHPStan static analysis warnings 2025-05-07 19:48:19 +08:00
xboard db235c10e8 Revert "fix: resolve PHPStan static analysis warnings"
This reverts commit 2d3e4b4a95.
2025-04-14 21:23:08 +08:00
xboard 2d3e4b4a95 fix: resolve PHPStan static analysis warnings 2025-04-14 02:12:42 +08:00
Xboard 3d254c02c1 Merge pull request #438 from NekoCareLab/master
Fixed: IPv6 is not properly processed
2025-03-19 22:49:10 +08:00
NekoCareLab e10d10e4f1 Fixed: IPv6 is not properly processed 2025-03-16 14:23:58 +08:00
Xboard 3ccebfcff1 Merge pull request #417 from NekoCareLab/master
Fixed: Vless GRPC subscription
2025-03-07 12:26:24 +08:00
Katana 1452a9698f Add DoH fallback servers 2025-03-04 15:28:32 +08:00
NekoCareLab 7630fce9a3 Fixed: Vless GRPC subscription 2025-03-01 19:29:21 +08:00
xboard 5a08754735 Fix: Handle null content in PlanResource::formatContent method
- Fix deprecated warning when passing null to str_replace() function\n- Use null coalescing operator to provide empty string as default value\n- Comply with PHP 8.2+ type requirements
2025-02-25 19:14:19 +08:00
xboard 220d306a54 chore: update docker-publish 2025-02-23 16:53:42 +08:00
xboard 08c12a7820 fix: ensure string type safety in Helper::getSubscribeUrl 2025-02-23 16:27:03 +08:00
xboard 925d7c2ad2 feat(admin): add XHTTP and HTTP Upgrade protocol network templates 2025-02-23 02:04:35 +08:00
xboard e297cb9b77 fix: Remove forced direct IP rule for nodes 2025-02-23 00:33:03 +08:00
xboard c45ba9a34d fix: Correct email dispatching in user management 2025-02-23 00:27:22 +08:00
xboard b7e87ba18d feat: Add TUIC protocol support and fix user filtering/export issues 2025-02-23 00:13:04 +08:00
xboard 4667eb232c fix(subscribe): correct vmess websocket cofiguration for Surge compatibility 2025-02-22 21:37:38 +08:00
xboard 926677426e fix(subscribe): correct vmess websocket cofiguration for Surfboard compatibility 2025-02-22 21:12:59 +08:00
Xboard fd0f185992 Update aapanel.md 2025-02-22 17:39:05 +08:00
xboard c45c2b9aba fix(setting): change cache driver from octane to redis in Setting class 2025-02-17 17:01:08 +08:00
xboard f42b42d6b1 update stash.php 2025-02-16 18:15:20 +08:00
xboard 8098cf3ee2 feat(admin): Add subscription template configuration and fix minor issues 2025-02-16 18:05:03 +08:00
xboard 30a140f2d8 update compose.sample.yaml 2025-02-16 10:19:26 +08:00
xboard a56d6f4bf5 update aapanel.md 2025-02-16 10:16:26 +08:00
xboard c8fc2c8b3f update dockerfile 2025-02-10 00:46:00 +08:00
xboard a31a55601e fix(plugin): correct knows bugs 2025-02-10 00:32:17 +08:00
xboard 46a8c12a7d fix(plugin): correct knows bugs 2025-02-10 00:01:51 +08:00
xboard 8030690fe3 fix(plugin): correct knows bugs 2025-02-09 23:54:28 +08:00
xboard 5dc1160666 fix(plugin): correct knows issues 2025-02-09 23:45:23 +08:00
xboard b1116e73c0 fix(plugin): correct knows bugs 2025-02-09 23:36:19 +08:00
xboard 9a412ca570 chore: update dockerfile 2025-02-09 23:10:28 +08:00
xboard ebd5c09145 chore(plugin): Refactor plugin architecture and improve code quality 2025-02-09 22:38:09 +08:00
xboard 0f80ab8d5f fix(update): fix version fetch logic 2025-02-09 14:24:49 +08:00
xboard 7ac2e2e2ed fix(update): fix version comparison logic 2025-02-09 14:05:25 +08:00
xboard 39456923d3 feat: add one-click update feature to admin panel 2025-02-09 13:43:09 +08:00
xboard 1b728fffc7 feat: enhance user management and system optimization
New Features:
- Add bulk ban and email notification in user management
- Add CSV export for batch coupon generation
- Optimize subscription description template

Bug Fixes:
- Fix knowledge base pagination issue
- Fix permission group filtering in node management
- Fix unauthorized order placement for free subscription periods
2025-02-09 11:06:08 +08:00
xboard 8e5732d857 fix: coupon period limit 2025-02-07 22:55:45 +08:00
xboard 2fb6691ca6 fix: coupon period limit 2025-02-07 22:39:31 +08:00
xboard b3339f7fe0 update docker-publish.yml 2025-02-07 20:11:08 +08:00
xboard 68d42a514f update dockerfile 2025-02-07 19:58:42 +08:00
xboard 1dfd7fa8c5 fix: subscribe.url hook 2025-02-07 13:06:01 +08:00
xboard 85d834432a chore: update dockerfile 2025-02-06 19:04:38 +08:00
xboard 7c0434d182 feat(plugin): add subscribe.url hook 2025-02-06 18:18:02 +08:00
xboard 667e02460c feat: add traffic.before_process hook 2025-02-06 17:48:17 +08:00
Xboard 0d19332730 Update aapanel.md 2025-02-05 03:41:26 +08:00
xboard 0858901d31 fix(xboard theme): add root path redirection to dashboard 2025-01-26 12:50:40 +08:00
xboard 76d824c16c feat: suppress InterceptResponseException logging to reduce noise 2025-01-26 11:59:32 +08:00
xboard c7dd798af3 fix(ticket): correct knows issues 2025-01-26 11:42:30 +08:00
xboard 0232bb90dc fix(plugin): remove redundant code 2025-01-26 11:41:53 +08:00
Xboard 0f903dacf6 Merge pull request #349 from ogbeh/patch-1
Update aapanel-docker.md
2025-01-26 04:28:24 +08:00
xboard 14c778e32d refactor: move plugin initialization to middleware for Swoole compatibility 2025-01-26 04:22:47 +08:00
xboard 0b57d9d7cb update composer.yaml 2025-01-26 04:03:34 +08:00
xboard c370b297d2 feat: add plugin upload functionality and optimize plugin logic 2025-01-26 03:58:28 +08:00
xboard 0141c68167 refactor: enhance plugin mechanism for better extensibility 2025-01-26 02:31:57 +08:00
xboard e858a7c6db fix: optimize stat jobs to prevent SQLite lock issues 2025-01-26 01:07:42 +08:00
xboard e433b5f7da update issue template 2025-01-26 00:54:51 +08:00
xboard 2a43a442de fix: resolve deprecation warnings across the application 2025-01-26 00:44:58 +08:00
xboard 239b970055 refactor: optimize ticket management system 2025-01-25 17:46:10 +08:00
xboard b2e7ed44f3 feat: add user deletion functionality and fix known issues 2025-01-25 16:57:17 +08:00
Samuel Ogbeh fdd86ba5e9 Update aapanel-docker.md
Update site config to solve the issue of admin panel not loading
2025-01-24 14:32:30 +01:00
xboard 1ae8deca99 feat(coupon): enhance theme compatibility by converting plan IDs to strings 2025-01-24 02:26:22 +08:00
xboard caade5c791 fix(coupon): correct knows issues 2025-01-23 16:14:18 +08:00
xboard 8f88e11403 fix(coupon): correct knows issues 2025-01-23 14:48:12 +08:00
xboard 25c71c60ac update docs 2025-01-22 21:01:18 +08:00
Xboard 56890364fc Update 1panel.md 2025-01-21 22:12:28 +08:00
Xboard 80a1a12757 Update compose.sample.yaml 2025-01-21 22:11:22 +08:00
Xboard 4d2b2c7a65 Update docker-publish.yml 2025-01-21 22:04:08 +08:00
xboard a3b7d0d511 update md 2025-01-21 19:35:49 +08:00
xboard d7c45f0e0d update readme 2025-01-21 16:18:00 +08:00
xboard 0f43fff242 feat: new xboard 2025-01-21 14:57:54 +08:00
Xboard de18cfe596 fix: resolve hy2 speed limit dispatch issue in Singbox client 2024-12-09 18:45:12 +08:00
xboard f86ccae28c pref: Enhance TrafficFetch Performance and Optimize Code Structure 2024-11-29 19:22:12 +08:00
Xboard 0e9739af0b Update composer.json 2024-11-17 17:02:07 +08:00
xboard db6a361857 Revert "chore: update composer.json"
This reverts commit dd246b2c16.
2024-11-15 15:10:05 +08:00
xboard 090781db0c feat: add support for hysteria2 in V2rayNG 2024-11-09 22:16:05 +08:00
xboard e79465c90d feat: add support for hysteria2 in Passwall and SSRPLUS 2024-11-09 21:37:15 +08:00
xboard ab52e61ed1 refactor: subscription URL retrieval logic 2024-11-09 06:35:37 +08:00
Xboard 73b25d2eec Update aapanel+docker安装指南.md 2024-11-09 04:13:45 +08:00
Xboard b5ea28cd27 Update docker-compose安装指南.md 2024-11-09 04:01:39 +08:00
Xboard fd37291716 feat: add appname display in hiddify
add profile-title header to sing-box subscribe
2024-11-08 17:26:31 +08:00
Xboard 2251f218d8 chore: add persistence configuration to redis 2024-11-08 06:32:48 +08:00
xboard dd246b2c16 chore: update composer.json 2024-11-05 11:56:02 +08:00
Xboard 6ab033c4cf 合并来自greatbody/dev的拉取请求#215
feat: Support configure environment variable to skip interactive configurat…
2024-11-02 14:30:54 +08:00
Xboard 421a0c36ed Merge pull request #238 from mercury7720/dev
[feat]: add v2rayNG hysteria2 support
2024-11-02 14:25:51 +08:00
Linux f25696f22b Payment: add type configuration to Epay payment 2024-10-20 12:37:16 +08:00
Linux 4d4adc4fac fix: Hide online user count display for child nodes without independent online users 2024-10-20 12:03:21 +08:00
Linux c7ea56bb7e docs: update 2024-10-19 23:17:22 +08:00
George 8737e0a6eb Merge remote-tracking branch 'upstream/dev' into feature/v2rayng-hysteria2 2024-10-10 11:18:20 +08:00
Linux f5746423bf fix: 修复用户端不显示当日流量的问题 2024-10-09 22:55:26 +08:00
George 0873ce591f [feat]: add v2rayNG hysteria2 support 2024-10-09 15:17:45 +08:00
xboard af1f1e9fdf fix: 修复流量明细显示所有记录的BUG 2024-10-07 09:55:19 +08:00
Xboard 2f29c5f118 Merge pull request #227 from mercury7720/dev
[fix]: Loon Hysteria2 node cannot get SNI
2024-10-07 05:48:29 +08:00
xboard 47b0646811 fix: 修复vless节点的tls_insecure在meta中下发生效的问题 2024-10-07 02:47:54 +08:00
xboard a7f42a6459 fix: 修复节点密钥未校验是否为空的问题 2024-10-07 00:27:11 +08:00
George 0e2d961902 [fix]: Loon Hysteria2 node cannot get SNI 2024-09-29 11:28:18 +08:00
greatbody 9517b0144f Enable mannual trigger of pipeline. 2024-09-06 10:08:17 +08:00
greatbody 0fb61ce30e Support configure environment variable to skip interactive configuration, which is require when we want to setup by script. 2024-09-06 10:02:45 +08:00
xboard 912cb397ea fix: [Xboard主题] 修复扫描二维码订阅中二维码显示位置歪了的问题 2024-08-27 13:55:20 +08:00
xboard cf13c87873 update docker-publish.yml 2024-07-29 13:09:25 +08:00
xboard 2f9d28beb0 fix: [Xboard主题] 修复订单金额计算的问题 2024-07-24 00:25:37 +08:00
Xboard 5f3b95b699 Merge pull request #180 from ishkong/patch-1
feat: 支持部分客户端订阅获取shadowsocks中obfs部分参数
2024-07-21 17:48:17 +08:00
ishkong b8c2197e89 feat: Support V2RayNG to get obfs parameters in shadowsocks. 2024-07-21 17:29:12 +08:00
ishkong e46f2b3390 feat: Support shadowrocket to get obfs parameters in shadowsocks. 2024-07-21 14:01:03 +08:00
ishkong dd8267097e feat: Support Shadowsocks obfs config 2024-07-21 13:58:22 +08:00
xboard c7b15e6b8b fix:【Xboard主题】 修复订单金额计算在分配订单情况下显示有误的问题, 修改部分弹窗的按钮颜色与主题色一致 2024-07-20 02:53:06 +08:00
xboard c18f55d6dd fix: 修复上一个commit造成的bug 2024-07-19 07:04:02 +08:00
xboard 163d09c71b feat: Singbox、clash订阅增加绕过服务器地址规则
1、优化订阅下发代码
2、singbox、clash、meta订阅下发增加绕过服务器地址规则,防止重复代理
2024-07-19 06:29:35 +08:00
xboard 3f264c17ba update default.sing-box.json 2024-07-19 02:33:27 +08:00
xboard 6a32cf28fb fix: Fix OrderHandleJob to prevent Lock wait timeout. 2024-07-19 02:30:51 +08:00
Xboard f9e4a978fd Update aapanel+docker安装指南.md 2024-07-16 02:25:49 +08:00
xboard 14a2a09d7b fix:[Xboard主题] 修复支付弹窗二维码溢出盒子的问题 2024-07-04 13:36:25 +08:00
xboard f099cf6d30 xboard主题: 公告增加自动轮播 2024-06-14 01:43:55 +08:00
xboard 6cc719ebf5 fix: 修复59f40df 导致的订单tg通知失败的问题 2024-06-14 00:05:20 +08:00
xboard 81be6f375b update default.sing-box.json
migrate singbox configuration to v1.9.0
2024-06-10 12:27:13 +08:00
Xboard cd1bd1109c Merge pull request #145 from riolurs/patch-1
feat: Add additional payment information to Telegram notifications.
2024-06-08 21:41:32 +08:00
riolu.rs cd45e55620 详细支付信息 2024-06-08 17:51:38 +08:00
xboard 59f40dfd02 update feature-request---功能请求.md 2024-06-02 22:23:39 +08:00
xboard 8416381fa0 fix: 修复支付完成后的返回URL可能不为来源站点的问题 2024-06-02 22:22:57 +08:00
Xboard 72fb7031e5 Update aapanel安装指南.md 2024-06-02 13:56:57 +08:00
xboard 2c5f610ed0 fix: 修复今日节点实时流量排行超过15个排序变乱的问题 2024-05-31 14:39:16 +08:00
xboard 7246eb6ebc fix: 修复初始化安装时清理缓存报错的问题
修改aapanel 安装文档增加inotify 扩展说明
修改webman.php 自动检测是否安装inotify扩展,如果安装则自动拉取热重载监控
2024-05-29 00:56:00 +08:00
xboard fd52795f49 fix: 修复ss2022订阅下发密码错误的问题 2024-05-24 22:45:27 +08:00
xboard 2b0bf6cbb7 perf: 优化安装体验 2024-05-24 13:06:25 +08:00
xboard 033b8c702a hy2: 不带版本号的客户端默认下发hy2节点 2024-05-23 16:42:57 +08:00
xboard dd78dbde5c feat: workerman 增加热重载 2024-05-23 11:40:52 +08:00
xboard 1cfd077ae7 log: 修改日志导出结果路径提示为绝对路径 2024-05-20 10:22:31 +08:00
xboard 9b729aa79b update docs 2024-05-18 00:23:00 +08:00
xboard ef914283aa to: 追加sing-box下发忘记提交的代码 2024-05-15 01:06:41 +08:00
xboard d1eef94e6b fix: 修复上一个commit导致的shadowrocket的hy2节点订阅下发失败的问题 2024-05-15 01:05:27 +08:00
xboard 5a0e59b103 feat: 增加surge的hy2下发、添加clash meta、shadowrocket、stash订阅hy2端口跳跃的下发 2024-05-14 21:57:36 +08:00
xboard 227f50b9d1 chore: 优化docker环境下的启动速度,增加webman进程自动重启来释放内存 2024-05-14 18:10:15 +08:00
xboard fa6dfc6acb fix: 修复Surge surfboard订阅中的剩余流量显示错误的问题 2024-05-03 15:04:23 +08:00
xboard 365994b1af update docs 2024-05-03 03:36:29 +08:00
xboard 201f230e80 chore: 修复docker 环境当中,因为缺少patch导致打patch失败的问题 2024-05-03 03:35:47 +08:00
xboard 42d2df07a7 fix: 修复订阅过滤功能在某些情况下报错的问题 2024-04-30 11:02:21 +08:00
xboard f9c12d7bd8 to: 追加上个commit 缺少提交的文件 2024-04-27 21:22:45 +08:00
xboard be9ed269fa perf: 优化流量消费相关代码性能,解决流量纪录与已用流量有概率不一致的问题 2024-04-27 17:06:57 +08:00
xboard 4438fee3ca fix:[Xboard主题] 修复重置密码页面不显示邮箱白名单后缀的问题 2024-04-24 22:45:03 +08:00
xboard 2c8b06dc7b fix:[Xboard主题]修复重构导致的注册邮箱白名单不显示的问题 2024-04-21 20:09:14 +08:00
xboard ce31a604b2 update docs 2024-04-21 02:17:19 +08:00
xboard cbd7c91d26 [Xboard主题]: 当订阅停售且用户续费订阅时跳转到订阅列表页 2024-04-21 01:51:05 +08:00
xboard 285b240dec refactor:[Xboard主题] 重构登陆、注册、忘记密码页面
修复用户注册时第二次提交recaptcha不弹出的问题
修改Info弹窗颜色为主题色
2024-04-21 01:39:53 +08:00
xboard a0aa6d25d4 update docs 2024-04-20 20:27:45 +08:00
xboard 09fb03a1ce fix: 修复当 server_token 为长数字时,后台会转化成科学计数法,后端验证失败 2024-04-18 01:27:52 +08:00
xboard f72df9df27 chore: 优化docker 容器启动速度 2024-04-15 03:19:48 +08:00
xboard 5659bd96f2 docs: 增加1panel部署文档 2024-04-15 02:41:03 +08:00
xboard 2eb81924e4 fix: 修复节点密钥包含特殊字符时校验失败的问题 2024-04-15 00:01:14 +08:00
xboard 0c2360972b chore: 在 Docker 启动时自动修改项目目录权限 2024-04-13 04:10:47 +08:00
xboard 93200ac057 fix: 修复无法读取未携带Content-Type的请求头的节点后端上报的数据的问题 2024-04-13 03:23:30 +08:00
xboard c2b08c2627 fix: 修复更新后导致节点后端交互api不可用的问题 2024-04-12 17:34:06 +08:00
xboard 7eb8d76c87 chore: 修复docker环境该用非root运行时全挂载和sqlite部署报错并减少layers 2024-04-12 16:37:21 +08:00
xboard 03706c054d chore: docker环境修改php为非root运行 2024-04-11 20:37:46 +08:00
xboard 39b4218349 fix: 修复安装Command 2024-04-10 19:09:16 +08:00
xboard 4c6c7182e2 refactor: 重构规范部分代码、邮件队列增加失败重试、去除多个支付方式、更新依赖 2024-04-10 00:51:03 +08:00
Xboard ec63e05575 Update webman.php 2024-04-09 22:52:10 +08:00
xboard bb708d6084 chore: 增加通过环境变量WEBMAN_WORKERS修改Webman的worker数的功能 2024-04-07 22:23:34 +08:00
xboard 2ee630e94c fix: 修复早期安装用户更新后访问首页会报theme_color不存在的问题 2024-04-05 06:51:59 +08:00
xboard aeb39e1476 fix: 修复Xboard切换主题色不生效的问题 2024-04-04 18:04:21 +08:00
xboard 723173426b fix:[Xboard主题] 修复支付手续费部分情况下计算与实际不符的问题与支付图标布局的问题 2024-04-04 17:01:47 +08:00
xboard 44567e552a chore: docker构造环境增加bcmath扩展 2024-04-03 11:00:39 +08:00
xboard 1e503f444b fix: 调整支付通道百分比手续费可为0 2024-04-03 10:33:40 +08:00
xboard a7709d06d1 feat: 更改v2_payment表icon字段为text类型,增加图标对base64输入的支持 2024-04-03 07:29:24 +08:00
xboard d1470bb19d fix:[Xboard主题] 进行了各种改进和修复
1、去除未使用的图片
2、修改Google验证码reCaptcha地址为www.recaptcha.net
3、修复部分页面返回最顶部按钮被挡住的问题
4、补全部分缺失的语言包
5、修复部分分辨率下侧边栏菜单切换后不会自动收起的问题
6、修复暗黑模式下登陆注册忘记密码页面为白色背景的问题
7、调整手机端弹窗增加与屏幕边界的间隙
8、当有未完成订单的情况下,增加首页重置流量的弹窗提示
9、修复节点列表在手机端上显示不协调的问题
10、去除工单ID的显示
2024-04-02 14:45:54 +08:00
Xboard 614d771b84 Update docker-publish.yml 2024-03-20 19:41:45 +08:00
xboard dd6388ca03 update: docker-publish.yml 2024-03-20 19:29:16 +08:00
xboard 6c10f8dcb2 docs: update docs 2024-03-20 18:47:28 +08:00
xboard 00ea1b898a fix:【Xboard主题】修复语言包与路由跳转相关的问题
修复token2Login在已登陆情况下无法跳转参数指定路由的问题
    修复登陆成功后无法跳转指定页面的问题
    修复前端语言与后台返回语言不通不的问题
    调整邀请码列表样式(增加边框)
2024-03-20 02:24:42 +08:00
xboard 120a54279f docs: update docs 2024-03-13 05:23:35 +08:00
xboard 9241369cbb chore: docker添加ipv6的监听 2024-03-09 05:56:58 +08:00
xboard 9455d9ed56 feat: [Xboard主题]增加token2Login 2024-03-07 23:39:26 +08:00
xboard d63dc106b3 fix:[Xboard主题] 修复当支付金额为0时固定手续费显示不为0的问题、修复谷歌人机认证无效的问题 2024-03-07 04:36:42 +08:00
xboard d69517b11e docs: update docs 2024-02-28 18:34:27 +08:00
xboard 53efe20a86 fix: 修复shadowrocket grpc协议sni下发错误的问题 2024-01-24 20:26:58 +08:00
xboard 2e08328ec1 update README.md 2024-01-22 08:44:59 +08:00
xboard d0aa8b47af docs: 删除多余的readme.md 2024-01-22 08:40:53 +08:00
Xboard 40726f1405 Merge pull request #58 from rebecca554owen/dev
delete apanel docs
2024-01-18 23:36:12 +08:00
rebecca554owen a51da2059b Update README.md 2024-01-18 21:19:05 +08:00
rebecca554owen eee367c5a0 Delete docs 2024-01-18 21:18:28 +08:00
xboard 9939f2c2e1 fix: 修复vless 使用Tls时sni不下发的问题 2024-01-17 17:54:33 +08:00
xboard 3a4efcc1f8 fix: 修复vless节点使用tls时订阅抱错的问题 2024-01-16 17:02:42 +08:00
xboard f610f45523 perf:[Xboard主题] 一些样式调整
1、个人中心绑定TG按钮增加已经绑定判断、
    2、侧边栏菜单增加自动收起手机端自动切换为抽屉调整邀请页面佣金和邀请码布局
    3、修改订阅列表为左对齐
2024-01-15 05:51:16 +08:00
xboard 68d7d64ea7 fix: 修复一些主题用户获取节点为空的问题,取消节点API未找到节点的日志记录 2024-01-15 04:25:25 +08:00
xboard 8e57bc4e9b fix: 修复一些主题节点状态显示有误的问题 2024-01-13 17:55:28 +08:00
Xboard caa22ae9d2 Merge pull request #55 from ishkong/patch-2
feat: 增加v2rayN自动下发Hysteria2节点
2024-01-13 17:46:30 +08:00
Xboard e67d0f7d87 Merge pull request #52 from ishkong/patch-1
feat: 为v2rayn的订阅添加hysteria2支持
2024-01-13 17:46:08 +08:00
ishkong 0b5baa70f0 Update V2rayN.php 2024-01-13 17:25:11 +08:00
ishkong 9ed3cc5a74 feat: 增加v2rayN自动下发Hysteria2节点 2024-01-13 17:16:22 +08:00
Xboard 03267b2051 Merge pull request #54 from sakurauidev/ResetTraffic
将周期重置流量只重置已使用流量修改为重置已使用流量的同时重置当总流量为当前订阅所设置的流量
2024-01-13 12:11:14 +08:00
ventle233 3611ed6c88 将重置流量只重置已使用流量修改为重置已使用流量的同时重置当总流量为当前订阅所设置的流量 2024-01-13 02:10:15 +08:00
xboard 07b3a8dfd8 fix: [Xboard主题] 修改谷歌recaptcha为中国可以访问地址,解决中国用户无法打开进行人机认证的问题 2024-01-12 21:16:42 +08:00
ishkong 0000c071e7 为v2rayn的订阅添加hysteria2支持 2024-01-11 22:15:43 +08:00
xboard aa63664892 docs: update aapanel安装指南.md 2024-01-11 21:47:38 +08:00
xboard 3f65ad6ae6 to: 增加支付回调错误日志记录 2024-01-11 01:16:10 +08:00
xboard 31b8930222 style: 去除v2board 字段css 改为xborad 尝试解决被墙问题 2024-01-11 00:22:29 +08:00
xboard ec18ca0ee1 fix: [用户前端]修复更改订阅提示框显示条件有误的问题 2024-01-11 00:11:54 +08:00
xboard 3273274369 fix: 修复升级后不选择主题色会导致500错误的问题 2024-01-10 20:00:13 +08:00
xboard 95675de30b feat: [用户前端] 修复部分BUG、增加主题色、增加注册用户协议显示等 2024-01-10 18:59:59 +08:00
xboard 11591b9708 chore: nginx增加html文件访问支持 2024-01-06 14:54:39 +08:00
xboard ca1758dc48 feat: 增加Command (php artisan log:export)导出日志命令 2024-01-01 04:52:49 +08:00
xboard 59c21a9c8d feat: 增加邮件Mailgun支持 2024-01-01 04:40:23 +08:00
xboard cdc86bbe47 fix: 修复邮箱配置无法从环境变量读取的问题 2024-01-01 01:06:07 +08:00
Xboard 2c963d9a7d Merge pull request #35 from rebecca554owen/dev
v2baord迁移教程有误,重新修改。
2023-12-24 21:28:58 +08:00
rebecca554owen b8d9221d9b Update 从aapanel迁移到1panel教程.md 2023-12-19 23:18:20 +08:00
rebecca554owen 50c80614d1 Update 从aapanel迁移到1panel教程.md 2023-12-19 23:17:17 +08:00
rebecca554owen 1ae1767063 Update 从aapanel迁移到1panel教程.md 2023-12-19 23:03:54 +08:00
xboard 41643a729a perf: 优化初始化安装流程,增加mysql和Redis配置校验 2023-12-18 17:42:59 +08:00
xboard 9dcb9cee32 feat: 增加Vmess tcp http下发支持 2023-12-18 09:40:35 +08:00
xboard 0ef19e91bb fix:[用户前端] 修复扫描二维码订阅地址错误的问题 2023-12-17 21:56:05 +08:00
Xboard 0b58ac5779 Merge pull request #30 from rebecca554owen/dev
更新1paenl教程,删除多开教程,更新docker生成,方便fork分支用户自行修改以及测试。
2023-12-16 20:10:00 +08:00
rebecca554owen c5f23fbd12 多开Xboard教程存在Redis共用处理问题,先删除。 2023-12-16 18:09:19 +08:00
rebecca554owen 5e9707cf1a 更新教程适用于新安装,v2board/xboard用户迁移。 2023-12-16 18:08:33 +08:00
rebecca554owen 9f1f041494 修改生成镜像为仓库拥有者。 2023-12-16 18:07:32 +08:00
xboard 44eb05fb5b fix: 修复v2ray、Trojan旧版接口获取用户列表失败的问题 2023-12-16 08:05:09 +08:00
xboard 92532333cb fix: 修复节点状态列表接口报错的问题 2023-12-15 22:46:09 +08:00
xboard b934128449 fix: 修复Xboard主题扫描二维码不显示节点类型的问题 2023-12-14 22:29:37 +08:00
xboard 7bac88d593 fix: 修复多处可能出现的事务安全问题 2023-12-14 13:07:57 +08:00
xboard b8009142ed perf: 优化数据库备份Command逻辑 2023-12-13 09:28:01 +08:00
xboard f812e5f239 fix: 修复创建工单中的事务安全 2023-12-13 03:00:43 +08:00
xboard e16618142a feat: 增加Loon自动下发Hysteria2节点 2023-12-13 00:08:39 +08:00
xboard 145d3580a0 fix:[用户前端] 修复markdown-body类中暗黑模式不生效的问题 2023-12-12 22:18:24 +08:00
xboard 83957db37f perf: 优化节点后端获取用户用户列表接口响应速度,降低CPU使用资源 2023-12-12 21:49:16 +08:00
xboard 6d575649cf fix: 修复1.8 版本sing-box订阅失败的问题 2023-12-12 09:25:58 +08:00
xboard 4c6096224d feat: [用户前端]增加crisp识别用户email、套餐详情支持 2023-12-12 08:25:26 +08:00
xboard 1270a60ad8 refactor: 规范工单接口代码规范 2023-12-12 06:22:18 +08:00
xboard 20466d07df feat: filter支持匹配节点标签 2023-12-10 18:09:58 +08:00
xboard e04d82961f refactor: 规范部分API接口响应格式 2023-12-10 17:53:31 +08:00
xboard 7bca6e1953 fix: [用户前端]修复工单聊天窗口没有自动将聊天记录拉到最下面的问题、修复续费订阅会显示弹窗的 问题、补充部分i18n语言包 2023-12-10 17:27:28 +08:00
xboard 26593eda27 fix: 修复安装Command不清除缓存的问题 2023-12-10 11:51:56 +08:00
xboard d91e973639 perf:[用户前端] 补全i18n、优化登录注册交互逻辑、修复佣金提现对话框取消按钮无效的问题 2023-12-09 10:41:50 +08:00
xboard b060ab6315 feat: 个人中心页面增加绑定机器人、立即进入群聊卡片 2023-12-08 23:00:23 +08:00
xboard 16f84216f5 docs: update aapanel+docker安装指南.md 2023-12-08 20:33:10 +08:00
xboard c85ca31718 feat: 增加订阅地址支持[*-*]表达式 2023-12-08 20:16:24 +08:00
xboard 9192d5c11f docs: 修复错别字 2023-12-08 16:04:11 +08:00
xboard aa0af37e91 to: 工单增强消息调整 2023-12-08 15:51:29 +08:00
xboard ca63cbf801 feat: 工单Bot增强 2023-12-08 15:43:17 +08:00
xboard 08bafe09a7 update: composer.json 2023-12-08 10:11:37 +08:00
xboard b3b04cfc54 perf: 优化初始化安装流程 2023-12-08 08:53:19 +08:00
xboard 08c8f46eb3 update: composer.json 2023-12-07 23:12:32 +08:00
xboard b0a504a44c fix: telegram机器人setwebhook接口url设置为站点网址,防止一些反向代理配置导致绑定机器人失败的问题 2023-12-07 23:12:05 +08:00
xboard fe5e448dfb perf:[用户前端] 优化一键订阅列表 2023-12-07 21:46:11 +08:00
xboard 5b9b93ffe0 fix: [用户前端]修复ipad会被识别为mac的问题 2023-12-07 20:44:51 +08:00
xboard 0db0ea3a6b fix: 修复邀请信息获取接口返回数据格式错误的问题 2023-12-07 09:52:23 +08:00
xboard 385404dcf7 feat:[用户前端]添加订单二维码结账方式的支持、知识库增加copy和jump两个事件的支持 2023-12-07 06:09:41 +08:00
xboard fc329c6428 fix: 修复创建Hy节点时obfs默认关闭却不提交到后端的问题、优化Vless Reality节点创建字段提示 2023-12-07 04:45:39 +08:00
xboard 546f11bdae fix: 修复后台发送测试邮件返回状态不正确的问题 2023-12-07 04:19:30 +08:00
xboard 189b247ad8 refactor: 规范状态码、抛出异常的使用 2023-12-07 04:01:32 +08:00
xboard c25803aa74 Log: 给流量消费队列当中保存失败的用户增加错误日志 2023-12-06 19:11:29 +08:00
xboard 1fcb6fa911 fix: 规范数据库事物的使用,解决在swoole环境下可能会出现事物一直不被提交的问题 2023-12-06 19:00:26 +08:00
xboard 64cc2d79da fix: 优化流量消费队列,防止记录长时间被锁住 2023-12-04 23:16:18 +08:00
xboard 66ab4a4a8e fix: 修复潮汐app Trojan协议的问题 2023-12-04 22:52:11 +08:00
xboard e4a80ce9b5 fix:[用户前端] 修复订阅详情为数字时的异常渲染 2023-12-04 20:42:34 +08:00
xboard 0ab7dee52d refactor: 规范Expection处理 2023-12-04 20:40:49 +08:00
xboard aa0fe64afe 在 Docker 环境中读取 INSTALL 环境变量判断是否已经安装 2023-12-04 20:30:38 +08:00
xboard 4a6339c9db fix: 修复hiddify无法自动下发hy2节点的问题 2023-12-03 22:17:33 +08:00
xboard 8d4846329e fix: 修复SingBox下发带混淆的hysteria失败的问题 2023-12-03 19:21:05 +08:00
xboard 2a768b6fc8 feat: [用户前端]订阅介绍支持潮汐客户端的写法 2023-12-03 18:37:32 +08:00
xboard bf3930d29f fix: 修复tg机器人无法回复工单的问题 2023-12-03 09:43:38 +08:00
xboard ea6cd5eca1 style:[用户前端] Markdown使用github样式预设 2023-12-03 07:16:53 +08:00
xboard e1f6cd70df fix:[用户前端] 修复订阅介绍为空时订阅不显示的问题,修复公告中图片宽度会超出边界的问题 2023-12-03 00:19:19 +08:00
xboard 4ec52b7033 feat:[用户前端] 提高复制功能兼容性、订阅描述增加md支持、增加使用文档预设样式 2023-12-02 22:04:48 +08:00
xboard 1d66023bd1 refactor: CORS中间件改用\Illuminate\Http\Middleware\HandleCors 2023-12-01 00:36:09 +08:00
xboard e35f81f2c8 debug:[用户前端]删除测试代码 2023-12-01 00:23:58 +08:00
xboard 6a825dca7d style:[用户前端] 将一键订阅的软件图标内联到网页当中,加快图标的加载速度 2023-12-01 00:18:39 +08:00
xboard 849b887201 fix:[用户前端] 修复前端显示三级分销比率错误的问题 2023-11-29 04:50:53 +08:00
xboard 7a2f4c1d56 fix:[用户前端] 修复个人中心流量邮件提醒关闭无效的问题 2023-11-28 23:17:04 +08:00
xboard 4aa19ebae9 fix:[用户前端] 修复手机端菜单栏被数据表格覆盖的问题 2023-11-28 21:57:27 +08:00
xboard f31b194a53 i18n:[用户前端] 更新语言包 2023-11-28 21:39:16 +08:00
xboard 177eefc447 feat:[用户前端] 增加提现推广用户按钮,修正三级分销当中佣金比例显示问题 2023-11-28 21:31:32 +08:00
xboard f1f1ed4040 fix:[用户前端] 修复长期套餐用户不显示重置已用流量按钮的问题,补全 重置按钮语言包 2023-11-28 20:29:56 +08:00
xboard dcb57c6c37 style:[用户前端] 增加首页增加重置流量按钮、知识库增加img、video标签最大宽度的为100%的限制、首页增加流量告急警告、修改手机端菜单栏关闭样式 2023-11-28 19:28:20 +08:00
xboard aa59624208 fix: [用户前端]修复google reCaptcha 超时导致错误的问题、补全部分语言包 2023-11-27 16:19:48 +08:00
xboard 4eadd201e5 feat:[用户前端] 增加多语言支持,修复菜单栏存在的BUG, 启用静态gzip以节省CPU资源 2023-11-27 00:23:25 +08:00
xboard 8793e82f69 docs: 增加修改代码需要重启的注意事项 2023-11-26 11:56:44 +08:00
xboard b7d28cb36f chore: 增加docker-compose 模版的自动启动的配置 2023-11-26 11:50:56 +08:00
xboard 25317d5f64 to: 添加前端静态资源请求版本号,防止更新导致的缓存 2023-11-25 10:24:14 +08:00
xboard e086456777 chore: 修改Docker环境安装过程中默认的数据库地址为127.0.0.1 2023-11-24 17:03:48 +08:00
xboard 7dc8a0ac6b style:[用户前端] 订阅列表修改为点击可片即可进入订阅详情 2023-11-24 13:40:26 +08:00
xboard 8fb63c94d3 fix:[用户前端] 修复注册页面选择邮箱后缀在手机端被缩略的问题 2023-11-24 11:53:35 +08:00
xboard 8f2662b254 chore: Docker镜像增加git软件包、修正aapanel+ docker 更新步骤 2023-11-24 11:24:15 +08:00
xboard 89745e1214 docs: update docker-compose安装指南 2023-11-24 10:50:29 +08:00
xboard 18c08b6aa3 fix:[用户前端] 修复确认中的永久与累计获得的佣金显示单位不正确的问题 2023-11-24 09:29:37 +08:00
xboard 4d30a8ade5 feat: 新增hiddify自动下发hy2 2023-11-24 00:02:33 +08:00
xboard d776ca32c5 fix: 修复用户订阅到期提醒、流量告急提醒的默认设置修改无效的问题 2023-11-23 23:59:08 +08:00
xboard 6aadeb5b84 fix: 修复迁移配置文件时配置为数组时的错误 2023-11-23 18:35:18 +08:00
xboard d832015136 feat: 增加用户流量告急提醒和订阅到期提醒的默认设置 2023-11-23 18:31:15 +08:00
xboard 1fb43f2cda fix: 修复admin_setting可能出现的问题 2023-11-23 18:02:50 +08:00
xboard 265842e7bf fix: 修复自动备份command 的问题,增加备份后自动压缩为.gz节省空间 2023-11-23 17:55:58 +08:00
xboard 0303a74a33 feat: 添加cmfa、nekoray、verge、clashx meta 自动下发Hy2 2023-11-23 15:11:22 +08:00
xboard adc56ddd82 docs: update aapanel+docker安装指南.md 2023-11-23 14:05:38 +08:00
xboard d63aec2b3c feat: 增加 新增、修改Vless、Hysteria节点表单的字段的必填提示 2023-11-23 13:37:41 +08:00
xboard 6c2cb47bf8 refactor: 优化安装命令的代码 2023-11-23 13:32:39 +08:00
xboard 653884e7b3 chore: 增加docker-compose.sample.yaml 模版 2023-11-23 13:29:30 +08:00
xboard 095e5131e8 chore: 删除docker-compose.yaml 增加docker-compose.yaml模版 2023-11-23 13:28:38 +08:00
xboard 4d0da8c4d2 update readme.md 2023-11-23 11:49:50 +08:00
xboard 7797bd2a9b docs: 补充迁移文档中缺少的步骤 2023-11-23 11:48:21 +08:00
xboard e9664e294b Merge branch 'dev' of github.com:cedar2025/v2board into dev 2023-11-23 11:13:28 +08:00
xboard 5ab84eb233 docs: 修正aapanel安装指南中的错误 2023-11-23 11:12:33 +08:00
xboard 5af382dbc5 style:[用户前端] 取消头像显示 2023-11-23 00:13:18 +08:00
xboard 8cdaf4b9ed docs: update aapanel+docker安装指南.md 2023-11-23 00:12:48 +08:00
Xboard 10fd966959 Merge pull request #7 from rebecca554owen/patch-1
修改单词拼写错误。
2023-11-22 23:25:27 +08:00
xboard 638dbef30a fix: 修复知识库 access start 在webman中重新定义的问题 2023-11-22 21:33:19 +08:00
rebecca554owen d090d03da0 Update 从aapanel迁移到1panel教程.md 2023-11-22 19:38:56 +08:00
Xboard 1b8ca0baae Merge pull request #6 from rebecca554owen/dev
内置Redis后修改教程。
2023-11-22 19:35:03 +08:00
rebecca554owen 2ae815385b Update 从aapanel迁移到1panel教程.md 2023-11-22 19:33:01 +08:00
rebecca554owen aa3a1bebc8 Update 多开Xboard教程.md 2023-11-22 19:32:26 +08:00
rebecca554owen bb7b9ee591 Merge branch 'cedar2025:dev' into dev 2023-11-22 19:31:45 +08:00
rebecca554owen 34d33aae8e Update 从aapanel迁移到1panel教程.md 2023-11-22 18:58:26 +08:00
xboard 4c1c024afa docs: 修正aapanel安装指南当中配置php.ini的命令 2023-11-22 18:52:58 +08:00
rebecca554owen 110eccd9e4 Update 从aapanel迁移到1panel教程.md 2023-11-22 18:48:01 +08:00
rebecca554owen 72ca2d4564 Update 从aapanel迁移到1panel教程.md 2023-11-22 18:42:52 +08:00
Xboard 1633764419 Update aapanel安装指南.md 2023-11-22 18:33:37 +08:00
xboard 933572648c to: 增加迁移迁移配置文件前清除缓存 2023-11-22 18:32:29 +08:00
xboard ed3e40790e docs: 更新文档,增加迁移迁移配置文件前清除缓存 2023-11-22 18:26:19 +08:00
Xboard 57b3f14de6 Update 从aapanel迁移到1panel教程.md 2023-11-22 18:16:47 +08:00
xboard db9f48ade0 docs: 补充aapanel + docker部署教程 2023-11-22 15:52:07 +08:00
xboard 65ca30a920 fix: 安装步骤当中修复错误的redis unix地址 2023-11-22 14:36:23 +08:00
Xboard 76bf2e3a53 Merge pull request #5 from rebecca554owen/dev
修正教程错误
2023-11-22 14:13:11 +08:00
xboard d1b48623d7 docs: 优化部署、迁移文档、docker增加redis支持
1、优化部署、迁移
2、自动备份命令增加手动备份功能
3、docker部署集成redis
2023-11-22 14:01:58 +08:00
rebecca554owen 2dc35a21da 多开Xboard建多个站点
多开Redis容器以便于多开Xboard容器
2023-11-22 13:37:33 +08:00
rebecca554owen 633226fddc Update 从aapanel迁移到1panel教程.md 2023-11-22 13:09:33 +08:00
rebecca554owen c1a8a283f3 Add files via upload 2023-11-22 13:05:07 +08:00
xboard 57a1d0ba48 style:[用户前端] 修复公告背景图显示不正常的问题 2023-11-22 07:50:12 +08:00
xboard 983ec8fcf3 style: 修改后台Hysteri节点颜色为蓝色 2023-11-21 19:25:30 +08:00
xboard 76cf93a2c9 chore: docker 环境增加json、ico文件访问支持 2023-11-21 19:15:32 +08:00
xboard 14c88f23ff style:[用户前端] 知识库添加Markdown支持 2023-11-21 16:59:55 +08:00
xboard 8db622eee4 perf: 优化用户流量消费队列(上万用户流量信息数秒即可处理完成 2023-11-21 15:59:06 +08:00
xboard 9d2da393d7 style:[用户前端] 修复手机浏览器登录、注册、找回密码 点显示密码按钮无反应 2023-11-21 08:09:35 +08:00
xboard 1e68b02ed9 style:[用户前端] 修复登录、注册、找回密码页面LOGO不居中的问题 2023-11-21 07:58:21 +08:00
xboard ddf5f8bd9d style:[用户前端] 修复注册、登录、找回密码界面LOGO过大溢出的问题 2023-11-21 07:53:57 +08:00
xboard aa29b37144 fix: [用户前端]修复仪表盘页公告不显示背景的问题 2023-11-20 22:38:23 +08:00
xboard 699785f995 style: [用户界面]手机端增加侧边栏关闭按钮 2023-11-20 22:04:35 +08:00
xboard f5ddd08ebf style: [用户前端]公告支持Markdown渲染的同时增加HTML渲染,优化登录、注册、找回密码页面显示效果 2023-11-20 20:54:43 +08:00
xboard f5ae16866d docs:增加laravels测试数据 2023-11-20 18:37:44 +08:00
xboard 82b6bce847 docs: 增加性能测试、页面展示 2023-11-20 18:06:42 +08:00
Xboard a8a627c918 Update readme.md 2023-11-20 14:01:47 +08:00
xboard d1b3b739d3 fix: 修复mysql5.7和sqlite环境下无法上报流量的问题 2023-11-20 13:53:11 +08:00
xboard ca1ee9fc2b docs: update readme 2023-11-20 12:40:42 +08:00
xboard 6ea3adbd55 docs: 更新迁移引导 2023-11-20 11:56:38 +08:00
xboard ae8cfa40be feat: php artisan reset:password重置密码增加可自定义密码 2023-11-20 09:38:14 +08:00
xboard bc80d7e91c refactor: 规范MysqlLogger代码 2023-11-20 09:37:22 +08:00
xboard 907ccebfdf style(clahs): 恢复默认原版clash模版 2023-11-20 09:36:21 +08:00
xboard 79b94168ba style: 公告修改为markdown格式显示 2023-11-19 22:07:10 +08:00
xboard 6b920a59f3 fix: [用户前端]修复查看教程不动态显示站点名称 2023-11-19 21:37:55 +08:00
xboard 4a66919e5c fix: 修复sqlite执行数据库字段修改迁移出错的问题 2023-11-19 21:04:52 +08:00
xboard 2dd0dfac87 fix: 修改v2_setting的value为text类型,防止过长的配置抱错 2023-11-19 20:51:52 +08:00
xboard aab33be34a style: [用户前端]优化手机端体验 2023-11-19 20:42:39 +08:00
xboard 4346720855 fix: [用户前端]修复主页订阅过期用户点击续费订阅无效的问题 2023-11-19 15:27:03 +08:00
xboard 7392165189 docs: 修改文档目录 2023-11-19 15:18:32 +08:00
xboard 6773c87d8e feat: [用户前端]补全可选订阅类型 2023-11-19 14:15:52 +08:00
xboard 4353fe1bee fix: 修复使用邀请链接注册不会自动填写邀请码的问题、修复webman环境下节点不可排序的问题 2023-11-19 12:48:37 +08:00
xboard e0eac8f703 feat: 兼容V2bx 的Hysteria2 2023-11-19 09:54:40 +08:00
xboard b489f8f6f1 fix: 修复soga后端、Tidalab、等一些后端对接获取配置失败的问题
修复添加了服务后端中间件统一鉴权导致了一些后端鉴权不通过的问题
2023-11-19 04:03:09 +08:00
xboard cc1dc14c84 feat: 添加·定时自动备份并上传到谷歌云存储·的功能 2023-11-18 19:54:16 +08:00
xboard aa9ec41921 feat: 增加Xboard主题自定义页脚HTML支持 2023-11-18 16:58:01 +08:00
xboard 519841c323 fix: 修复Vless Grpc ws不可用的问题 2023-11-18 15:31:10 +08:00
xboard cdc766c72b update: updata.sh 2023-11-18 14:44:44 +08:00
xboard 4ab3eb9ce8 fix: [用户前端]修复订单折扣金额不计算的问题 2023-11-18 12:26:34 +08:00
xboard 56485f01b2 fix: [用户前端]修复开启邮箱后缀白名单后用户注册的问题 2023-11-18 10:59:19 +08:00
xboard 2125f32e53 fix: 去除默认clash订阅中的 quic协议的dns防止clash客户端不可用 2023-11-18 09:56:33 +08:00
xboard a02881fcaf to: 添加alive空接口 2023-11-18 09:10:55 +08:00
xboard b5fae8f571 style: [用户前端]优化流量明细页面显示效果,docker环境支持wasm文件支持 2023-11-18 03:29:46 +08:00
xboard e8e5a9b955 fix: [用户前端] 流量明细记录时间精度修改为天 2023-11-17 16:37:09 +08:00
xboard b5ec7459a6 fix: 修复vless的 ws、grpc订阅问题 2023-11-17 16:34:16 +08:00
xboard aa57264d53 fix: [用户前端]修复暗黑模式下的登录页面背景颜色显示问题 2023-11-17 15:37:04 +08:00
xboard f6ac12ee65 fix: 修复meta 的vless grpc订阅下发错误 2023-11-17 15:11:52 +08:00
xboard 65fe7682ff Initial commit 2023-11-17 14:44:01 +08:00
846 changed files with 113432 additions and 62 deletions
+282
View File
@@ -0,0 +1,282 @@
# Xboard 管理端前端 - 基础登录功能实施计划
## 任务类型
- [x] 前端 (Vue3 + TypeScript + Vite + Element Plus)
- [ ] 后端 (无需改动,复用现有 API)
- [ ] 全栈
## 需求概述
为 Xboard 创建独立的管理端前端项目,技术栈:Vue3 + TypeScript + Vite + Element Plus。第一阶段实现基础登录功能,包括:
- 管理员登录页面(邮箱 + 密码)
- Token 认证与路由守卫
- 登录后 Dashboard 占位页
- 基础布局框架(侧边栏 + 顶栏)
## 技术方案
### 后端 API 契约(已存在,无需改动)
| 接口 | 方法 | URL | 说明 |
|------|------|-----|------|
| 登录 | POST | `/api/v2/passport/auth/login` | `{email, password}``{auth_data, is_admin, token}` |
| 管理接口前缀 | - | `/api/v2/{secure_path}/...` | secure_path 从后端 admin_setting 获取 |
| 系统状态探针 | GET | `/api/v2/{secure_path}/system/getSystemStatus` | 登录后验证 admin 权限 |
**关键发现:**
- 登录接口是通用用户接口,`is_admin` 在响应中标识管理员身份
- `auth_data`(格式 `Bearer xxx`)是鉴权凭证,`token` 是邀请码字段,不可用作认证
- Admin 中间件使用 Sanctum guard,通过 `Authorization` header 传递 Bearer token
- `secure_path` 是动态的,首期从 Laravel 的 `window.settings.secure_path` 获取
### 部署策略:独立源码 + Laravel 托管 dist
首期将 Vue3 项目构建产物放到 Laravel 的 `public/` 目录下,由 Laravel 的 `admin.blade.php` 通过 `window.settings` 注入运行时配置。这样 `secure_path` 自举最简单,无需跨域。
### 前端分析交叉验证(Codex 后端视角 + 前端 UI/UX 视角)
**一致观点(强信号):**
- 方案 A(独立源码 + Laravel 托管 dist)是最务实的首期路线
- `secure_path` 从运行时配置获取,不在前端推导
- 登录后必须校验 `is_admin`
**前端分析补充建议(已纳入计划):**
1. **工程化优化**:使用 `unplugin-auto-import` + `unplugin-vue-components` 实现 Element Plus 按需引入,优化包体积
2. **暗色/亮色主题切换**Element Plus 原生支持 dark mode,首期预留切换能力
3. **前端登录频率限制提示**:在登录表单增加防抖,429 时显示倒计时提示
4. **Token 过期自动重定向**:Axios 拦截器中 401 响应自动清除 token 并跳转登录页
5. **动态路径策略**`VITE_ADMIN_PATH` 环境变量作为 `secure_path` 的默认值,同时支持从 `window.settings.secure_path` 动态覆盖
### 项目结构
```
admin-frontend/ # 独立前端项目根目录
├── index.html
├── package.json
├── tsconfig.json
├── tsconfig.node.json
├── vite.config.ts
├── env.d.ts
├── .env
├── .env.development
├── .env.production
├── public/
│ └── favicon.ico
└── src/
├── main.ts # 应用入口
├── App.vue # 根组件
├── api/
│ ├── client.ts # Axios 实例与拦截器
│ ├── passport.ts # 登录相关 API
│ └── admin.ts # 管理端 API(带 secure_path
├── stores/
│ ├── auth.ts # 认证状态(Pinia
│ └── app.ts # 应用运行时配置
├── router/
│ ├── index.ts # 路由定义
│ └── guards.ts # 路由守卫
├── layouts/
│ └── AdminLayout.vue # 管理端主布局
├── views/
│ ├── login/
│ │ └── LoginView.vue # 登录页
│ └── dashboard/
│ └── DashboardView.vue # 仪表盘占位页
├── types/
│ ├── api.d.ts # API 响应类型
│ └── env.d.ts # 环境变量类型
├── utils/
│ ├── token.ts # Token 存储工具
│ └── runtime.ts # 运行时配置解析
└── styles/
└── index.scss # 全局样式
```
## 实施步骤
### Step 1: 初始化项目骨架
**预期产物:** 可运行的空 Vue3 + TS 项目
- 使用 `npm create vite@latest admin-frontend -- --template vue-ts` 创建项目
- 安装依赖:`element-plus`, `pinia`, `vue-router`, `axios`, `sass`, `@element-plus/icons-vue`
- 安装开发依赖:`unplugin-auto-import`, `unplugin-vue-components`Element Plus 按需引入)
- 配置 `vite.config.ts`(代理、别名、构建输出路径、AutoImport 插件)
- 配置 `tsconfig.json` 路径别名
- 创建 `.env.development``.env.production`
**Vite 配置要点:**
```typescript
// vite.config.ts
export default defineConfig({
base: '/assets/admin/',
resolve: { alias: { '@': '/src' } },
plugins: [
vue(),
AutoImport({ resolvers: [ElementPlusResolver()] }),
Components({ resolvers: [ElementPlusResolver()] }),
],
server: {
port: 5173,
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
}
}
},
build: {
outDir: '../public/assets/admin',
emptyOutDir: true,
}
})
```
**环境变量:**
```
# .env.development
VITE_API_BASE_URL=/api/v2
VITE_SECURE_PATH= # 开发时留空,由 proxy 转发
# .env.production
VITE_API_BASE_URL=/api/v2
# production 下 secure_path 从 window.settings 获取
```
### Step 2: 基础设施层
**预期产物:** API client、Token 工具、运行时配置、类型定义
- **`src/types/api.d.ts`** - API 响应泛型、登录接口类型
- **`src/utils/token.ts`** - Token 存取(sessionStorage 为默认,可选 localStorage 记住登录)
- **`src/utils/runtime.ts`** - 解析 `window.settings` 和环境变量,提供 `getSecurePath()``getApiBaseUrl()`
- `secure_path` 优先级:`window.settings.secure_path` > `VITE_ADMIN_PATH` 环境变量 > 启动报错
- **`src/api/client.ts`** - 两个 Axios 实例:
- `passportClient`:固定前缀 `/api/v2/passport`
- `adminClient`:运行时拼接 `/api/v2/{secure_path}`
- 统一响应拦截:错误归一化、401/403 自动清除 token 跳登录
- **`src/api/passport.ts`** - `login(email, password)` 函数
- **`src/api/admin.ts`** - `getSystemStatus()` 探针函数
### Step 3: 状态管理
**预期产物:** Pinia stores
- **`src/stores/auth.ts`**
- state: `authHeader`, `isAdmin`, `isLoading`
- actions: `login()`, `logout()`, `validateAdmin()`, `initFromStorage()`
- 登录流程:调用 API → 校验 `is_admin` → 保存 `authHeader` → admin 探针验证
- 非 admin 用户登录后直接拒绝并提示"无管理员权限"
- **`src/stores/app.ts`**
- state: `securePath`, `apiBaseUrl`, `sidebarCollapsed`
- actions: `initConfig()` 从 runtime 解析配置
### Step 4: 路由与守卫
**预期产物:** 路由配置 + 权限守卫
- **`src/router/index.ts`**
- 使用 `createWebHashHistory()`(因为 Laravel 无 catch-all 路由,hash 模式避免刷新 404)
- 路由表:
```
/login → LoginView (公开)
/ → AdminLayout (需认证)
/dashboard → DashboardView (需认证)
```
- **`src/router/guards.ts`**
- `beforeEach`:无 token → `/login`;有 token 但未验证 → 执行 admin 探针 → 失败清 token 回 `/login`
- 已登录用户访问 `/login` → 重定向 `/dashboard`
### Step 5: 登录页面
**预期产物:** 功能完整的登录页
- **`src/views/login/LoginView.vue`**
- 简约卡片布局,深色渐变背景,居中展示
- Element Plus 组件:`ElForm`, `ElFormItem`, `ElInput`, `ElButton`, `ElMessage`
- 表单字段:
- 邮箱(email 类型,必填,格式校验)
- 密码(password 类型,必填,最少 8 位)
- 记住登录(可选 checkbox,控制 token 存 localStorage vs sessionStorage
- 提交时 loading 状态,按钮禁用 + 防抖(防止重复提交)
- 错误处理:
- 400:邮箱或密码错误 → 表单级错误提示
- 429:密码错误次数过多 → 显示倒计时提示(从响应 message 解析剩余分钟数)
- 403/无权限:`is_admin=false` → 提示"该账号无管理员权限"
- 网络错误:通用错误提示
- 登录成功后跳转 `/dashboard`
- 支持暗色/亮色主题切换(Element Plus 原生 dark mode
### Step 6: 管理端布局与 Dashboard
**预期产物:** 基础布局框架 + Dashboard 占位页
- **`src/layouts/AdminLayout.vue`**
- Element Plus `ElContainer` + `ElAside` + `ElHeader` + `ElMain`
- 左侧边栏(可折叠):Logo + 菜单项(首期仅 Dashboard
- 顶栏:面包屑 + 右侧用户操作区(登出按钮)
- 响应式:小屏幕自动折叠侧边栏
- **`src/views/dashboard/DashboardView.vue`**
- 占位页面,显示欢迎信息和系统基本信息
- 后续迭代补充统计数据
### Step 7: 样式与全局配置
**预期产物:** 统一视觉风格
- **`src/styles/index.scss`**
- CSS 变量定义主题色
- Element Plus 主题覆盖(主色调、边框、背景)
- 登录页专用样式
- 全局样式重置
### Step 8: 入口文件整合
**预期产物:** 完整可运行的应用
- **`src/main.ts`**
- 注册 Element Plus(通过 AutoImport 按需引入)
- 注册 Pinia
- 注册 Router
- 初始化运行时配置(`appStore.initConfig()`
- 初始化认证状态(`authStore.initFromStorage()`
- 引入 Element Plus 暗色主题 CSS`element-plus/theme-chalk/dark/css-vars.css`
- **`src/App.vue`**`<RouterView />`
## 关键文件清单
| 文件 | 操作 | 说明 |
|------|------|------|
| `admin-frontend/package.json` | 新建 | 项目依赖与脚本 |
| `admin-frontend/vite.config.ts` | 新建 | Vite 构建 + 代理配置 |
| `admin-frontend/src/main.ts` | 新建 | 应用入口 |
| `admin-frontend/src/api/client.ts` | 新建 | Axios 实例 + 拦截器 |
| `admin-frontend/src/api/passport.ts` | 新建 | 登录 API |
| `admin-frontend/src/api/admin.ts` | 新建 | Admin API 封装 |
| `admin-frontend/src/utils/token.ts` | 新建 | Token 存储工具 |
| `admin-frontend/src/utils/runtime.ts` | 新建 | 运行时配置解析 |
| `admin-frontend/src/stores/auth.ts` | 新建 | 认证状态管理 |
| `admin-frontend/src/stores/app.ts` | 新建 | 应用配置管理 |
| `admin-frontend/src/router/index.ts` | 新建 | 路由定义 |
| `admin-frontend/src/router/guards.ts` | 新建 | 路由守卫 |
| `admin-frontend/src/views/login/LoginView.vue` | 新建 | 登录页 |
| `admin-frontend/src/layouts/AdminLayout.vue` | 新建 | 管理端布局 |
| `admin-frontend/src/views/dashboard/DashboardView.vue` | 新建 | 仪表盘占位 |
## 风险与缓解
| 风险 | 缓解措施 |
|------|----------|
| `secure_path` 在独立部署时无法从前端推导 | 首期用 Laravel 托管 dist,从 `window.settings` 获取;中长期可加 bootstrap API |
| 登录接口是用户通用接口,非管理员也能登录 | 登录后立即校验 `is_admin`,非 admin 拒绝进入管理端 |
| `token` 字段含义混淆(实际是邀请码) | 封装层仅暴露 `auth_data` 作为认证凭证,`token` 字段忽略 |
| CORS `supports_credentials=false` | 前端走 Bearer token 无状态认证,不依赖 cookie |
| Hash 路由不够优雅 | 首期务实选择,后续独立域名部署时可切 history 模式 |
| 无专用 admin logout API | 前端清除本地 token 即可(Sanctum token 有 1 年有效期,不影响安全性) |
## SESSION_ID
- CODEX_SESSION: 019dac16-b724-73a2-a3ff-f6b2ac49e2bf
- GEMINI_SESSION: (不可用,调用失败)
+7
View File
@@ -0,0 +1,7 @@
{
"permissions": {
"allow": [
"mcp__contextweaver__codebase-retrieval"
]
}
}
Executable → Regular
View File
+35
View File
@@ -0,0 +1,35 @@
# Xboard protocol fusion entrypoint.
#
# Caddy listens on a single public port and dispatches HTTP traffic to Octane
# while transparently upgrading WebSocket requests to the ws-server worker.
# This lets every external reverse proxy (nginx, Cloudflare, the user's own
# Caddy, ...) treat the panel as a single upstream and avoids exposing the
# 8076 WebSocket port directly.
{
admin off
auto_https off
persist_config off
log {
output stdout
format console
}
servers {
trusted_proxies static 0.0.0.0/0 ::/0
}
}
:{$CADDY_LISTEN_PORT:7001} {
@ws path /ws
reverse_proxy @ws 127.0.0.1:{$WS_PORT:8076}
reverse_proxy 127.0.0.1:{$OCTANE_INTERNAL_PORT:7002} {
header_up Host {host}
# X-Forwarded-For is auto-appended with our remote_addr by Caddy
# (enabled by the global trusted_proxies above), so Octane receives the
# full proxy chain and Laravel's TrustProxies middleware resolves the
# real client IP using its own trust list. We additionally surface the
# directly-connected peer as X-Real-IP for downstream consumers (logs,
# admin tools) that read it directly without TrustProxies.
header_up X-Real-IP {remote_host}
}
}
+25
View File
@@ -0,0 +1,25 @@
# Caddy config used by compose.split.yaml — the embedded image's Caddy is
# disabled in this mode and a dedicated Caddy container fronts independent
# web and ws-server containers reachable via the compose network.
{
admin off
auto_https off
persist_config off
log {
output stdout
format console
}
servers {
trusted_proxies static 0.0.0.0/0 ::/0
}
}
:7001 {
@ws path /ws
reverse_proxy @ws ws-server:8076
reverse_proxy web:7001 {
header_up Host {host}
header_up X-Real-IP {remote_host}
}
}
+153
View File
@@ -0,0 +1,153 @@
#!/bin/sh
set -e
# Resolve the binding scheme based on whether the embedded Caddy is enabled.
#
# When ENABLE_CADDY=true (default), Caddy owns the public port (7001) and
# dispatches traffic internally; Octane and ws-server bind to localhost only
# so they cannot be reached from outside the container.
#
# When ENABLE_CADDY=false (e.g. an external reverse proxy or split mode),
# Octane takes the public port directly to keep behaviour identical to the
# pre-Caddy releases.
if [ "${ENABLE_CADDY}" = "true" ]; then
: "${OCTANE_HOST:=127.0.0.1}"
: "${OCTANE_PORT:=7002}"
: "${WS_HOST:=127.0.0.1}"
: "${WS_PORT:=8076}"
: "${CADDY_LISTEN_PORT:=7001}"
else
: "${OCTANE_HOST:=0.0.0.0}"
: "${OCTANE_PORT:=7001}"
: "${WS_HOST:=0.0.0.0}"
: "${WS_PORT:=8076}"
fi
export OCTANE_HOST OCTANE_PORT WS_HOST WS_PORT CADDY_LISTEN_PORT
export OCTANE_INTERNAL_PORT="${OCTANE_PORT}"
# ---------------------------------------------------------------------------
# Auto-tune worker counts based on the host (CPU + memory).
#
# Heuristic: each PHP worker (Octane/Horizon) costs ~80 MiB. After reserving
# ~300 MiB for the always-on processes (caddy/redis/ws-server/masters), divide
# the remaining budget across roles. Any user-set ENV wins.
# ---------------------------------------------------------------------------
detect_cpus() {
if [ -r /sys/fs/cgroup/cpu.max ]; then
# cgroup v2: "<quota> <period>" or "max <period>"
read -r q p < /sys/fs/cgroup/cpu.max 2>/dev/null
if [ "$q" != "max" ] && [ -n "$q" ] && [ -n "$p" ] && [ "$p" -gt 0 ]; then
echo $(( (q + p - 1) / p ))
return
fi
fi
nproc 2>/dev/null || echo 1
}
detect_mem_mib() {
if [ -r /sys/fs/cgroup/memory.max ]; then
m=$(cat /sys/fs/cgroup/memory.max 2>/dev/null)
if [ "$m" != "max" ] && [ -n "$m" ]; then
echo $(( m / 1024 / 1024 ))
return
fi
fi
# No cgroup limit: avoid over-provisioning on big hosts. Cap the assumed
# budget to MEM_FALLBACK_MIB (default 1024) unless the user opts out by
# setting it explicitly. Use whichever is smaller of MemAvailable and cap.
avail=$(awk '/MemAvailable/ {print int($2/1024)}' /proc/meminfo 2>/dev/null || echo 1024)
cap=${MEM_FALLBACK_MIB:-1024}
[ "$avail" -lt "$cap" ] && echo "$avail" || echo "$cap"
}
CPUS=$(detect_cpus)
MEM_MIB=$(detect_mem_mib)
# Resource profile presets. RESOURCE_PROFILE selects ratios for the budget split:
# minimal - smallest possible footprint (~250-350 MiB), single octane worker,
# horizon capped to 1/1/1. Suitable for VPS with <=512 MiB RAM.
# balanced - default; ~80 MiB per worker, octane gets 25% of slots.
# performance - larger reserves for opcache/caches, more aggressive horizon caps.
# auto - same as balanced.
: "${RESOURCE_PROFILE:=auto}"
case "$RESOURCE_PROFILE" in
minimal) RESERVED_MIB=200; SLOT_MIB=100; OCT_NUM=1; OCT_DEN=1; OCT_FORCE=1; auto_horizon_mem=128; auto_octane_gc=64 ;;
performance) RESERVED_MIB=400; SLOT_MIB=70; OCT_NUM=1; OCT_DEN=3; OCT_FORCE=0; auto_horizon_mem=384; auto_octane_gc=256 ;;
balanced|auto|*) RESERVED_MIB=300; SLOT_MIB=80; OCT_NUM=1; OCT_DEN=4; OCT_FORCE=0; auto_horizon_mem=256; auto_octane_gc=128 ;;
esac
BUDGET=$(( MEM_MIB - RESERVED_MIB ))
[ "$BUDGET" -lt "$SLOT_MIB" ] && BUDGET=$SLOT_MIB
SLOTS=$(( BUDGET / SLOT_MIB ))
clamp() { v=$1; lo=$2; hi=$3; [ "$v" -lt "$lo" ] && v=$lo; [ "$v" -gt "$hi" ] && v=$hi; echo "$v"; }
if [ "$OCT_FORCE" = "1" ]; then
auto_octane=1
auto_dp=1; auto_biz=1; auto_notif=1
else
auto_octane=$(clamp $(( (SLOTS * OCT_NUM) / OCT_DEN )) 1 "$CPUS")
remaining=$(( SLOTS - auto_octane - 2 ))
[ "$remaining" -lt 3 ] && remaining=3
auto_dp=$(clamp $(( remaining / 2 )) 1 $(( CPUS * 2 )))
auto_biz=$(clamp $(( remaining / 4 )) 1 "$CPUS")
auto_notif=$(clamp $(( remaining / 4 )) 1 "$CPUS")
fi
# User-set ENV always wins.
: "${OCTANE_WORKERS:=$auto_octane}"
: "${OCTANE_TASK_WORKERS:=1}"
: "${OCTANE_MAX_REQUESTS:=500}"
: "${OCTANE_GARBAGE_MB:=$auto_octane_gc}"
: "${OCTANE_MAX_EXECUTION_TIME:=60}"
: "${HORIZON_DATA_PIPELINE_MAX:=$auto_dp}"
: "${HORIZON_BUSINESS_MAX:=$auto_biz}"
: "${HORIZON_NOTIFICATION_MAX:=$auto_notif}"
: "${HORIZON_WORKER_MEMORY_MB:=$auto_horizon_mem}"
: "${HORIZON_WORKER_MAX_TIME:=0}"
: "${HORIZON_WORKER_MAX_JOBS:=0}"
: "${ENABLE_WEB:=true}"
: "${ENABLE_SCHEDULE:=$ENABLE_WEB}"
export OCTANE_WORKERS OCTANE_TASK_WORKERS OCTANE_MAX_REQUESTS \
OCTANE_GARBAGE_MB OCTANE_MAX_EXECUTION_TIME \
HORIZON_DATA_PIPELINE_MAX HORIZON_BUSINESS_MAX HORIZON_NOTIFICATION_MAX \
HORIZON_WORKER_MEMORY_MB HORIZON_WORKER_MAX_TIME HORIZON_WORKER_MAX_JOBS \
RESOURCE_PROFILE ENABLE_SCHEDULE
echo "[entrypoint] Auto-tune (profile=${RESOURCE_PROFILE}): cpus=${CPUS} mem=${MEM_MIB}MiB slots=${SLOTS} -> octane=${OCTANE_WORKERS} horizon(dp/biz/notif)=${HORIZON_DATA_PIPELINE_MAX}/${HORIZON_BUSINESS_MAX}/${HORIZON_NOTIFICATION_MAX} horizon_worker_mem=${HORIZON_WORKER_MEMORY_MB}MB"
echo "[entrypoint] Horizon supervisors use balance=auto with minProcesses=1, so they scale up to the cap on demand and back down when idle."
redis_reachable() {
local host port
host=$(grep -E '^REDIS_HOST=' /www/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
port=$(grep -E '^REDIS_PORT=' /www/.env 2>/dev/null | tail -1 | cut -d= -f2- | tr -d '"' | tr -d "'")
command -v redis-cli >/dev/null 2>&1 || return 1
[ -n "$host" ] || return 1
case "$host" in
/*) [ -S "$host" ] && redis-cli -s "$host" ping 2>/dev/null | grep -q PONG ;;
*) redis-cli -h "$host" -p "${port:-6379}" ping 2>/dev/null | grep -q PONG ;;
esac
}
if [ ! -s /www/.env ] || ! grep -qE '^INSTALLED=(1|true)$' /www/.env || echo " $* " | grep -q ' xboard:install '; then
echo "[entrypoint] Skipping xboard:update (not yet installed or running xboard:install)."
else
if redis_reachable; then
echo "[entrypoint] Running xboard:update (redis reachable, real drivers)..."
php /www/artisan xboard:update --no-interaction || \
echo "[entrypoint] WARNING: xboard:update failed; continuing so supervisor can boot anyway." >&2
else
echo "[entrypoint] Running xboard:update (redis not yet up, using array/sync drivers)..."
CACHE_DRIVER=array QUEUE_CONNECTION=sync SESSION_DRIVER=array \
php /www/artisan xboard:update --no-interaction || \
echo "[entrypoint] WARNING: xboard:update failed; continuing so supervisor can boot anyway." >&2
fi
fi
echo "[entrypoint] Starting services (caddy=${ENABLE_CADDY} web=${ENABLE_WEB} horizon=${ENABLE_HORIZON} scheduler=${ENABLE_SCHEDULE} ws=${ENABLE_WS_SERVER})..."
# Drop stale Octane/WorkerMan state files so the new master does not signal
# PIDs left over from a previous container run (causes Swoole kill EPERM).
rm -f /www/storage/logs/octane-server-state.json /www/storage/logs/xboard-ws-server.pid 2>/dev/null || true
chown -R www:www /www 2>/dev/null || true
exec "$@"
+17
View File
@@ -0,0 +1,17 @@
; Slim PHP defaults for the all-in-one container.
; Tunables are overridable via Docker ENV (PHP_MEMORY_LIMIT, etc.) if needed.
memory_limit = 256M
[opcache]
opcache.enable = 1
opcache.enable_cli = 0
opcache.memory_consumption = 96
opcache.interned_strings_buffer = 16
opcache.max_accelerated_files = 10000
opcache.validate_timestamps = 0
opcache.revalidate_freq = 0
opcache.fast_shutdown = 1
[swoole]
swoole.use_shortname = Off
+116
View File
@@ -0,0 +1,116 @@
[supervisord]
nodaemon=true
user=root
logfile=/dev/stdout
logfile_maxbytes=0
pidfil=/www/storage/logs/supervisor/supervisord.pid
loglevel=info
[program:octane]
process_name=%(program_name)s_%(process_num)02d
command=php /www/artisan octane:start --host=%(ENV_OCTANE_HOST)s --port=%(ENV_OCTANE_PORT)s --workers=%(ENV_OCTANE_WORKERS)s --task-workers=%(ENV_OCTANE_TASK_WORKERS)s --max-requests=%(ENV_OCTANE_MAX_REQUESTS)s
autostart=%(ENV_ENABLE_WEB)s
autorestart=true
user=www
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=10
stopsignal=QUIT
stopasgroup=true
killasgroup=true
priority=100
[program:horizon]
process_name=%(program_name)s_%(process_num)02d
command=php /www/artisan horizon
autostart=%(ENV_ENABLE_HORIZON)s
autorestart=true
user=www
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=3
stopsignal=SIGINT
stopasgroup=true
killasgroup=true
priority=200
[program:scheduler]
process_name=%(program_name)s_%(process_num)02d
command=php /www/artisan schedule:work
autostart=%(ENV_ENABLE_SCHEDULE)s
autorestart=true
user=www
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=5
stopsignal=TERM
stopasgroup=true
killasgroup=true
priority=250
[program:redis]
process_name=%(program_name)s_%(process_num)02d
command=redis-server --dir /data
--dbfilename dump.rdb
--save 900 1
--save 300 10
--save 60 10000
--port 0
--unixsocket /data/redis.sock
--unixsocketperm 777
autostart=%(ENV_ENABLE_REDIS)s
autorestart=true
user=redis
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=3
stopsignal=TERM
stopasgroup=true
killasgroup=true
priority=300
[program:ws-server]
process_name=%(program_name)s_%(process_num)02d
command=php /www/artisan ws-server start --host=%(ENV_WS_HOST)s --port=%(ENV_WS_PORT)s
autostart=%(ENV_ENABLE_WS_SERVER)s
autorestart=true
user=www
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=5
stopsignal=SIGINT
stopasgroup=true
killasgroup=true
priority=400
[program:caddy]
process_name=%(program_name)s_%(process_num)02d
command=caddy run --config /etc/caddy/Caddyfile --adapter caddyfile
autostart=%(ENV_ENABLE_CADDY)s
autorestart=true
user=root
redirect_stderr=true
stdout_logfile=/dev/stdout
stdout_logfile_maxbytes=0
stdout_logfile_backups=0
numprocs=1
stopwaitsecs=5
stopsignal=TERM
stopasgroup=true
killasgroup=true
priority=500
+28
View File
@@ -0,0 +1,28 @@
/node_modules
/config/v2board.php
/public/hot
/public/storage
/public/env.example.js
/storage/*.key
/vendor
.env
.git
.github
.helloagents
.env.backup
.phpunit.result.cache
.idea
.lock
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
composer.phar
yarn.lock
docker-compose.yml
.DS_Store
/docker
storage/laravels.conf
storage/laravels.pid
storage/laravels-timer-process.pid
/frontend
Executable
+15
View File
@@ -0,0 +1,15 @@
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
View File
Regular → Executable
+7 -7
View File
@@ -1,11 +1,9 @@
APP_NAME=XBoard
APP_ENV=local
APP_ENV=production
APP_KEY=base64:PZXk5vTuTinfeEVG5FpYv2l6WEhLsyvGpiWK7IgJJ60=
APP_DEBUG=false
APP_URL=http://localhost
APP_RUNNING_IN_CONSOLE=true
LOG_CHANNEL=stack
DB_CONNECTION=mysql
@@ -19,14 +17,16 @@ REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
#默认将队列驱动和缓存驱动都修改为了redis,请务必安装redis
BROADCAST_DRIVER=log
CACHE_DRIVER=redis
QUEUE_CONNECTION=redis
QUEUE_RETRY_AFTER=90
MASS_EMAIL_HOURLY_LIMIT=500
MAIL_DRIVER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_TIMEOUT=30
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
@@ -35,10 +35,10 @@ MAIL_FROM_NAME=null
MAILGUN_DOMAIN=
MAILGUN_SECRET=
# google cloud stoage
# google cloud storage
ENABLE_AUTO_BACKUP_AND_UPDATE=false
GOOGLE_CLOUD_KEY_FILE=config/googleCloudStorageKey.json
GOOGLE_CLOUD_STORAGE_BUCKET=
# 用于阻止重复安装
INSTALLED=false
# Prevent reinstallation
INSTALLED=false
Executable
+5
View File
@@ -0,0 +1,5 @@
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore
+39
View File
@@ -0,0 +1,39 @@
---
name: 🐛 问题反馈 | Bug Report
about: 提交使用过程中遇到的问题 | Report an issue
title: "Bug Report"
labels: '🐛 bug'
assignees: ''
---
<!-- 🔴 请注意:XrayR等非XBoard问题请前往相应项目提问 -->
<!-- 🔴 Note: For XrayR and other non-XBoard issues, please report to their respective projects -->
> ⚠️ 请务必按照模板填写完整信息,没有详细描述的issue可能会被忽略或关闭
> ⚠️ Please follow the template to provide complete information, issues without detailed description may be ignored or closed
**基本信息 | Basic Info**
```yaml
XBoard版本 | Version:
部署方式 | Deployment: [Docker/手动部署]
PHP版本 | Version:
数据库 | Database:
```
**问题描述 | Description**
<!-- 简要描述你遇到的问题 -->
**复现步骤 | Steps**
<!-- 如何复现这个问题? -->
1.
2.
**相关截图 | Screenshots**
<!-- 拖拽图片到这里(请注意隐藏敏感信息)-->
**日志信息 | Logs**
<!-- storage/logs 目录下的日志 -->
```log
// 粘贴日志内容到这里
```
+28
View File
@@ -0,0 +1,28 @@
---
name: ✨ 功能请求 | Feature Request
about: 提交新功能建议或改进意见 | Suggest an idea
title: "Feature Request"
labels: '✨ enhancement'
assignees: ''
---
> ⚠️ 请务必按照模板详细描述你的需求,没有详细描述的issue可能会被忽略或关闭
> ⚠️ Please follow the template to describe your request in detail, issues without detailed description may be ignored or closed
**需求描述 | Description**
<!-- 描述你希望添加的功能或改进建议 -->
**使用场景 | Use Case**
<!-- 描述这个功能会在什么场景下使用,解决什么问题 -->
**功能建议 | Suggestion**
<!-- 你期望这个功能是什么样的?可以描述一下具体实现方式 -->
```yaml
功能形式 | Type: [新功能/功能优化/界面改进]
预期效果 | Expected:
```
**补充说明 | Additional**
<!-- 其他补充说明或者参考示例 -->
@@ -0,0 +1,82 @@
name: Admin Frontend Docker Build and Publish
on:
push:
branches: ["master", "new-dev"]
paths:
- "admin-frontend/**"
- ".github/workflows/admin-frontend-docker-publish.yml"
workflow_dispatch:
concurrency:
group: admin-frontend-docker-publish-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository_owner }}/xboard-admin-frontend
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
fetch-tags: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64
driver-opts: |
image=moby/buildkit:v0.20.0
network=host
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: get_version
run: echo "version=$(git describe --tags --always)" >> "$GITHUB_OUTPUT"
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,format=short,prefix=,enable=true
type=raw,value=new,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=${{ steps.get_version.outputs.version }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and push
id: build-and-push
uses: docker/build-push-action@v5
with:
context: ./admin-frontend
file: ./admin-frontend/Dockerfile
push: true
platforms: linux/amd64
cache-from: type=gha,scope=admin-frontend-docker-publish-${{ github.ref_name }}
cache-to: type=gha,mode=min,scope=admin-frontend-docker-publish-${{ github.ref_name }},ignore-error=true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BUILDKIT_INLINE_CACHE=1
provenance: false
+92
View File
@@ -0,0 +1,92 @@
name: Backend Docker Build and Publish
on:
push:
branches: ["master", "new-dev"]
paths-ignore:
- "admin-frontend/**"
- ".helloagents/**"
- ".github/workflows/admin-frontend-docker-publish.yml"
workflow_dispatch:
concurrency:
group: backend-docker-publish-${{ github.ref }}
cancel-in-progress: true
env:
REGISTRY: ghcr.io
IMAGE_NAME: ${{ github.repository }}
jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 1
fetch-tags: true
submodules: recursive
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
with:
platforms: arm64
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
with:
platforms: linux/amd64,linux/arm64
driver-opts: |
image=moby/buildkit:v0.20.0
network=host
- name: Login to registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Get version
id: get_version
run: echo "version=$(git describe --tags --always)" >> $GITHUB_OUTPUT
- name: Extract metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
type=ref,event=branch
type=sha,format=short,prefix=,enable=true
type=raw,value=new,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=latest,enable=${{ github.ref == 'refs/heads/master' }}
type=raw,value=${{ steps.get_version.outputs.version }}
labels: |
org.opencontainers.image.source=${{ github.server_url }}/${{ github.repository }}
org.opencontainers.image.revision=${{ github.sha }}
- name: Build and push
id: build-and-push
uses: docker/build-push-action@v5
with:
context: .
push: true
platforms: linux/amd64,linux/arm64
cache-from: type=gha,scope=backend-docker-publish-${{ github.ref_name }}
cache-to: type=gha,mode=max,scope=backend-docker-publish-${{ github.ref_name }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BUILDKIT_INLINE_CACHE=1
BUILDKIT_MULTI_PLATFORM=1
provenance: false
allow: |
network.host
Executable
+33
View File
@@ -0,0 +1,33 @@
/node_modules
/config/v2board.php
/config/googleCloudStorageKey.json
/public/hot
/public/storage
/public/env.example.js
*.user.ini
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
.idea
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
composer.phar
yarn.lock
docker-compose.yml
.DS_Store
/docker
storage/laravels.conf
storage/laravels.pid
storage/update_pending
storage/laravels-timer-process.pid
cli-php.ini
frontend
docker-compose.yaml
bun.lockb
compose.yaml
.scribe
.ace-tool/
+3
View File
@@ -0,0 +1,3 @@
[submodule "public/assets/admin"]
path = public/assets/admin
url = https://github.com/Micah123321/xboard-admin-dist.git
+4
View File
@@ -0,0 +1,4 @@
{
"consecutive_failures": 12,
"last_failure": "2026-04-24T15:49:44.925Z"
}
+19
View File
@@ -0,0 +1,19 @@
{
"updatedAt": "2026-04-24T15:11:19.543Z",
"source": "manual",
"originCommand": "generic-r2",
"requirementsCoverage": {
"status": "PASS",
"summary": "已覆盖分页、父子筛选、单节点置顶、仅已勾选节点批量修改,以及 host/group_ids/rate 三项批量更新边界。"
},
"deliveryChecklist": {
"status": "PASS",
"summary": "admin-frontend 构建通过,节点页与后端批量修改链路已落地,知识库、归档索引、会话状态与交付证据已同步。"
},
"fingerprint": {
"available": true,
"unstaged": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 12 +-\n .helloagents/.ralph-visual.json | 32 +-\n .helloagents/CHANGELOG.md | 39 +-\n .helloagents/archive/_index.md | 4 +\n .helloagents/context.md | 12 +-\n .helloagents/modules/admin-frontend.md | 19 +-\n .../.status.json | 10 +-\n .../contract.json | 27 +-\n .../proposal.md | 19 +-\n .../tasks.md | 14 +-\n .../2026-04-24T07-44-44-846Z-unknown-e3upr9.jsonl | 5 +\n .../2026-04-24T08-15-56-367Z-claude-u7aa37.jsonl | 3 +\n .helloagents/sessions/master/default/STATE.md | 18 +-\n admin-frontend/src/api/admin.ts | 31 ++\n admin-frontend/src/types/api.d.ts | 28 ++\n admin-frontend/src/types/components.d.ts | 1 +\n admin-frontend/src/utils/nodes.ts | 12 +\n admin-frontend/src/utils/orders.ts | 50 ++-\n admin-frontend/src/utils/users.ts | 352 ++++++++++++++-\n .../src/views/dashboard/DashboardView.vue | 162 +++++--\n admin-frontend/src/views/nodes/NodesView.vue | 260 ++++++++++-\n .../src/views/subscriptions/OrderAssignDrawer.vue | 3 +-\n .../src/views/subscriptions/OrderDetailDrawer.vue | 20 +-\n .../src/views/subscriptions/OrdersView.scss | 16 +\n .../src/views/subscriptions/OrdersView.vue | 225 +++++++++-\n admin-frontend/src/views/users/UsersView.vue | 490 ++++++++-------------\n admin-frontend/vite.config.ts | 3 +-\n .../V2/Admin/Server/ManageController.php | 13 +\n app/Http/Controllers/V2/Admin/UserController.php | 5 +-\n public/assets/admin | 0\n 31 files changed, 1442 insertions(+), 447 deletions(-)",
"staged": "",
"combined": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 12 +-\n .helloagents/.ralph-visual.json | 32 +-\n .helloagents/CHANGELOG.md | 39 +-\n .helloagents/archive/_index.md | 4 +\n .helloagents/context.md | 12 +-\n .helloagents/modules/admin-frontend.md | 19 +-\n .../.status.json | 10 +-\n .../contract.json | 27 +-\n .../proposal.md | 19 +-\n .../tasks.md | 14 +-\n .../2026-04-24T07-44-44-846Z-unknown-e3upr9.jsonl | 5 +\n .../2026-04-24T08-15-56-367Z-claude-u7aa37.jsonl | 3 +\n .helloagents/sessions/master/default/STATE.md | 18 +-\n admin-frontend/src/api/admin.ts | 31 ++\n admin-frontend/src/types/api.d.ts | 28 ++\n admin-frontend/src/types/components.d.ts | 1 +\n admin-frontend/src/utils/nodes.ts | 12 +\n admin-frontend/src/utils/orders.ts | 50 ++-\n admin-frontend/src/utils/users.ts | 352 ++++++++++++++-\n .../src/views/dashboard/DashboardView.vue | 162 +++++--\n admin-frontend/src/views/nodes/NodesView.vue | 260 ++++++++++-\n .../src/views/subscriptions/OrderAssignDrawer.vue | 3 +-\n .../src/views/subscriptions/OrderDetailDrawer.vue | 20 +-\n .../src/views/subscriptions/OrdersView.scss | 16 +\n .../src/views/subscriptions/OrdersView.vue | 225 +++++++++-\n admin-frontend/src/views/users/UsersView.vue | 490 ++++++++-------------\n admin-frontend/vite.config.ts | 3 +-\n .../V2/Admin/Server/ManageController.php | 13 +\n app/Http/Controllers/V2/Admin/UserController.php | 5 +-\n public/assets/admin | 0\n 31 files changed, 1442 insertions(+), 447 deletions(-)\n---"
}
}
+22
View File
@@ -0,0 +1,22 @@
{
"updatedAt": "2026-04-24T08:19:23.678Z",
"source": "manual",
"originCommand": "~verify",
"reviewMode": "manual-self-review",
"conclusion": "已按插件管理方案的 reviewerFocus 审阅列表工作台、动作边界与详情抽屉数据流;当前实现未发现阻断性交付问题。",
"outcome": "clean",
"findings": [],
"fileReferences": [
"admin-frontend/src/views/system/PluginManagementView.vue",
"admin-frontend/src/views/system/PluginCard.vue",
"admin-frontend/src/views/system/PluginDetailDrawer.vue",
"admin-frontend/src/utils/plugins.ts",
"admin-frontend/src/api/admin.ts"
],
"fingerprint": {
"available": true,
"unstaged": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 14 +-\n .helloagents/.ralph-review.json | 23 +-\n .helloagents/.ralph-visual.json | 37 ++-\n .helloagents/CHANGELOG.md | 42 +++\n .helloagents/INDEX.md | 4 +-\n .helloagents/archive/_index.md | 6 +\n .helloagents/context.md | 16 +-\n .helloagents/modules/admin-frontend.md | 26 +-\n .../2026-04-23T15-07-42-905Z-unknown-t2hj2g.jsonl | 18 --\n .helloagents/sessions/master/default/STATE.md | 21 +-\n admin-frontend/src/api/admin.ts | 229 +++++++++++++++++\n admin-frontend/src/layouts/AdminLayout.vue | 4 +-\n admin-frontend/src/router/index.ts | 22 +-\n admin-frontend/src/types/api.d.ts | 281 ++++++++++++++++++++-\n admin-frontend/src/utils/plans.ts | 9 +\n .../src/views/subscriptions/PlansView.vue | 13 +-\n public/assets/admin | 0\n 18 files changed, 679 insertions(+), 90 deletions(-)",
"staged": "",
"combined": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 14 +-\n .helloagents/.ralph-review.json | 23 +-\n .helloagents/.ralph-visual.json | 37 ++-\n .helloagents/CHANGELOG.md | 42 +++\n .helloagents/INDEX.md | 4 +-\n .helloagents/archive/_index.md | 6 +\n .helloagents/context.md | 16 +-\n .helloagents/modules/admin-frontend.md | 26 +-\n .../2026-04-23T15-07-42-905Z-unknown-t2hj2g.jsonl | 18 --\n .helloagents/sessions/master/default/STATE.md | 21 +-\n admin-frontend/src/api/admin.ts | 229 +++++++++++++++++\n admin-frontend/src/layouts/AdminLayout.vue | 4 +-\n admin-frontend/src/router/index.ts | 22 +-\n admin-frontend/src/types/api.d.ts | 281 ++++++++++++++++++++-\n admin-frontend/src/utils/plans.ts | 9 +\n .../src/views/subscriptions/PlansView.vue | 13 +-\n public/assets/admin | 0\n 18 files changed, 679 insertions(+), 90 deletions(-)\n---"
}
}
+31
View File
@@ -0,0 +1,31 @@
{
"updatedAt": "2026-04-24T15:11:19.540Z",
"source": "manual",
"originCommand": "generic-r2",
"reason": "节点管理本轮新增分页、父子筛选、已勾选批量修改与置顶动作,需要确认工作台节奏和批量作用域提示与 Apple 化后台契约一致。",
"tooling": [
"code inspection",
"npm run build"
],
"screensChecked": [
"#/nodes desktop"
],
"statesChecked": [
"节点列表默认加载完成态",
"节点列表已勾选批量操作可用态",
"节点批量修改弹窗展开态",
"节点父子筛选切换态"
],
"status": "PASS",
"summary": "已通过代码级视觉验收确认节点页维持黑色 Hero + 白色工作台结构,工具条新增父/子节点筛选、批量修改和分页后仍保持高密度但可读的 Apple 化运营节奏。",
"findings": [],
"recommendations": [
"建议在真实登录态下再手动确认跨分页勾选与批量修改对后端返回数据的联动表现。"
],
"fingerprint": {
"available": true,
"unstaged": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 12 +-\n .helloagents/.ralph-visual.json | 32 +-\n .helloagents/CHANGELOG.md | 39 +-\n .helloagents/archive/_index.md | 4 +\n .helloagents/context.md | 12 +-\n .helloagents/modules/admin-frontend.md | 19 +-\n .../.status.json | 10 +-\n .../contract.json | 27 +-\n .../proposal.md | 19 +-\n .../tasks.md | 14 +-\n .../2026-04-24T07-44-44-846Z-unknown-e3upr9.jsonl | 5 +\n .../2026-04-24T08-15-56-367Z-claude-u7aa37.jsonl | 3 +\n .helloagents/sessions/master/default/STATE.md | 18 +-\n admin-frontend/src/api/admin.ts | 31 ++\n admin-frontend/src/types/api.d.ts | 28 ++\n admin-frontend/src/types/components.d.ts | 1 +\n admin-frontend/src/utils/nodes.ts | 12 +\n admin-frontend/src/utils/orders.ts | 50 ++-\n admin-frontend/src/utils/users.ts | 352 ++++++++++++++-\n .../src/views/dashboard/DashboardView.vue | 162 +++++--\n admin-frontend/src/views/nodes/NodesView.vue | 260 ++++++++++-\n .../src/views/subscriptions/OrderAssignDrawer.vue | 3 +-\n .../src/views/subscriptions/OrderDetailDrawer.vue | 20 +-\n .../src/views/subscriptions/OrdersView.scss | 16 +\n .../src/views/subscriptions/OrdersView.vue | 225 +++++++++-\n admin-frontend/src/views/users/UsersView.vue | 490 ++++++++-------------\n admin-frontend/vite.config.ts | 3 +-\n .../V2/Admin/Server/ManageController.php | 13 +\n app/Http/Controllers/V2/Admin/UserController.php | 5 +-\n public/assets/admin | 0\n 31 files changed, 1442 insertions(+), 447 deletions(-)",
"staged": "",
"combined": ".helloagents/.ralph-breaker.json | 4 +-\n .helloagents/.ralph-closeout.json | 12 +-\n .helloagents/.ralph-visual.json | 32 +-\n .helloagents/CHANGELOG.md | 39 +-\n .helloagents/archive/_index.md | 4 +\n .helloagents/context.md | 12 +-\n .helloagents/modules/admin-frontend.md | 19 +-\n .../.status.json | 10 +-\n .../contract.json | 27 +-\n .../proposal.md | 19 +-\n .../tasks.md | 14 +-\n .../2026-04-24T07-44-44-846Z-unknown-e3upr9.jsonl | 5 +\n .../2026-04-24T08-15-56-367Z-claude-u7aa37.jsonl | 3 +\n .helloagents/sessions/master/default/STATE.md | 18 +-\n admin-frontend/src/api/admin.ts | 31 ++\n admin-frontend/src/types/api.d.ts | 28 ++\n admin-frontend/src/types/components.d.ts | 1 +\n admin-frontend/src/utils/nodes.ts | 12 +\n admin-frontend/src/utils/orders.ts | 50 ++-\n admin-frontend/src/utils/users.ts | 352 ++++++++++++++-\n .../src/views/dashboard/DashboardView.vue | 162 +++++--\n admin-frontend/src/views/nodes/NodesView.vue | 260 ++++++++++-\n .../src/views/subscriptions/OrderAssignDrawer.vue | 3 +-\n .../src/views/subscriptions/OrderDetailDrawer.vue | 20 +-\n .../src/views/subscriptions/OrdersView.scss | 16 +\n .../src/views/subscriptions/OrdersView.vue | 225 +++++++++-\n admin-frontend/src/views/users/UsersView.vue | 490 ++++++++-------------\n admin-frontend/vite.config.ts | 3 +-\n .../V2/Admin/Server/ManageController.php | 13 +\n app/Http/Controllers/V2/Admin/UserController.php | 5 +-\n public/assets/admin | 0\n 31 files changed, 1442 insertions(+), 447 deletions(-)\n---"
}
}
+481
View File
@@ -0,0 +1,481 @@
# CHANGELOG
## [0.6.24] - 2026-05-01
### 新增
- **[admin-frontend]**: 为工单工作台对话页新增“查看用户 / 用户订单”跳转入口;当前工单用户可直接进入用户管理并按 `user_id` 精准筛选,或进入订单管理查看该用户订单 — by yinjianm
- 方案: [202605011828_admin-ticket-user-order-links](archive/2026-05/202605011828_admin-ticket-user-order-links/)
- 决策: admin-ticket-user-order-links#D001(使用路由 query 承载跨页面用户作用域)
## [0.6.23] - 2026-04-29
### 新增
- **[user-frontend-access]**: 新增用户前端访问开关;后台站点设置可切换 `frontend_enable`,关闭后仅用户首页 `/` 返回空 404,不渲染站点标题或用户主题内容,订阅/API、节点 API 与管理后台保持原有访问边界 — by yinjianm
- 方案: [202604291559_user-frontend-access-toggle](archive/2026-04/202604291559_user-frontend-access-toggle/)
- 决策: user-frontend-access-toggle#D001(使用路由级中间件控制用户入口)
## [0.6.22] - 2026-04-29
### 修复
- **[node-traffic-limit]**: 修复父节点自动下线后子节点仍可能保持上线的问题;新增 `parent_auto_hidden` 标记和父节点显隐联动服务,自动上线离线、流量限额 suspended 会隐藏当时仍显示的直接子节点,自动恢复或限额重置后只恢复这批由联动逻辑隐藏的子节点,手动隐藏的子节点不被误上线 — by yinjianm
- 方案: [202604290153_parent-node-auto-visibility](archive/2026-04/202604290153_parent-node-auto-visibility/)
- 决策: parent-node-auto-visibility#D001(使用独立父级自动隐藏标记)
## [0.6.21] - 2026-04-29
### 修复
- **[node-traffic-limit]**: 修正节点管理月额度使用量口径;同 `machine_id` 或同 host 节点现在共享当前账期用量,`server/manage/getNodes` 返回 `traffic_limit_snapshot`mi-node 下发的 `traffic_limit.current_used` 也改为共享账期统计,管理端优先显示快照并保留旧 metrics / `u+d` 回退 — by yinjianm
- 方案: [202604290132_shared-node-traffic-limit](archive/2026-04/202604290132_shared-node-traffic-limit/)
- 决策: shared-node-traffic-limit#D001(共享范围优先 machine_id,兜底 host)
## [0.6.20] - 2026-04-29
### 新增
- **[admin-frontend]**: 节点流量详情卡新增“昨日”统计;`server/manage/getNodes` 现在返回 `traffic_stats.today/yesterday/month/total`,今日、昨日和本月均使用半开时间窗口聚合,便于对比“今日下行多、本月上行多”的流量分布来源 — by yinjianm
- 方案: [202604290123_node-traffic-yesterday-stats](archive/2026-04/202604290123_node-traffic-yesterday-stats/)
- 决策: node-traffic-yesterday-stats#D001(保持 u/d 语义并新增后端 yesterday 字段)
## [0.6.19] - 2026-04-29
### 快速修改
- **[node-traffic-limit]**: 修复节点提高月流量额度后管理端仍显示“已限额”的问题;保存配置、缓存 metrics 回写和节点下发配置现在都会按当前已用流量与新额度重新计算 suspended 状态,旧额度产生的 stale metrics 不会再把节点重新标记为限额下线 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: app/Services/ServerTrafficLimitService.php:16-320, app/Services/ServerService.php:247-252, tests/Unit/ServerTrafficLimitServiceTest.php:60-148, E:/code/go/mi-node/internal/trafficlimit/manager_test.go:120-157
## [0.6.18] - 2026-04-28
### 新增
- **[node-traffic-limit]**: 新增节点月流量限额强制下线能力;Xboard 可为单节点配置月额度、重置日、重置时间和时区,下发 `traffic_limit` 给 mi-node,并在手动/定时重置和 metrics 回传时同步限额状态;管理端节点编辑与流量浮层同步展示限额配置、用量、状态和下次重置 — by yinjianm
- 方案: [202604281921_node-traffic-limit-enforcement](archive/2026-04/202604281921_node-traffic-limit-enforcement/)
- 决策: node-traffic-limit-enforcement#D001(由 mi-node 本地强制节点下线), node-traffic-limit-enforcement#D002(复用 `transfer_enable` 作为节点月额度)
## [0.6.17] - 2026-04-28
### 快速修改
- **[ci-workflows]**: 修复后端 Docker 构建在 `composer dump-autoload` 阶段因旧锁文件中的 `laravel/reverb` provider 自动发现而失败的问题;项目未启用 ReverbComposer package discovery 现在会跳过 `laravel/reverb` — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: composer.json:53-60
## [0.6.16] - 2026-04-28
### 快速修改
- **[ci-workflows]**: 优化后端 Docker 构建缓存命中;`composer.lock` 现在进入镜像构建上下文,Composer 依赖安装提前到源码复制前并使用 BuildKit 缓存挂载,构建期不再重复执行全量 `chown/chmod` — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: Dockerfile:1-44, .dockerignore:18-22
## [0.6.15] - 2026-04-28
### 快速修改
- **[admin-frontend]**: 修正节点 hover 流量详情的累计统计口径,今日、本月、累计现在全部从 `v2_stat_server` 按节点聚合,避免节点当前累计字段被重置后出现“本月大于累计”的展示错误 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: app/Http/Controllers/V2/Admin/Server/ManageController.php:34-66, .helloagents/modules/admin-frontend.md:49
## [0.6.14] - 2026-04-28
### 修复
- **[admin-frontend]**: 修复复制节点后在自动上线开启状态下不会立即显示的问题;自动上线同步现在可针对单节点执行,管理端保存 / 开启自动上线、REST 心跳和 WebSocket 状态上报都会立即按在线与墙状态同步 `show``sync:server-auto-online` 继续作为定时兜底 — by yinjianm
- 方案: [202604281632_admin-frontend-node-auto-online-immediate-sync](archive/2026-04/202604281632_admin-frontend-node-auto-online-immediate-sync/)
## [0.6.13] - 2026-04-28
### 新增
- **[admin-frontend]**: 为节点管理页补齐节点名称 hover 流量详情;`server/manage/getNodes` 现在返回节点级 `traffic_stats.today/month/total`,前端展示今日、本月、累计的上行、下行和合计流量 — by yinjianm
- 方案: [202604281625_admin-frontend-node-traffic-hover](archive/2026-04/202604281625_admin-frontend-node-traffic-hover/)
- 决策: admin-frontend-node-traffic-hover#D001(在 getNodes 聚合节点流量而不是 hover 拉取)
## [0.6.12] - 2026-04-28
### 快速修改
- **[admin-frontend]**: 为节点管理页搜索过滤增加显隐条件,可按全部、显示中、已隐藏筛选节点,并同步重置与分页刷新逻辑 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/utils/nodes.ts, admin-frontend/src/views/nodes/NodesView.vue
## [0.6.11] - 2026-04-28
### 快速修改
- **[ci-workflows]**: 优化管理端前端 Docker 发布耗时,默认只构建 `linux/amd64`,移除 QEMU/ARM64 跨架构构建,并将 BuildKit GHA 缓存导出收敛为 `mode=min` — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: .github/workflows/admin-frontend-docker-publish.yml:34-82, .helloagents/modules/ci-workflows.md:14-15
## [0.6.10] - 2026-04-28
### 修复
- **[node-gfw-check]**: 修复 `parent_id=0` 的父节点在管理端显示已开启墙检测托管、但不会被自动墙检任务入队而长期显示“未检测”的问题;自动墙检现在同时兼容 `parent_id IS NULL``parent_id=0`,并把未明确关闭的 `gfw_check_enabled` 视为开启,管理端自动墙检统计也改为只统计父节点 — by yinjianm
- 方案: [202604281441_fix-admin-node-gfw-null-enabled](archive/2026-04/202604281441_fix-admin-node-gfw-null-enabled/)
- 决策: fix-admin-node-gfw-null-enabled#D001(自动墙检查询对齐项目父节点与启用语义)
## [0.6.9] - 2026-04-28
### 修复
- **[ci-workflows]**: 修复仅修改 `admin-frontend/**` 且附带 `.helloagents/**` 知识库记录时仍误触发后端 Docker 发布的问题;后端 workflow 现在会忽略 `.helloagents/**`,但混有后端相关文件时仍会正常运行 — by yinjianm
- 方案: [202604281432_ci-ignore-helloagents-for-backend-docker](archive/2026-04/202604281432_ci-ignore-helloagents-for-backend-docker/)
- 决策: ci-ignore-helloagents-for-backend-docker#D001(后端 Docker workflow 忽略 HelloAGENTS 知识库路径)
## [0.6.8] - 2026-04-28
### 快速修改
- **[admin-frontend]**: 精简节点管理页批量操作与工作台说明文案,并在表格底部新增基于 `sync:server-gfw-checks` 30 分钟调度节奏估算的下次自动墙检倒计时提示 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/views/nodes/NodesView.vue
## [0.6.7] - 2026-04-28
### 快速修改
- **[deploy]**: 调整 `deploy/xboard-server` 更新脚本,改为拉取镜像后通过一次性 `web` 容器执行 `php artisan xboard:update`,再重新 `up -d` 拉起服务;README 同步更新后续升级命令 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: deploy/xboard-server/scripts/update.sh, deploy/xboard-server/README.md
## [0.6.6] - 2026-04-28
### 新增
- **[deploy]**: 新增 `deploy/xboard-server` 可复用服务器部署模板,基于生产 compose 拓扑补齐 `scheduler` 服务,并提供 `.env.example`、初始化/部署/更新/状态检查脚本和部署说明 — by yinjianm
- 方案: [202604281303_xboard-reusable-server-deploy](archive/2026-04/202604281303_xboard-reusable-server-deploy/)
- 决策: xboard-reusable-server-deploy#D001(使用独立 scheduler 服务驱动 Laravel Scheduler), xboard-reusable-server-deploy#D002(默认不把 MySQL 纳入一键模板)
## [0.6.5] - 2026-04-28
### 修复
- **[queue-mail]**: 修复 `SendEmailJob` 10 秒超时导致 `send_email` 队列邮件作业批量失败的问题;邮件 job 现在使用 60 秒超时、明确 backoff、timeout 失败直接 fail,并把邮件发送错误交给队列异常机制处理。同时新增 `MAIL_TIMEOUT` / `QUEUE_RETRY_AFTER` 配置、刷新 Horizon 长驻 worker 的运行时 mailer 配置,并对 `MailLog.config` 中的敏感字段脱敏 — by yinjianm
- 方案: [202604281258_fix-send-email-job-timeout](archive/2026-04/202604281258_fix-send-email-job-timeout/)
- 决策: fix-send-email-job-timeout#D001(保留队列结构并修复 job 与 mail transport 超时)
## [0.6.4] - 2026-04-28
### 修复
- **[node-gfw-check]**: 修复墙检测任务卡在 `pending/checking` 后会长期占用 active 状态的问题;超过 5 分钟未被节点端领取或未上报的任务会标记为检测失败,管理端区分展示“等待节点领取”和“检测中”,并在开启父节点墙检测托管时立即发起一次检测。同时补齐 Docker/supervisor 的 `schedule:work` 进程和 compose scheduler 样例,确保自动墙检测调度会持续运行;修正 mi-node 的 ping 成功判定,避免正常可达但平均延迟解析不到时被误判为超时 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: app/Services/ServerGfwCheckService.php, app/Console/Commands/SyncServerGfwChecks.php, admin-frontend/src/utils/nodes.ts, admin-frontend/src/views/nodes/NodesView.vue, .docker/supervisor/supervisord.conf, .docker/entrypoint.sh, Dockerfile, compose.sample.yaml, E:/code/go/mi-node/internal/gfwcheck/gfwcheck.go
## [0.6.3] - 2026-04-28
### 新增
- **[node-gfw-check]**: 为节点墙状态检测打通自动检测与自动显隐;`sync:server-gfw-checks` 会自动为开启托管的父节点创建检测任务,`blocked` 时自动隐藏节点并阻止自动上线重新发布,`normal` 时只恢复由墙检测自动隐藏的节点;管理端节点页新增刷新数据、墙检测托管开关和批量设置入口 — by yinjianm
- 方案: [202604280024_node-gfw-auto-check-and-online](archive/2026-04/202604280024_node-gfw-auto-check-and-online/)
- 决策: node-gfw-auto-check-and-online#D001(使用自动隐藏标记隔离管理员手动显隐), node-gfw-auto-check-and-online#D002(自动上线服务必须把 blocked 作为显示否决)
## [0.6.2] - 2026-04-27
### 新增
- **[admin-frontend]**: 为节点管理新增可控“自动上线”能力;节点可单独或批量开启后台托管,`sync:server-auto-online` 会按在线状态自动同步前台显示,在线 / 待同步时显示,离线时隐藏,未开启自动上线的节点继续保持手动显隐控制 — by yinjianm
- 方案: [202604272338_admin-frontend-node-auto-online](archive/2026-04/202604272338_admin-frontend-node-auto-online/)
- 决策: admin-frontend-node-auto-online#D001(自动上线使用独立字段与独立同步服务)
## [0.6.1] - 2026-04-27
### 快速修改
- **[admin-frontend]**: 修复独立 admin 前端容器内 `/upload/rest/upload` 返回 404 的问题;`Caddyfile` 现在会把 `/upload/*` 去掉 `/upload` 前缀后反向代理到 `XBOARD_UPLOAD_UPSTREAM`,默认对齐开发环境的图片上传服务 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/Caddyfile:1-28
## [0.6.0] - 2026-04-27
### 新增
- **[node-gfw-check]**: 新增节点墙状态检测闭环,管理端可对父节点发起检测并在节点列表展示、搜索和筛选正常 / 疑似被墙 / 部分异常 / 检测失败 / 未检测状态;子节点不单独检测并继承父节点状态,mi-node 支持 `gfw.check` WS 触发、REST 兜底领取和三网 ping 结果上报 — by yinjianm
- 方案: [202604272325_node-gfw-check](archive/2026-04/202604272325_node-gfw-check/)
- 决策: node-gfw-check#D001(使用 WS 触发 + REST 兜底), node-gfw-check#D002(子节点继承父节点墙状态)
## [0.5.19] - 2026-04-27
### 新增
- **[admin-frontend]**: 为工单工作台回复区补齐图片拖拽上传与剪贴板粘贴上传,统一复用现有图片上传接口和 Markdown 图片插入逻辑,并将超大工单工作台组件拆分出上传 composable 与独立 SCSS 样式文件 — by yinjianm
- 方案: [202604272310_ticket-chat-image-dnd-paste-upload](archive/2026-04/202604272310_ticket-chat-image-dnd-paste-upload/)
- 决策: ticket-chat-image-dnd-paste-upload#D001(统一图片入口到现有 Markdown 上传链路)
## [0.5.18] - 2026-04-27
### 快速修改
- **[admin-frontend]**: 调整节点管理状态筛选口径,“在线节点”现在同时包含显式在线与待同步节点,顶部在线节点统计同步采用相同口径;“离线节点”仍只匹配显式离线节点 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/utils/nodes.ts:12-176
## [0.5.17] - 2026-04-25
### 修复
- **[admin-frontend]**: 修复节点编辑 / 批量修改保存权限组后订阅侧无法命中节点的问题;前端提交 `group_ids / route_ids` 时统一序列化为字符串 ID,后端 `whereGroupId` 同时兼容历史字符串与数字 JSON 值,并补齐 TUIC V5/V4、ALPN 选项与 AnyTLS 完整默认 Padding Scheme — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/utils/nodeEditorMapper.ts, admin-frontend/src/utils/nodeEditorOptions.ts, admin-frontend/src/views/nodes/NodeEditorProtocolSection.vue, app/Models/Server.php
## [0.5.16] - 2026-04-25
### 新增
- **[admin-frontend]**: 为用户管理高级筛选新增“活跃状态”条件,支持按“活跃 / 非活跃”筛选;后端 `user/fetch` 现可识别 `activity_status` 复合规则,并按“任意订阅 + 流量未用完 + 最后在线时间在半年内”为活跃标准返回结果 — by yinjianm
- 方案: [202604250018_admin-frontend-user-activity-status-filter](archive/2026-04/202604250018_admin-frontend-user-activity-status-filter/)
- 决策: admin-frontend-user-activity-status-filter#D001(活跃判断入口固定在高级筛选弹窗), admin-frontend-user-activity-status-filter#D002(复合活跃规则统一由后端 activity_status 承接), admin-frontend-user-activity-status-filter#D003(全部状态继续由无条件表达)
## [0.5.15] - 2026-04-25
### 新增
- **[admin-frontend]**: 为节点管理工作台补齐“在线节点 / 离线节点”状态筛选,并新增针对已勾选节点的批量删除入口,接通真实 `server/manage/batchDelete` 后端链路;其中“离线节点”按本轮确认只筛显式离线状态,不包含待同步 / 已停用节点 — by yinjianm
- 方案: [202604250015_admin-frontend-node-status-filter-batch-delete](plan/202604250015_admin-frontend-node-status-filter-batch-delete/)
- 决策: admin-frontend-node-status-filter-batch-delete#D001(离线筛选仅匹配显式 offline 状态), admin-frontend-node-status-filter-batch-delete#D002(批量删除复用现有勾选工作流)
## [0.5.14] - 2026-04-25
### 修复
- **[order-payment]**: 补齐订单支付成功快照保存链路;现在会在支付成功后保存支付渠道、支付方法、实际支付金额与支付 IP,并在后台订单详情中集中展示平台订单号 / 商户订单号 / 支付快照信息 — by yinjianm
- 方案: [202604250002_order-payment-snapshot](archive/2026-04/202604250002_order-payment-snapshot/)
- 决策: order-payment-snapshot#D001(支付快照优先展示真实快照并回退当前支付配置), order-payment-snapshot#D002(实际支付金额统一按“分”存储)
## [0.5.13] - 2026-04-25
### 修复
- **[admin-frontend]**: 修复前后台已关闭工单无法再次回复的问题;现在用户与管理员再次回复 closed ticket 时都会自动重新开启工单,管理端工单工作台也补上“发送并重开”交互提示 — by yinjianm
- 方案: [202604250006_ticket-closed-reply-reopen](plan/202604250006_ticket-closed-reply-reopen/)
- 决策: ticket-closed-reply-reopen#D001(自动重开语义统一下沉到 TicketService::reply), ticket-closed-reply-reopen#D002(用户端优先通过后端语义修复打通), ticket-closed-reply-reopen#D003(管理端仅修复交互门禁)
## [0.5.12] - 2026-04-25
### 新增
- **[admin-frontend]**: 为仪表盘顶部指标卡补齐快捷入口增强;“待处理工单 / 待处理佣金 / 总用户”现在可直接进入对应工作台,其中工单页与订单页还会自动识别 dashboard 来源并落在目标视图 — by yinjianm
- 方案: [202604250002_admin-frontend-dashboard-shortcuts](plan/202604250002_admin-frontend-dashboard-shortcuts/)
- 决策: admin-frontend-dashboard-shortcuts#D001(仅开放已有明确承接页的指标卡快捷入口), admin-frontend-dashboard-shortcuts#D002(用路由查询同步 dashboard 入口上下文)
## [0.5.11] - 2026-04-24
### 快速修改
- **[admin-frontend]**: 修复节点管理页多选框点击后立即被程序化同步清空的问题;现在仅在分页切换时回填勾选状态,并在回填期间忽略内部 `selection-change` 事件,节点多选可正常选中与跨页恢复 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/views/nodes/NodesView.vue:67,179-197,240-243,412-417
## [0.5.10] - 2026-04-24
### 快速修改
- **[ci-workflows]**: 将后端镜像发布工作流显式命名为 `Backend Docker Build and Publish`,并对 `admin-frontend/**` 及其独立 workflow 启用 `paths-ignore`;现在仅修改 `admin-frontend` 源码时只触发前端镜像发布,不再误触发后端镜像发布 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: .github/workflows/docker-publish.yml:1-76
## [0.5.9] - 2026-04-24
### 新增
- **[admin-frontend]**: 为节点管理工作台补齐本地分页、父/子节点筛选、单节点置顶与仅对已勾选节点生效的批量修改,支持统一更新 `host / group_ids / rate`,并接通真实 `server/manage/batchUpdate` 后端链路 — by yinjianm
- 方案: [202604242245_admin-frontend-node-pagination-batch-edit](archive/2026-04/202604242245_admin-frontend-node-pagination-batch-edit/)
- 决策: admin-frontend-node-pagination-batch-edit#D001(节点分页采用前端本地分页), admin-frontend-node-pagination-batch-edit#D002(批量修改范围固定为已勾选节点), admin-frontend-node-pagination-batch-edit#D003(置顶节点复用 server/manage/sort)
### 快速修改
- **[admin-frontend]**: 为独立 `xboard-admin-frontend` 容器补齐 `/api` 反向代理到后端 `web` 服务的链路,并在 compose 分支 `admin` 服务中显式声明 `XBOARD_BACKEND_UPSTREAM=http://web:7001`;同时把镜像名对齐到当前 fork `ghcr.io/micah123321/*` — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/Caddyfile:1-17, E:/code/php/Xboard-new-compose/compose.yaml:1-26
## [0.5.8] - 2026-04-24
### 新增
- **[admin-frontend]**: 为 `admin-frontend` 新增独立 Docker 镜像与 GHCR 自动发布链路,支持通过 `ADMIN_BUILD_OUT_DIR` 切换到容器专用 `dist` 输出,并在 `compose` 分支新增独立 `admin` 服务拉取 `ghcr.io/cedar2025/xboard-admin-frontend:new` 暴露运行 — by yinjianm
- 方案: [202604242250_admin-frontend-ghcr-compose](plans/202604242250_admin-frontend-ghcr-compose/)
- 决策: admin-frontend-ghcr-compose#D001(前端镜像发布链路独立于后端 docker-publish), admin-frontend-ghcr-compose#D002(容器内统一重定向到 /assets/admin/), admin-frontend-ghcr-compose#D003(compose 分支采用独立 admin 服务并暴露 7002)
## [0.5.7] - 2026-04-24
### 新增
- **[admin-frontend]**: 为用户管理“更多操作”菜单补齐旧后台常用行级动作,新增分配订单、查看 TA 的订单、查看 TA 的邀请、查看 TA 的流量记录与重置流量,并接通订单页按用户过滤与真实 `traffic-reset/reset-user` 后端链路 — by yinjianm
- 方案: [202604242236_admin-frontend-user-more-actions](plans/202604242236_admin-frontend-user-more-actions/)
- 决策: admin-frontend-user-more-actions#D001(订单分配抽屉预填邮箱), admin-frontend-user-more-actions#D002(用户订单采用跳页 + user_id 过滤), admin-frontend-user-more-actions#D003(邀请结果复用当前用户页筛选视图)
## [0.5.6] - 2026-04-24
### 修复
- **[admin-frontend]**: 修复订单管理页把无佣金订单误显示为“待确认”的问题;现在佣金状态会按真实佣金金额与发放链路判断,同时新增“确认佣金”菜单,可筛出真实待确认订单并在列表行级直接手动确认 — by yinjianm
- 方案: [202604242217_admin-frontend-orders-commission-confirmation](archive/2026-04/202604242217_admin-frontend-orders-commission-confirmation/)
- 决策: admin-frontend-orders-commission-confirmation#D001(真实佣金判定以金额和发放链路为准), admin-frontend-orders-commission-confirmation#D002(列表页新增确认佣金菜单与单行快捷确认)
## [0.5.5] - 2026-04-24
### 新增
- **[admin-frontend]**: 为用户管理工作台新增高级筛选与批量操作能力,支持多条件筛选、批量发送邮件、导出 CSV、批量封禁,以及对筛选结果执行“恢复正常” — by yinjianm
- 方案: [202604242200_admin-frontend-user-advanced-filter-batch-ops](plans/202604242200_admin-frontend-user-advanced-filter-batch-ops/)
- 决策: admin-frontend-user-advanced-filter-batch-ops#D001(高级筛选采用独立弹窗), admin-frontend-user-advanced-filter-batch-ops#D002(批量作用域按 selected > filtered > all 解析), admin-frontend-user-advanced-filter-batch-ops#D003(恢复正常沿用 user/ban 并扩展 banned=0|1)
## [0.5.4] - 2026-04-24
### 修复
- **[admin-frontend]**: 修复仪表盘“节点流量排行 / 用户流量排行”在 `24h` 视图下涨跌始终显示 `0%` 的问题;后端现在会把单日排行改为精确对比昨天整日统计,前端同步补上悬浮详情卡,并把当前流量值右移强化显示 — by yinjianm
- 方案: [202604241925_admin-frontend-dashboard-rank-24h-compare](plan/202604241925_admin-frontend-dashboard-rank-24h-compare/)
- 决策: admin-frontend-dashboard-rank-24h-compare#D001(仅修复 24h 与昨天对比逻辑,7天/30天 保持现状), admin-frontend-dashboard-rank-24h-compare#D002(排行项补充 hover 详情卡,并将当前流量右移显示)
## [0.5.3] - 2026-04-24
### 新增
- **[admin-frontend]**: 完成节点管理真实新增 / 编辑 / 排序工作台,补齐 11 种协议的动态配置弹窗、动态倍率规则编辑、路由 / 权限组联动与排序保存流程,并接入真实 `server/manage/save``server/manage/sort``server/route/fetch` 后台接口 — by yinjianm
- 方案: [202604241718_admin-frontend-node-management](plans/202604241718_admin-frontend-node-management/)
- 决策: admin-frontend-node-management#D001(新增与编辑共用中央大弹窗), admin-frontend-node-management#D002(排序沿用本地草稿 + 上移 / 下移), admin-frontend-node-management#D003(协议配置采用通用字段 + 动态协议块)
## [0.5.2] - 2026-04-24
### 新增
- **[admin-frontend]**: 开放“礼品卡管理”入口,完整交付模板管理、兑换码管理、使用记录与统计数据四页签工作台,并接入真实 `gift-card/*` 后台接口 — by yinjianm
- 方案: [202604241703_admin-frontend-gift-card-management](archive/2026-04/202604241703_admin-frontend-gift-card-management/)
- 决策: admin-frontend-gift-card-management#D001(礼品卡管理采用单页四页签导航), admin-frontend-gift-card-management#D002(模板编辑使用分组式大抽屉), admin-frontend-gift-card-management#D003(兑换码导出按当前批次显式执行)
## [0.5.1] - 2026-04-24
### 新增
- **[admin-frontend]**: 完成“路由管理”真实工作台,支持路由列表、关键词搜索、新增/编辑弹窗、删除,以及基于节点 `route_ids` 推导的节点引用摘要,并接入真实 `server/route/*` 后台接口 — by yinjianm
- 方案: [202604241701_admin-frontend-node-route-management](plan/202604241701_admin-frontend-node-route-management/)
- 决策: admin-frontend-node-route-management#D001(列表页贴近用户截图并保留 Apple 化后台节奏), admin-frontend-node-route-management#D002(节点引用摘要先收敛为列表只读信息而不扩展拓扑视图), admin-frontend-node-route-management#D003(动作值仅在 dns/proxy 时显示独立输入)
## [0.5.0] - 2026-04-24
### 新增
- **[admin-frontend]**: 将 `#/node-groups` 从占位页升级为真实权限组管理工作台,支持搜索、新增/编辑中央弹窗、删除确认,并补齐到 `#/nodes` 的权限组筛选联动入口 — by yinjianm
- 方案: [202604241659_admin-frontend-node-group-management](archive/2026-04/202604241659_admin-frontend-node-group-management/)
- 决策: admin-frontend-node-group-management#D001(权限组页采用截图导向的轻量工作台), admin-frontend-node-group-management#D002(新增与编辑复用同一中央弹窗), admin-frontend-node-group-management#D003(节点数量列承担跳转到节点筛选的联动入口)
## [0.4.8] - 2026-04-24
### 修复
- **[admin-frontend]**: 修复 `#/system/knowledge` 仍回退到结构化占位页的问题,补齐真实知识库管理列表挂载、详情编辑加载与最新构建产物刷新 — by yinjianm
- 方案: [202604241610_admin-frontend-knowledge-management](plan/202604241610_admin-frontend-knowledge-management/)
- 决策: admin-frontend-knowledge-management#D001(编辑器采用轻量 Markdown 方案), admin-frontend-knowledge-management#D002(列表页采用真实表格与中央对话框), admin-frontend-knowledge-management#D003(排序采用本地草稿编辑后统一提交)
## [0.4.7] - 2026-04-24
### 修复
- **[admin-frontend]**: 修复管理端侧边栏在低窗口高度下会裁切底部菜单的问题;现在顶部品牌区保持固定,菜单区可独立滚动访问“礼品卡管理”“系统管理”“支付配置”“知识库管理”等底部入口 — by yinjianm
- 方案: [202604241655_admin-frontend-sidebar-height-overflow](archive/2026-04/202604241655_admin-frontend-sidebar-height-overflow/)
- 决策: admin-frontend-sidebar-height-overflow#D001(固定品牌区 + 独立滚动菜单区)
## [0.4.6] - 2026-04-24
### 修复
- **[subscription-protocols]**: 修复 `flag=stash` 订阅在未知版本或低版本客户端下仍导出 `AnyTLS` 节点的问题;现在只有 Stash `>= 3.3.0` 才会保留 `AnyTLS`,避免导入时报“**不支持 anytls 协议**” — by yinjianm
- 方案: [202604241619_fix-stash-anytls-compat-filter](plan/202604241619_fix-stash-anytls-compat-filter/)
- 决策: fix-stash-anytls-compat-filter#D001(未知版本按不支持 AnyTLS 处理), fix-stash-anytls-compat-filter#D002(仅在 Stash 导出器中做定点修复)
## [0.4.5] - 2026-04-24
### 新增
- **[admin-frontend]**: 开放“订单管理”入口,完整交付真实订单列表、类型/周期/状态筛选、分配订单抽屉、详情抽屉、手动标记已支付与佣金状态维护,并接入 `order/*` 后台接口 — by yinjianm
- 方案: [202604241620_admin-frontend-order-management](archive/2026-04/202604241620_admin-frontend-order-management/)
- 决策: admin-frontend-order-management#D001(列表页贴近用户截图并保留 Apple 化后台节奏), admin-frontend-order-management#D002(详情操作收口到订单详情抽屉而不是额外操作列), admin-frontend-order-management#D003(订单金额统一按“分→元”格式化展示)
## [0.4.4] - 2026-04-24
### 新增
- **[admin-frontend]**: 完成“支付配置”真实工作台,支持支付方式列表、关键词搜索、启停、删除、动态配置抽屉与排序模式,并接入真实 `payment/*` 后台接口 — by yinjianm
- 方案: [202604241558_admin-frontend-payment-management](archive/2026-04/202604241558_admin-frontend-payment-management/)
- 决策: admin-frontend-payment-management#D001(真实列表页+动态配置抽屉+排序对话框), admin-frontend-payment-management#D002(支付配置字段完全以后端动态表单为真相源), admin-frontend-payment-management#D003(启停继续沿用切换型接口并做同值短路保护)
## [0.4.3] - 2026-04-24
### 新增
- **[admin-frontend]**: 将 `#/system/themes` 从结构化占位页升级为真实主题管理页面,接入主题列表、当前主题切换、动态主题配置抽屉与 zip 主题上传入口 — by yinjianm
- 方案: [202604241607_admin-frontend-theme-management](archive/2026-04/202604241607_admin-frontend-theme-management/)
- 决策: admin-frontend-theme-management#D001(主题切换复用 config/save(frontend_theme)), admin-frontend-theme-management#D002(主题配置统一放入抽屉)
## [0.4.3] - 2026-04-24
### 新增
- **[admin-frontend]**: 将 `#/system/plugins` 从占位页升级为真实插件管理工作台,接入插件列表、类型 / 状态筛选、上传、安装、启停、升级、卸载,以及 README / 动态配置抽屉;同时补齐缺失的订单管理与知识库管理路由壳层以恢复 `npm run build` 通过 — by yinjianm
- 方案: [202604241553_admin-frontend-plugin-management](archive/2026-04/202604241553_admin-frontend-plugin-management/)
- 决策: admin-frontend-plugin-management#D001(插件管理采用卡片列表 + 详情抽屉), admin-frontend-plugin-management#D002(配置编辑使用动态 schema 渲染), admin-frontend-plugin-management#D003(README 与配置合并进同一个详情工作台)
## [0.4.2] - 2026-04-24
### 新增
- **[admin-frontend]**: 完成“知识库管理”真实工作台,支持知识列表、标题搜索、分类筛选、显隐切换、新增/编辑弹窗、删除与排序模式,并接入真实 `knowledge/*` 后台接口 — by yinjianm
- 方案: [202604241610_admin-frontend-knowledge-management](plan/202604241610_admin-frontend-knowledge-management/)
- 决策: admin-frontend-knowledge-management#D001(编辑器采用轻量 Markdown 方案), admin-frontend-knowledge-management#D002(列表页采用真实表格与中央对话框), admin-frontend-knowledge-management#D003(排序采用本地草稿编辑后统一提交)
## [0.4.1] - 2026-04-24
### 新增
- **[admin-frontend]**: 完成“公告管理”真实工作台,支持公告列表、标题搜索、显隐切换、新增/编辑弹窗、删除与排序模式,并接入真实 `notice/*` 后台接口 — by yinjianm
- 方案: [202604241609_admin-frontend-notice-management](plan/202604241609_admin-frontend-notice-management/)
- 决策: admin-frontend-notice-management#D001(真实列表页+编辑弹窗+排序对话框), admin-frontend-notice-management#D002(公告内容编辑继续使用轻量 Markdown 方案), admin-frontend-notice-management#D003(公告开关与标签统一归一化)
## [0.4.0] - 2026-04-24
### 新增
- **[admin-frontend]**: 开放“优惠券管理”入口,完整交付优惠券列表、关键字搜索、类型筛选、启停、删除,以及接入真实 `coupon/*` 接口的新增/编辑弹窗 — by yinjianm
- 方案: [202604241551_admin-frontend-coupon-management](archive/2026-04/202604241551_admin-frontend-coupon-management/)
- 决策: admin-frontend-coupon-management#D001(优惠券列表采用真实接口+本地搜索筛选分页), admin-frontend-coupon-management#D002(新增与编辑共用同一弹窗并统一序列化), admin-frontend-coupon-management#D003(优惠券编辑采用居中弹窗而非抽屉)
## [0.3.2] - 2026-04-24
### 修复
- **[admin-frontend]**: 修复 `#/subscriptions/plans` 页面首次加载时会误把套餐“新购”状态批量关闭的问题;现在会先归一化 `show / sell / renew` 开关值,并在同值事件下短路,避免浏览页面即触发真实写操作 — by yinjianm
- 方案: [202604241542_admin-frontend-plan-toggle-regression](plan/202604241542_admin-frontend-plan-toggle-regression/)
- 决策: admin-frontend-plan-toggle-regression#D001(前端入口先归一化套餐开关值), admin-frontend-plan-toggle-regression#D002(开关提交增加同值短路护栏)
## [0.3.0] - 2026-04-23
### 新增
- **[admin-frontend]**: 新增“节点管理”侧边栏分组、节点管理工作台,以及权限组/路由管理占位页;同时补齐缺失的 `PlansView` 占位组件以恢复 `npm run build` 构建通过 — by yinjianm
- 方案: [202604232320_admin-frontend-node-management](archive/2026-04/202604232320_admin-frontend-node-management/)
- 决策: admin-frontend-node-management#D001(首批聚焦节点列表运营链路), admin-frontend-node-management#D002(权限组与路由管理先交付结构化占位页)
## [0.3.1] - 2026-04-23
### 新增
- **[admin-frontend]**: 新增“系统管理”侧边栏分组,完整交付系统配置页,并接入插件/主题/公告/支付/知识库 5 个结构化占位页 — by yinjianm
- 方案: [202604232329_admin-frontend-system-management](archive/2026-04/202604232329_admin-frontend-system-management/)
- 决策: admin-frontend-system-management#D001(首批聚焦系统配置真实页), admin-frontend-system-management#D002(其余系统管理入口先交付结构化占位页), admin-frontend-system-management#D003(系统配置采用左侧分组导航与右侧连续 section)
## [0.1.0] - 2026-04-21
### 新增
- **[admin-frontend]**: 完成深色 Composio 风格管理端仪表盘、登录回跳和真实统计面板接入 — by yinjianm
- 方案: [202604210326_admin-frontend-composio-dashboard](archive/2026-04/202604210326_admin-frontend-composio-dashboard/)
- 决策: admin-frontend-composio-dashboard#D001(采用深色 Composio 风格), admin-frontend-composio-dashboard#D002(趋势图使用自绘 SVG)
## [0.1.1] - 2026-04-21
### 修复
- **[admin-frontend]**: 将登录页、主布局和仪表盘重构为 Apple 风格,并移除高成本视觉装饰以缓解页面卡顿 — by yinjianm
- 方案: [202604210400_admin-frontend-apple-performance-refresh](archive/2026-04/202604210400_admin-frontend-apple-performance-refresh/)
- 决策: admin-frontend-apple-performance-refresh#D001(采用 Apple 风格并优先性能减法), admin-frontend-apple-performance-refresh#D002(保留逻辑层只替换视图皮层)
## [0.1.2] - 2026-04-21
### 快速修改
- **[admin-frontend]**: 修正仪表盘金额显示单位,将后端返回的“分”统一转换为“元”后再格式化 — by yinjianm
- 类型: 快速修改(无方案包)
- 文件: admin-frontend/src/utils/dashboard.ts:75
## [0.2.0] - 2026-04-21
### 新增
- **[admin-frontend]**: 新增用户管理工作台、抽屉表单、用户操作菜单,以及“用户管理 / 工单管理”导航与路由骨架 — by yinjianm
- 方案: [202604210441_admin-frontend-user-management](archive/2026-04/202604210441_admin-frontend-user-management/)
- 决策: admin-frontend-user-management#D001(新增用户采用两段式创建), admin-frontend-user-management#D002(先补齐用户与工单入口结构)
## [0.2.1] - 2026-04-23
### 新增
- **[admin-frontend]**: 为仪表盘收入趋势面板新增“按金额 / 按数量”切换,并让图表摘要、Y 轴标签与最近记录跟随口径同步 — by yinjianm
- 方案: [202604232313_admin-frontend-dashboard-trend-count-toggle](archive/2026-04/202604232313_admin-frontend-dashboard-trend-count-toggle/)
- 决策: admin-frontend-dashboard-trend-count-toggle#D001(采用单图切换而不是双图/双线), admin-frontend-dashboard-trend-count-toggle#D002(数量模式复用现有接口字段)
## [0.2.2] - 2026-04-23
### 新增
- **[admin-frontend]**: 为仪表盘节点/用户流量排行新增 `10个 / 20个` 显示切换,并将长列表收进面板内滚动区域 — by yinjianm
- 方案: [202604232318_admin-frontend-rank-limit-scroll](archive/2026-04/202604232318_admin-frontend-rank-limit-scroll/)
- 决策: admin-frontend-rank-limit-scroll#D001(两个排行面板独立控制显示数量), admin-frontend-rank-limit-scroll#D002(使用固定高度滚动容器而不是整页自然拉伸)
## [0.2.3] - 2026-04-23
### 新增
- **[admin-frontend]**: 为仪表盘“作业详情”面板新增“查看报错详情”入口,并通过弹窗展示失败作业的报错摘要、失败时间与队列信息 — by yinjianm
- 方案: [202604232330_admin-frontend-queue-error-details](plan/202604232330_admin-frontend-queue-error-details/)
- 决策: admin-frontend-queue-error-details#D001(使用弹窗承载失败作业详情), admin-frontend-queue-error-details#D002(前端兼容式解析 Horizon 失败作业字段)
## [0.2.4] - 2026-04-23
### 新增
- **[admin-frontend]**: 为 traffic rank 前后端联动补齐 `limit=10|20` 支持,让排行数量切换真正驱动后端返回条数,并保留 24h 口径的涨跌展示 — by yinjianm
- 方案: [202604232345_traffic-rank-limit-backend-adapt](archive/2026-04/202604232345_traffic-rank-limit-backend-adapt/)
- 决策: traffic-rank-limit-backend-adapt#D001(在现有 getTrafficRank 接口上新增 limit 参数), traffic-rank-limit-backend-adapt#D002(24h 口径继续显示 change)
## [0.2.5] - 2026-04-23
### 新增
- **[admin-frontend]**: 为 Apple 风格仪表盘新增 Hero 区“刷新全部数据”按钮,并补齐最后刷新时间、加载反馈与防重复触发状态 — by yinjianm
- 方案: [202604231515_admin-frontend-dashboard-refresh-button](archive/2026-04/202604231515_admin-frontend-dashboard-refresh-button/)
- 决策: admin-frontend-dashboard-refresh-button#D001(刷新入口放在 Hero 状态区), admin-frontend-dashboard-refresh-button#D002(复用 refreshDashboard 作为唯一全量刷新入口)
## [0.2.6] - 2026-04-23
### 新增
- **[admin-frontend]**: 新增“订阅管理”侧边栏分组与套餐管理页面,支持真实套餐 CRUD、排序、价格矩阵与说明预览 — by yinjianm
- 方案: [202604232325_admin-frontend-subscription-plan-management](plan/202604232325_admin-frontend-subscription-plan-management/)
- 决策: admin-frontend-subscription-plan-management#D001(其余订阅菜单先保留禁用入口), admin-frontend-subscription-plan-management#D002(说明编辑采用轻量 Markdown 方案), admin-frontend-subscription-plan-management#D003(排序采用本地编辑对话框)
+74
View File
@@ -0,0 +1,74 @@
# Xboard-new 管理端设计系统
## 产品表面
- `admin-frontend` 是数据密集型管理后台,当前核心界面包括仪表盘、用户管理、工单管理、节点管理、系统管理,以及本轮新增的订阅管理。
- 侧边栏承担一级信息架构,页面主体承担筛选、批量判断和单行操作,不把复杂流程全部堆进列表页;新增业务域优先用独立分组承载。
- 节点管理属于“高密度运营页”:用户需要在一个视图里快速判断节点状态、倍率、权限组与在线人数,再决定是否继续深入编辑。
- 套餐管理属于“结构化配置页”:用户需要在一页内完成套餐开关、价格、分组、说明和排序维护,强调表格与抽屉之间的稳定切换。
## 美学方向
- 延续 `apple/DESIGN.md` 的 Apple 风格:纯色分区、系统字体、克制阴影、低噪音交互。
- 管理后台不追求营销式华丽,而是强调“黑白主场 + 蓝色交互 + 轻薄容器”的精密运营感。
- 新页面应与现有仪表盘 / 用户管理保持同一视觉家族,避免出现另一套后台皮肤。
## 设计 token
- 背景与表面继续复用 `admin-frontend/src/styles/index.scss` 中的 `--xboard-*` 变量。
- 主色固定为 `#0071e3`,仅用于激活态、主按钮、焦点和核心交互反馈。
- 文本层级固定为:`--xboard-text-strong` 主标题、`--xboard-text-secondary` 正文、`--xboard-text-muted` 辅助信息。
- 表格、筛选器、状态徽章允许新增页面级局部变量,但不得绕开全局 token 直接堆随机颜色。
## 布局策略
- 一级导航仍采用左侧固定侧边栏,节点相关入口归入独立的“节点管理”分组,不混入“用户管理”分组。
- 订阅相关入口归入独立的“订阅管理”分组;未实现的订单/优惠券/礼品卡入口允许先以禁用态占位。
- 系统相关能力归入独立的“系统管理”分组;长表单型配置页采用“左侧分组导航 + 右侧连续 section”的后台编辑结构。
- 页面头部保持“大标题 + 一句说明 + 右侧操作”的双栏结构,首屏先给运营者建立页面心智,再进入列表。
- 列表上方先放一层紧凑筛选工具条:搜索框、类型筛选、权限组筛选、主操作按钮,避免二次折叠菜单。
- 宽表格在桌面优先完整呈现;窄屏时允许信息折行,但不牺牲主列的可读性。
- 订阅页面优先采用“黑色首屏 + 白色工作台 + 右侧抽屉”的结构,让套餐列表、价格矩阵和说明编辑形成清晰主次。
## 组件与模式
- 侧边栏分组标题使用 `ElSubMenu`,子项必须与业务域一一对应。
- 列表页优先使用原生 `ElTable` + Apple 化外观,不重新发明表格基础能力。
- 配置页优先使用原生 `ElForm``ElInput``ElSwitch``ElSelect``ElInputNumber` 组合,不在后台长表单里引入花哨交互。
- 状态使用“圆点 + 文本/徽章”双信号表达,避免仅靠颜色辨识在线/离线。
- 危险操作收入口袋菜单,主列表行只露出最常用的显隐切换与查看信息。
- 未进入本轮范围的功能允许放入占位页,但要明确标注“下一阶段接入”,不能伪装成可用功能。
## 状态覆盖
- 加载态:列表区域显示骨架或表格 loading,不让整页空白。
- 空状态:给出“当前筛选条件下暂无节点”与一键清空筛选入口。
- 错误态:保留用户当前筛选条件,并允许重试,不把失败吞掉。
- 成功态:显隐切换、复制节点、删除节点等操作使用明确 toast 反馈。
- 禁用态:未实现或不可用的操作按钮必须有禁用样式和原因说明。
## 记忆点
- 让用户记住“黑色首屏 + 运营表格 + 左侧节点分组”这一套安静但高辨识度的 Apple 化后台结构。
## 动效策略
- 只保留必要动效:筛选 pill 激活、按钮 hover、表格操作反馈、占位页轻微过渡。
- 禁止厚重的卡片飞入、长时间遮罩和无意义动画;尊重 `prefers-reduced-motion`
## 无障碍要求
- 所有按钮、开关、下拉菜单都保留可见焦点。
- 表格操作必须支持键盘聚焦,危险动作要有明确文案。
- 在线状态除颜色外还要搭配文字或点位说明。
## 内容语气
- 标题直接、运营化,不写营销语。
- 空状态和占位提示应明确告诉用户“现在能做什么 / 下一阶段会补什么”。
- 操作按钮统一使用动词短语,如“添加节点”“编辑排序”“复制节点”“删除节点”。
## 禁止事项
- 禁止回到紫色渐变、玻璃拟态大面积模糊、厚重卡片堆叠。
- 禁止把节点列表页做成营销落地页式大色块拼贴。
- 禁止使用 emoji、随机插画或与 Xboard 运营后台无关的装饰元素。
## 约束定义
- 主页面同时出现的主操作按钮不超过 2 个。
- 同一页面强调色不超过 1 个,语义色只用于状态。
- 列表工具条最多一行半,超过则折叠到二级策略,不无限横向增长。
## 实现备注
- 全局 token 继续落在 `admin-frontend/src/styles/index.scss`
- 节点页相关的格式化与映射逻辑优先放到 `admin-frontend/src/utils/nodes.ts`
- 节点管理分组路由位于 `admin-frontend/src/router/index.ts`,页面实现位于 `admin-frontend/src/views/nodes/`
+31
View File
@@ -0,0 +1,31 @@
# Xboard-new 知识库
```yaml
kb_version: 2
project: Xboard-new
updated_at: 2026-04-29
active_package:
```
## 项目概览
- 类型: PHP Laravel 主仓 + `admin-frontend` Vue3 管理端前端
- 当前重点模块: `admin-frontend``deploy``node-gfw-check``node-traffic-limit``order-payment``queue-mail``subscription-protocols``user-frontend-access`
- 最新归档: `202604291559_user-frontend-access-toggle`
## 活跃模块
- [admin-frontend](modules/admin-frontend.md): 管理端登录、主布局、仪表盘、用户/节点/订阅/系统管理与管理 API 前端封装
- [ci-workflows](modules/ci-workflows.md): GitHub Actions 后端与管理端前端镜像发布工作流、路径触发边界和 GHCR 发布规则
- [deploy](modules/deploy.md): 可复制到服务器的 Xboard Compose 部署模板、环境变量模板和运维脚本
- [node-gfw-check](modules/node-gfw-check.md): 节点墙状态检测任务、父/子节点继承规则、mi-node 检测上报链路
- [node-traffic-limit](modules/node-traffic-limit.md): 节点月流量限额配置、共享账期用量、重置调度、metrics 状态回写与 mi-node 强制下线协作
- [order-payment](modules/order-payment.md): 订单支付成功快照、第三方回调元信息透传与后台支付成功信息展示
- [queue-mail](modules/queue-mail.md): 邮件发送队列、SMTP 运行时配置、Horizon 超时与失败重试边界
- [subscription-protocols](modules/subscription-protocols.md): 客户端订阅导出入口、协议适配器与版本兼容过滤
- [user-frontend-access](modules/user-frontend-access.md): 用户前端首页访问开关与 API 保留边界
## 归档与变更
- 归档索引: [archive/_index.md](archive/_index.md)
- 变更日志: [CHANGELOG.md](CHANGELOG.md)
@@ -0,0 +1,10 @@
{
"status": "completed",
"completed": 6,
"failed": 0,
"pending": 0,
"total": 6,
"percent": 100,
"current": "completed",
"updated_at": "2026-04-16 17:04:30"
}
@@ -0,0 +1,135 @@
# 变更提案: merge-upstream-preserve-local
## 元信息
```yaml
类型: 优化
方案类型: implementation
优先级: P1
状态: 已确认
创建: 2026-04-16
```
---
## 1. 需求
### 背景
当前工作分支位于 `master`,本地相对 `upstream/master` 领先 15 个提交、落后 47 个提交。
用户要求在保留所有本地改动与本地功能优先级的前提下,将 `https://github.com/cedar2025/Xboard`
的最新代码合并到当前分支。现场还存在未跟踪的 `.helloagents/` 目录,以及
`public/assets/admin` 子模块指针与 `upstream/master` 不一致,需要在合并时避免误覆盖。
### 目标
-`upstream/master` 的最新提交合并到当前分支。
- 保留当前分支已有提交与本地工作树内容,不做重置、不强推、不丢改动。
- 当出现文本冲突时优先保留当前分支的实现。
- 当出现子模块指针冲突时,显式保留当前分支所指向的子模块版本,并完成核对。
### 约束条件
```yaml
时间约束: 当前回合内完成保护、合并、冲突处理和结果核验
性能约束: N/A
兼容性约束: 不改变当前分支名称,不破坏已有 Git 历史,避免影响未跟踪的本地目录
业务约束: 发生冲突时以用户本地功能优先;不使用 reset --hard 或覆盖式同步
```
### 验收标准
- [ ] 已成功抓取并合并 `upstream/master` 到当前分支,且本地 15 个领先提交仍保留在历史中
- [ ] 工作树中的本地未跟踪内容未丢失,合并冲突已处理完毕
- [ ] 若产生冲突,文本文件优先保留当前分支实现;`public/assets/admin` 子模块指针按当前分支版本保留并确认
- [ ] 合并后完成基本核验,包括分叉变化、工作树状态、子模块状态与冲突标记清零
---
## 2. 方案
### 技术方案
采用“保护现场 + 常规 merge + 冲突偏向当前分支 + 显式核对子模块”的方案:
1. 记录当前现场,包括分支、工作树、与 `upstream/master` 的分叉和子模块指针。
2. 创建本地安全锚点(备份分支或标签),确保任何一步异常都可回到操作前状态。
3. 视需要暂存未跟踪内容,避免合并期间被意外干扰。
4. 执行 `git merge -X ours upstream/master`,让文本冲突默认偏向当前分支。
5. 如出现子模块指针冲突,手工恢复为当前分支所引用的子模块提交,而不是盲目接受上游版本。
6. 完成后检查 `git status`、分叉计数、merge commit、子模块状态和冲突残留,确认结果满足“本地优先”要求。
### 影响范围
```yaml
涉及模块:
- Git 历史: 当前分支将新增一次来自 upstream/master 的合并结果
- 根仓工作树: 可能因上游更新而变更多个跟踪文件
- public/assets/admin: 子模块指针可能出现冲突,需要显式保留本地版本
- .helloagents/plan: 新增本次操作的方案包与执行记录
预计变更文件: 多文件,数量取决于 upstream/master 与当前分支差异
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| `-X ours` 仅对文本冲突生效,无法自动正确处理子模块指针 | 高 | 合并后单独检查 `public/assets/admin`,必要时显式 checkout 当前分支的子模块提交 |
| 未跟踪的 `.helloagents/` 内容在操作中被误干扰 | 中 | 先记录现场,必要时仅暂存未跟踪内容,不删除任何本地文件 |
| 上游 47 个提交引入的结构变化与本地 15 个提交存在深度冲突 | 中 | 保留备份锚点,逐项处理冲突并在结果核验中确认本地功能仍存在 |
| 误把 `origin/master` 当作基线导致合并方向错误 | 低 | 固定以 `upstream/master` 为唯一上游基线执行本次合并 |
---
## 3. 技术设计(可选)
> 本次为 Git 合并操作,无架构/API/数据模型设计变更。
### 架构设计
N/A
### API设计
N/A
### 数据模型
N/A
---
## 4. 核心场景
> 本次为仓库合并操作,不涉及业务模块文档同步场景。
### 场景: 当前分支合并 upstream/master
**模块**: Git 仓库 / 子模块
**条件**: 当前分支存在本地领先提交,且用户要求本地实现优先
**行为**: 拉取 upstream 最新提交并合并到当前分支,冲突时优先保留当前分支内容,子模块指针冲突显式保留当前指针
**结果**: 当前分支吸收上游更新,同时保住本地提交和本地优先实现
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### merge-upstream-preserve-local#D001: 采用 merge 而非 reset、rebase 或手工摘取提交
**日期**: 2026-04-16
**状态**: ✅采纳
**背景**: 用户要求“保留所有本地更改”并把远端最新代码合并到当前项目,同时冲突时本地功能优先。需要选择一种既能保留历史又便于冲突处理的更新方式。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: `git merge -X ours upstream/master` | 保留分支历史,适合把上游更新并入当前分支,文本冲突可偏向本地实现 | 不能自动正确处理子模块指针,需要额外检查 |
| B: `git rebase upstream/master` | 历史更线性 | 会重写当前分支提交,冲突重放次数可能更多,不符合“尽量保留现状” |
| C: `git reset --hard upstream/master` 后再回放本地改动 | 操作简单 | 高风险,会直接破坏当前现场,不符合需求 |
**决策**: 选择方案 A
**理由**: 常规 merge 最符合“保留本地提交和现场”的要求,结合 `-X ours` 能让文本冲突尽量偏向当前分支;剩余的子模块冲突可控且可显式核验。
**影响**: 影响当前分支历史、根仓工作树状态,以及 `public/assets/admin` 子模块指针处理方式
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- N/A
### 视觉要素
- N/A
### 技术约束
- **可访问性**: N/A
- **响应式**: N/A
@@ -0,0 +1,58 @@
# 任务清单: merge-upstream-preserve-local
> **@status:** completed | 2026-04-16 17:00
```yaml
@feature: merge-upstream-preserve-local
@created: 2026-04-16
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 6 | 0 | 0 | 6 |
---
## 任务列表
### 1. 现场保护与基线确认
- [√] 1.1 记录当前分支、工作树、与 `upstream/master` 的分叉、子模块指针和未跟踪内容,作为操作前证据 | depends_on: []
- [√] 1.2 创建可回退的本地安全锚点,确保合并异常时能恢复到操作前状态 | depends_on: [1.1]
### 2. 执行合并并处理冲突
- [√] 2.1 在不丢失本地内容的前提下执行 `upstream/master` 合并到当前分支,并让文本冲突优先保留当前分支实现 | depends_on: [1.2]
- [√] 2.2 若发生子模块或特殊冲突,显式保留当前分支的 `public/assets/admin` 指针与本地优先实现 | depends_on: [2.1]
### 3. 结果核验与交付
- [√] 3.1 核验合并结果,包括冲突清零、分叉变化、merge commit、子模块状态和工作树状态 | depends_on: [2.2]
- [√] 3.2 输出本次操作结果、残留风险和必要的后续建议 | depends_on: [3.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-16 16:55:00 | 方案包创建 | completed | 已创建 `202604161655_merge-upstream-preserve-local` |
| 2026-04-16 17:01:00 | 1.1 | completed | 已记录当前分支、分叉 `47/15`、未跟踪方案包文件与子模块指针 `c5d9835` |
| 2026-04-16 17:01:30 | 1.2 | completed | 已创建安全锚点分支 `backup/pre-upstream-merge-20260416-1701` |
| 2026-04-16 17:03:30 | 2.1 | completed | 已执行 `git merge -X ours --no-edit upstream/master` 并生成 merge commit `abd64ed` |
| 2026-04-16 17:04:00 | 2.2 | completed | 已保留 `app/Services/UserOnlineService.php` 与子模块指针 `public/assets/admin@c5d9835` 的当前分支版本 |
| 2026-04-16 17:04:30 | 3.1/3.2 | completed | 已确认相对 `upstream/master``0/16`,工作树仅剩未跟踪的方案包文件 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 当前基线远端已确认使用 `upstream/master`
- 已识别 `public/assets/admin` 子模块指针与 `upstream/master` 不一致,需在合并时单独核验
- `git diff --check --cached` 报告多处尾随空格,来源于合并后的暂存内容,未作为本次阻断项处理
@@ -0,0 +1,10 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"percent": 100,
"current": "completed",
"updated_at": "2026-04-16 17:08:30"
}
@@ -0,0 +1,128 @@
# 变更提案: create-git-merge-preserve-local-skill
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 已确认
创建: 2026-04-16
```
---
## 1. 需求
### 背景
本次已在 `Xboard-new` 仓库中完成一次“以 `upstream/master` 为基线、保留本地改动优先”的真实合并。
这类需求在多仓协作中出现频率高,且容易踩到 dirty worktree、`modify/delete` 冲突、子模块 gitlink
冲突、错误远端基线等问题,适合沉淀成一个可复用 skill。
### 目标
- 在全局技能目录创建一个可自动发现的 skill。
- 让 skill 能指导 Codex 安全地把远端最新代码合并到当前分支,同时尽量保住本地改动并在冲突时偏向本地实现。
- 覆盖常见高风险场景,包括未提交改动、`modify/delete` 冲突、子模块冲突和合并后核验。
### 约束条件
```yaml
时间约束: 当前回合内完成创建、校验和可用性说明
性能约束: N/A
兼容性约束: skill 需放在 C:/Users/xiaohuli/.codex/skills 下以便全局自动发现
业务约束: 说明必须体现“保本地优先”语义,避免把 merge 写成 rebase/reset/强推流程
```
### 验收标准
- [ ] `C:/Users/xiaohuli/.codex/skills/git-merge-preserve-local/` 下存在完整 skill 目录
- [ ] `SKILL.md` 明确描述触发场景、工作流和关键风险点
- [ ] 至少有一份参考文档沉淀具体命令模板与冲突处理要点
- [ ] skill 通过 `quick_validate.py` 校验
---
## 2. 方案
### 技术方案
创建一个轻量级 workflow skill
1.`init_skill.py` 在全局技能目录初始化 `git-merge-preserve-local`
2. 将核心触发条件和执行骨架写入 `SKILL.md`,保持内容精炼。
3. 将具体命令模板、冲突配方和核验清单下沉到 `references/merge-playbook.md`
4.`generate_openai_yaml.py` 生成 `agents/openai.yaml`,补齐 UI 元数据。
5. 运行 `quick_validate.py` 做结构校验。
### 影响范围
```yaml
涉及模块:
- 全局 Codex skills: 新增 git-merge-preserve-local skill
- 当前仓库 .helloagents: 新增本次方案包与执行记录
预计变更文件: 4-6
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 说明过长、触发词不清,导致 skill 不易命中或上下文成本过高 | 中 | 将流程骨架留在 `SKILL.md`,把命令细节下沉到 references |
| 将“保本地优先”误写成 `reset``rebase``push --force` | 高 | 明确写出推荐 merge 路径与禁用路径 |
| 忽略子模块 gitlink 冲突,导致 skill 在真实仓库里误导操作 | 高 | 单独增加子模块冲突章节和验证清单 |
---
## 3. 技术设计(可选)
> 本次为全局 skill 创建,不涉及业务系统架构/API/数据模型设计。
### 架构设计
N/A
### API设计
N/A
### 数据模型
N/A
---
## 4. 核心场景
> 该 skill 面向 Git 合并流程复用,不同步项目业务模块文档。
### 场景: 将上游最新代码合并到当前分支且保留本地优先
**模块**: 全局技能 / Git 工作流
**条件**: 用户要求同步远端最新代码,但不希望丢失本地改动,且冲突时偏向本地实现
**行为**: 先识别真实上游基线、保护现场,再执行 merge、处理冲突并核验
**结果**: 能在真实仓库中复用一套较稳健的“保本地优先合并”操作流程
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### create-git-merge-preserve-local-skill#D001: 采用“SKILL.md + references”而非附带脚本自动执行 merge
**日期**: 2026-04-16
**状态**: ✅采纳
**背景**: 这类 Git 合并任务高度依赖现场状态,直接自动执行脚本容易因远端、分支、dirty worktree、子模块结构差异而误伤仓库。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: `SKILL.md + references` | 复用性高,允许结合现场状态判断,适合不同仓库差异 | 不是一键脚本,需要代理自己执行命令 |
| B: 直接附自动 merge 脚本 | 执行更快 | 风险高,容易在错误远端/错误分支/脏工作树下误操作 |
**决策**: 选择方案 A
**理由**: 该问题的关键不是缺少命令,而是缺少“什么时候用什么命令”的判断框架;skill 更适合作为操作协议而不是盲目自动化脚本。
**影响**: skill 主要由说明文档构成,强调流程判断、冲突配方和验证步骤
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- N/A
### 视觉要素
- N/A
### 技术约束
- **可访问性**: N/A
- **响应式**: N/A
@@ -0,0 +1,57 @@
# 任务清单: create-git-merge-preserve-local-skill
> **@status:** completed | 2026-04-16 17:09
```yaml
@feature: create-git-merge-preserve-local-skill
@created: 2026-04-16
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 5 | 0 | 0 | 5 |
---
## 任务列表
### 1. 方案与骨架
- [√] 1.1 初始化全局 skill 目录与基础骨架,确认目标路径和资源结构 | depends_on: []
- [√] 1.2 编写 skill 的触发描述、主流程和风险约束 | depends_on: [1.1]
### 2. 参考资料与元数据
- [√] 2.1 编写 references 中的命令模板、冲突配方和核验清单 | depends_on: [1.2]
- [√] 2.2 生成或补齐 `agents/openai.yaml` 元数据 | depends_on: [2.1]
### 3. 校验与交付
- [√] 3.1 运行 skill 校验并修复结构问题 | depends_on: [2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-16 17:03:00 | 方案包创建 | completed | 已创建 `202604161703_create-git-merge-preserve-local-skill` |
| 2026-04-16 17:04:00 | 1.1 | completed | 已初始化 `C:/Users/xiaohuli/.codex/skills/git-merge-preserve-local`,并创建 `SKILL.md` |
| 2026-04-16 17:07:00 | 1.2/2.1 | completed | 已写入主流程与 `references/merge-playbook.md` |
| 2026-04-16 17:08:00 | 2.2 | completed | 已补齐 `agents/openai.yaml` |
| 2026-04-16 17:08:30 | 3.1 | completed | `generate_openai_yaml.py``quick_validate.py` 因缺少 `yaml` 依赖失败,已改用手工结构校验并通过 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 目标目录已确认使用 `C:/Users/xiaohuli/.codex/skills`
- 计划创建 skill 名称为 `git-merge-preserve-local`
- `agents/openai.yaml` 在首次初始化时因 `short_description` 超长未生成,后续已手工补齐
- 本机 Python 环境缺少 `PyYAML`,因此未使用 `generate_openai_yaml.py` / `quick_validate.py` 完成最终步骤
@@ -0,0 +1,10 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"percent": 100,
"current": "completed",
"updated_at": "2026-04-18 00:33:30"
}
@@ -0,0 +1,127 @@
# 变更提案: fix-clashmeta-flow-map-export
## 元信息
```yaml
类型: 修复
方案类型: implementation
优先级: P1
状态: 已确认
创建: 2026-04-18
```
---
## 1. 需求
### 背景
当前 Clash Meta 订阅模板本身是合法的 block style YAML,但服务端在导出订阅时会重新执行
`Yaml::dump(...)`。由于 `inline` 深度设置过低,深层节点对象会被压成单行 flow map,
例如 TUIC 节点被输出为 `{ name: ..., alpn: [h3, h2, http/1.1], ... }`
在部分 Clash Meta 客户端中,这种超长单行 flow map 会触发:
`Flow map in block collection must be sufficiently indented and end with a }`
### 目标
- 修复 Clash Meta 订阅导出,避免代理节点被压成易出错的单行 flow map。
- 保持改动最小,仅影响 `ClashMeta` 导出链路。
- 不改动模板文件和其他协议导出器。
### 约束条件
```yaml
时间约束: 当前回合内完成修复与静态验证
性能约束: 不引入额外运行时依赖
兼容性约束: 不改动节点字段语义,仅调整 YAML 序列化风格
业务约束: 仅修复 Clash MetaClash / Stash 暂不联动修改
```
### 验收标准
- [ ] `app/Protocols/ClashMeta.php` 中 YAML 导出策略已调整,深层对象优先输出为 block style
- [ ] 不再依赖单行 flow map 来表示 `proxies` 中的 TUIC 等节点对象
- [ ] 改动范围限制在 `ClashMeta` 导出逻辑与方案包记录
- [ ] 完成最小静态验证并明确运行验证受限原因
---
## 2. 方案
### 技术方案
`ClashMeta` 中依赖 `Yaml::dump(...)` 的默认风格选择,替换为显式的 block style YAML 渲染,
避免 `proxies``proxy-groups` 等深层结构被压缩成单行 flow map。
本次仅修改:
1. `app/Protocols/ClashMeta.php` 的 YAML 渲染路径;
2. 在代码旁增加一行说明性注释,明确修复目的;
3. 不改模板、不改节点字段构造、不改 Clash / Stash。
### 影响范围
```yaml
涉及模块:
- ClashMeta 订阅导出: YAML 序列化风格调整
- .helloagents 方案包: 记录本次修复过程
预计变更文件: 2-4
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 导出 YAML 变得更“展开”,文件体积略增 | 低 | 只调整序列化风格,不改字段内容 |
| 同类问题在 `Clash` / `Stash` 中也存在,但本次未修 | 中 | 范围明确限制为 Clash Meta,后续可按需补修 |
| 本机无 PHP / vendor,无法直接做运行时生成验证 | 中 | 通过代码路径与参数语义做静态验证,并在结论中说明限制 |
---
## 3. 技术设计(可选)
> 本次为序列化参数修复,不涉及架构/API/数据模型设计。
### 架构设计
N/A
### API设计
N/A
### 数据模型
N/A
---
## 4. 核心场景
### 场景: 导出含长 TUIC 节点的 Clash Meta 订阅
**模块**: Clash Meta 订阅导出
**条件**: 用户订阅中包含较长节点名、`alpn` 数组、`udp-relay-mode` 等字段
**行为**: 服务端生成 YAML 订阅文本
**结果**: 节点对象以 block style 输出,避免客户端在解析长单行 flow map 时失败
---
## 5. 技术决策
### fix-clashmeta-flow-map-export#D001: 显式渲染 block style YAML,不再依赖 dumper 的默认风格选择
**日期**: 2026-04-18
**状态**: ✅采纳
**背景**: 问题的根源在序列化风格,而不是 TUIC 节点字段本身的构造。仅修改 `Yaml::dump` 参数后,服务器真值仍然返回单行 flow map。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 继续微调 `Yaml::dump` 参数 | 改动小 | 已被服务器真值否定,不能保证摆脱 flow map |
| B: 显式输出 block style YAML | 可完全控制 `proxies` / `proxy-groups` / `rules` 的格式 | 代码量更大,需要自定义渲染 |
**决策**: 选择方案 B
**理由**: 服务器真值已经证明仅调参数不够,必须显式控制 YAML 输出风格,才能彻底避免客户端继续收到 `- { ... }`
**影响**: 仅影响 Clash Meta 订阅的最终文本格式,不影响节点字段语义
---
## 6. 成果设计
### 设计方向
- N/A
### 视觉要素
- N/A
### 技术约束
- **可访问性**: N/A
- **响应式**: N/A
@@ -0,0 +1,52 @@
# 任务清单: fix-clashmeta-flow-map-export
> **@status:** completed | 2026-04-18 00:30
```yaml
@feature: fix-clashmeta-flow-map-export
@created: 2026-04-18
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 问题定位与修复
- [√] 1.1 确认报错来自 Clash Meta 导出后的单行 flow map,而不是原始模板语法 | depends_on: []
- [√] 1.2 调整 `ClashMeta` 的 YAML dump 参数,避免深层代理对象被压成单行 flow map | depends_on: [1.1]
### 2. 验证与交付
- [√] 2.1 对修复做最小验证,确认改动路径和影响范围 | depends_on: [1.2]
- [√] 2.2 总结修复结果、残留风险和后续建议 | depends_on: [2.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-18 00:29:00 | 方案包创建 | completed | 已创建 `202604180029_fix-clashmeta-flow-map-export` |
| 2026-04-18 00:31:00 | 1.1 | completed | 已确认问题点在 `ClashMeta.php``Yaml::dump(..., 2, 4, ...)` |
| 2026-04-18 00:32:00 | 1.2 | completed | 初始尝试已将 `ClashMeta` dump inline 深度提升到 `10` |
| 2026-04-18 00:33:00 | 2.1 | completed | 服务器真值显示 `?flag=meta` 仍返回 `- { ... }`,确认仅调参数无效 |
| 2026-04-18 00:33:30 | 2.2 | completed | 已切换为显式 block style YAML 渲染方案,并保留运行验证受限说明 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 本次只修 `ClashMeta`,未联动 `Clash` / `Stash`
- 本机缺少 `php``vendor`,无法在当前工作区执行运行时订阅生成验证
- 当前 diff 还包含换行符提示:Git 显示该文件后续可能按工作树策略从 LF 触碰为 CRLF
@@ -0,0 +1,10 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"percent": 100,
"current": "completed",
"updated_at": "2026-04-18 00:45:30"
}
@@ -0,0 +1,129 @@
# 变更提案: optimize-docker-publish-workflow
## 元信息
```yaml
类型: 优化
方案类型: implementation
优先级: P1
状态: 已确认
创建: 2026-04-18
```
---
## 1. 需求
### 背景
当前 `.github/workflows/docker-publish.yml` 在每次 push 到 `master` / `new-dev` 时都会执行双架构镜像构建并推送。
现有流程存在几个明显的性能与正确性问题:
- Dockerfile 在构建过程中重新 `git clone` 仓库和子模块,绕过了 Actions 已 checkout 的工作区。
- workflow 通过 `CACHEBUST=${{ github.sha }}` 强制让源码层每次失去缓存,以确保 `git clone` 拉到新代码,但这也让缓存收益极低。
- workflow 中“Get version”在“Extract metadata”之后,`steps.get_version.outputs.version` 的引用顺序不正确。
- `build-push-action` 同时声明了 `push: true``outputs: type=registry,push=true`,存在冗余。
- QEMU 配置包含 `amd64`,但原生 `ubuntu-latest` 已能直接构建 `amd64`
### 目标
- 在不改变现有分支触发与双架构产物策略的前提下,缩短 Docker 发布耗时。
- 保持 `master` / `new-dev` 的镜像输出逻辑不变。
- 修正 workflow 中的明显顺序与冗余配置问题。
### 约束条件
```yaml
时间约束: 当前回合内完成方案、实现和基本验证
性能约束: 优先优化热路径,不引入新的外部依赖
兼容性约束: 保持 master/new-dev 双架构发布行为不变
业务约束: 不通过减少镜像产物种类来换速度
```
### 验收标准
- [ ] `docker-publish.yml` 保持 `master` / `new-dev` 触发和双架构推送
- [ ] Dockerfile 改为使用 GitHub Actions 工作区源码,而不是在构建阶段重新 `git clone`
- [ ] workflow 去除明显冗余和错误顺序配置
- [ ] `.dockerignore` 收紧不必要上下文,减少上传到 BuildKit 的内容
---
## 2. 方案
### 技术方案
采用“保留产物策略不变、优化构建输入与缓存路径”的方案:
1. `actions/checkout` 增加 `submodules: recursive`,让 CI 工作区直接具备完整源码与子模块。
2. 修改 Dockerfile,删除构建期 `git clone` / `git submodule update` 逻辑,改为直接 `COPY` 工作区源码。
3. 删除 workflow 中为配合构建期 `git clone` 而存在的 `CACHEBUST` build arg。
4. 修正 metadata/version 步骤顺序,移除无效的“Update version in app.php”和冗余 `outputs` 配置。
5. 收紧 `.dockerignore`,排除 `.git``.github``.helloagents` 等不会进入运行时镜像的目录。
6. 保留双架构构建,但只在 QEMU 中声明需要模拟的 `arm64`
### 影响范围
```yaml
涉及模块:
- .github/workflows/docker-publish.yml: 发布编排与构建参数
- Dockerfile: 镜像构建输入与缓存路径
- .dockerignore: 构建上下文裁剪
预计变更文件: 3
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 直接使用工作区源码后,若 checkout 未带子模块,构建会缺少 admin dist | 中 | 在 checkout 中显式启用 `submodules: recursive` |
| `.dockerignore` 排除过多文件导致运行时缺资源 | 中 | 只排除明显不应进入镜像的 Git/CI/本地知识库目录 |
| 删除构建期 `git clone` 后,版本号注入逻辑与现有预期不一致 | 低 | 移除当前本就不会进镜像的版本更新步骤,避免继续保留伪生效逻辑 |
---
## 3. 技术设计(可选)
> 本次为 CI 与构建链优化,不涉及业务 API 或数据模型设计。
### 架构设计
N/A
### API设计
N/A
### 数据模型
N/A
---
## 4. 核心场景
### 场景: push 到发布分支时执行镜像发布
**模块**: GitHub Actions / Docker Buildx
**条件**: 开发者 push 到 `master``new-dev`
**行为**: checkout 完整源码与子模块,直接用工作区作为 Docker 构建输入,利用 GHA 缓存构建并推送双架构镜像
**结果**: 在不减少镜像产物的前提下减少无谓的源码重拉取、上下文与步骤浪费
---
## 5. 技术决策
### optimize-docker-publish-workflow#D001: 改为基于工作区源码构建镜像
**日期**: 2026-04-18
**状态**: ✅采纳
**背景**: 当前 Dockerfile 构建期重新 `git clone`,导致必须用 `CACHEBUST` 强制刷新源码层,缓存收益差且 workflow 内对工作区做的修改无法进入镜像。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 保持构建期 `git clone`,仅修修 workflow 小问题 | 改动小 | 无法根治缓存失效与无效步骤问题 |
| B: 直接基于 Actions 工作区 `COPY` 构建 | 能复用 checkout 结果,减少源码重复获取,缓存路径更合理 | 需要同步处理子模块与构建上下文 |
**决策**: 选择方案 B
**理由**: 这是在不改变发布产物策略的前提下,收益最大且风险可控的提速路径。
**影响**: workflow checkout 配置、Dockerfile 源码输入方式、`.dockerignore` 内容
---
## 6. 成果设计
### 设计方向
- N/A
### 视觉要素
- N/A
### 技术约束
- **可访问性**: N/A
- **响应式**: N/A
@@ -0,0 +1,52 @@
# 任务清单: optimize-docker-publish-workflow
> **@status:** completed | 2026-04-18 00:44
```yaml
@feature: optimize-docker-publish-workflow
@created: 2026-04-18
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 方案与上下文
- [√] 1.1 确认当前 workflow 和 Dockerfile 的主要耗时点与失效缓存路径 | depends_on: []
### 2. 工作流与构建链优化
- [√] 2.1 优化 `.github/workflows/docker-publish.yml` 的步骤顺序、checkout 配置和冗余项 | depends_on: [1.1]
- [√] 2.2 优化 `Dockerfile` 以直接消费 CI 工作区源码并删除构建期重复拉仓逻辑 | depends_on: [2.1]
- [√] 2.3 收紧 `.dockerignore`,减少不必要构建上下文 | depends_on: [2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-18 00:40:00 | 方案包创建 | completed | 已创建 `202604180040_optimize-docker-publish-workflow` |
| 2026-04-18 00:42:00 | 1.1 | completed | 已确认主要瓶颈是构建期重复 `git clone``CACHEBUST` 强制失效缓存与 workflow 冗余步骤 |
| 2026-04-18 00:44:00 | 2.1 | completed | 已优化 checkout、QEMU、metadata/version 顺序、缓存 scope 与冗余输出配置 |
| 2026-04-18 00:45:00 | 2.2 | completed | 已移除 Dockerfile 中构建期 `git clone`/`git submodule update`,改为直接 `COPY` 工作区源码 |
| 2026-04-18 00:45:30 | 2.3 | completed | 已在 `.dockerignore` 中排除 `.git``.github``.helloagents` 上下文 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 目标是“低风险提速”,不调整双架构产物策略
- 当前仓库不存在 `composer.lock`,本次不围绕 lockfile 进行优化
- 未执行真实多架构镜像构建,仅完成文本级自检与配置核对
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 7,
"failed": 0,
"pending": 0,
"total": 7,
"done": 7,
"percent": 100,
"current": "开发实施完成,待归档",
"updated_at": "2026-04-21 03:42:00"
}
@@ -0,0 +1,207 @@
# 变更提案: admin-frontend-composio-dashboard
## 元信息
```yaml
类型: 新功能 + 重构
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-21
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 已完成基础登录、认证存储、路由守卫和一个占位版 `DashboardView`,但登录成功后的跳转仅固定到 `/dashboard`,无法保留原始访问意图;仪表盘也尚未接入管理端真实统计接口,无法承载后台运营视图。用户已明确要求继续沿 `.claude/plan/admin-frontend-login.md` 推进,并将视觉方向切换为深色 Composio 风格,同时保持参考图中的核心功能结构。
### 目标
- 在不改后端 API 的前提下,实现登录成功后的可靠跳转,支持受保护路由回跳。
- 基于现有管理端接口实现真实数据仪表盘,包括核心统计卡片、收入趋势、节点/用户流量排行、队列与系统状态。
- 将后台主视觉统一到深色 Composio 风格,形成可继续扩展的管理端首页基线。
### 约束条件
```yaml
时间约束: 本轮在现有 admin-frontend 基础上增量完成,不扩展到更多后台业务页面
性能约束: 仪表盘首版避免引入重型图表依赖,尽量复用现有 Vue3 + Element Plus 栈
兼容性约束: 保持 Hash 路由、window.settings.secure_path 运行时配置、现有登录鉴权方式
业务约束: 仅复用后端现有接口,不新增 Laravel Controller/Route,不改变 secure_path 自举逻辑
```
### 验收标准
- [ ] 未登录访问受保护页面时可带 `redirect` 回到目标页,登录成功后正确跳转。
- [ ] 仪表盘成功调用 `stat/getStats``stat/getOrder``stat/getTrafficRank``system/getSystemStatus``system/getQueueStats` 并显示真实数据。
- [ ] 首页包含深色 Composio 风格的统计卡片、收入趋势、节点排行、用户排行、队列/系统状态区块,并支持桌面与移动端。
- [ ] `admin-frontend` 可以通过 `npm run build`
---
## 2. 方案
### 技术方案
`admin-frontend` 内完成三层增量改造:
1. 数据层
扩展 `src/types/api.d.ts``src/api/admin.ts`,为管理端仪表盘建立明确的统计、趋势、排行、系统状态类型与请求封装。
2. 认证与导航层
调整 `src/router/guards.ts``src/views/login/LoginView.vue`,在未登录时把目标路由写入 `redirect` 查询参数;登录成功后优先跳转目标路由,否则进入 `/dashboard`
3. 视图与视觉层
重构 `src/layouts/AdminLayout.vue``src/views/dashboard/DashboardView.vue` 与全局样式,采用深色 Composio 风格:
- 近黑背景 + 低对比边框
- `JetBrains Mono` 数字与技术标签
- 冷蓝/青色信号强调
- 以“夜间指挥中心”方式组织统计信息
趋势图首版采用自绘 SVG 折线图,避免为单页仪表盘引入新的重型图表库。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/api: 新增后台仪表盘数据请求封装
- admin-frontend/src/types: 补充管理端统计响应类型
- admin-frontend/src/router: 调整登录回跳逻辑
- admin-frontend/src/views/login: 登录成功跳转逻辑增强
- admin-frontend/src/views/dashboard: 从占位页升级为真实运营仪表盘
- admin-frontend/src/layouts: 主布局视觉升级
- admin-frontend/src/styles: 统一深色视觉变量与全局基线
预计变更文件: 8-10
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 后端接口字段与前端预期存在轻微偏差 | 中 | 直接以仓库内 Controller 返回结构为准建模,类型保持可扩展 |
| 管理端趋势图无现成图表库 | 低 | 使用自绘 SVG,减少依赖和构建风险 |
| 深色重构影响现有登录页与布局一致性 | 中 | 同步更新全局样式变量,确保登录页与后台主框架共享同一视觉系统 |
| 移动端侧边栏与大屏布局冲突 | 中 | 采用断点折叠、卡片栈式布局和横向滚动安全兜底 |
---
## 3. 技术设计(可选)
> 涉及架构变更、API设计、数据模型变更时填写
### 架构设计
```mermaid
flowchart TD
A[LoginView] --> B[AuthStore.login]
B --> C[passport/auth/login]
B --> D[getSystemStatus]
A --> E[Router redirect]
E --> F[DashboardView]
F --> G[getStats]
F --> H[getOrder]
F --> I[getTrafficRank]
F --> J[getSystemStatus]
F --> K[getQueueStats]
```
### API设计
#### GET /api/v2/{secure_path}/stat/getStats
- **请求**: 无
- **响应**: `todayIncome/currentMonthIncome/traffic/users/onlineNodes` 等仪表盘总览数据
#### GET /api/v2/{secure_path}/stat/getOrder
- **请求**: `start_date`, `end_date`, `type?`
- **响应**: `list[] + summary`,用于收入趋势图与摘要
#### GET /api/v2/{secure_path}/stat/getTrafficRank
- **请求**: `type=node|user`, `start_time`, `end_time`
- **响应**: Top 10 排行及环比变化
#### GET /api/v2/{secure_path}/system/getSystemStatus
- **请求**: 无
- **响应**: `schedule`, `horizon`, `schedule_last_runtime`
#### GET /api/v2/{secure_path}/system/getQueueStats
- **请求**: 无
- **响应**: `failedJobs`, `jobsPerMinute`, `recentJobs`, `processes`, `wait`, `status`
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| DashboardStats | object | 仪表盘总览统计 |
| OrderTrendPoint | object | 收入趋势日维度数据点 |
| TrafficRankItem | object | 节点或用户排行项 |
| QueueStats | object | Horizon/队列运行状态 |
---
## 4. 核心场景
> 执行完成后同步到对应模块文档
### 场景: 登录后回跳
**模块**: auth / router / login
**条件**: 用户未登录访问受保护路由
**行为**: 路由守卫记录目标地址,登录成功后优先跳转原目标
**结果**: 用户不会被强制打回固定首页
### 场景: 仪表盘总览
**模块**: dashboard
**条件**: 管理员登录成功并进入首页
**行为**: 页面并行拉取总览、趋势、排行和系统状态数据
**结果**: 用户看到真实的收入、用户、流量和队列运行信息
### 场景: 运营态分析
**模块**: dashboard
**条件**: 用户切换时间范围或排行类型
**行为**: 页面重新请求对应接口并刷新局部区块
**结果**: 后台可快速识别收入波动、流量头部节点与活跃用户
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### admin-frontend-composio-dashboard#D001: 仪表盘视觉采用深色 Composio 风格而非参考图浅色风格
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 用户明确选择“以 DESIGN.md 为准,做深色 Composio 风格仪表盘,但功能结构对齐参考图”。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 浅色还原参考图 | 更接近截图 | 与仓库既定 DESIGN.md 和现有深色登录页割裂 |
| B: 深色 Composio 风格 | 与既定设计系统一致,辨识度更高 | 需要重做布局与视觉细节 |
**决策**: 选择方案 B
**理由**: 用户已明确选定深色方向,且当前登录页已具备深色基础,继续向“夜间控制台”统一更稳妥。
**影响**: `AdminLayout``DashboardView``LoginView`、全局样式变量
### admin-frontend-composio-dashboard#D002: 趋势图采用自绘 SVG 而非新增图表依赖
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 当前项目仅需单个折线趋势图,引入 ECharts 等库会增加体积和维护成本。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 引入图表库 | 功能全、配置丰富 | 增加依赖与样式整合成本 |
| B: 自绘 SVG 折线图 | 体积轻、可完全匹配设计语言 | 需手工处理坐标和交互 |
**决策**: 选择方案 B
**理由**: 本轮诉求聚焦仪表盘首页,SVG 已足够覆盖折线图、悬浮提示和时间序列展示。
**影响**: `DashboardView` 内部图表实现方式,不改构建依赖
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- **美学基调**: Nocturnal Command Center。像深夜运行的运维控制台,近黑背景中浮出冷蓝信号、低对比边框和技术排版,强调“被数据照亮”的感觉。
- **记忆点**: 大面积近黑留白里嵌入发光式统计卡片与自绘蓝青折线图,数字像终端仪表一样被点亮。
- **参考**: 仓库 [DESIGN.md](/E:/code/php/Xboard-new/DESIGN.md) 的 Composio 风格规范 + 用户提供的后台参考图功能结构
### 视觉要素
- **配色**: 背景 `#0f0f0f` / 卡片内层 `#000000` / 线框 `rgba(255,255,255,0.08~0.12)` / 强调蓝 `#0007cd` / 信号青 `#00ffff`
- **字体**: `IBM Plex Sans` 作为界面正文,`JetBrains Mono` 作为数字、标签和技术指标;中文回退到 `PingFang SC``Microsoft YaHei`
- **布局**: 顶部密集统计卡片 + 中段趋势图双栏摘要 + 下段双排行 + 底部系统状态;桌面端强调控制台网格感,移动端改为单列堆叠
- **动效**: 卡片和图表采用分层淡入、边框亮起与轻微上浮;筛选切换使用短时透明度过渡
- **氛围**: 低对比边框、局部蓝青径向辉光、硬朗分割线和轻量噪点质感,避免普通 SaaS 白卡片质感
### 技术约束
- **可访问性**: 保证关键指标和文字在深色背景上的对比度;图表与状态块提供文本值而非只靠颜色
- **响应式**: `>=1280px` 四列指标卡,`768-1279px` 两列,`<768px` 单列;排行和图表区域允许安全降级为纵向布局
@@ -0,0 +1,59 @@
# 任务清单: admin-frontend-composio-dashboard
> **@status:** completed | 2026-04-21 03:43
```yaml
@feature: admin-frontend-composio-dashboard
@created: 2026-04-21
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 7 | 0 | 0 | 7 |
---
## 任务列表
### 1. 数据模型与接口
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts` 中补充仪表盘、趋势、排行、队列状态的类型定义 | depends_on: []
- [√] 1.2 在 `admin-frontend/src/api/admin.ts` 中实现总览、趋势、排行、系统与队列状态接口封装 | depends_on: [1.1]
### 2. 认证与跳转
- [√] 2.1 在 `admin-frontend/src/router/guards.ts` 中为受保护路由增加 `redirect` 回跳逻辑 | depends_on: [1.2]
- [√] 2.2 在 `admin-frontend/src/views/login/LoginView.vue` 中实现登录成功后的目标路由跳转与错误处理增强 | depends_on: [2.1]
### 3. 布局与视觉
- [√] 3.1 在 `admin-frontend/src/layouts/AdminLayout.vue``admin-frontend/src/styles/index.scss` 中重构 Composio 风格后台框架与全局视觉变量 | depends_on: [2.2]
### 4. 仪表盘页面
- [√] 4.1 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中实现总览卡片、收入趋势图、节点/用户排行、系统状态区块 | depends_on: [1.2,3.1]
- [√] 4.2 完成 `admin-frontend` 构建验证并修正类型/样式问题 | depends_on: [4.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-21 03:26 | 方案包初始化 | completed | 已生成 proposal/tasks 并锁定深色 Composio 仪表盘方向 |
| 2026-04-21 03:34 | 1.x / 2.x | completed | 已补充接口类型、管理端请求封装、登录回跳逻辑 |
| 2026-04-21 03:39 | 3.1 / 4.1 | completed | 已完成深色后台框架、登录页重构与仪表盘主视图实现 |
| 2026-04-21 03:40 | 4.2 | completed | `npm run build` 通过,产物输出到 `public/assets/admin` |
| 2026-04-21 03:42 | 验收 | completed | 已启动 Vite 开发服务并确认 `/assets/admin/``/#/login` 可访问 |
---
## 执行备注
- 当前任务基于 `.claude/plan/admin-frontend-login.md` 续作,但以本方案包作为本轮实现和验收的事实记录。
- 本轮不新增后端接口,仅消费仓库内已存在的管理端统计与系统状态接口。
- 页面运行态验收已覆盖构建与静态入口访问;仪表盘真实业务数据联调仍依赖实际 `secure_path` 与管理员鉴权环境。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"done": 5,
"percent": 100,
"current": "Apple 风格性能重构完成,待归档",
"updated_at": "2026-04-21 04:13:00"
}
@@ -0,0 +1,183 @@
# 变更提案: admin-frontend-apple-performance-refresh
## 元信息
```yaml
类型: 重构 + 优化
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-21
```
---
## 1. 需求
### 背景
上一轮管理端首页已完成深色 Composio 风格仪表盘,但用户反馈“页面非常卡顿”。结合当前实现可见,卡顿风险主要来自全局远程字体加载、固定噪点层、多个径向渐变与模糊装饰、较重阴影以及偏复杂的深色视觉特效。用户本轮明确要求改为 `apple/DESIGN.md` 设计体系,并将登录页、主布局和仪表盘统一重做。
### 目标
- 将登录页、主布局、仪表盘首页整体切换为 Apple 风格视觉体系。
- 明确降低页面运行时开销,优先删除高成本视觉装饰和非必要动画。
- 保留现有数据接入、登录回跳和后台业务信息结构,不回退功能。
### 约束条件
```yaml
时间约束: 本轮仅重做 admin-frontend 的登录页、主布局、仪表盘首页
性能约束: 去除远程字体依赖、固定背景噪点层、强滤镜和高频装饰性重绘
兼容性约束: 保持现有 Vue3 + Vite + Element Plus 栈,不新增重型 UI 或图表依赖
业务约束: 登录逻辑、secure_path、自定义 API 请求和统计接口保持不变
```
### 验收标准
- [ ] 登录页、主布局、仪表盘首页统一符合 Apple 设计系统,视觉更克制、轻量、清晰。
- [ ] 移除当前页面中的高成本装饰层,首屏样式明显降载。
- [ ] 仪表盘的数据接口、排行、趋势、系统状态功能保持可用。
- [ ] `admin-frontend` 重新构建通过。
---
## 2. 方案
### 技术方案
本轮采用“保留逻辑,重写视图皮层”的方式:
1. 全局样式降载
`src/styles/index.scss` 中移除 Google Fonts、固定噪点遮罩、全局径向辉光与过重背景层,改为 Apple 风格的系统字体栈、纯色背景与轻量层次。
2. 登录页重构
将当前双辉光深色登录页重构为 Apple 式大标题 + 清爽表单卡布局,保留登录回跳逻辑,只替换视觉和结构。
3. 主布局重构
把当前“夜间控制台”侧栏和头部压缩为更克制的 Apple 导航语言,减少边框、渐变、信号灯和装饰芯片。
4. 仪表盘重构
保留真实数据接口与 SVG 趋势图,但改成 Apple 风格的黑/浅灰分区、简洁卡片、单一蓝色交互重点和更轻的图表样式。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/styles: 全局视觉与性能基线
- admin-frontend/src/views/login: 登录页 Apple 风格重构
- admin-frontend/src/layouts: 主布局和导航样式重构
- admin-frontend/src/views/dashboard: 仪表盘内容重排与轻量样式替换
预计变更文件: 4-6
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 视觉重构影响当前布局层级 | 中 | 保持数据结构和主要 DOM 分区稳定,只重写样式与局部布局 |
| Apple 风格若过度追求极简导致信息密度下降 | 中 | 保留统计卡片、趋势图、排行和状态分区,只减少装饰噪音 |
| 去除装饰层后页面可能显得“过空” | 低 | 用黑/浅灰区块切换、系统字体、轻阴影和单一蓝色 CTA 建立节奏 |
---
## 3. 技术设计(可选)
> 涉及架构变更、API设计、数据模型变更时填写
### 架构设计
```mermaid
flowchart TD
A[index.scss] --> B[LoginView]
A --> C[AdminLayout]
A --> D[DashboardView]
D --> E[getDashboardStats]
D --> F[getOrderTrend]
D --> G[getTrafficRank]
D --> H[getSystemStatus/getQueueStats]
```
### API设计
#### GET /api/v2/{secure_path}/stat/getStats
- **请求**: 无
- **响应**: 仪表盘总览统计
#### GET /api/v2/{secure_path}/stat/getOrder
- **请求**: `start_date`, `end_date`
- **响应**: 收入趋势与汇总
#### GET /api/v2/{secure_path}/stat/getTrafficRank
- **请求**: `type`, `start_time`, `end_time`
- **响应**: 节点/用户排行
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| DashboardStats | object | 统计卡片数据 |
| OrderTrendData | object | 收入趋势图数据 |
| TrafficRankResponse | object | 排行区数据 |
| QueueStats/SystemStatus | object | 作业详情与系统状态数据 |
---
## 4. 核心场景
> 执行完成后同步到对应模块文档
### 场景: 登录进入后台
**模块**: LoginView / router
**条件**: 用户访问登录页或被守卫重定向到登录页
**行为**: 用户输入管理员账号密码并提交
**结果**: 登录成功后按原有 redirect 规则返回目标页
### 场景: 查看首页经营数据
**模块**: DashboardView
**条件**: 管理员进入仪表盘
**行为**: 页面加载总览、趋势、排行和系统状态
**结果**: 页面用更轻量的 Apple 风格区块展示相同业务信息
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### admin-frontend-apple-performance-refresh#D001: 采用 Apple 设计系统并优先做性能减法
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 用户已明确指出当前页面“非常卡顿”,并要求按 `apple/DESIGN.md` 重做。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 保留 Composio 风格,仅做性能微调 | 改动小 | 无法满足用户指定的 Apple 方向 |
| B: Apple 风格 + 性能减法重构 | 同时解决风格偏差和卡顿 | 需要重写多个页面的样式结构 |
**决策**: 选择方案 B
**理由**: 这次诉求的核心不是补功能,而是重新定义页面体验和运行成本。
**影响**: 登录页、主布局、仪表盘、全局样式
### admin-frontend-apple-performance-refresh#D002: 维持现有数据逻辑,仅替换视图皮层
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 当前 API 封装和跳转逻辑已完成,不需要在本轮视觉重构中回退或重写。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 连逻辑层一起重做 | 可重新整理代码 | 超出本轮目标,风险更高 |
| B: 保留逻辑层,重构页面与样式 | 风险可控,收益集中 | 需要在旧结构中做设计转换 |
**决策**: 选择方案 B
**理由**: 用户反馈集中在“前端效果卡顿”,而不是数据和接口错误。
**影响**: `api/*``router/*` 只做最小配合,改动集中于视图和样式
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- **美学基调**: Apple Product Editorial。像 Apple 产品页与系统面板的混合体,控制住装饰噪音,让内容像展品一样陈列。
- **记忆点**: 黑色英雄区和浅灰信息区交替展开,单一 Apple Blue 成为全页唯一强调色。
- **参考**: [apple/DESIGN.md](/E:/code/php/Xboard-new/apple/DESIGN.md)
### 视觉要素
- **配色**: 黑色 `#000000`、浅灰 `#f5f5f7`、正文深灰 `#1d1d1f`、交互蓝 `#0071e3`
- **字体**: 采用系统栈模拟 SF Pro 体验,优先 `-apple-system`, `BlinkMacSystemFont`, `SF Pro Display`, `SF Pro Text`, `Helvetica Neue`, Arial, sans-serif`
- **布局**: 英雄区大标题 + 轻卡片信息区 + 简洁双列内容;信息通过区块切换而不是发光边框表达层级
- **动效**: 仅保留轻量 hover 和淡入,不保留大面积 blur、辉光、滤镜动画
- **氛围**: 纯色背景、轻阴影、玻璃感顶栏;不使用噪点、网格、径向发光和复杂纹理
### 技术约束
- **可访问性**: 文字与背景维持高对比;交互色仅使用 Apple Blue
- **响应式**: 登录页双栏在窄屏下改为单列;仪表盘卡片和内容区在平板/手机下自动折叠为单列
@@ -0,0 +1,54 @@
# 任务清单: admin-frontend-apple-performance-refresh
> **@status:** completed | 2026-04-21 04:14
```yaml
@feature: admin-frontend-apple-performance-refresh
@created: 2026-04-21
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 5 | 0 | 0 | 5 |
---
## 任务列表
### 1. 全局视觉与性能基线
- [√] 1.1 在 `admin-frontend/src/styles/index.scss` 中移除高成本装饰层并建立 Apple 风格全局变量 | depends_on: []
### 2. 登录与布局
- [√] 2.1 在 `admin-frontend/src/views/login/LoginView.vue` 中将登录页重构为 Apple 风格轻量布局 | depends_on: [1.1]
- [√] 2.2 在 `admin-frontend/src/layouts/AdminLayout.vue` 中重构主布局与头部导航,去除当前控制台式装饰 | depends_on: [1.1]
### 3. 仪表盘
- [√] 3.1 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中重构为 Apple 风格信息分区并保留现有统计功能 | depends_on: [1.1,2.2]
- [√] 3.2 完成 `admin-frontend` 构建验证并修正重构引入的问题 | depends_on: [2.1,2.2,3.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-21 04:00 | 方案包初始化 | completed | 已锁定 Apple 风格 + 性能减法方向 |
| 2026-04-21 04:10 | 1.1 / 2.x | completed | 已移除远程字体与全局重装饰,完成登录页和主布局 Apple 化 |
| 2026-04-21 04:12 | 3.1 | completed | 已将仪表盘重构为 Apple 风格分区,同时保留现有数据接口 |
| 2026-04-21 04:12 | 3.2 | completed | `npm run build` 通过,运行态入口 `200` |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 本轮不回退上一轮的数据接入和登录回跳逻辑,仅重构视图皮层和高成本样式。
- 运行态验证已确认 `/assets/admin/``/#/login` 可访问;真实性能评估仍建议在真实后台数据环境里再观察一次滚动与切换体验。
@@ -0,0 +1 @@
{"status":"completed","completed":8,"failed":0,"pending":0,"total":8,"done":8,"percent":100,"current":"已完成用户管理页面、路由与构建验证,待归档方案包","updated_at":"2026-04-21 05:05:00"}
@@ -0,0 +1,208 @@
# 变更提案: admin-frontend-user-management
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-21
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 已完成登录、主布局与仪表盘,但业务路由仍只有 `/dashboard`。用户本轮明确要求继续沿 [.claude/plan/admin-frontend-login.md](/E:/code/php/Xboard-new/.claude/plan/admin-frontend-login.md) 推进,按照 [apple/DESIGN.md](/E:/code/php/Xboard-new/apple/DESIGN.md) 的 Apple 风格,为后台补齐“用户管理 / 工单管理”入口,且优先完整实现“用户管理”页面。参考图已经给出了目标交互形态,包括左侧菜单分组、用户列表、行内更多操作菜单,以及右侧抽屉式新增/编辑用户表单。
### 目标
- 在管理端新增“用户管理”业务页,完成菜单、路由、页面与真实接口接入。
- 让用户管理页具备可用的搜索、分页、状态展示、更多操作菜单,以及新增/编辑用户抽屉。
- 预留“工单管理”菜单与路由入口,使后台导航结构与参考图对齐,但本轮不展开工单业务实现。
### 约束条件
```yaml
时间约束: 本轮只完整实现“用户管理”,工单管理仅补路由入口和占位页
性能约束: 保持当前轻量 Apple 风格,不新增重型表格或状态管理依赖
兼容性约束: 保持现有 Vue3 + TypeScript + Vite + Element Plus 栈与 hash 路由模式
业务约束: 后端接口沿用现有 `/api/v2/{secure_path}/user/*`、`/plan/fetch`,不改 Laravel API
```
### 验收标准
- [ ] 管理端左侧导航新增“用户管理”分组,包含“用户管理”和“工单管理”两个入口。
- [ ] 用户管理页可通过真实接口完成列表读取、分页、基础筛选、状态/套餐/流量展示。
- [ ] 用户管理页支持新增用户、编辑用户、复制订阅地址、重置密钥、封禁和删除等操作入口,并带明确确认反馈。
- [ ] `admin-frontend` 构建通过,新增页面在桌面和移动端都能正常访问。
---
## 2. 方案
### 技术方案
本轮采用“扩展现有管理壳层 + 新增用户管理业务模块”的方案:
1. 扩展管理端数据层
`src/types/api.d.ts` 中补充用户、套餐、分页与表单类型;在 `src/api/admin.ts` 中新增用户列表、用户详情、套餐列表、用户创建/更新/重置密钥/封禁/删除等请求封装。
2. 新增用户管理视图
`src/views/users/` 下拆分页面与抽屉组件。列表页负责搜索、表格、分页、更多操作菜单;抽屉组件负责新增/编辑表单。视觉上延续 Apple 风格的浅灰画布、白色内容区与单一蓝色交互重点。
3. 对齐后端真实创建能力
后端 `user/generate` 只能直接创建基础字段(邮箱、密码、套餐、到期时间),无法一次性写入完整表单字段。因此新增用户时采用“两段式”流程:
- 先调用 `user/generate` 创建基础账号
- 再按邮箱回查用户 ID,并调用 `user/update` 补齐流量、余额、佣金、权限、限速、设备数、备注等扩展字段
4. 补齐导航与路由
将当前仅有仪表盘的侧边栏调整为分组导航,新增 `/users` 路由和 `/tickets` 占位路由;本轮仅实现 `UsersView` 的完整业务功能。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/router: 新增用户管理与工单管理路由
- admin-frontend/src/layouts: 调整侧边栏菜单结构与导航文案
- admin-frontend/src/api: 扩展用户与套餐相关请求
- admin-frontend/src/types: 新增用户管理数据类型
- admin-frontend/src/views/users: 新增用户列表页与表单抽屉
- admin-frontend/src/views/tickets: 新增工单管理占位页
预计变更文件: 7-9
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 后端新增用户接口字段不足,无法一次提交完整表单 | 中 | 前端采用 `generate + fetch + update` 两段式创建流程 |
| 参考图中的“在线设备”字段后端列表接口未直接返回 | 中 | 本轮优先展示可用业务字段,设备相关展示使用已有限制字段和可退化文案 |
| 用户删除属于破坏性操作 | 中 | 在前端增加显式确认和操作完成提示,避免误删 |
---
## 3. 技术设计(可选)
> 涉及路由扩展、API映射与表单编排,需填写。
### 架构设计
```mermaid
flowchart TD
A[AdminLayout 侧边栏菜单] --> B[UsersView 用户管理页]
A --> C[TicketsPlaceholderView 工单占位页]
B --> D[UserToolbar 搜索与操作]
B --> E[UserTable 列表与更多操作]
B --> F[UserFormDrawer 新增/编辑抽屉]
B --> G[admin.ts 用户管理接口]
F --> G
G --> H[/user/fetch]
G --> I[/user/generate]
G --> J[/user/update]
G --> K[/user/resetSecret]
G --> L[/user/ban]
G --> M[/user/destroy]
G --> N[/plan/fetch]
```
### API设计
#### ANY /api/v2/{secure_path}/user/fetch
- **请求**: `current`, `pageSize`, `filter[]`, `sort[]`
- **响应**: `{ data: UserListItem[], total: number }`
#### GET /api/v2/{secure_path}/user/getUserInfoById
- **请求**: `id`
- **响应**: 单个用户详情,含邀请人信息
#### POST /api/v2/{secure_path}/user/generate
- **请求**: `email_prefix`, `email_suffix`, `password`, `plan_id`, `expired_at`
- **响应**: `success(true)` 或批量结果
#### POST /api/v2/{secure_path}/user/update
- **请求**: `id` + 用户扩展字段(余额、佣金、流量、权限、限速、设备数、备注等)
- **响应**: `success(true)`
#### GET /api/v2/{secure_path}/plan/fetch
- **请求**: 无
- **响应**: 套餐列表,用于表单选择和表格展示
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| AdminUserListItem | object | 用户列表行数据,包含套餐、邀请人、权限组、流量、状态等 |
| AdminUserFormModel | object | 抽屉表单模型,覆盖新增/编辑时的基础与扩展字段 |
| AdminPlanOption | object | 订阅计划选项,用于表单下拉与列表展示 |
| AdminPaginationResult<T> | object | 用户列表分页结果 |
---
## 4. 核心场景
> 执行完成后同步到对应模块文档
### 场景: 浏览用户列表
**模块**: UsersView
**条件**: 管理员已登录并进入 `/users`
**行为**: 页面读取用户列表、套餐信息并渲染搜索栏、表格、分页
**结果**: 管理员可快速查看用户状态、流量、到期时间与套餐
### 场景: 新增用户
**模块**: UserFormDrawer / admin.ts
**条件**: 管理员在用户管理页点击“创建用户”
**行为**: 管理员填写抽屉表单,前端先生成基础账号,再补写扩展字段
**结果**: 新用户创建成功,列表自动刷新并提示结果
### 场景: 编辑或执行行内操作
**模块**: UsersView / UserFormDrawer
**条件**: 列表中存在目标用户
**行为**: 管理员打开更多菜单执行编辑、复制订阅地址、重置密钥、封禁或删除
**结果**: 对应操作完成并反馈到列表状态
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### admin-frontend-user-management#D001: 新增用户采用“两段式创建”以兼容现有后端接口
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 参考表单包含余额、佣金、流量、角色、限速、设备数、备注等字段,但后端 `user/generate` 仅支持基础创建字段。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 仅用 `user/generate` 并缩减表单字段 | 实现简单 | 无法对齐参考页字段深度 |
| B: 先 `generate`,再按邮箱回查并 `update` | 能保留完整表单能力 | 前端流程更复杂 |
**决策**: 选择方案 B
**理由**: 既不改后端,也能最大化还原参考抽屉中的管理能力。
**影响**: `admin.ts``UsersView``UserFormDrawer`
### admin-frontend-user-management#D002: 先补齐用户/工单路由结构,但本轮仅交付完整用户页
**日期**: 2026-04-21
**状态**: ✅采纳
**背景**: 用户要求“添加用户管理、工单管理路由,先完成用户管理”,既要有完整导航结构,又要控制当前实现范围。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 只加用户管理,不处理工单入口 | 实现最小 | 与用户点名的导航结构不一致 |
| B: 同时补齐用户/工单入口,工单先占位 | 与目标结构一致,后续扩展顺滑 | 需要新增一个占位页面 |
**决策**: 选择方案 B
**理由**: 先把信息架构铺平,后续实现工单页时不必再改侧边栏和路由骨架。
**影响**: `router/index.ts``layouts/AdminLayout.vue`
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- **美学基调**: Apple Admin Ledger。像 Apple 系统设置和内部运营面板的结合体,用极少的颜色和干净层级承载高密度数据。
- **记忆点**: 浅灰页面基底上嵌入一块大尺寸白色数据工作台,右侧抽屉像系统级面板一样滑入。
- **参考**: 用户提供的用户列表、操作菜单、抽屉表单和侧边栏截图 + [apple/DESIGN.md](/E:/code/php/Xboard-new/apple/DESIGN.md)
### 视觉要素
- **配色**: 背景 `#f5f5f7`、表格/抽屉 `#ffffff`、标题 `#1d1d1f`、强调蓝 `#0071e3`、危险态 `#c93428`
- **字体**: 延续当前系统字体栈 `-apple-system`, `BlinkMacSystemFont`, `SF Pro Display`, `SF Pro Text`, `Helvetica Neue`, Arial, sans-serif`
- **布局**: 页面顶部为标题与操作条,中部为单块白色表格工作区;抽屉从右侧进入,表单按字段组自然分段
- **动效**: 仅保留表格 hover、高亮状态和抽屉进出动画,避免复杂动效
- **氛围**: 轻边框、软阴影、玻璃顶栏,避免深色重装饰和泛滥卡片分割
### 技术约束
- **可访问性**: 所有状态色均保留文字标签;删除、封禁等危险操作必须有二次确认
- **响应式**: 窄屏下工具栏折行、表格横向滚动、抽屉宽度自适应到视口
@@ -0,0 +1,62 @@
# 任务清单: admin-frontend-user-management
> **@status:** completed | 2026-04-21 05:02
```yaml
@feature: admin-frontend-user-management
@created: 2026-04-21
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 8 | 0 | 0 | 8 |
---
## 任务列表
### 1. 数据层与类型
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts` 中补充用户管理、套餐、分页和表单类型 | depends_on: []
- [√] 1.2 在 `admin-frontend/src/api/admin.ts` 中新增用户列表、详情、创建、更新、套餐、重置密钥、封禁、删除等接口封装 | depends_on: [1.1]
### 2. 用户管理视图
- [√] 2.1 新增 `admin-frontend/src/views/users/UserFormDrawer.vue`,实现新增/编辑用户抽屉表单和两段式创建流程 | depends_on: [1.1,1.2]
- [√] 2.2 新增 `admin-frontend/src/views/users/UsersView.vue`,实现搜索、列表、分页、状态展示和更多操作菜单 | depends_on: [1.1,1.2]
- [√] 2.3 在 `admin-frontend/src/views/users/UsersView.vue` 中完成抽屉联动、复制订阅地址、重置密钥、封禁、删除与刷新反馈 | depends_on: [2.1,2.2]
### 3. 导航与路由
- [√] 3.1 在 `admin-frontend/src/router/index.ts``admin-frontend/src/layouts/AdminLayout.vue` 中补齐“用户管理 / 工单管理”菜单和路由结构 | depends_on: [2.2]
- [√] 3.2 新增 `admin-frontend/src/views/tickets/TicketsView.vue` 作为工单管理占位页,保持后续扩展入口稳定 | depends_on: [3.1]
### 4. 验收
- [√] 4.1 完成 `admin-frontend` 构建验证并修正新增页面引入的问题 | depends_on: [2.3,3.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-21 04:41 | 方案包初始化 | completed | 已确认本轮完整实现用户管理,工单管理仅补入口与占位页 |
| 2026-04-21 04:49 | 1.1 / 1.2 | completed | 已补齐用户管理类型定义与 admin API 封装 |
| 2026-04-21 04:54 | 2.1 / 2.2 / 2.3 | completed | 已完成用户列表页、抽屉表单和更多操作菜单联动 |
| 2026-04-21 04:56 | 3.1 / 3.2 | completed | 已补齐用户管理 / 工单管理菜单与路由,并新增工单占位页 |
| 2026-04-21 05:00 | 4.1 | completed | `npm run build` 通过;使用管理员账号验证登录后已跳转 `/users`,静态 preview 下真实数据请求因缺少 Laravel 运行环境未完成 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 本轮新增用户需要兼容后端 `user/generate` 的字段限制,前端会做创建后补写。
- 参考图中的工单管理仅作为下一步入口,本轮不实现工单列表、会话与回复逻辑。
- 真实数据接口联调受当前终端无 `php` 运行环境限制,浏览器验证覆盖到登录成功、路由跳转和页面结构渲染,未覆盖 Laravel 注入的 `window.settings` 与真实后台数据返回。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"done": 4,
"percent": 100,
"current": "Dashboard 全量刷新按钮实现、验证与知识库同步完成,待归档",
"updated_at": "2026-04-23 15:43:00"
}
@@ -0,0 +1,44 @@
{
"version": 1,
"source": "~auto",
"originCommand": "auto",
"verifyMode": "test-first",
"reviewerFocus": [],
"testerFocus": [
"Hero 区刷新按钮是否触发整页数据刷新",
"刷新中是否有明确状态反馈并阻止重复点击",
"Dashboard 页面构建后是否保持现有 Apple 风格层级"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"proposal.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "本轮为 Dashboard 顶部新增显式操作按钮,需要确认视觉风格与交互状态一致。",
"screens": [
"dashboard desktop",
"dashboard mobile"
],
"states": [
"refresh idle",
"refresh loading"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,92 @@
# 变更提案: admin-frontend-dashboard-refresh-button
## 元信息
```yaml
类型: 增强
方案类型: implementation
优先级: P2
状态: 已完成
创建: 2026-04-23
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 仪表盘已经具备总览、趋势、排行与系统状态的数据拉取能力,但缺少一个显式、统一的“全量刷新”入口。用户希望在 `http://localhost:5173/assets/admin/#/dashboard` 对应的首页,基于 `apple/DESIGN.md` 的 Apple 风格,为整页数据增加刷新按钮。
### 目标
-`admin-frontend/src/views/dashboard/DashboardView.vue` 中增加一个整页全量刷新按钮。
- 刷新动作需要覆盖统计卡、收入趋势、节点/用户排行、系统与队列状态。
- 刷新按钮的视觉语言需延续当前 Apple 风格,不引入额外的重装饰。
### 约束条件
```yaml
技术约束:
- 保持现有 Vue3 + TypeScript + Vite + Element Plus 栈
- 复用现有 refreshDashboard 数据流,不重复造接口层逻辑
UI约束:
- 以 apple/DESIGN.md 为设计基线
- 使用单一蓝色强调与黑色 Hero 区的克制表达
行为约束:
- 刷新时需有明确加载反馈
- 刷新中避免重复点击触发并发请求
```
### 验收标准
- [√] Hero 区新增“刷新全部数据”入口,桌面和移动端都可正常使用。
- [√] 点击后会统一刷新总览、趋势、排行和系统状态。
- [√] 刷新中有可见状态反馈,并阻止重复触发。
- [√] `admin-frontend` 构建通过。
- [√] 本地页面完成一次视觉验收,确认按钮与 Apple 风格一致。
---
## 2. 方案
### 技术方案
1. 在仪表盘 Hero 右侧状态区加入全量刷新按钮,作为当前页面最直接的系统操作入口。
2. 复用现有 `refreshDashboard()` 逻辑,对其补充成功提示、最后刷新时间记录与手动触发入口。
3. 为按钮增加刷新中状态、旋转图标、禁用交互和辅助文案,保证状态完整。
4. 保持当前卡片、趋势图与系统面板的数据结构不变,只增强顶部操作层。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/views/dashboard/DashboardView.vue
- .helloagents/CHANGELOG.md
- .helloagents/modules/admin-frontend.md
预计变更文件: 3
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| Hero 区新增操作后破坏原有视觉平衡 | 中 | 采用胶囊按钮、弱对比边框和状态副文案,保持 Apple 风格节奏 |
| 刷新逻辑重复触发导致请求堆叠 | 中 | 刷新中禁用按钮,并复用现有 loading 状态 |
| 用户中途要求停止 playwright-cli,运行态截图验收受限 | 中 | 改为构建验证 + 结构化代码视觉自检,并记录为本轮视觉验收证据 |
---
## 3. 核心场景
### 场景: 管理员手动刷新仪表盘
**模块**: DashboardView
**条件**: 管理员已进入 `/dashboard`
**行为**: 点击 Hero 区“刷新全部数据”按钮
**结果**: 页面统一刷新统计卡、趋势、排行和系统状态,并反馈最新同步状态
---
## 4. 技术决策
### admin-frontend-dashboard-refresh-button#D001: 刷新入口放在 Hero 状态区
**日期**: 2026-04-23
**状态**: ✅采纳
**理由**: Hero 区是仪表盘总控入口,能在不增加新卡片或工具栏负担的前提下,让刷新动作保持高可见性。
### admin-frontend-dashboard-refresh-button#D002: 复用 refreshDashboard 作为唯一全量刷新入口
**日期**: 2026-04-23
**状态**: ✅采纳
**理由**: 当前页面已经通过 `refreshDashboard()` 聚合总览、趋势和排行的刷新逻辑,沿用该入口可避免逻辑分叉。
@@ -0,0 +1,54 @@
# 任务清单: admin-frontend-dashboard-refresh-button
> **@status:** completed | 2026-04-23 15:43
```yaml
@feature: admin-frontend-dashboard-refresh-button
@created: 2026-04-23
@status: completed
@mode: R3
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 方案与范围
- [√] 1.1 锁定刷新范围为整页全量刷新,并确认 Hero 区为按钮落点 | depends_on: []
### 2. 仪表盘实现
- [√] 2.1 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中增加 Hero 区全量刷新按钮与状态文案 | depends_on: [1.1]
- [√] 2.2 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中补齐最后刷新时间、加载反馈与防重复触发逻辑 | depends_on: [2.1]
### 3. 验证与同步
- [√] 3.1 运行 `npm run build` 验证 `admin-frontend` 构建通过 | depends_on: [2.1,2.2]
- [√] 3.2 完成本地视觉验收并同步知识库变更记录 | depends_on: [3.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-23 15:15 | 方案包初始化 | completed | 已锁定整页全量刷新范围与 Apple 风格约束 |
| 2026-04-23 15:24 | 2.1 / 2.2 | completed | 已在 Hero 区加入全量刷新按钮、最后刷新时间与加载反馈 |
| 2026-04-23 15:26 | 3.1 | completed | `npm run build` 通过 |
| 2026-04-23 15:42 | 3.2 | completed | 按用户要求停止 playwright-cli,改用结构化代码视觉自检并完成知识库同步 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 本轮只增强仪表盘顶部操作层,不改动后端接口契约和图表数据结构。
- 运行态视觉验收原计划使用浏览器自动化,但用户中途明确要求“不再运行 playwright-cli”,因此改为基于构建结果和代码结构的视觉自检。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"done": 4,
"percent": 100,
"current": "Dashboard 收入趋势金额/数量切换已完成,待归档",
"updated_at": "2026-04-23 23:20:00"
}
@@ -0,0 +1,98 @@
# 变更提案: admin-frontend-dashboard-trend-count-toggle
## 元信息
```yaml
类型: 功能增强
方案类型: implementation
优先级: P1
状态: 执行中
创建: 2026-04-23
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 仪表盘的“收入趋势”模块仅支持按金额查看趋势线。用户希望在不破坏现有 Apple 风格页面结构的前提下,补充“按数量”视角,让管理员在同一图表区域中切换查看订单数量走势。
### 目标
-`admin-frontend/src/views/dashboard/DashboardView.vue` 的趋势面板中新增“金额 / 数量”切换。
- 切换到“数量”后,图表 Y 轴、摘要卡片与最近记录同步以订单数量为主展示。
- 保持 `apple/DESIGN.md` 的 Apple 风格约束:纯色分区、单一强调蓝、克制交互和低装饰噪音。
### 约束条件
```yaml
范围约束: 仅调整 admin-frontend 仪表盘趋势模块及其图表工具逻辑
视觉约束: 延续 Apple 风格,不引入双图、双线、多色复杂图例
技术约束: 不新增图表库,继续复用现有 SVG 图表实现
业务约束: 不修改后端接口,前端基于现有趋势返回字段实现切换
```
### 验收标准
- [ ] 趋势面板新增“按金额 / 按数量”切换,默认保持“按金额”。
- [ ] 切换到“按数量”时,图表线条、Y 轴标签、摘要卡片和最近记录与数量口径一致。
- [ ] 视觉样式仍符合 `apple/DESIGN.md`,新增交互保持克制、清晰、可访问。
- [ ] `admin-frontend` 构建通过,产物成功输出到 `public/assets/admin`
---
## 2. 方案
### 技术方案
1.`src/utils/dashboard.ts` 中把趋势图构建逻辑参数化,支持金额/数量两种指标,并根据口径生成对应的 Y 轴标签格式。
2.`src/views/dashboard/DashboardView.vue` 中新增趋势显示模式状态、切换按钮和摘要视图模型。
3. 保持现有 `getOrderTrend` 接口调用方式,直接复用响应中的 `paid_total``paid_count``commission_total``commission_count` 等字段完成数量视图。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/views/dashboard/DashboardView.vue
- admin-frontend/src/utils/dashboard.ts
- public/assets/admin (构建产物输出)
预计变更文件: 2-4
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 数量视图摘要语义不清 | 中 | 采用“成交订单 / 佣金订单 / 日均成交”三段式摘要,并保留金额作为辅助信息 |
| 图表参数化后影响原金额模式 | 中 | 默认金额模式不变,并通过构建验证确保类型与模板连接正确 |
| 子模块产物状态与根仓状态不同步 | 中 | 构建后同时检查根仓与 `public/assets/admin` 子模块状态 |
---
## 3. 成果设计
### 设计方向
- **美学基调**: 延续当前 Apple 风格的浅灰内容面板 + 单一蓝色交互重点。
- **交互模式**: 在现有时间筛选旁新增一组低干扰 segmented pills,用于切换“按金额 / 按数量”。
- **记忆点**: 同一张克制的趋势图,在不增加视觉负担的情况下完成经营口径切换。
### 视觉要素
- **配色**: 继续使用 `#0071e3` 作为唯一强调色;背景和卡片保持 `#ffffff / #f5f5f7 / #fbfbfd` 层次。
- **排版**: 不新增标题层级,切换器作为次级控制区,与时间范围筛选并列。
- **状态**: 激活态用浅蓝底 + 浅蓝边框,未激活态保持白底细边框。
### 实施结果
- 已在趋势面板头部增加独立的“按金额 / 按数量”切换分组。
- 已将趋势图 SVG 构建逻辑扩展为双口径模式,数量模式下自动切换 Y 轴标签为“笔”。
- 已将摘要卡片和最近记录改为跟随当前口径同步展示。
---
## 4. 技术决策
### admin-frontend-dashboard-trend-count-toggle#D001: 采用单图切换而不是双图/双线
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 用户在确认环节明确选择“金额 / 数量切换”方案。
**决策**: 在同一趋势图区域中,通过切换按钮切换图表口径和摘要信息。
**理由**: 该方案最符合 Apple 风格的克制表达,同时不会显著增加页面密度。
### admin-frontend-dashboard-trend-count-toggle#D002: 数量模式复用现有接口字段,不新增后端联调
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 现有趋势接口已返回 `paid_count``commission_count` 等字段。
**决策**: 前端直接基于现有响应切换图表指标和摘要视图。
**理由**: 可以在最小范围内完成需求,避免扩展后端接口或引入新请求。
@@ -0,0 +1,49 @@
# 任务清单: admin-frontend-dashboard-trend-count-toggle
> **@status:** completed | 2026-04-23 23:20
```yaml
@feature: admin-frontend-dashboard-trend-count-toggle
@created: 2026-04-23
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 趋势图模式切换
- [√] 1.1 在 `admin-frontend/src/utils/dashboard.ts` 中扩展趋势图构建逻辑,支持金额/数量双口径 | depends_on: []
- [√] 1.2 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中加入“按金额 / 按数量”切换和对应摘要展示 | depends_on: [1.1]
### 2. 验证与产物
- [√] 2.1 运行 `admin-frontend` 构建验证,确认类型检查和 Vite 构建通过 | depends_on: [1.2]
- [√] 2.2 复核根仓与 `public/assets/admin` 子模块状态,确保产物变更可见 | depends_on: [2.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-23 23:13 | 方案包初始化 | completed | 已确认采用“金额 / 数量切换”并进入实现 |
| 2026-04-23 23:17 | 1.1 / 1.2 | completed | 已完成趋势图双口径切换、摘要卡片和最近记录联动 |
| 2026-04-23 23:20 | 2.1 / 2.2 | completed | `npm run build` 通过,根仓与 `public/assets/admin` 子模块均检测到产物变更 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 当前仓已有一个未完成的旧方案包 `202604210515_admin-frontend-ticket-management`,本轮不复用其模板内容,单独创建新方案包以避免混淆。
- 由于 `public/assets/admin` 是独立子模块,构建后前端产物变更主要体现在子模块工作区;根仓继续显示 `m public/assets/admin` 属于正常现象。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"done": 4,
"percent": 100,
"current": "排行面板 10/20 切换与滚动容器已完成,等待归档",
"updated_at": "2026-04-23 23:38:00"
}
@@ -0,0 +1,92 @@
# 变更提案: admin-frontend-rank-limit-scroll
## 元信息
```yaml
类型: 功能增强
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-23
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 仪表盘中的“节点流量排行”和“用户流量排行”都固定只显示前 6 条,列表区域也会随着内容高度自然撑开。用户希望在不破坏现有 Apple 风格基线的前提下,让两个排行面板都支持 `10 个 / 20 个` 显示切换,并将排行内容放进可滚动的展示区域,避免页面被长列表拉得过高。
### 目标
-`admin-frontend/src/views/dashboard/DashboardView.vue` 的两个流量排行面板中新增 `10 个 / 20 个` 显示数量切换。
- 让节点排行和用户排行都支持独立控制显示数量,并在列表较长时使用固定高度滚动区域承载内容。
- 延续 `apple/DESIGN.md` 的 Apple 风格:纯色分区、单一蓝色强调、低装饰噪音、清晰可访问的按钮状态。
### 约束条件
```yaml
范围约束: 仅调整 admin-frontend 仪表盘排行面板的交互和样式,不改后端接口
视觉约束: 保持 Apple 风格,不引入表格化重组件或高密度控制栏
技术约束: 继续复用现有 Vue3 + TypeScript + Element Plus + 原生样式体系
工作树约束: 保留当前未提交的趋势图口径切换改动,在其基础上完成本轮排行增强
```
### 验收标准
- [ ] “节点流量排行”和“用户流量排行”均提供 `10 个 / 20 个` 数量切换。
- [ ] 切换后列表展示条数与选择一致,且面板内容区域保持可滚动,不因为长列表破坏整体布局。
- [ ] 新增交互仍符合 `apple/DESIGN.md` 的视觉基线,并具备可见焦点与明确激活态。
- [ ] `admin-frontend` 构建通过,根仓与 `public/assets/admin` 子模块状态可见。
---
## 2. 方案
### 技术方案
1.`DashboardView.vue` 中新增节点排行和用户排行各自的显示条数状态,并通过计算属性统一产出当前应渲染的列表。
2. 在排行面板头部保留现有时间范围筛选,同时补充轻量级 segmented pills 作为 `10 / 20` 显示数量切换控件。
3. 为排行列表增加固定高度滚动容器、轻量滚动条样式和面板内边距节奏,让 20 条模式下仍维持 Apple 风格的整洁感。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/views/dashboard/DashboardView.vue
- public/assets/admin (构建产物输出)
预计变更文件: 1-3
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 排行面板头部控件过多导致拥挤 | 中 | 把时间筛选与数量筛选分成两组,保持同一视觉语言但明确主次 |
| 滚动容器高度不合适影响信息密度 | 中 | 采用按 10/20 模式自适应的最大高度,同时在移动端回退为更紧凑布局 |
| 当前工作树已有趋势图增强改动 | 中 | 在现有未提交改动上增量实现,并通过构建验证确认两项增强可同时成立 |
---
## 3. 成果设计
### 设计方向
- **美学基调**: 延续当前 Apple 风格浅色信息面板,让排行区域像可浏览的信息胶囊,而不是后台表格。
- **交互模式**: 时间范围和显示数量都使用 pill 按钮;数量按钮作为次级控制,保持克制但清晰。
- **记忆点**: 同一个排行面板中,长列表被收进柔和滚动视窗,滚动时仍保持整洁的白底与单一蓝色强调。
### 视觉要素
- **配色**: 沿用 `#0071e3` 作为唯一强调色,滚动容器背景继续使用 `#fbfbfd` / `#ffffff` 层次。
- **排版**: 面板头部分成信息区与控件区,控件区按分组排列;列表内部继续保留名称、流量值、蓝色进度条和涨跌百分比。
- **状态**: 激活态为浅蓝底 + 浅蓝边框;滚动条使用低对比灰蓝色,避免视觉噪音。
---
## 4. 技术决策
### admin-frontend-rank-limit-scroll#D001: 两个排行面板独立控制显示数量
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 节点排行和用户排行虽然共享时间范围,但使用场景不同,用户可能需要分别查看不同数量。
**决策**: 节点排行与用户排行分别维护自己的 `10 / 20` 数量切换状态。
**理由**: 这样不会把两个排行耦合成单一控制,也更贴合面板级交互。
### admin-frontend-rank-limit-scroll#D002: 使用固定高度滚动容器而不是整页自然拉伸
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 20 条排行如果完全展开,会让 dashboard 纵向长度显著增加,破坏当前首页节奏。
**决策**: 在排行面板内引入滚动容器,并按 10/20 模式设置不同的最大高度。
**理由**: 能在保留更多信息的同时维持 Apple 风格的页面节奏和阅读效率。
@@ -0,0 +1,49 @@
# 任务清单: admin-frontend-rank-limit-scroll
> **@status:** completed | 2026-04-23 23:38
```yaml
@feature: admin-frontend-rank-limit-scroll
@created: 2026-04-23
@status: completed
@mode: R3
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 排行交互增强
- [√] 1.1 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中新增节点排行和用户排行的 `10 / 20` 显示数量状态与计算视图 | depends_on: []
- [√] 1.2 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中为两个排行面板加入数量切换控件,并调整头部布局 | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中加入滚动容器和 Apple 风格滚动条样式 | depends_on: [1.2]
### 2. 验证与状态
- [√] 2.1 运行 `admin-frontend` 构建验证,并确认根仓与 `public/assets/admin` 子模块状态 | depends_on: [1.3]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-23 23:18 | 方案包初始化 | completed | 已确认在 Apple 风格基线上为两个排行面板增加 10/20 切换和滚动容器 |
| 2026-04-23 23:31 | 1.1 / 1.2 / 1.3 | completed | 已为两个排行面板补齐 10/20 切换、独立显示状态和滚动容器样式 |
| 2026-04-23 23:37 | 2.1 | completed | `npm run build` 通过;浏览器直达 `/dashboard` 会因未提供管理员登录态跳转到 `/#/login?redirect=/dashboard` |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 当前工作树已存在一个未完成的趋势图口径切换方案包 `202604232313_admin-frontend-dashboard-trend-count-toggle`,本轮在保留其代码改动的前提下继续增强 dashboard 排行区域。
- 本轮视觉联调受本地管理员登录态限制,已通过构建、代码级 UI 自检和浏览器路由快照完成兜底验证。
@@ -0,0 +1,51 @@
{
"updatedAt": "2026-04-23T15:23:18.713Z",
"version": 1,
"source": "~auto",
"originCommand": "plan",
"verifyMode": "review-first",
"reviewerFocus": [
"节点管理侧边栏分组是否清晰且与现有 Apple 风格后台一致",
"未实现的创建/排序能力是否被透明标注为后续接入"
],
"testerFocus": [
"节点列表是否真实连接 /server/manage/getNodes 与 /server/group/fetch",
"搜索、类型筛选、权限组筛选与显隐切换是否存在真实数据流",
"节点相关新路由是否可以正常进入"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"plan.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "节点管理属于整页新建后台视图,需要确认导航、列表密度与占位页结构在浏览器中符合 Apple 风格契约",
"screens": [
"#/nodes desktop",
"#/node-groups desktop",
"#/node-routes desktop"
],
"states": [
"节点列表默认加载完成态",
"节点列表筛选结果态",
"权限组管理占位态",
"路由管理占位态"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,54 @@
# admin-frontend 节点管理首批交付 — 实施规划
## 目标与范围
-`admin-frontend` 增加节点管理信息架构,并先交付“节点管理”主页面。
- 页面目标不是一次性做完整节点中后台,而是先打通“可看、可筛、可切显隐、可做基础行级操作”的运营主链路。
## 架构与实现策略
- 在现有 `AdminLayout` 基础上新增“节点管理”二级分组,保持侧边栏结构统一。
- 新增 `/nodes``/node-groups``/node-routes` 三个路由,其中 `/nodes` 为真实功能页,其余两页为明确占位页。
- 节点列表页直接消费现有后端接口,不在前端猜测或重塑接口契约:
- `/server/manage/getNodes`
- `/server/group/fetch`
- `/server/manage/update`
- `/server/manage/copy`
- `/server/manage/drop`
- 复杂的节点格式化逻辑(地址、状态、标签、筛选选项)下沉到 `utils/nodes.ts`,避免页面组件膨胀。
## 完成定义
- 侧边栏出现“节点管理”分组,且可以进入 3 个子入口。
- `/nodes` 页面可真实拉取节点与权限组数据。
- 用户可以通过搜索、节点类型和权限组筛选列表。
- 用户可以切换节点显隐状态,并在界面中获得成功/失败反馈。
- 用户可以通过更多菜单执行复制节点与删除节点;未覆盖的编辑/排序功能有明确边界提示。
- 验证主路径:`review-first`
- reviewer 关注边界:导航结构是否清晰、页面是否与 Apple 风格一致、未实现功能是否被透明标注。
- tester 关注边界:构建是否通过、节点列表是否真实连接 API、筛选与显隐切换是否存在数据流。
## 文件结构
- `admin-frontend/src/router/index.ts`
- `admin-frontend/src/layouts/AdminLayout.vue`
- `admin-frontend/src/api/admin.ts`
- `admin-frontend/src/types/api.d.ts`
- `admin-frontend/src/utils/nodes.ts`(新增)
- `admin-frontend/src/views/nodes/NodesView.vue`(新增)
- `admin-frontend/src/views/nodes/NodeGroupsView.vue`(新增)
- `admin-frontend/src/views/nodes/NodeRoutesView.vue`(新增)
## UI / 设计约束
- 节点管理首页保留黑色 hero + 白色表格壳层的 Apple 后台节奏。
- 过滤器采用紧凑 pill / select 混合布局,优先满足快速运营判断。
- 列表状态用圆点、标签和辅助文字三层表达,不只靠颜色。
- 占位页不做空白页,而是交付可继续扩展的结构化提示页。
## 风险与验证
- 风险 1:后端节点字段可能存在空值或差异,页面要做健壮格式化。
- 风险 2:节点显隐切换的字段是 `show`,前端需保持与布尔/整型兼容。
- 风险 3:权限组接口若返回结构偏轻,前端需要容错处理。
- 验证方式:
- `npm run build`
- 本地预览 + 浏览器检查 `/nodes``/node-groups``/node-routes`
## 决策记录
- [2026-04-23] 节点管理首批交付聚焦列表运营链路,不在本轮接入完整节点编辑表单,避免 UI 范围失控。
- [2026-04-23] 权限组管理 / 路由管理先交付占位页,保证侧边栏信息架构先稳定下来。
@@ -0,0 +1,37 @@
# admin-frontend 节点管理首批交付 — 需求
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
## 核心目标
-`admin-frontend` 中新增“节点管理”侧边栏分组。
- 优先实现“节点管理”主页面,使管理者可以在 Apple 风格后台中查看、搜索、筛选和执行基础节点操作。
- 页面视觉以 `apple/DESIGN.md` 为参考,并与现有 Apple 化仪表盘、用户管理、工单管理保持一致。
## 功能边界
- 必须新增节点管理分组,包含:节点管理、权限组管理、路由管理 3 个入口。
- 必须实现“节点管理”列表页,覆盖:
- 节点列表拉取
- 关键字段展示(节点 ID、显隐、节点、地址、在线人数、倍率、权限组)
- 搜索
- 类型筛选
- 权限组筛选
- 显隐切换
- 行级更多操作菜单
- 权限组管理、路由管理本轮只要求提供结构化占位页,为下一轮真实接入留入口。
## 非目标
- 本轮不实现完整的节点创建 / 编辑大表单。
- 本轮不实现拖拽排序或完整排序编辑器。
- 本轮不重做后端接口,不新增 Laravel 管理端 API。
## 技术约束
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`
- 后端真相源以现有 Laravel 管理接口为准,节点列表使用 `/server/manage/getNodes`
- 视觉契约优先级:本方案 > `.helloagents/DESIGN.md` > `apple/DESIGN.md` 的参考原则。
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`
## 质量要求
- 页面必须保持 Apple 风格的一致性和高密度运营后台可读性。
- 异步列表必须覆盖加载、空和错误反馈。
- 危险操作要有确认提示。
- 最终至少完成一次构建验证与一次浏览器级视觉验收。
@@ -0,0 +1,13 @@
# admin-frontend 节点管理首批交付 — 任务分解
## 任务列表
- [x] 任务1:补齐本轮 UI 契约与方案产物(涉及文件:`.helloagents/DESIGN.md``.helloagents/plans/202604232320_admin-frontend-node-management/*`;完成标准:存在可执行需求、方案、任务与合同文件;验证方式:文件检查)
- [x] 任务2:扩展后台导航与路由结构(涉及文件:`admin-frontend/src/router/index.ts``admin-frontend/src/layouts/AdminLayout.vue`;完成标准:侧边栏出现节点管理分组并可进入 3 个子页面;验证方式:`npm run build` + 浏览器检查导航)
- [x] 任务3:接入节点管理数据模型与 API(涉及文件:`admin-frontend/src/api/admin.ts``admin-frontend/src/types/api.d.ts``admin-frontend/src/utils/nodes.ts`;完成标准:前端可拉取节点与权限组并完成必要格式化;验证方式:`npm run build`
- [x] 任务4:实现节点管理主页面(涉及文件:`admin-frontend/src/views/nodes/NodesView.vue`;完成标准:节点列表具备搜索、筛选、显隐切换、复制/删除基础能力,并覆盖加载/空/错误状态;验证方式:`npm run build` + 浏览器检查 `/nodes`
- [x] 任务5:实现权限组 / 路由管理占位页(涉及文件:`admin-frontend/src/views/nodes/NodeGroupsView.vue``admin-frontend/src/views/nodes/NodeRoutesView.vue`;完成标准:可从侧边栏进入,页面明确说明下一阶段接入范围;验证方式:`npm run build` + 浏览器检查对应路由)
- [x] 任务6:完成验证、视觉验收与知识库同步(涉及文件:`.helloagents/CHANGELOG.md``.helloagents/.ralph-visual.json``.helloagents/.ralph-closeout.json`;完成标准:构建通过、视觉检查完成、知识库记录本轮变更;验证方式:命令输出 + 证据文件)
## 进度
- [x] 已创建方案包并冻结首批交付范围。
- [x] 已完成 admin-frontend 节点管理首批页面与知识库同步。
@@ -0,0 +1,55 @@
{
"updatedAt": "2026-04-23T15:35:17.621Z",
"version": 1,
"source": "~auto",
"originCommand": "plan",
"verifyMode": "review-first",
"reviewerFocus": [
"系统管理侧边栏分组是否清晰且与现有 Apple 风格后台一致",
"系统配置页的左侧分组导航与右侧长表单结构是否清晰可读",
"其余系统管理入口是否被透明标注为后续接入"
],
"testerFocus": [
"系统管理新路由是否可以正常进入",
"系统配置页是否真实连接 /config/fetch 与 /config/save",
"保存反馈与辅助按钮是否存在真实数据流"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"plan.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "系统管理属于整页新建后台视图,需要确认导航、系统配置长表单层级与占位页结构在浏览器中符合 Apple 风格契约",
"screens": [
"#/system/config desktop",
"#/system/plugins desktop",
"#/system/themes desktop",
"#/system/notices desktop",
"#/system/payments desktop",
"#/system/knowledge desktop"
],
"states": [
"系统配置默认加载完成态",
"系统配置保存态",
"系统配置错误/重试态",
"系统模块占位态"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,63 @@
# admin-frontend 系统管理首批交付 — 实施规划
## 目标与范围
-`admin-frontend` 增加“系统管理”信息架构,并先交付“系统配置”主页面。
- 页面目标不是一次性做完整后台系统中心,而是先打通“可进入、可读取、可编辑、可保存”的配置主链路,同时把其余 5 个系统管理入口先稳定为可访问占位页。
## 架构与实现策略
- 在现有 `AdminLayout` 基础上新增“系统管理”二级分组,保持侧边栏结构统一。
- 新增以下路由:
- `/system/config` 为真实功能页
- `/system/plugins`
- `/system/themes`
- `/system/notices`
- `/system/payments`
- `/system/knowledge`
- 系统配置页直接消费现有后端接口,不在前端猜测或重塑接口契约:
- `/config/fetch`
- `/config/save`
- `/config/testSendMail`
- `/config/setTelegramWebhook`
- 配置字段分组、控件元信息与序列化逻辑下沉到 `utils/systemConfig.ts`,避免页面组件膨胀。
- 占位页使用统一的 `SystemPlaceholderView`,以一致的结构说明本轮范围与下一阶段扩展点。
## 完成定义
- 侧边栏出现“系统管理”分组,且可以进入 6 个子入口。
- `/system/config` 页面可真实拉取配置数据,并按 9 个配置分组组织内容。
- 用户可以修改并保存系统配置,保存后获得成功/失败反馈。
- 邮件设置与 Telegram 设置保留辅助动作入口(测试邮件 / 设置 Webhook),但不在本轮额外扩展复杂工作流。
- 其余 5 个系统管理子页可从侧边栏正常进入,并明确标注“下一阶段接入”。
- 验证主路径:`review-first`
- reviewer 关注边界:系统管理信息架构是否清晰、系统配置表单层级是否贴近 Apple 风格后台、占位页是否透明说明未实现范围。
- tester 关注边界:菜单与路由是否真实连通、系统配置页是否真实连接 `/config/fetch``/config/save`、保存链路与辅助按钮是否存在真实数据流。
## 文件结构
- `admin-frontend/src/router/index.ts`
- `admin-frontend/src/layouts/AdminLayout.vue`
- `admin-frontend/src/api/admin.ts`
- `admin-frontend/src/types/api.d.ts`
- `admin-frontend/src/utils/systemConfig.ts`(新增)
- `admin-frontend/src/views/system/SystemConfigView.vue`(新增)
- `admin-frontend/src/views/system/SystemPlaceholderView.vue`(新增)
- `.helloagents/DESIGN.md`
## UI / 设计约束
- 系统配置首页保留黑色 hero + 白色配置壳层的 Apple 后台节奏。
- 左侧使用紧凑分组导航,右侧使用连续表单 section,优先满足“快速定位配置块”的后台效率诉求。
- 页面首屏只保留一个主保存动作和少量辅助描述,不堆砌营销式视觉元素。
- 占位页不做空白页,而是交付可继续扩展的结构化提示页。
## 风险与验证
- 风险 1:配置接口字段类型包含布尔、数值、数组和长文本,前端需要统一序列化与表单回填。
- 风险 2`/config/fetch` 返回分组对象,系统配置页必须避免直接把后端分组名暴露成低可读开发术语。
- 风险 3:本地静态预览环境可能缺少 Laravel 注入或后台认证,浏览器验收要区分“结构验收”和“真实联调”边界。
- 验证方式:
- `npm run build`
- 本地预览 + 浏览器检查 `#/system/config`
- 浏览器检查 `#/system/plugins``#/system/themes``#/system/notices``#/system/payments``#/system/knowledge`
## 决策记录
- [2026-04-23] 系统管理首批交付聚焦“系统配置真实页 + 其余入口占位页”,避免在一轮内同时展开多个 CRUD 模块。
- [2026-04-23] “系统配置”保留左侧配置分组导航,优先满足后台场景中的长表单定位效率。
- [2026-04-23] 前台主题相关配置不混入本轮系统配置页,而是留在“主题配置”入口的后续阶段实现。
@@ -0,0 +1,51 @@
# admin-frontend 系统管理首批交付 — 需求
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
## 核心目标
-`admin-frontend` 中新增“系统管理”一级侧边栏分组。
- 优先实现“系统配置”页面,并尽量贴近用户提供的目标结构:左侧分组导航 + 右侧长表单编辑区。
- 页面视觉以 `apple/DESIGN.md` 为参考,并与现有 Apple 化仪表盘、用户管理、工单管理保持同一后台设计语言。
## 功能边界
- 必须新增系统管理分组,包含:
- 系统配置
- 插件管理
- 主题配置
- 公告管理
- 支付配置
- 知识库管理
- 必须实现“系统配置”真实页面,覆盖:
- 站点设置
- 安全设置
- 订阅设置
- 邀请 & 佣金设置
- 节点配置
- 邮件设置
- Telegram 设置
- APP 设置
- 订阅模板
- “系统配置”必须接入现有 Laravel 管理接口的真实数据读取与保存链路。
- 插件管理、主题配置、公告管理、支付配置、知识库管理本轮只要求提供结构化占位页,为下一轮真实接入留入口。
## 非目标
- 本轮不实现插件、主题、公告、支付、知识库的完整 CRUD 页面。
- 本轮不重做后端配置 API,不新增 Laravel 管理端接口。
- 本轮不把前台主题配置混入“系统配置”页;主题能力保留在“主题配置”入口的后续阶段实现。
## 技术约束
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`
- 后端真相源以现有 Laravel 管理接口为准,系统配置使用:
- `GET /config/fetch`
- `POST /config/save`
- `POST /config/testSendMail`
- `POST /config/setTelegramWebhook`
- 视觉契约优先级:本方案 > `.helloagents/DESIGN.md` > `apple/DESIGN.md` 的参考原则。
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`
## 质量要求
- 系统配置页必须保持 Apple 风格的一致性,并具备后台长表单的高可读性。
- 异步页面必须覆盖加载、错误、保存成功与未修改状态反馈。
- 表单交互需要明确区分主操作与辅助操作,避免一屏出现过多高强调按钮。
- 最终至少完成一次构建验证与一次浏览器级视觉验收。
@@ -0,0 +1,13 @@
# admin-frontend 系统管理首批交付 — 任务分解
## 任务列表
- [x] 任务1:补齐本轮 UI 契约与方案产物(涉及文件:`.helloagents/DESIGN.md``.helloagents/plans/202604232329_admin-frontend-system-management/*`;完成标准:存在可执行需求、方案、任务与合同文件;验证方式:文件检查)
- [x] 任务2:扩展后台导航与路由结构(涉及文件:`admin-frontend/src/router/index.ts``admin-frontend/src/layouts/AdminLayout.vue`;完成标准:侧边栏出现系统管理分组并可进入 6 个子页面;验证方式:`npm run build` + 浏览器检查导航)
- [x] 任务3:接入系统配置数据模型与 API(涉及文件:`admin-frontend/src/api/admin.ts``admin-frontend/src/types/api.d.ts``admin-frontend/src/utils/systemConfig.ts`;完成标准:前端可拉取并保存系统配置,字段可完成必要的回填与序列化;验证方式:`npm run build`
- [x] 任务4:实现系统配置主页面(涉及文件:`admin-frontend/src/views/system/SystemConfigView.vue`;完成标准:页面具备 9 个配置分组、加载/错误/保存反馈、左侧导航与真实保存入口;验证方式:`npm run build` + 浏览器检查 `#/system/config`
- [x] 任务5:实现其余系统管理占位页(涉及文件:`admin-frontend/src/views/system/SystemPlaceholderView.vue`;完成标准:其余 5 个入口可正常访问,并明确说明下一阶段接入范围;验证方式:`npm run build` + 浏览器检查对应路由)
- [x] 任务6:完成验证、视觉验收与知识库同步(涉及文件:`.helloagents/CHANGELOG.md``.helloagents/modules/admin-frontend.md``.helloagents/.ralph-visual.json``.helloagents/.ralph-closeout.json`;完成标准:构建通过、视觉检查完成、知识库记录本轮变更;验证方式:命令输出 + 证据文件)
## 进度
- [x] 已冻结系统管理首批范围与系统配置优先级。
- [x] 已完成 admin-frontend 系统管理导航、路由与系统配置页面。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"done": 4,
"percent": 100,
"current": "traffic rank 的 10/20 limit 联动已完成,待归档",
"updated_at": "2026-04-23 23:52:00"
}
@@ -0,0 +1,89 @@
# 变更提案: traffic-rank-limit-backend-adapt
## 元信息
```yaml
类型: 功能增强 + 接口适配
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-23
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 的节点/用户流量排行已经补上了 `10个 / 20个` 切换 UI,但后端 `stat/getTrafficRank` 接口仍固定只取前 10 条,所以前端切到 20 条时实际上拿不到更多数据。同时,用户进一步明确:24 小时口径下依然要显示增幅/减幅,不需要特殊隐藏。
### 目标
- 让后端 `getTrafficRank` 支持按请求返回 `10``20` 条数据。
- 让前端在节点排行/用户排行切换显示数量时,把对应的 `limit` 传给后端重新请求。
- 保持 24h 口径下继续返回并显示涨幅/减幅,不额外关闭该能力。
### 约束条件
```yaml
范围约束: 仅调整 traffic rank 相关前后端逻辑,不扩展到其他 dashboard 模块
接口约束: 不新增新接口,在现有 /stat/getTrafficRank 基础上增量支持 limit 参数
业务约束: 24h / 7天 / 30天 都继续允许返回 change,前端不对 24h 单独隐藏
工作树约束: 在当前脏工作树基础上最小增量修改,只触达本轮确有关系的文件
```
### 验收标准
- [ ] `stat/getTrafficRank` 接口支持接收 `limit=10|20`,并按参数返回对应条数。
- [ ] dashboard 前端在节点/用户排行切换显示数量时,会向后端请求对应 limit,而不是仅前端截断。
- [ ] 24h 口径下排行仍显示增幅/减幅,前后端都不额外屏蔽该字段。
- [ ] `admin-frontend` 构建通过,相关 PHP 文件语法检查通过。
---
## 2. 方案
### 技术方案
1.`app/Http/Controllers/V2/Admin/StatController.php``getTrafficRank()` 中新增 `limit` 参数校验,并把当前节点/用户排行查询的 `limit(10)` 改为动态 limit。
2.`admin-frontend/src/api/admin.ts``getTrafficRank()` 中支持传入 `limit` 参数。
3.`admin-frontend/src/views/dashboard/DashboardView.vue``loadRankings()` 中分别把 `nodeRankLimit``userRankLimit` 传给对应接口,并在显示数量变化时重新请求排行数据。
### 影响范围
```yaml
涉及模块:
- app/Http/Controllers/V2/Admin/StatController.php
- admin-frontend/src/api/admin.ts
- admin-frontend/src/views/dashboard/DashboardView.vue
- public/assets/admin (构建产物输出)
预计变更文件: 3-4
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| limit 参数放开后请求值异常 | 中 | 后端仅允许 `10``20`,避免任意放大查询 |
| 前端 limit 切换后仍沿用旧数据 | 中 | 对 `nodeRankLimit` / `userRankLimit` 增加 watch,变化即重新拉取 |
| 当前工作树已有 dashboard 相关脏改动 | 中 | 只做最小补丁,并通过构建与 git diff 核对本轮触达文件 |
---
## 3. 成果设计
### 设计方向
- **交互基线**: 维持现有 Apple 风格排行面板,不新增可视化噪音。
- **数据行为**: 数量切换真正驱动后端返回更多排行项,而不是仅靠前端裁切。
- **显示规则**: 24 小时口径仍保留涨跌百分比展示,与 7 天/30 天保持一致。
---
## 4. 技术决策
### traffic-rank-limit-backend-adapt#D001: 在现有 getTrafficRank 接口上新增 limit 参数
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 前端已经存在 10/20 切换控件,但后端固定 limit 10 导致能力不完整。
**决策**: 不新增新接口,直接在 `getTrafficRank` 上增加受控 `limit` 参数。
**理由**: 改动最小,且与现有 dashboard 请求模型保持一致。
### traffic-rank-limit-backend-adapt#D002: 24h 口径继续显示 change
**日期**: 2026-04-23
**状态**: ✅采纳
**背景**: 用户明确要求 24 小时口径也允许展示增幅/减幅。
**决策**: 保持后端始终返回 `change`,前端不为 24h 增加隐藏逻辑。
**理由**: 行为统一,避免不同时间口径的 UI 规则分裂。
@@ -0,0 +1,49 @@
# 任务清单: traffic-rank-limit-backend-adapt
> **@status:** completed | 2026-04-23 23:52
```yaml
@feature: traffic-rank-limit-backend-adapt
@created: 2026-04-23
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
### 1. 接口适配
- [√] 1.1 在 `app/Http/Controllers/V2/Admin/StatController.php` 中为 `getTrafficRank` 增加 `limit=10|20` 参数支持 | depends_on: []
- [√] 1.2 在 `admin-frontend/src/api/admin.ts` 中为 `getTrafficRank` 透传 `limit` 参数 | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/views/dashboard/DashboardView.vue` 中让 10/20 切换重新请求后端排行数据 | depends_on: [1.2]
### 2. 验证
- [√] 2.1 运行前后端验证(PHP 语法检查 + admin-frontend 构建),确认 24h change 未被关闭 | depends_on: [1.3]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-23 23:45 | 方案包初始化 | completed | 已确认后端需支持 10/20 limit,且 24h 继续展示增幅/减幅 |
| 2026-04-23 23:49 | 1.1 / 1.2 / 1.3 | completed | 已完成后端 limit 参数接入、前端 API 透传与排行数量切换后的重新请求 |
| 2026-04-23 23:51 | 2.1 | completed | `npm run build` 通过;本机缺少 `php` CLI,无法直接执行 `php -l`,已以最小 PHP 补丁和代码复核兜底 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 当前工作树已存在多项未提交 dashboard 相关改动;本轮仅聚焦 traffic rank 前后端适配。
- 24h 涨跌展示未额外增加隐藏逻辑,前端仍直接渲染 `formatPercent(item.change)`;后端继续为所有时间口径返回 `change`
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 6,
"failed": 0,
"pending": 0,
"total": 6,
"done": 6,
"percent": 100,
"current": "优惠券管理页面、弹窗与构建验证已完成,等待归档",
"updated_at": "2026-04-24 16:28:00"
}
@@ -0,0 +1,196 @@
# 变更提案: admin-frontend-coupon-management
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 执行中
创建: 2026-04-24
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 已完成仪表盘、用户管理、节点管理、套餐管理与系统配置,但“订阅管理”分组下的“优惠券管理”仍是禁用占位。用户本轮明确要求参考 `apple/DESIGN.md`、项目级 `.helloagents/DESIGN.md` 与提供的两张参考图,继续补完真正可用的优惠券管理页面,包括列表工作台与新增/编辑弹窗。
### 目标
- 开放侧边栏中的“优惠券管理”入口,并接入真实页面与路由。
- 基于现有 Laravel `coupon/*` 接口,完成优惠券列表、搜索、类型筛选、启停、删除、新增与编辑。
- 页面视觉延续当前 Apple 化后台,尽量还原参考图中的黑白结构、紧凑表格与表单弹窗。
### 约束条件
```yaml
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + Vite,不引入额外状态管理或重型日期/富文本依赖
业务约束: 后端接口仅使用现有 `/coupon/fetch` `/coupon/generate` `/coupon/update` `/coupon/drop`,不改 Laravel API
数据约束: 套餐限制项沿用现有 `/plan/fetch` 返回结果,优惠券周期限制遵循后端 legacy period 键值
视觉约束: 遵循 `apple/DESIGN.md` 与 `.helloagents/DESIGN.md`,保持与仪表盘/套餐管理同一视觉家族
```
### 验收标准
- [ ] 左侧“订阅管理”分组中的“优惠券管理”由禁用态切换为真实可点击入口,并进入独立页面。
- [ ] 优惠券管理页支持真实数据读取、关键字搜索、类型筛选、本地分页、启用开关、编辑和删除。
- [ ] “添加优惠券 / 编辑优惠券”弹窗支持名称、批量生成数量、自定义优惠码、类型和值、有效期、总使用次数、每人使用次数、指定周期与指定订阅。
- [ ] 页面中的类型标签、剩余次数、每人限制、有效期与过期提示可正确展示,并与后端字段含义一致。
- [ ] `admin-frontend` 构建通过,且知识库同步反映“优惠券管理”已从占位入口升级为真实页面。
---
## 2. 方案
### 技术方案
1. 扩展 `src/types/api.d.ts``src/api/admin.ts`,新增优惠券列表项、保存载荷、分页查询与计划选项的类型、请求封装。
2. 新增 `src/utils/coupons.ts`,集中处理优惠券类型标签、legacy period 选项、时间范围换算、表单默认值、列表本地过滤与过期文案。
3. 新增 `src/views/subscriptions/CouponsView.vue``CouponEditorDialog.vue`
- `CouponsView` 负责黑色首屏、工具条、表格、分页、行内开关与操作按钮。
- `CouponEditorDialog` 负责新增/编辑表单、指定周期/订阅、时间范围和数值字段校验。
4.`AdminLayout.vue``router/index.ts` 中启用“优惠券管理”菜单与 `/subscriptions/coupons` 路由,同时保持“订单管理 / 礼品卡管理”为未完成状态。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/layouts: 开放优惠券菜单入口
- admin-frontend/src/router: 新增优惠券管理路由
- admin-frontend/src/api: 新增 coupon 接口封装
- admin-frontend/src/types: 新增优惠券类型定义
- admin-frontend/src/utils: 新增优惠券数据转换与展示逻辑
- admin-frontend/src/views/subscriptions: 新增优惠券页面、弹窗与样式
预计变更文件: 7-9
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| `/coupon/fetch` 的服务端筛选能力有限,关键字无法同时覆盖名称与券码 | 中 | 前端优先一次拉取合理数量后做本地搜索与分页,避免错误的 AND 过滤 |
| 编辑接口复用 `/coupon/generate`,字段与新增表单共用,空值和 legacy period 容易提交错误 | 中 | 在 `utils/coupons.ts` 中统一序列化,空数组转 `undefined`,时间统一转 Unix 秒 |
| 参考图包含较丰富的表格状态与表单布局,若实现不克制容易脱离既有后台风格 | 中 | 复用现有 Apple Admin token、表格与弹窗风格,不额外引入第二套后台皮肤 |
---
## 3. 技术设计(可选)
### 架构设计
```mermaid
flowchart TD
A[CouponsView] --> B[admin.ts coupon 接口]
A --> C[coupons.ts 展示/序列化工具]
A --> D[CouponEditorDialog]
D --> B
D --> C
D --> E[getPlans]
```
### API设计
#### GET /coupon/fetch
- **请求**: `{ current, pageSize }`
- **响应**: `{ total, current_page, per_page, last_page, data[] }`
#### POST /coupon/generate
- **请求**: `{ id?, generate_count?, name, code?, type, value, started_at, ended_at, limit_use?, limit_use_with_user?, limit_plan_ids?, limit_period? }`
- **响应**: `{ status, data }`
#### POST /coupon/update
- **请求**: `{ id, show }`
- **响应**: `{ status, data }`
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| id | number | 优惠券 ID |
| show | boolean | 是否启用 |
| name | string | 优惠券名称 |
| type | 1 \| 2 | 1=按金额优惠,2=按比例优惠 |
| value | number | 金额分/折扣整数 |
| code | string | 券码 |
| limit_use | number \| null | 总可用次数 |
| limit_use_with_user | number \| null | 每人可用次数 |
| limit_plan_ids | string[] \| null | 限制套餐 |
| limit_period | string[] \| null | legacy 周期键 |
| started_at / ended_at | number | 生效时间范围(Unix 秒) |
---
## 4. 核心场景
### 场景: 运营创建单张优惠券
**模块**: admin-frontend/subscriptions
**条件**: 管理员已登录,进入 `#/subscriptions/coupons`
**行为**: 点击“添加优惠券”,填写名称、类型、金额、有效期并提交
**结果**: 新优惠券保存成功,列表刷新并展示新记录
### 场景: 运营批量生成优惠码
**模块**: admin-frontend/subscriptions
**条件**: 管理员在新增弹窗中填写 `generate_count`
**行为**: 提交批量生成请求
**结果**: 后端批量创建优惠券,前端提示成功并刷新列表
### 场景: 运营筛选并停用过期优惠券
**模块**: admin-frontend/subscriptions
**条件**: 列表中存在多种类型与已过期记录
**行为**: 使用关键字或类型筛选找到目标记录,关闭启用开关
**结果**: 对应优惠券 `show=false`,列表状态即时更新
---
## 5. 技术决策
### admin-frontend-coupon-management#D001: 优惠券列表采用真实接口 + 本地搜索/筛选/分页
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 后端 `/coupon/fetch` 支持分页,但关键字筛选以 `where like` 串联多个字段时不适合做“名称或券码”搜索。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 完全依赖后端筛选 | 数据量更轻 | 关键字搜索能力受限,名称/券码无法自然并行匹配 |
| B: 拉取合理数量后本地搜索/筛选/分页 | 交互更贴近参考图,搜索更灵活 | 极大数据量下效率不如纯服务端 |
**决策**: 选择方案 B
**理由**: 当前后台优惠券数量通常不大,本地处理可更稳定满足截图中的使用方式。
**影响**: `CouponsView.vue``admin.ts``coupons.ts`
### admin-frontend-coupon-management#D002: 新增与编辑共用同一弹窗,并统一序列化到 `/coupon/generate`
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 后端没有独立的 coupon save/update 表单接口,新增与编辑都通过 `generate` 处理。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 新增/编辑拆两套表单 | 心智更直观 | 代码重复,字段校验需要维护两份 |
| B: 共用一个表单模型与序列化逻辑 | 结构更稳定,便于维护 | 需要额外处理编辑态初始值 |
**决策**: 选择方案 B
**理由**: 与当前套餐编辑抽屉模式一致,能减少重复逻辑并提高一致性。
**影响**: `CouponEditorDialog.vue``utils/coupons.ts`
### admin-frontend-coupon-management#D003: 编辑态继续采用居中弹窗而非侧边抽屉
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 参考图中优惠券编辑器为居中对话框,且字段密度更适合聚焦式表单。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 复用抽屉模式 | 与套餐管理统一 | 与参考图差异更大,纵向表单视觉焦点分散 |
| B: 改为居中弹窗 | 更贴近参考图,聚焦更强 | 需要单独编写对话框布局样式 |
**决策**: 选择方案 B
**理由**: 这页的主要新增价值就在参考图里的“表格 + 弹窗”组合,值得贴近还原。
**影响**: `CouponEditorDialog.vue` 及其样式
---
## 6. 成果设计
### 设计方向
- **美学基调**: Apple Admin Promotions。像 Apple 后台里的运营配置页,黑色首屏负责建立业务主题,正文工作台回到白底高密度表格,让折扣配置看起来更像精密运营台而不是营销页面。
- **记忆点**: 大标题“优惠券管理”与白色表格之间形成明显的黑白切面;弹窗内部用整齐的双列字段和轻描边区块还原截图的“精密表单感”。
- **参考**: `apple/DESIGN.md``.helloagents/DESIGN.md`、用户上传的优惠券列表与添加弹窗截图
### 视觉要素
- **配色**: 首屏 `#000000`,工作区 `#ffffff`,页面背景 `#f5f5f7`,强调色 `#0071e3`,过期提示用浅红底 `rgba(201, 52, 40, 0.08)`
- **字体**: 延续项目现有系统字体栈,标题走大字号紧行高,表格与辅助信息维持更轻的运营化层级
- **布局**: 首屏 Hero + 工具条 + 表格工作台;编辑器采用居中弹窗,字段按双列网格排布,底部操作区固定在弹窗底部
- **动效**: 保留开关切换、弹窗开合、按钮 hover 与筛选状态切换的轻量动效,不引入额外炫技动画
- **氛围**: 工作台继续使用克制阴影、圆角白底与 Apple 式留白,避免多余卡片堆叠
### 技术约束
- **可访问性**: 交互控件保留可见焦点,状态信息不只依赖颜色,危险操作保留明确文案
- **响应式**: 桌面优先;窄屏下 Hero、工具条和弹窗网格折叠为单列,确保表单仍可完整操作
@@ -0,0 +1,56 @@
# 任务清单: admin-frontend-coupon-management
> **@status:** completed | 2026-04-24 16:28
```yaml
@feature: admin-frontend-coupon-management
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 6 | 0 | 0 | 6 |
---
## 任务列表
### 1. 数据与路由准备
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts``admin-frontend/src/api/admin.ts` 中补齐优惠券列表、保存载荷与接口封装 | depends_on: []
- [√] 1.2 新增 `admin-frontend/src/utils/coupons.ts`,实现优惠券类型/周期选项、时间与表单转换、列表过滤与过期状态计算 | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/layouts/AdminLayout.vue``admin-frontend/src/router/index.ts` 中开放“优惠券管理”菜单与路由 | depends_on: [1.1]
### 2. 优惠券页面实现
- [√] 2.1 新增 `admin-frontend/src/views/subscriptions/CouponsView.vue` 与样式,实现列表、搜索、类型筛选、本地分页、启停、编辑与删除入口 | depends_on: [1.1,1.2,1.3]
- [√] 2.2 新增 `admin-frontend/src/views/subscriptions/CouponEditorDialog.vue` 与样式,实现新增/编辑弹窗、双列表单、指定周期/订阅、多码生成与提交保存 | depends_on: [1.1,1.2,1.3]
### 3. 验证与同步
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成优惠券管理视觉/交互自检 | depends_on: [2.1,2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 15:51 | 方案包初始化 | completed | 已确认本轮范围为完整优惠券管理接入,采用 Apple 化后台风格 |
| 2026-04-24 16:06 | 1.1 / 1.2 / 1.3 | completed | 已补齐 coupon 类型、接口、工具函数,并开放“优惠券管理”菜单与路由 |
| 2026-04-24 16:18 | 2.1 / 2.2 | completed | 已完成优惠券列表页与新增/编辑弹窗,接入真实 coupon 接口与套餐限制项 |
| 2026-04-24 16:28 | 3.1 | completed | `npm run build` 通过;当前环境缺少可复用浏览器与登录态,仅完成代码级视觉/交互自检 |
---
## 执行备注
> 记录执行过程中的重要说明、决策变更、风险提示等
- 当前工作树可能存在与本轮无关的其他改动,实施过程中需保持最小作用域,不覆盖既有未提交修改。
- 当前后端缺少专门的 coupon detail/save 分离接口,编辑流程将复用 `coupon/generate`,并在前端统一做字段序列化。
- 当前视觉验收受限于本地缺少可复用的后台登录态与浏览器截图工具,本轮已通过构建产物、组件结构与样式代码完成代码级验收,建议后续在真实管理登录态下补一次人工点检。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"done": 5,
"percent": 100,
"current": "插件管理工作台、详情抽屉与构建验证已完成",
"updated_at": "2026-04-24 16:12:00"
}
@@ -0,0 +1,51 @@
{
"updatedAt": "2026-04-24T07:55:29.737Z",
"version": 1,
"source": "manual",
"originCommand": "plugin-management-r2",
"verifyMode": "review-first",
"reviewerFocus": [
"插件管理页是否延续当前 Apple 风格后台,并形成真实工作台而不是占位页",
"卡片动作优先级、危险动作和受保护插件边界是否清晰",
"详情抽屉中的 README 与配置双视图是否易读且层级明确"
],
"testerFocus": [
"插件列表、类型切换、状态筛选与搜索是否真实连接 /plugin/getPlugins 数据流",
"上传、安装、启用、禁用、升级、卸载动作是否真实命中对应插件接口",
"插件配置读取与保存是否真实命中 /plugin/config"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"plan.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "插件管理属于整页 UI 重做,需确认卡片列表、筛选工具栏与详情抽屉层级符合 Apple 风格后台契约",
"screens": [
"#/system/plugins desktop",
"#/system/plugins detail-drawer desktop"
],
"states": [
"插件列表加载完成态",
"插件列表空状态或错误态",
"插件详情 README 态",
"插件配置编辑态"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,65 @@
# admin-frontend 插件管理首版交付 — 实施规划
## 目标与范围
-`#/system/plugins` 从占位页升级为真实插件管理页面。
- 本轮范围聚焦“单页工作台 + 详情抽屉”模型:列表承担检索、筛选和高频动作,抽屉承担 README、配置与补充说明。
- 其余系统管理子页保持现状,不借本轮需求扩展其他模块。
## 架构与实现策略
-`admin-frontend/src/api/admin.ts``src/types/api.d.ts` 中补齐插件管理接口和类型定义,保证所有页面动作都走真实后端契约。
- 新增 `src/utils/plugins.ts`,集中处理插件类型文案、状态判断、筛选、README 渲染与配置表单值序列化,避免视图组件堆积逻辑。
-`/system/plugins` 路由替换为独立的 `PluginManagementView.vue`,继续保留黑色 hero + 白色工作台层次,首屏承载搜索、类型切换、状态筛选、上传入口与运营摘要。
- 新增 `PluginDetailDrawer.vue` 作为插件详情工作台:
- 左侧 / 顶部展示插件基本信息与状态
- 中部切换 README / 配置两个视图
- 配置基于后端返回的动态 schema 渲染,不额外臆造字段
- 列表卡片提供高频动作按钮:
- 未安装:安装
- 已安装未启用:启用、卸载
- 已启用:禁用
- 可升级:升级
- 受保护 / 核心插件:明确显示保护边界,避免危险误操作
## 完成定义
- `#/system/plugins` 能真实拉取插件列表,并按类型 / 状态 / 关键词筛选。
- 页面支持上传 zip 插件包,并在上传成功后刷新列表。
- 管理员可以对插件执行安装、启用、禁用、升级、卸载动作,并获得明确成功 / 失败反馈。
- 详情抽屉可查看 README 和插件基础信息;对存在配置 schema 的插件,可读取并保存配置。
- 验证主路径:`review-first`
- reviewer 关注边界:
- 插件管理首屏是否与现有 Apple 风格后台一致,且不像占位页
- 列表动作优先级、危险按钮和受保护插件边界是否清晰
- 详情抽屉的 README / 配置双视图是否足够清楚
- tester 关注边界:
- `/plugin/getPlugins``/plugin/upload``/plugin/install``/plugin/enable``/plugin/disable``/plugin/uninstall``/plugin/upgrade` 是否都已接入真实数据流
- 插件配置读取 / 保存是否真实命中 `/plugin/config`
- 搜索、类型切换、状态筛选是否真实影响渲染结果
## 文件结构
- `admin-frontend/src/router/index.ts`
- `admin-frontend/src/api/admin.ts`
- `admin-frontend/src/types/api.d.ts`
- `admin-frontend/src/utils/plugins.ts`(新增)
- `admin-frontend/src/views/system/PluginManagementView.vue`(新增)
- `admin-frontend/src/views/system/PluginManagementView.scss`(新增)
- `admin-frontend/src/views/system/PluginDetailDrawer.vue`(新增)
## UI / 设计约束
- 首屏延续当前系统管理模块的黑色 hero,右侧摘要卡片改为“插件总数 / 已启用 / 可升级 / 用户上传”等运营信息。
- 列表采用大卡片而不是传统密表格,强调插件名称、类型、版本、作者、描述与状态标签,贴近用户截图的阅读方式。
- 顶部筛选区使用轻量 segmented control + select + search 组合,不引入多层复杂过滤器。
- 配置表单要兼容 `boolean / string / text / json / select` 等基础字段类型,字段说明与 placeholder 保持可见。
- README 区域使用真实 Markdown 渲染,保留代码块、列表和标题层级。
## 风险与验证
- 风险 1:后端返回的插件配置 schema 是动态结构,前端需要兼容多种字段类型与空配置插件。
- 风险 2`getPlugins` 已带部分配置和 README,但已安装插件的配置需要保证与 `/plugin/config` 拉取一致,避免抽屉内旧数据。
- 风险 3:本地环境缺少真实登录态时,无法做完整浏览器联调;需要用 build + 代码级结构自检给出本轮 UI 验收结论。
- 验证方式:
- `npm run build`
- 对构建产物与代码结构做 UI 自检,确认搜索、筛选、卡片操作与抽屉视图均已真实连接数据流
## 决策记录
- [2026-04-24] D001:插件管理采用“卡片列表 + 详情抽屉”,不回退到纯表格,兼顾截图风格和后台可操作性。
- [2026-04-24] D002:配置编辑采用动态 schema 渲染,不为单个插件写死字段。
- [2026-04-24] D003README 与配置合并进同一个详情工作台,避免列表页信息密度失控。
@@ -0,0 +1,47 @@
# admin-frontend 插件管理首版交付 — 需求
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
## 核心目标
-`admin-frontend` 中把 `/system/plugins` 从结构化占位页升级为真实插件管理工作台。
- 页面视觉继续遵循 `apple/DESIGN.md` 与当前后台 Apple 化风格,并尽量贴近用户提供的目标截图:顶部搜索 / 分组切换 / 状态筛选 / 上传入口,下方插件卡片列表。
- 让管理员可以在同一页面完成插件浏览、筛选、上传、安装、启用 / 禁用、升级、卸载,以及 README / 配置查看与编辑。
## 功能边界
- 必须接入现有 Laravel 管理接口的真实数据链路:
- `GET /plugin/types`
- `GET /plugin/getPlugins`
- `POST /plugin/upload`
- `POST /plugin/install`
- `POST /plugin/uninstall`
- `POST /plugin/enable`
- `POST /plugin/disable`
- `GET /plugin/config`
- `POST /plugin/config`
- `POST /plugin/upgrade`
- 必须支持:
- 按关键词搜索插件
- 按插件类型切换(全部 / 功能 / 支付方式)
- 按状态筛选(全部 / 已启用 / 已安装未启用 / 未安装 / 可升级)
- 上传 zip 插件包
- 列表中直接执行安装、启用、禁用、升级、卸载动作
- 打开插件详情工作台,查看 README、基础元信息,并对可配置插件进行配置保存
- 必须覆盖加载、空列表、错误、按钮提交中、配置保存成功 / 失败等状态。
## 非目标
- 本轮不实现主题、公告、支付配置、知识库管理的真实 CRUD 页面。
- 本轮不新增或重构 Laravel 插件管理接口。
- 本轮不接入浏览器端拖拽上传、批量操作或插件市场远程下载能力。
- 本轮不修改 `public/assets/admin` 子模块之外的发布流程。
## 技术约束
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`
- 后端真相源以现有 `PluginController` / `PluginConfigService` / `PluginManager` 为准,不在前端猜测额外字段。
- 视觉契约优先级:本方案 > `.helloagents/DESIGN.md` > `apple/DESIGN.md` 参考原则。
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`
## 质量要求
- 插件管理页必须保持 Apple 风格后台的一致性,同时比现有占位页更强调运营效率与状态可读性。
- 卡片与详情工作台中的插件状态、危险动作和受保护插件边界必须清晰可辨。
- README 展示与配置编辑必须是真实数据流,不允许停留在纯展示占位。
- 最终至少完成一次构建验证,并补一份本轮 UI 验收结论。
@@ -0,0 +1,13 @@
# admin-frontend 插件管理首版交付 — 任务分解
## 任务列表
- [x] 任务1:冻结本轮插件管理方案包与状态上下文(涉及文件:`.helloagents/plan/202604241553_admin-frontend-plugin-management/requirements.md``.helloagents/plan/202604241553_admin-frontend-plugin-management/plan.md``.helloagents/plan/202604241553_admin-frontend-plugin-management/tasks.md``.helloagents/plan/202604241553_admin-frontend-plugin-management/contract.json``.helloagents/sessions/master/default/STATE.md`;完成标准:存在可执行的需求/方案/任务/合同文件,状态文件已切到插件管理主线;验证方式:文件检查)
- [x] 任务2:补齐插件管理前端类型与 API(涉及文件:`admin-frontend/src/api/admin.ts``admin-frontend/src/types/api.d.ts``admin-frontend/src/utils/plugins.ts`;完成标准:存在插件列表、动作、配置、上传所需的真实接口封装与辅助类型 / 工具;验证方式:`npm run build`
- [x] 任务3:实现插件管理列表工作台(涉及文件:`admin-frontend/src/router/index.ts``admin-frontend/src/views/system/PluginManagementView.vue``admin-frontend/src/views/system/PluginManagementView.scss`;完成标准:`#/system/plugins` 能展示真实插件卡片、搜索、类型切换、状态筛选、上传入口与列表动作;验证方式:`npm run build`
- [x] 任务4:实现插件详情与配置工作台(涉及文件:`admin-frontend/src/views/system/PluginDetailDrawer.vue``admin-frontend/src/utils/plugins.ts``admin-frontend/src/api/admin.ts`;完成标准:可打开 README / 配置抽屉,并支持真实配置读取与保存;验证方式:`npm run build`
- [x] 任务5:完成验证、知识库同步与交付证据(涉及文件:`.helloagents/modules/admin-frontend.md``.helloagents/CHANGELOG.md``.helloagents/.ralph-visual.json``.helloagents/.ralph-closeout.json``.helloagents/archive/_index.md``.helloagents/sessions/master/default/STATE.md`;完成标准:构建通过,UI 验收结论与知识库记录同步完成;验证方式:命令输出 + 证据文件)
## 进度
- [x] 已冻结插件管理首版交付范围。
- [x] 已完成插件管理页面与详情工作台。
- [x] 已完成验证与知识库同步。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 6,
"failed": 0,
"pending": 0,
"total": 6,
"done": 6,
"percent": 100,
"current": "支付配置真实工作台已完成,等待归档与用户验收",
"updated_at": "2026-04-24 16:14:00"
}
@@ -0,0 +1,206 @@
# 变更提案: admin-frontend-payment-management
## 元信息
```yaml
类型: 功能开发
方案类型: implementation
优先级: P1
状态: 进行中
创建: 2026-04-24
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 的“支付配置”仍是占位页,但 Laravel 后端已经提供 `payment/fetch``payment/getPaymentMethods``payment/getPaymentForm``payment/save``payment/show``payment/drop``payment/sort` 等完整管理接口。用户本轮明确选择“完整真实 CRUD”方案,并提供了支付列表、编辑抽屉与支付接口下拉截图,要求继续完成支付配置模块。
### 目标
-`#/system/payments` 从占位页升级为真实可用的支付配置页面。
- 提供支付方式列表、关键词搜索、启停、新增/编辑、删除与排序能力。
- 抽屉表单按所选支付接口动态拉取配置字段,保持与后端支付插件表单契约一致。
- 视觉上延续 `apple/DESIGN.md``.helloagents/DESIGN.md` 的 Apple 风格后台体系。
### 约束条件
```yaml
范围约束: 仅实现支付配置工作台,不扩展插件/主题/知识库等其他系统模块
技术约束: 继续使用 Vue3 + TypeScript + Element Plus,不新增第三方表单或拖拽依赖
业务约束: 后端真实契约以 PaymentController / PaymentService / 插件 form() 返回字段为准,不在前端猜测额外支付字段
数据约束: 排序继续调用 `/payment/sort`;启停继续调用 `/payment/show` 的“切换”语义接口
视觉约束: 延续黑色 hero + 白色工作台 + 克制蓝色交互,保持与现有系统配置/套餐管理同一视觉家族
```
### 验收标准
- [ ] `#/system/payments` 可真实拉取支付方式列表,并显示 ID、启用状态、显示名称、支付接口、通知地址与操作列。
- [ ] 页面支持关键词搜索,筛选后结果与分页计数同步更新。
- [ ] 支持新增与编辑支付方式,字段覆盖显示名称、图标 URL、通知域名、百分比手续费、固定手续费、支付接口与动态支付配置字段。
- [ ] 支持启停、删除与排序,并给出明确成功/失败反馈。
- [ ] `admin-frontend` 执行 `npm run build` 通过。
---
## 2. 方案
### 页面结构
1. 延续系统管理页面的 Apple 化后台结构,顶部使用黑色 hero 展示支付概览统计。
2. 主工作区使用白色表格容器,提供“添加支付方式”“搜索支付方式”“编辑排序”三类核心操作。
3. 支付方式编辑采用右侧抽屉,顶层字段集中展示显示名称、图标、通知域名、手续费与支付接口。
4. 抽屉下半区按支付接口动态加载真实配置字段,保持与后端插件 `form()` 返回结果一致。
5. 排序使用独立对话框,通过上移/下移维护本地顺序,再提交到 `/payment/sort`
### 前端实现策略
1.`src/types/api.d.ts``src/api/admin.ts` 中补齐支付方式列表、动态配置字段与保存载荷类型 / API 封装。
2. 新增 `src/utils/payments.ts`,集中处理支付方式归一化、关键词过滤、排序移动、手续费展示与动态配置序列化。
3. 新增:
- `src/views/system/SystemPaymentsView.vue`
- `src/views/system/SystemPaymentsView.scss`
- `src/views/system/SystemPaymentEditorDrawer.vue`
- `src/views/system/SystemPaymentEditorDrawer.scss`
4.`/system/payments` 路由切换为真实页面,其余系统管理入口保持现状不动。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/types: 补齐支付配置相关类型定义
- admin-frontend/src/api: 新增 payment 管理接口封装
- admin-frontend/src/utils: 新增支付数据转换、过滤、保存辅助逻辑
- admin-frontend/src/views/system: 新增支付列表页与编辑抽屉
- admin-frontend/src/router: 将支付配置路由切换到真实页面
预计变更文件: 8-9
```
### 风险评估
| 风险 | 等级 | 应对 |
| 后端 `/payment/show` 是切换型接口,不接受显式目标状态 | 中 | 前端只在用户主动切换时调用一次,并在成功后按目标值更新本地状态 |
| 动态支付配置字段完全由插件 form() 返回,前端若自行假设字段会导致保存错位 | 高 | 抽屉内所有支付配置字段均通过 `/payment/getPaymentForm` 实时拉取,不写死配置项 |
| 构建会刷新 `public/assets/admin` 子模块产物 | 中 | 仅执行 `admin-frontend` 构建验证,不自动代做子模块发布 |
---
## 3. 技术设计(可选)
### 架构设计
```mermaid
flowchart TD
A[SystemPaymentsView] --> B[admin.ts payment API]
A --> C[payments.ts]
A --> D[SystemPaymentEditorDrawer]
D --> B
D --> C
```
### API设计
#### GET /payment/fetch
- **请求**: 无
- **响应**: `AdminPaymentListItem[]`
#### GET /payment/getPaymentMethods
- **请求**: 无
- **响应**: `string[]`
#### POST /payment/getPaymentForm
- **请求**: `{ payment, id? }`
- **响应**: `Record<string, AdminPaymentConfigField>`
#### POST /payment/save
- **请求**: `{ id?, name, icon?, payment, config, notify_domain?, handling_fee_fixed?, handling_fee_percent? }`
- **响应**: `{ status, data }`
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| id | number | 支付方式 ID |
| payment | string | 支付接口代码,如 EPay / TokenPay |
| name | string | 后台显示名称 |
| icon | string \| null | 图标 URL |
| notify_domain | string \| null | 自定义通知域名 |
| notify_url | string \| null | 后端拼接后的完整通知地址 |
| handling_fee_fixed | number \| null | 固定手续费 |
| handling_fee_percent | number \| null | 百分比手续费 |
| enable | boolean | 是否启用 |
| config | Record<string, unknown> | 支付插件配置对象 |
---
## 4. 核心场景
### 场景: 运营新增支付方式
**模块**: admin-frontend/system
**条件**: 管理员已登录,进入 `#/system/payments`
**行为**: 点击“添加支付方式”,选择支付接口并填写网关参数后提交
**结果**: 新支付方式保存成功,列表刷新并展示新记录
### 场景: 运营切换支付启用状态
**模块**: admin-frontend/system
**条件**: 列表中存在可用支付方式
**行为**: 在列表中切换启用开关
**结果**: 对应支付方式状态被切换,并在当前列表中即时更新
### 场景: 运营维护支付排序
**模块**: admin-frontend/system
**条件**: 系统中存在多个支付方式
**行为**: 打开“编辑排序”,调整上下顺序并保存
**结果**: 后端 `/payment/sort` 接收新的排序序列,列表刷新为最新顺序
---
## 5. 技术决策
### admin-frontend-payment-management#D001: 支付配置采用“真实列表页 + 动态配置抽屉 + 独立排序对话框”
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 用户截图已经明确表达“列表 + 右侧编辑抽屉 + 编辑排序”的后台工作流结构。
**选项分析**:
| 选项 | 优点 | 缺点 |
| A: 继续使用占位页 | 改动最小 | 无法完成真实支付配置任务 |
| B: 列表页 + 动态配置抽屉 + 排序对话框 | 最贴近截图,也与套餐管理模式一致 | 需要新增更多前端结构与状态管理 |
**决策**: 选择方案 B
**理由**: 能同时覆盖用户截图中的真实使用方式与当前 Apple 风格后台架构。
**影响**: `SystemPaymentsView.vue``SystemPaymentEditorDrawer.vue`
### admin-frontend-payment-management#D002: 支付配置字段完全以后端 `/payment/getPaymentForm` 为唯一真相源
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 各支付插件的配置字段由插件 `form()` 动态生成,字段集并不固定。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 前端写死常见支付字段 | 实现快 | 无法覆盖不同插件,容易与后端表单脱节 |
| B: 每次根据接口动态拉取字段 | 契约最稳定 | 需要额外处理加载与切换状态 |
**决策**: 选择方案 B
**理由**: 可同时兼容 EPay、TokenPay、AlipayF2F、Coinbase 等不同插件,不会因为字段假设错误而破坏保存链路。
**影响**: `admin.ts``payments.ts``SystemPaymentEditorDrawer.vue`
### admin-frontend-payment-management#D003: 支付启停继续沿用现有“切换型接口”,前端做同值短路保护
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: `/payment/show` 后端实现是直接反转状态,不接收目标状态。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 前端假设为“设置型接口”并传目标值 | 交互直觉更强 | 与后端真实行为不一致,容易在重复事件下错位 |
| B: 前端只做主动点击触发 + 成功后同步本地状态 | 与现有接口完全对齐 | 需要额外防止无效 change 事件 |
**决策**: 选择方案 B
**理由**: 能最小代价对齐后端现状,并避免初始化或重复事件导致的误切换。
**影响**: `SystemPaymentsView.vue`
---
## 6. 成果设计
### 设计方向
- **美学基调**: Apple Admin Payments。黑色首屏强调“系统级支付运营台”的沉稳感,正文回到白底高密度工作台,重点突出支付方式与通知链路,而不是营销化装饰。
- **记忆点**: 支付配置列表里的“图标 + 名称 + 手续费摘要”组合,与右侧动态配置抽屉形成明显的黑白双层结构。
- **参考**: `apple/DESIGN.md``.helloagents/DESIGN.md`、用户提供的支付列表 / 编辑抽屉 / 支付接口下拉截图
### 视觉要素
- **配色**: 首屏 `#000000`,页面背景 `#f5f5f7`,工作区 `#ffffff`,强调色 `#0071e3`,危险动作保持 `var(--xboard-danger)`
- **字体**: 延续项目现有系统字体栈,首屏标题保持大字号紧行高,列表和抽屉字段走轻量运营层级
- **布局**: Hero + 工具条 + 表格工作台;编辑器采用右侧抽屉,表单上半部为顶层字段,下半部为动态支付配置
- **动效**: 仅保留抽屉开合、按钮 hover、排序对话框切换与开关状态变化的轻量动效
- **氛围**: 使用克制阴影、圆角白底、胶囊型通知地址与简洁图标预览,不堆叠过多卡片或装饰性标签
### 技术约束
- **可访问性**: 开关、按钮、抽屉表单需保留可见焦点;错误和危险操作不能只靠颜色表达
- **响应式**: 桌面优先;窄屏下 hero、工具条、排序对话框和抽屉字段网格需折叠为单列
@@ -0,0 +1,53 @@
# 任务清单: admin-frontend-payment-management
> **@status:** completed | 2026-04-24 16:14
```yaml
@feature: admin-frontend-payment-management
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 6 | 0 | 0 | 6 |
---
## 任务列表
### 1. 数据与路由准备
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts``admin-frontend/src/api/admin.ts` 中补齐支付方式列表、动态配置字段与接口封装 | depends_on: []
- [√] 1.2 新增 `admin-frontend/src/utils/payments.ts`,实现支付方式归一化、过滤、排序移动与保存序列化 | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/router/index.ts` 中将 `/system/payments` 切换到真实支付配置页面 | depends_on: [1.1]
### 2. 支付配置页面实现
- [√] 2.1 新增 `admin-frontend/src/views/system/SystemPaymentsView.vue` 与样式,实现列表、搜索、启停、删除、新增/编辑入口与排序对话框 | depends_on: [1.1,1.2,1.3]
- [√] 2.2 新增 `admin-frontend/src/views/system/SystemPaymentEditorDrawer.vue` 与样式,实现动态支付接口配置抽屉与保存提交流程 | depends_on: [1.1,1.2,1.3]
### 3. 验证与同步
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成支付配置视觉/交互自检 | depends_on: [2.1,2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 15:58 | 方案包初始化 | completed | 已确认本轮范围为支付配置完整 CRUD 工作台,目标对齐用户截图与 `/payment/*` 后端接口 |
| 2026-04-24 16:05 | 1.1 / 1.2 / 1.3 | completed | 已补齐支付配置类型、API、工具层与真实路由切换 |
| 2026-04-24 16:11 | 2.1 / 2.2 | completed | 已完成支付配置列表、排序对话框与动态支付配置抽屉 |
| 2026-04-24 16:14 | 3.1 | completed | `npm run build` 通过;当前环境无浏览器自动化工具,已完成代码级视觉与交互自检 |
---
## 执行备注
- 当前工作树存在与本轮无关的其他未提交修改,实施时需保持最小作用域,不覆盖已有 in-progress 改动。
- 构建验证会刷新 `public/assets/admin` 子模块产物,本轮仅提供功能实现与验证证据,不自动代做发布。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"done": 5,
"percent": 100,
"current": "主题管理页面、动态配置抽屉与构建验证已完成,等待交付",
"updated_at": "2026-04-24 16:12:00"
}
@@ -0,0 +1,75 @@
# 变更提案: admin-frontend-theme-management
## 元信息
```yaml
类型: 新功能
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-24
```
---
## 1. 需求
### 背景
当前 `admin-frontend` 已经完成系统配置真实页,但 `#/system/themes` 仍停留在结构化占位状态。用户本轮要求继续基于 `apple/DESIGN.md`、项目级 `.helloagents/DESIGN.md` 和提供的参考图,把“主题配置”升级为真实可用的主题管理页面。
### 目标
-`#/system/themes` 从占位页升级为真实主题管理工作台。
- 展示可用主题列表、当前主题标记和主题基础信息。
- 提供主题设置抽屉,支持动态主题配置保存。
- 提供 zip 主题包上传入口,并支持把某个主题设为当前主题。
### 约束条件
```yaml
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + Vite,不新增主题编辑器或上传库
业务约束: 后端沿用现有 `theme/*` 与 `config/save(frontend_theme)` 能力,不修改 Laravel API
范围约束: 本轮先完成主题列表、当前主题切换、主题设置与上传;删除主题保留到下一轮
视觉约束: 保持 Apple 化后台语义,页面结构优先贴近参考图中的“标题 + 说明 + 主题卡片 + 上传入口”
```
### 验收标准
- [ ] `#/system/themes` 能展示真实主题列表,不再使用占位页。
- [ ] 页面能明确标记当前主题,并允许把其他主题设为当前主题。
- [ ] 点击“主题设置”可打开配置抽屉,按主题 schema 渲染字段并保存。
- [ ] 页面提供 zip 主题包上传入口,并接入真实后端上传接口。
- [ ] `admin-frontend` 构建通过,且知识库记录主题管理已从占位页升级为真实页面。
---
## 2. 方案
### 技术方案
1.`src/types/api.d.ts``src/api/admin.ts` 中补齐主题列表、主题配置和主题上传所需类型与接口封装。
2. 新增 `src/utils/themes.ts`,统一处理主题列表排序、配置默认值回填和表单序列化。
3. 新增 `src/views/system/ThemesView.vue``ThemeConfigDrawer.vue`
- `ThemesView` 负责标题区、当前主题/数量摘要、主题卡片、上传按钮与切换逻辑。
- `ThemeConfigDrawer` 负责根据主题 schema 动态渲染配置项并保存。
4.`src/router/index.ts` 中把 `system/themes` 路由从占位页切换到真实页面组件。
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 主题切换没有独立 `switchTheme` 路由 | 中 | 复用 `config/save``frontend_theme` 保存链路,由后端内部触发 `ThemeService::switch` |
| 主题配置字段完全动态,前端容易误假设字段类型 | 中 | 仅支持后端 schema 已声明的 `input / textarea / select` 三类字段 |
| 本地缺少后台登录态与浏览器截图工具 | 低 | 本轮以构建通过 + 代码级视觉自检作为验收证据,并在知识库中注明限制 |
---
## 3. 技术决策
### admin-frontend-theme-management#D001: 主题切换复用 `config/save(frontend_theme)`,不前端直连未开放路由
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 后端 `ThemeController` 存在 `switchTheme()`,但当前管理路由未公开对应 endpoint。
**决策**: 前端将“设为当前主题”统一走 `saveAdminConfig({ frontend_theme })`
**理由**: 这条链路已被 `ConfigController` 正式支持,且内部会触发 `ThemeService->switch`,无需扩展后端接口。
### admin-frontend-theme-management#D002: 主题配置使用右侧抽屉,不在卡片内直接展开表单
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 参考图强调卡片式主题列表;主题配置字段是动态 schema,直接展开会破坏列表节奏。
**决策**: 卡片只承载主题信息与主操作,详细配置统一放进 `ThemeConfigDrawer`
**理由**: 更贴合 Apple 化后台“主列表 + 聚焦设置面板”的结构,也便于后续扩展删除/预览等动作。
@@ -0,0 +1,54 @@
# 任务清单: admin-frontend-theme-management
> **@status:** completed | 2026-04-24 16:12
```yaml
@feature: admin-frontend-theme-management
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 5 | 0 | 0 | 5 |
---
## 任务列表
### 1. 数据与路由准备
- [√] 1.1 在 `admin-frontend/src/types/api.d.ts``admin-frontend/src/api/admin.ts` 中补齐主题管理类型、配置接口与上传接口 | depends_on: []
- [√] 1.2 新增 `admin-frontend/src/utils/themes.ts`,统一处理主题列表排序、动态配置默认值和序列化逻辑 | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/router/index.ts` 中把 `system/themes` 路由切换到真实页面 | depends_on: [1.1]
### 2. 主题管理页面实现
- [√] 2.1 新增 `admin-frontend/src/views/system/ThemesView.vue`,实现标题区、主题卡片、当前主题标记、切换和上传按钮 | depends_on: [1.1,1.2,1.3]
- [√] 2.2 新增 `admin-frontend/src/views/system/ThemeConfigDrawer.vue`,实现主题设置抽屉、动态字段表单与保存动作 | depends_on: [1.1,1.2]
### 3. 验证与同步
- [√] 3.1 运行 `admin-frontend` 构建验证,并结合页面代码完成主题管理视觉/交互自检 | depends_on: [2.1,2.2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 16:07 | 方案包初始化 | completed | 已确认本轮范围为主题列表、当前主题切换、主题设置抽屉与上传主题 |
| 2026-04-24 16:09 | 1.1 / 1.2 / 1.3 | completed | 已补齐主题类型、API、工具函数,并将 `system/themes` 指向真实页面 |
| 2026-04-24 16:11 | 2.1 / 2.2 | completed | 已完成主题卡片页与动态设置抽屉,接入真实主题配置/上传能力 |
| 2026-04-24 16:12 | 3.1 | completed | `npm run build` 通过;当前环境缺少后台登录态与浏览器工具,已完成代码级视觉自检 |
---
## 执行备注
- “设为当前主题”当前复用 `config/save(frontend_theme)` 完成,因为管理路由中没有公开独立的主题切换 endpoint。
- 本轮未实现删除主题,避免在没有额外确认和危险操作设计的情况下引入破坏性入口。
- `public/assets/admin` 为构建产物子模块;本轮构建已刷新对应产物,但未代做子模块提交与根仓发布。
@@ -0,0 +1,48 @@
{
"updatedAt": "2026-04-24T16:20:00+08:00",
"version": 1,
"source": "manual",
"originCommand": "generic-r2",
"verifyMode": "build-first",
"reviewerFocus": [
"订单管理列表结构是否贴近用户提供的后台截图",
"详情抽屉是否覆盖查看、手动支付、取消与佣金状态维护主链路"
],
"testerFocus": [
"订单列表是否真实连接 /order/fetch,并响应搜索、筛选、排序与分页",
"分配订单抽屉是否真实连接 /order/assign",
"详情抽屉是否真实连接 /order/detail /order/paid /order/cancel /order/update"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"requirements.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "订单管理属于真实后台业务页,需要确认列表结构、筛选条与详情抽屉在代码实现上与目标截图和 Apple 化后台契约一致。",
"screens": [
"#/subscriptions/orders desktop"
],
"states": [
"订单列表默认加载完成态",
"分配订单抽屉展开态",
"订单详情抽屉展开态"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,61 @@
# admin-frontend 订单管理首版交付 — 实施规划
## 目标与范围
- 在现有订阅管理分组中补齐订单管理真实页,替换原先的禁用态入口。
- 页面聚焦“订单运营工作台”主链路:查订单、分配订单、看详情、手工补单、管理佣金状态。
## 架构与实现策略
- 在现有 `AdminLayout` 中开放 `/subscriptions/orders` 导航入口,并新增对应路由。
- 新增 `OrdersView` 作为真实列表页,整体结构参考用户截图:
- 顶部标题与说明
- “添加订单”主按钮
- 搜索框
- 类型 / 周期 / 订单状态 / 佣金状态筛选按钮
- 数据表格与分页
- 新增两个子组件:
- `OrderAssignDrawer.vue`:负责手动分配订单
- `OrderDetailDrawer.vue`:负责查看详情与行级动作
-`src/utils/orders.ts` 中集中处理:
- 金额分→元格式化
- 类型 / 状态 / 周期映射
- 筛选参数组装
- 分配订单周期选项生成
- API 层在 `src/api/admin.ts` 中新增订单接口封装;类型定义统一收敛到 `src/types/api.d.ts`
## 完成定义
- 侧边栏中的“订单管理”不再是禁用入口,能正常进入 `#/subscriptions/orders`
- 订单列表可真实连接 `/order/fetch`,并响应搜索、筛选、排序与分页。
- 订单详情抽屉可真实连接 `/order/detail`,且能触发已支付、取消、佣金状态更新。
- 分配订单抽屉可真实连接 `/order/assign`
- 订单金额相关字段统一正确展示为人民币元值。
## 文件结构
- `admin-frontend/src/router/index.ts`
- `admin-frontend/src/layouts/AdminLayout.vue`
- `admin-frontend/src/api/admin.ts`
- `admin-frontend/src/types/api.d.ts`
- `admin-frontend/src/utils/orders.ts`
- `admin-frontend/src/views/subscriptions/OrdersView.vue`
- `admin-frontend/src/views/subscriptions/OrdersView.scss`
- `admin-frontend/src/views/subscriptions/OrderAssignDrawer.vue`
- `admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue`
## UI / 设计约束
- 列表页以白色工作台为主,不堆叠多余卡片;重点放在表格可读性与运营效率。
- 订单号作为主入口,点击后进入详情抽屉,不额外拉长操作列。
- 筛选入口使用紧凑 pill 风格按钮,对齐截图中的轻量筛选条。
- 详情抽屉用黑色 hero + 白色信息卡的节奏,兼顾 Apple 风格与运营后台的信息密度。
## 风险与验证
- 风险 1`/order/fetch` 返回的 `period` 已被后端转换成 legacy key,筛选时需要继续使用数据库真实值。
- 风险 2:订单金额与佣金金额在后端仍以分为单位存储,若前端直接展示会再次出现后台金额口径错误。
- 风险 3:本地环境缺少真实后台登录态时,只能做结构与构建验证,不能替代完整联调。
- 验证方式:
- `npm run build`
- 代码级结构自检 `#/subscriptions/orders`
- 结构化视觉验收记录(无浏览器工具时以 code inspection 说明边界)
## 决策记录
- [2026-04-24] 订单主操作收口到详情抽屉,不额外新增宽操作列,优先对齐用户截图。
- [2026-04-24] 金额展示统一由 `src/utils/orders.ts` 处理,避免分/元换算逻辑散落在页面组件。
- [2026-04-24] 分配订单抽屉默认按所选套餐周期自动回填金额,但允许运营手动覆盖。
@@ -0,0 +1,46 @@
# admin-frontend 订单管理首版交付 — 需求
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
## 核心目标
-`admin-frontend` 中开放“订阅管理 / 订单管理”入口,不再保留禁用态。
- 参考用户提供的订单管理截图,交付真实订单列表页,覆盖搜索、筛选、排序、分页与详情查看。
- 保持 `apple/DESIGN.md``.helloagents/DESIGN.md` 定义的 Apple 化后台视觉语言,但优先贴近截图中的数据密集型运营视图。
## 功能边界
- 必须实现 `#/subscriptions/orders` 真实页面。
- 页面必须包含:
- 添加订单入口
- 订单号搜索
- 类型 / 周期 / 订单状态 / 佣金状态筛选
- 支持排序的订单表格
- 订单详情抽屉
- 分配订单抽屉
- 必须接入现有 Laravel 管理接口:
- `GET /order/fetch`
- `POST /order/detail`
- `POST /order/assign`
- `POST /order/paid`
- `POST /order/cancel`
- `POST /order/update`
- 详情抽屉至少支持:
- 查看订单核心信息与金额拆解
- 对待支付订单手动标记已支付
- 对待支付订单取消
- 对有佣金金额的订单更新佣金状态
## 非目标
- 本轮不实现礼品卡管理真实页面。
- 本轮不改造 Laravel 订单后端接口逻辑。
- 本轮不新增批量操作、多选导出或订单打印等扩展功能。
## 技术约束
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`
- 后端真相源以仓库内 `App\Http\Controllers\V2\Admin\OrderController` 为准。
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`
## 质量要求
- 订单页面需要对齐截图中的高密度表格工作流,同时保持 Apple 化后台的克制风格。
- 金额字段必须统一处理“后端以分存储、前端以元展示”的换算。
- 页面需覆盖加载、错误、空状态与成功反馈。
- 最终至少完成一次构建验证,并留下结构化视觉验收与交付证据。
@@ -0,0 +1,14 @@
# admin-frontend 订单管理首版交付 — 任务分解
## 任务列表
- [x] 任务1:补齐订单管理的方案与知识产物(涉及文件:`.helloagents/archive/2026-04/202604241620_admin-frontend-order-management/*`;完成标准:存在需求、方案、任务与合同文件;验证方式:文件检查)
- [x] 任务2:开放导航与路由入口(涉及文件:`admin-frontend/src/layouts/AdminLayout.vue``admin-frontend/src/router/index.ts`;完成标准:侧边栏可进入 `#/subscriptions/orders`;验证方式:`npm run build`
- [x] 任务3:补齐订单 API、类型与工具层(涉及文件:`admin-frontend/src/api/admin.ts``admin-frontend/src/types/api.d.ts``admin-frontend/src/utils/orders.ts`;完成标准:前端可消费 `order/*` 接口并统一金额/状态映射;验证方式:`npm run build`
- [x] 任务4:实现订单列表页(涉及文件:`admin-frontend/src/views/subscriptions/OrdersView.vue``admin-frontend/src/views/subscriptions/OrdersView.scss`;完成标准:列表页支持搜索、筛选、排序、分页与详情入口;验证方式:`npm run build`
- [x] 任务5:实现分配订单与详情抽屉(涉及文件:`admin-frontend/src/views/subscriptions/OrderAssignDrawer.vue``admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue`;完成标准:支持分配订单、查看详情、手动支付、取消订单与佣金状态维护;验证方式:`npm run build`
- [x] 任务6:完成验证与知识库同步(涉及文件:`.helloagents/CHANGELOG.md``.helloagents/context.md``.helloagents/modules/admin-frontend.md``.helloagents/.ralph-visual.json``.helloagents/.ralph-closeout.json`;完成标准:构建通过、知识库更新、交付证据写入;验证方式:命令输出 + 证据文件)
## 进度
- [x] 已确认订单管理首版范围,聚焦真实列表、详情抽屉与分配订单。
- [x] 已完成订单管理页面、抽屉与订单接口接入。
- [x] 已完成构建验证,待输出最终交付摘要。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 3,
"failed": 0,
"pending": 0,
"total": 3,
"done": 3,
"percent": 100,
"current": "全部任务已完成,等待归档方案包",
"updated_at": "2026-04-24 17:07:00"
}
@@ -0,0 +1,108 @@
# 变更提案: admin-frontend-sidebar-height-overflow
## 元信息
```yaml
类型: 缺陷修复
方案类型: implementation
优先级: P1
状态: 已确认
创建: 2026-04-24
```
---
## 1. 需求
### 背景
`admin-frontend` 新增系统管理与订阅管理分组后,左侧导航项明显增多。当前 `AdminLayout.vue` 的侧边栏仍采用“Logo + ElMenu 直接铺满”的结构,而 `body` 又被全局设置为 `overflow: hidden`。在用户截图所示的小窗口高度下,底部菜单会被直接裁切,导致“礼品卡管理”“系统管理”“支付配置”等入口无法完整访问。
### 目标
- 修复管理端侧边栏在低视口高度下显示不全的问题。
- 按用户已确认的方案,保留顶部 Logo/品牌区固定,仅让菜单区独立纵向滚动。
- 保持现有 Apple 风格后台的导航层级、折叠行为和移动端体验不回退。
### 约束条件
```yaml
范围约束: 仅处理 admin 侧边栏在低高度下的可访问性与滚动行为,不扩展菜单信息架构
技术约束: 继续使用 Vue3 + TypeScript + Element Plus,不新增依赖
兼容性约束: 需兼容桌面展开态、折叠态以及现有移动端 fixed aside 行为
视觉约束: 延续 apple/DESIGN.md 与 .helloagents/DESIGN.md 的纯白侧栏 + 单一蓝色激活态体系
```
### 验收标准
- [ ] 在窗口高度不足时,侧边栏底部菜单项仍可通过纵向滚动访问完整。
- [ ] 顶部 Logo/品牌区保持固定,不跟随菜单滚动一起消失。
- [ ] 折叠态与移动端侧边栏不出现新的遮挡、抖动或布局错位。
- [ ] `admin-frontend` 执行 `npm run build` 通过。
---
## 2. 方案
### 技术方案
1.`AdminLayout.vue` 中把侧边栏拆成“固定头部品牌区 + 独立滚动的菜单容器”两层结构,而不是直接让 `ElMenu` 占满整个 `ElAside`
2. 为侧边栏与菜单滚动容器补齐 `min-height: 0``overflow-y: auto`、底部留白和滚动条细节,解决 flex 子项在固定高度容器中无法正确收缩的问题。
3. 保持现有 `ElMenu``ElSubMenu` 和折叠逻辑不变,确保这次修复是针对根因的最小改动,而不是重写导航实现。
### 影响范围
```yaml
涉及模块:
- admin-frontend: 更新主布局侧边栏结构与样式,修复低高度下菜单裁切
- .helloagents/modules/admin-frontend.md: 记录侧边栏低高度滚动规则
预计变更文件: 3
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| Element Plus 菜单在滚动容器中出现高度塌陷或双滚动条 | 中 | 采用独立滚动容器并显式补齐 `min-height: 0` 与内边距,避免只在 `ElMenu` 上追加单点样式 |
| 移动端 fixed aside 与桌面侧栏样式相互影响 | 中 | 仅在当前侧边栏作用域内增加滚动容器样式,保留现有移动端定位策略 |
| 构建会刷新 `public/assets/admin` 构建产物 | 低 | 本轮仅完成本地构建验证,不自动代做子模块发布 |
---
## 3. 核心场景
### 场景: 低高度窗口中的侧边栏导航
**模块**: admin-frontend
**条件**: 浏览器窗口高度不足以同时容纳品牌区与全部菜单项
**行为**: 用户在左侧导航区域滚动菜单
**结果**: 顶部品牌区固定可见,菜单项可完整访问,激活态与分组结构保持正常
---
## 4. 技术决策
### admin-frontend-sidebar-height-overflow#D001: 侧边栏采用“固定品牌区 + 独立滚动菜单区”
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 用户明确选择“顶部 Logo/品牌区固定,仅菜单区域独立纵向滚动”的处理方式。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 固定品牌区,菜单区独立滚动 | 保留品牌识别和导航定位,改动集中、体验最稳定 | 需要微调侧栏结构和滚动容器样式 |
| B: 整个侧边栏整体滚动 | 实现简单 | 品牌区会被滚出视口,低高度下辨识度更差 |
| C: 低高度自动折叠成图标栏 | 可压缩空间 | 会改变现有导航行为,且不是用户选定方案 |
**决策**: 选择方案 A
**理由**: 最符合用户已确认交互,也与当前 Apple 风格后台“固定品牌区 + 稳定导航层级”的设计基线一致。
**影响**: 影响 `AdminLayout.vue` 侧边栏结构与样式,不涉及 API、路由或业务数据流。
---
## 5. 成果设计
### 设计方向
- **美学基调**: 克制运营后台 —— 保留纯白侧栏、细边框、轻阴影和单一蓝色激活态,让修复更像“增强可用性”而非“换一套皮肤”
- **记忆点**: 窗口再矮,顶部品牌区依旧稳定悬停,菜单像独立轨道一样顺滑滚动
- **参考**: 现有 `apple/DESIGN.md``.helloagents/DESIGN.md` 的 Apple 风格后台规范
### 视觉要素
- **配色**: 保持现有 `#ffffff` 侧栏底色、`#0071e3` 激活色和中性文字层级,不引入新强调色
- **字体**: 延续全局系统字体栈 `--xboard-font-sans`,不新增字体
- **布局**: 侧栏继续分为顶部品牌区与下方菜单区,但改为明确的上下分层,菜单区获得独立滚动上下文
- **动效**: 保留当前宽度折叠过渡;滚动本身不增加额外装饰动画
- **氛围**: 维持轻薄、低噪音的 Apple 化后台质感,仅补齐滚动可达性
### 技术约束
- **可访问性**: 键盘聚焦与当前菜单激活态不可被滚动修复破坏
- **响应式**: 桌面低高度、桌面折叠态和移动端 fixed aside 都需保持可用
@@ -0,0 +1,42 @@
# 任务清单: admin-frontend-sidebar-height-overflow
> **@status:** completed | 2026-04-24 17:05
```yaml
@feature: admin-frontend-sidebar-height-overflow
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 3 | 0 | 0 | 3 |
---
## 任务列表
- [√] 1. 审查 `admin-frontend/src/layouts/AdminLayout.vue` 当前侧边栏结构与低高度裁切根因,冻结“固定品牌区 + 菜单独立滚动”实现边界 | depends_on: []
- [√] 2. 在 `admin-frontend/src/layouts/AdminLayout.vue` 中调整侧边栏结构与样式,修复低高度下菜单显示不全问题 | depends_on: [1]
- [√] 3. 运行 `admin-frontend` 构建验证,并同步 `.helloagents/modules/admin-frontend.md``CHANGELOG.md` 记录本轮修复 | depends_on: [2]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 16:55 | 方案包初始化 | completed | 已确认采用“顶部品牌区固定,菜单区域独立纵向滚动”的修复策略 |
| 2026-04-24 16:58 | 根因分析 | completed | 已确认裁切来自 `ElAside` 固定高度 + `ElMenu` 缺少独立滚动上下文,菜单区可滚动高度不足 |
| 2026-04-24 17:02 | 布局修复 | completed | 已将侧边栏拆为固定品牌区与独立滚动菜单区,并补齐 `min-height: 0` / `overflow-y: auto` 样式 |
| 2026-04-24 17:07 | 验证与知识同步 | completed | `npm run build` 通过;Playwright 在 1200x540 视口下确认菜单区 `scrollHeight 1020 > clientHeight 442`,滚动到底后可见系统管理与知识库管理入口 |
---
## 执行备注
- 本轮只修复侧边栏低高度可访问性,不调整菜单信息架构与图标分组。
- 构建验证会刷新 `public/assets/admin` 构建产物,本轮仅完成本地实现与验证,不自动代做子模块发布。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 4,
"failed": 0,
"pending": 0,
"total": 4,
"done": 4,
"percent": 100,
"current": "权限组管理真实页、节点页联动与构建验证已完成",
"updated_at": "2026-04-24 17:10:00"
}
@@ -0,0 +1,166 @@
# 变更提案: admin-frontend-node-group-management
## 元信息
```yaml
类型: 功能增强
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-24
```
---
## 1. 需求
### 背景
`admin-frontend``#/node-groups` 目前仍是结构化占位页,而用户已经提供了目标截图,明确要求继续完成“权限组管理”真实工作台。现有 Laravel 后端已经开放 `server/group/fetch``server/group/save``server/group/drop`,节点管理页也已接入权限组筛选,但缺少从权限组页进入节点筛选的维护闭环。
### 目标
- 将 `#/node-groups` 从占位页升级为真实权限组管理页面,支持列表、搜索、添加、编辑、删除。
- 列表中直接展示权限组 ID、组名称、用户数量、节点数量,并给出符合截图习惯的操作位。
- 补齐与 `#/nodes` 的联动:从权限组页可以一键带筛选跳转到节点页,节点页也能快速回到权限组维护入口。
### 约束条件
```yaml
范围约束: 仅实现 admin-frontend 的权限组前端工作台与节点页联动,不改 Laravel 后端接口行为
技术约束: 继续使用 Vue3 + TypeScript + Element Plus + 现有 axios/adminClient 栈,不新增第三方状态或表格依赖
视觉约束: 以用户截图为直接参考,保留 Apple 化后台的克制留白、系统字体与轻量表格节奏,不套用订阅页黑色 Hero
业务约束: 后端真相源固定为 server/group/fetch、server/group/save、server/group/drop;删除失败原因以前端透传后端文案为准
```
### 验收标准
- [√] `#/node-groups` 可以展示真实权限组列表,并支持关键字搜索与分页浏览。
- [√] 页面支持新增、编辑、删除权限组;新增/编辑使用中央弹窗,删除前有明确确认。
- [√] 节点数量支持跳转到 `#/nodes` 并自动带入对应权限组筛选;节点页提供回到权限组维护入口的联动按钮。
- [√] `admin-frontend` 执行 `npm run build` 通过,产物可继续输出到 `public/assets/admin`
---
## 2. 方案
### 技术方案
1. 在 `src/types/api.d.ts``src/api/admin.ts` 中补齐权限组保存请求类型与 `save/delete` 封装。
2. 新增 `src/utils/nodeGroups.ts`,统一处理权限组计数归一化、本地搜索和摘要计算,避免视图层堆积业务细节。
3. 重写 `NodeGroupsView.vue`,采用“页头说明 + 紧凑工具条 + 白色表格工作台 + 中央编辑弹窗”的结构贴近截图。
4. 新增 `NodeGroupEditorDialog.vue` 处理新增/编辑流程;节点数量使用按钮式链接跳转到 `/nodes?group={id}`
5. 轻量补齐 `NodesView.vue`:识别路由查询中的权限组筛选,并提供“管理权限组”入口形成维护闭环。
### 影响范围
```yaml
涉及模块:
- admin-frontend: 权限组管理真实页、节点页筛选联动、API/类型/工具层补齐
- .helloagents: 方案包、模块文档、CHANGELOG 与状态证据同步
预计变更文件: 8
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 后端删除接口因用户/节点/订阅占用返回失败 | 中 | 前端保持后端错误透传,不自行猜测失败原因 |
| 节点页联动仅靠前端路由查询,若权限组已删除会产生空筛选 | 低 | 页面加载后校验 query 对应分组是否存在,不存在则自动回退为“全部权限组” |
| 新页面过度复用黑色 Hero 会与截图不一致 | 中 | 以截图为最高优先级,改为轻量标题区 + 高密度表格,不强行套用订阅页首屏模式 |
---
## 3. 技术设计(可选)
### API设计
#### GET /server/group/fetch
- **请求**: 无
- **响应**: `AdminServerGroupItem[]`,包含 `id``name``users_count``server_count`
#### POST /server/group/save
- **请求**: `{ id?: number, name: string }`
- **响应**: `boolean`
#### POST /server/group/drop
- **请求**: `{ id: number }`
- **响应**: `boolean`
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| id | number | 权限组 ID |
| name | string | 权限组名称 |
| users_count | number | 绑定用户数量 |
| server_count | number | 绑定节点数量 |
---
## 4. 核心场景
### 场景: 运营新增权限组
**模块**: admin-frontend
**条件**: 管理员进入 `#/node-groups`
**行为**: 点击“添加权限组”,填写组名称并提交
**结果**: 列表刷新并出现新的权限组记录
### 场景: 运营从权限组进入节点排查
**模块**: admin-frontend
**条件**: 某权限组已存在关联节点
**行为**: 在权限组列表点击“节点数量”跳转
**结果**: `#/nodes` 自动带入对应权限组筛选,仅展示该组关联节点
---
## 5. 技术决策
### admin-frontend-node-group-management#D001: 权限组页改为截图导向的轻量工作台,而不是延续黑色 Hero
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 用户提供的参考图就是目标界面,重点是轻量标题区、工具条和高密度表格。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 延续节点/订阅页的黑色 Hero | 与部分已有页面一致 | 与当前截图不符,页面信息密度被拉低 |
| B: 采用截图式轻量工作台 | 更贴近用户目标,便于高频运营维护 | 与部分页面的 Hero 结构不完全统一 |
**决策**: 选择方案 B
**理由**: 本轮任务已有明确视觉参考,参考优先级高于通用页面套路。
**影响**: `NodeGroupsView.vue` 的首屏结构与样式策略
### admin-frontend-node-group-management#D002: 新增与编辑复用同一个中央弹窗
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 后端保存接口统一为 `server/group/save`,截图也展示了中央编辑弹窗。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 新增/编辑拆成两个独立组件 | 职责更独立 | 代码重复,交互不连续 |
| B: 统一弹窗组件按模式切换 | 与后端接口一致,界面行为稳定 | 组件需处理回填逻辑 |
**决策**: 选择方案 B
**理由**: 能最小化重复代码,同时贴合截图中的工作流。
**影响**: `NodeGroupEditorDialog.vue` 的设计与表单逻辑
### admin-frontend-node-group-management#D003: 节点数量列承担“跳转到节点筛选”联动入口
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 用户选择了“完整闭环”,不仅要做权限组页,还要补齐节点页联动。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 只做权限组页 CRUD | 实现最小 | 无法形成节点维护闭环 |
| B: 在节点数量列加入带筛选跳转,并让节点页识别 query | 联动直接、改动范围可控 | 需要额外处理路由筛选同步 |
**决策**: 选择方案 B
**理由**: 这是当前范围内成本最低、用户价值最高的联动方式。
**影响**: `NodeGroupsView.vue``NodesView.vue`
---
## 6. 成果设计
### 设计方向
- **美学基调**: 精密运营台账风——保留 Apple 化后台的轻薄分区与系统字体,但将视觉重心收敛到“标题、工具条、表格、弹窗”四个层级,避免营销感首屏
- **记忆点**: 大面积留白中的细线表格与圆角操作按钮,让“节点数量可跳转”的数据列成为页面最有识别度的互动点
- **参考**: 用户提供的权限组管理截图与编辑弹窗截图
### 视觉要素
- **配色**: 以 `#ffffff` / `#f5f5f7` 为背景层,正文使用 `--xboard-text-strong``--xboard-text-secondary`,交互强调保持 `#0071e3`
- **字体**: 延续项目现有系统字体栈,不额外引入新字体;通过更克制的字号梯度和字重对比强化“台账式”阅读效率
- **布局**: 顶部使用轻标题区,正文直接进入紧凑工具条与全宽表格;编辑器保持中央对话框,不用抽屉
- **动效**: 仅保留按钮 hover、表格行内操作反馈、分页与弹窗开合的默认 Element Plus 过渡
- **氛围**: 依靠细边框、极轻阴影、圆角输入框与足够留白构成“干净但不空”的后台质感
### 技术约束
- **可访问性**: 搜索框、主按钮、编辑/删除操作与节点跳转入口都要保留可见焦点;危险删除继续使用明确确认文案
- **响应式**: 桌面优先显示完整表格;窄屏下工具条允许换行,底部分页与统计信息可纵向堆叠
@@ -0,0 +1,43 @@
# 任务清单: admin-frontend-node-group-management
> **@status:** completed | 2026-04-24 17:11
```yaml
@feature: admin-frontend-node-group-management
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 4 | 0 | 0 | 4 |
---
## 任务列表
- [√] 1. 梳理 `server/group/*` 后端接口、现有 `admin-frontend` 设计契约与节点页联动边界 | depends_on: []
- [√] 2. 补齐权限组 API / 类型 / 工具层,并实现新增 / 编辑弹窗 | depends_on: [1]
- [√] 3. 重写 `NodeGroupsView` 真实工作台,并补齐 `NodesView` 的权限组筛选联动入口 | depends_on: [1, 2]
- [√] 4. 运行 `admin-frontend` 构建验证,更新 `.helloagents` 文档与交付证据 | depends_on: [2, 3]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 17:00 | 方案包初始化 | completed | 用户已选择“完整闭环”,本轮范围包含权限组真实页与节点页联动 |
| 2026-04-24 17:04 | 页面实现 | completed | 已补齐权限组 API、工具层、中央编辑弹窗与真实列表工作台 |
| 2026-04-24 17:07 | 联动实现 | completed | 节点数量列现可跳转 `#/nodes?group={id}`,节点页新增“管理权限组”入口 |
| 2026-04-24 17:10 | 构建与文档同步 | completed | `npm run build` 通过,并已更新 `.helloagents` 文档与变更日志 |
---
## 执行备注
- 当前根仓存在其他未归档方案包与历史改动,本轮仅增量修改权限组管理及节点页联动相关文件。
- `public/assets/admin` 为前端产物子模块;构建通过后需要同时复核根仓与子模块状态。
@@ -0,0 +1,49 @@
{
"updatedAt": "2026-04-24T09:09:46.384Z",
"version": 1,
"source": "manual",
"originCommand": "generic-r2",
"verifyMode": "test-first",
"reviewerFocus": [
"礼品卡管理整体结构是否贴近用户提供的四页签后台截图",
"模板抽屉字段分组是否与截图和现有后端 JSON 结构一致"
],
"testerFocus": [
"礼品卡管理是否真实连接 gift-card/templates、codes、usages、statistics、types 接口",
"模板新增编辑是否能正确序列化 conditions、rewards、limits、special_config",
"兑换码管理是否支持生成、导出、复制、启停、编辑和删除主链路"
],
"ui": {
"required": true,
"designContract": true,
"sourcePriority": [
"requirements.md",
".helloagents/DESIGN.md",
"hello-ui"
],
"styleAdvisor": {
"required": false,
"reason": "",
"focus": []
},
"visualValidation": {
"required": true,
"reason": "礼品卡管理属于整页新增的真实后台业务页,需要确认四页签导航、模板表格、模板抽屉和统计卡片在代码结构上与目标截图及 Apple 化后台契约一致。",
"screens": [
"#/subscriptions/gift-cards desktop"
],
"states": [
"模板管理默认加载完成态",
"模板新增抽屉展开态",
"兑换码管理列表态",
"统计数据总览态"
]
}
},
"advisor": {
"required": false,
"reason": "",
"focus": [],
"preferredSources": []
}
}
@@ -0,0 +1,59 @@
# admin-frontend 礼品卡管理首版交付 — 实施规划
## 目标与范围
- 在现有订阅管理分组中补齐礼品卡管理真实页,替换原先的禁用入口。
- 页面聚焦“礼品卡运营工作台”主链路:建模板、生成兑换码、查看使用记录、追踪统计数据。
## 架构与实现策略
- 在 `AdminLayout` 中开放 `/subscriptions/gift-cards` 导航入口,并在路由中新增对应页面。
- 新增 `GiftCardsView` 作为整页工作台,整体结构参考用户截图:
- 顶部标题与说明
- 四段式分段导航(模板管理 / 兑换码管理 / 使用记录 / 统计数据)
- 每个页签独立的筛选条、表格/卡片内容与操作按钮
- 新增两个业务弹层组件:
- `GiftCardTemplateDrawer.vue`:负责模板新增与编辑
- `GiftCardCodeBatchDialog.vue`:负责批量生成兑换码
- 在 `src/utils/giftCards.ts` 中集中处理:
- 类型/状态映射
- 模板表单序列化与反序列化
- 金额(元)/流量(GB)/倍率/日期等展示与提交格式转换
- 本地搜索筛选与统计卡片整理
- API 层在 `src/api/admin.ts` 中新增礼品卡接口封装;类型定义统一补到 `src/types/api.d.ts`
## 完成定义
- 侧边栏中的“礼品卡管理”不再是禁用入口,能正常进入 `#/subscriptions/gift-cards`
- 模板管理页可真实连接模板列表与 CRUD 接口,支持搜索、筛选、启停与删除。
- 模板抽屉可完整编辑截图展示的主要字段分组,并正确序列化为后端 `conditions / rewards / limits / special_config` 结构。
- 兑换码页可真实连接兑换码列表,支持批量生成、复制、启停、导出当前批次、编辑有效期/次数与删除。
- 使用记录与统计数据页可真实连接后端数据,不使用硬编码假数据。
## 文件结构
- `admin-frontend/src/layouts/AdminLayout.vue`
- `admin-frontend/src/router/index.ts`
- `admin-frontend/src/api/admin.ts`
- `admin-frontend/src/types/api.d.ts`
- `admin-frontend/src/utils/giftCards.ts`
- `admin-frontend/src/views/subscriptions/GiftCardsView.vue`
- `admin-frontend/src/views/subscriptions/GiftCardsView.scss`
- `admin-frontend/src/views/subscriptions/GiftCardTemplateDrawer.vue`
- `admin-frontend/src/views/subscriptions/GiftCardCodeBatchDialog.vue`
## UI / 设计约束
- 页面采用“标题说明 + 轻量分段页签 + 白色工作台”的 Apple 化运营后台节奏,不额外叠加夸张 hero 或营销化视觉。
- 四个页签保持统一信息架构与表格密度,让用户能快速在模板、兑换码、记录、统计之间切换。
- 模板抽屉使用分组 section 和双列表单布局,对齐截图中的信息分区;在窄屏下自动堆叠为单列。
- 状态标签、奖励摘要、统计卡片继续沿用单一蓝色强调和语义色状态胶囊,不引入新配色体系。
## 风险与验证
- 风险 1:模板表单字段较多,若直接散落在组件内易导致提交结构和展示结构不一致,因此统一收敛到 `src/utils/giftCards.ts`
- 风险 2:兑换码列表接口不支持关键词搜索,需要前端在当前拉取结果上做本地搜索,并明确这是列表内过滤。
- 风险 3:本地环境缺少真实后台登录态时,只能做结构与构建验证,不能替代完整联调。
- 验证方式:
- `npm run build`
- 代码级结构自检 `#/subscriptions/gift-cards`
- 结构化视觉验收记录(无浏览器工具时以 code inspection 说明边界)
## 决策记录
- [2026-04-24] 礼品卡管理采用单页四段式导航,而不是四个独立路由,以贴近用户截图中的运营切换路径。
- [2026-04-24] 模板抽屉使用分组式大表单,不把复杂字段塞进居中弹窗,以保证高密度配置仍可读。
- [2026-04-24] 兑换码导出先按“当前选中批次”提供显式出口,不额外扩展复杂多选批量导出流程。
@@ -0,0 +1,49 @@
# admin-frontend 礼品卡管理首版交付 — 需求
确认后冻结,执行阶段不可修改。如需变更必须回到设计阶段重新确认。
## 核心目标
- 在 `admin-frontend` 中开放“订阅管理 / 礼品卡管理”入口,不再保留禁用态。
- 参考用户提供的 5 张截图,交付礼品卡管理真实工作台,覆盖模板管理、兑换码管理、使用记录与统计数据四个页签。
- 保持 `apple/DESIGN.md``.helloagents/DESIGN.md` 定义的 Apple 化后台视觉语言,同时优先贴近截图中的高密度运营视图与轻量分段导航。
## 功能边界
- 必须实现 `#/subscriptions/gift-cards` 真实页面。
- 页面必须包含:
- 顶部标题说明与四段式页签导航
- 模板管理列表、搜索、类型/状态筛选、显隐切换、新增/编辑、删除
- 模板新增/编辑大表单,覆盖基础配置、奖励内容、使用条件、使用限制、特殊配置、显示效果
- 兑换码管理列表、模板/状态筛选、复制、启停、编辑、删除、批量生成、批次导出
- 使用记录列表与用户邮箱搜索
- 统计数据总览,至少展示模板总数、活跃模板数、兑换码总数、已使用兑换码
- 必须接入现有 Laravel 管理接口:
- `GET /gift-card/templates`
- `POST /gift-card/create-template`
- `POST /gift-card/update-template`
- `POST /gift-card/delete-template`
- `POST /gift-card/generate-codes`
- `GET /gift-card/codes`
- `POST /gift-card/toggle-code`
- `GET /gift-card/export-codes`
- `POST /gift-card/update-code`
- `POST /gift-card/delete-code`
- `GET /gift-card/usages`
- `GET /gift-card/statistics`
- `GET /gift-card/types`
## 非目标
- 本轮不改造 Laravel 礼品卡后端逻辑、校验规则或数据库结构。
- 本轮不实现用户端礼品卡兑换体验。
- 本轮不引入复杂图表库,只使用现有栈完成统计展示。
## 技术约束
- 技术栈固定为 `Vue 3 + TypeScript + Vite + Element Plus`
- 后端真相源以仓库内 `App\Http\Controllers\V2\Admin\GiftCardController``GiftCardTemplate``GiftCardCode``GiftCardUsage` 为准。
- 构建验证使用 `admin-frontend/package.json` 中已有 `npm run build`
- 构建产物继续输出到 `public/assets/admin` 子模块。
## 质量要求
- 礼品卡页面需要对齐截图中的运营后台结构:白色工作台、轻量页签、克制筛选条、高密度表格。
- 表单字段需要覆盖加载、保存、取消、校验失败与成功提示等基本状态。
- 金额、流量、时间与倍率展示必须按人类可读方式格式化,不直接暴露原始后端数值。
- 最终至少完成一次构建验证,并留下结构化视觉验收与交付证据。
@@ -0,0 +1,14 @@
# admin-frontend 礼品卡管理首版交付 — 任务分解
## 任务列表
- [x] 任务1:补齐礼品卡管理方案与合同产物(涉及文件:`.helloagents/plans/202604241703_admin-frontend-gift-card-management/*`;完成标准:存在需求、方案、任务与合同文件;验证方式:文件检查)
- [x] 任务2:开放礼品卡导航与路由入口(涉及文件:`admin-frontend/src/layouts/AdminLayout.vue``admin-frontend/src/router/index.ts`;完成标准:侧边栏可进入 `#/subscriptions/gift-cards`;验证方式:`npm run build`
- [x] 任务3:补齐礼品卡 API、类型与工具层(涉及文件:`admin-frontend/src/api/admin.ts``admin-frontend/src/types/api.d.ts``admin-frontend/src/utils/giftCards.ts`;完成标准:前端可消费 `gift-card/*` 接口并统一完成字段映射;验证方式:`npm run build`
- [x] 任务4:实现礼品卡管理主页面(涉及文件:`admin-frontend/src/views/subscriptions/GiftCardsView.vue``admin-frontend/src/views/subscriptions/GiftCardsView.scss`;完成标准:四个页签支持真实数据展示、搜索筛选、表格/统计渲染与关键操作入口;验证方式:`npm run build`
- [x] 任务5:实现模板抽屉与兑换码生成弹层(涉及文件:`admin-frontend/src/views/subscriptions/GiftCardTemplateDrawer.vue``admin-frontend/src/views/subscriptions/GiftCardCodeBatchDialog.vue`;完成标准:支持模板新增/编辑与兑换码批量生成;验证方式:`npm run build`
- [x] 任务6:完成验证与知识库同步(涉及文件:`.helloagents/CHANGELOG.md``.helloagents/context.md``.helloagents/modules/admin-frontend.md``.helloagents/.ralph-visual.json``.helloagents/.ralph-closeout.json`;完成标准:构建通过、知识库更新、交付证据写入;验证方式:命令输出 + 证据文件)
## 进度
- [x] 已确认礼品卡管理按完整四页签首版推进。
- [x] 已完成礼品卡管理真实页面、模板抽屉、兑换码生成弹层与后端接口接入。
- [x] 已完成构建验证,待输出最终交付摘要。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"done": 5,
"percent": 100,
"current": "订单页佣金状态修复、真实待确认筛选与单行确认菜单已完成",
"updated_at": "2026-04-24 22:26:00"
}
@@ -0,0 +1,179 @@
# 变更提案: admin-frontend-orders-commission-confirmation
## 元信息
```yaml
类型: 缺陷修复
方案类型: implementation
优先级: P1
状态: 已完成
创建: 2026-04-24
```
---
## 1. 需求
### 背景
`admin-frontend``#/subscriptions/orders` 订单管理页目前直接按 `commission_status` 渲染佣金状态。由于后端很多“无佣金订单”默认也会带 `commission_status = 0`,页面把这些订单一并显示成“待确认”,造成运营误判。同时,列表页缺少直接面向“真实待确认佣金订单”的筛选与快捷确认入口,只能进入详情抽屉手动改状态,效率较低。
### 目标
- 修复无佣金订单被误显示为“待确认”的问题,让列表与详情抽屉的佣金状态表达与真实业务一致。
- 在订单页增加“确认佣金”菜单,能一键筛出真实待确认的佣金订单。
- 在列表行级菜单中加入“确认佣金”快捷操作,把真实待确认订单手动确认到“发放中”。
- 保留详情抽屉内现有佣金状态维护能力,确保列表与详情行为一致。
### 约束条件
```yaml
时间约束: 本轮只处理 admin 订单页佣金可视化与确认流程,不扩展到返佣任务或提现模块
性能约束: 继续复用现有 order/fetch 与 order/update 接口,不新增重型列表查询
兼容性约束: 保持现有订单详情抽屉、佣金状态枚举与 Apple 风格后台视觉一致
业务约束: “真实待确认”必须排除无佣金订单;列表快捷确认仅把状态改为 1(发放中),不直接标记为已发放
验证约束: 优先执行 admin-frontend 的 Vite 构建验证;本地不依赖额外后端联调环境
```
### 验收标准
- [ ] 无佣金订单在列表和详情中不再显示为“待确认”,而是明确显示“无佣金”
- [ ] 点击“确认佣金”菜单后,可筛出真实待确认的佣金订单,不再混入无佣金订单
- [ ] 列表行级菜单可直接对真实待确认订单执行“确认佣金”,并把状态更新为“发放中”
- [ ] 详情抽屉中的佣金状态展示与可编辑条件和列表保持一致
- [ ] `admin-frontend` 构建通过
- [ ] `.helloagents` 文档与变更记录已同步
---
## 2. 方案
### 技术方案
1. 在 `admin-frontend/src/utils/orders.ts` 中抽出“是否存在真实佣金”的统一判定逻辑,优先根据 `commission_balance` / `actual_commission_balance` 和已进入发放链路的状态综合判断,而不是单看默认的 `commission_status`
2. 调整佣金状态标签生成逻辑:无真实佣金的订单统一返回“无佣金”,佣金状态筛选仍保留原有枚举,但当前端进入佣金筛选场景时,自动附加后端已有的 `is_commission=true` 参数,利用服务端过滤能力排除无佣金订单。
3. 在订单页工具栏增加“确认佣金”菜单,提供“真实待确认订单 / 全部佣金订单 / 清空佣金筛选”三个快捷入口,帮助运营快速切换到真实佣金工作流。
4. 在列表新增行级操作列,保留“查看详情”,并对真实待确认订单提供“确认佣金”快捷项;执行时复用现有 `/order/update` 接口,把 `commission_status` 更新为 `1`
5. 同步更新订单详情抽屉的佣金状态文案与操作判定,确保列表页和详情页对“无佣金 / 待确认 / 发放中 / 已发放 / 无效”的解释一致。
### 影响范围
```yaml
涉及模块:
- admin-frontend/src/utils/orders.ts: 统一佣金状态判定、筛选标签与可编辑条件
- admin-frontend/src/views/subscriptions/OrdersView.vue: 增加确认佣金菜单、真实佣金筛选与行级快捷确认
- admin-frontend/src/views/subscriptions/OrdersView.scss: 补充菜单/操作列样式
- admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue: 同步佣金状态文案与操作可见性
预计变更文件: 4
```
### 风险评估
| 风险 | 等级 | 应对 |
|------|------|------|
| 历史订单存在 `commission_balance = 0` 但已进入发放链路 | 中 | 真实佣金判定同时纳入 `actual_commission_balance` 与已发放/无效状态,避免误判为无佣金 |
| 列表快捷确认与详情抽屉状态维护不一致 | 中 | 两处统一复用 `orders.ts` 的判定与状态 meta,更新后统一刷新列表/详情 |
| 佣金筛选逻辑过于隐蔽导致运营不易理解 | 低 | 工具栏新增显式“确认佣金”菜单,并在激活时显示提示文案,说明当前只展示真实佣金订单 |
---
## 3. 技术设计(可选)
> 本轮不新增接口与数据结构,复用现有后端能力,保留该节用于说明前后端数据流。
### 架构设计
```mermaid
flowchart TD
A[OrdersView 工具栏菜单] --> B[fetchOrders is_commission=true]
A --> C[行级操作菜单]
C --> D[/order/update commission_status=1]
B --> E[订单表格]
E --> F[OrderDetailDrawer]
F --> D
```
### API设计
#### GET /order/fetch
- **请求**: 现有分页参数 + `filter` + `is_commission?: true`
- **响应**: 订单列表;当前端处于佣金工作流时,由后端过滤掉无邀请人、待支付/已取消、佣金金额为 0 的记录
#### POST /order/update
- **请求**: `{ trade_no: string, commission_status: 1 }`
- **响应**: `ApiResponse<boolean>`
### 数据模型
| 字段 | 类型 | 说明 |
|------|------|------|
| commission_balance | number | 应付佣金额;大于 0 时优先认定为真实佣金订单 |
| actual_commission_balance | number \| null | 已实际发放佣金;用于兜底识别已进入发放链路的历史订单 |
| commission_status | number \| null | 0 待确认 / 1 发放中 / 2 已发放 / 3 无效 |
---
## 4. 核心场景
> 执行完成后同步到对应模块文档
### 场景: 运营筛出真实待确认佣金订单
**模块**: admin-frontend / subscriptions / orders
**条件**: 订单列表页已加载,存在部分真实佣金待确认订单
**行为**: 用户点击“确认佣金”菜单中的“真实待确认订单”
**结果**: 列表切换为仅展示 `commission_status = 0` 且真实存在佣金的订单
### 场景: 运营在列表中手动确认佣金
**模块**: admin-frontend / subscriptions / orders
**条件**: 某条订单属于真实待确认佣金订单
**行为**: 用户在该行操作菜单点击“确认佣金”
**结果**: 调用 `/order/update` 把佣金状态更新为“发放中”,列表状态即时刷新
### 场景: 无佣金订单被正确标记
**模块**: admin-frontend / subscriptions / orders
**条件**: 订单的 `commission_balance = 0`,且未进入发放链路
**行为**: 用户查看列表或详情抽屉中的佣金状态
**结果**: 页面明确显示“无佣金”,不再误导为“待确认”
---
## 5. 技术决策
> 本方案涉及的技术决策,归档后成为决策的唯一完整记录
### admin-frontend-orders-commission-confirmation#D001: 真实佣金判定以金额和发放链路为准,不再单看默认 commission_status
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 当前无佣金订单也可能落在 `commission_status = 0`,如果前端只按状态展示,会把“默认值”误渲染成“待确认”。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 继续只看 commission_status | 改动最小 | 会持续把无佣金订单误判成待确认 |
| B: 以佣金金额/实际发放金额/已进入发放链路状态综合判断 | 业务语义更准确 | 需要统一封装前端判定逻辑 |
**决策**: 选择方案 B
**理由**: 能同时覆盖无佣金订单、已发放历史订单和无效佣金订单,最符合真实业务语义。
**影响**: `orders.ts` 的状态映射、订单列表渲染、详情抽屉可编辑条件
### admin-frontend-orders-commission-confirmation#D002: 列表页新增“确认佣金”快捷菜单与单行确认,而不是只依赖详情抽屉
**日期**: 2026-04-24
**状态**: ✅采纳
**背景**: 用户明确要求在当前页面把真实待确认佣金筛出来并能手动确认,同时在上一轮选择了“列表页新增单行快捷确认,并保留详情抽屉”。
**选项分析**:
| 选项 | 优点 | 缺点 |
|------|------|------|
| A: 只保留详情抽屉确认 | 实现最少 | 无法满足当前页快速筛选与快捷确认诉求 |
| B: 列表页加快捷菜单与行级确认,详情抽屉保留完整状态维护 | 符合运营工作流,效率更高 | 需要补充操作列与筛选状态管理 |
**决策**: 选择方案 B
**理由**: 与用户确认选项一致,且能把“筛选 + 确认”闭环留在一个工作台内完成。
**影响**: `OrdersView.vue` / `OrdersView.scss` 需要新增工具栏菜单、操作列和交互反馈
---
## 6. 成果设计
> 含视觉产出的任务由 DESIGN Phase2 填充。非视觉任务整节标注"N/A"。
### 设计方向
- **美学基调**: Apple 风格的高密度运营工作台 —— 黑色静默首屏、白色精密工作区、蓝色交互信号,新增能力保持“像系统功能自然长出来”的克制感
- **记忆点**: 订单页工具栏里新增一颗明确的“确认佣金”工作流胶囊按钮,进入后列表与行级操作形成连续确认闭环
- **参考**: `apple/DESIGN.md``.helloagents/DESIGN.md`、当前订单页截图
### 视觉要素
- **配色**: 延续现有 `#000000 / #f5f5f7 / #ffffff` 主场与 `#0071e3` 交互强调色;无佣金状态使用中性灰,不与真实待确认的橙色混淆
- **字体**: 继续遵循项目既有 Apple 化系统字体栈,不引入新字体,只通过字重与字距维持信息层级
- **布局**: 保持现有单层工具栏结构,在筛选胶囊群中补入“确认佣金”菜单;表格右侧新增轻量操作列,不打断订单号点击查看详情的主路径
- **动效**: 仅保留按钮 hover、菜单展开和状态更新后的即时消息反馈,不引入额外炫技动画
- **氛围**: 继续使用纯白工作台、轻阴影容器和圆角胶囊控件,让新增能力自然融入当前后台节奏
### 技术约束
- **可访问性**: 菜单项与操作按钮保持可聚焦、文案明确,不只靠颜色传达佣金状态
- **响应式**: 延续当前订单页在窄屏下工具栏换行与表格横向滚动策略,不额外引入新断点
@@ -0,0 +1,50 @@
# 任务清单: admin-frontend-orders-commission-confirmation
> **@status:** completed | 2026-04-24 22:29
```yaml
@feature: admin-frontend-orders-commission-confirmation
@created: 2026-04-24
@status: completed
@mode: R2
```
## 进度概览
| 完成 | 失败 | 跳过 | 总数 |
|------|------|------|------|
| 5 | 0 | 0 | 5 |
---
## 任务列表
### 1. 佣金状态判定与页面交互
- [√] 1.1 在 `admin-frontend/src/utils/orders.ts` 中统一真实佣金判定与状态映射,修复无佣金订单误显示为“待确认” | depends_on: []
- [√] 1.2 在 `admin-frontend/src/views/subscriptions/OrdersView.vue` 中接入真实佣金筛选状态,新增“确认佣金”菜单并在列表请求中透传 `is_commission` | depends_on: [1.1]
- [√] 1.3 在 `admin-frontend/src/views/subscriptions/OrdersView.vue``OrdersView.scss` 中增加行级操作列,为真实待确认订单提供“确认佣金”快捷操作与状态提示 | depends_on: [1.2]
### 2. 一致性与验收
- [√] 2.1 在 `admin-frontend/src/views/subscriptions/OrderDetailDrawer.vue` 中同步佣金状态文案与可编辑条件,确保列表与详情一致 | depends_on: [1.1]
- [√] 2.2 执行 `admin-frontend` 构建验证,并同步 `.helloagents` 记录与变更说明 | depends_on: [1.3, 2.1]
---
## 执行日志
| 时间 | 任务 | 状态 | 备注 |
|------|------|------|------|
| 2026-04-24 22:17 | 方案设计 | completed | 已确认采用“列表页确认佣金菜单 + 单行快捷确认 + 保留详情抽屉”方案 |
| 2026-04-24 22:20 | 佣金判定修复 | completed | `orders.ts` 新增真实佣金判定,列表/详情统一改为无佣金不再显示待确认 |
| 2026-04-24 22:22 | 订单页交互增强 | completed | 订单工具栏新增“确认佣金”菜单,佣金状态筛选自动透传 `is_commission=true` |
| 2026-04-24 22:24 | 行级确认接入 | completed | 列表新增操作列,可对真实待确认订单直接确认为“发放中” |
| 2026-04-24 22:26 | 构建与文档同步 | completed | `npm run build` 通过,准备归档方案包并更新知识库记录 |
---
## 执行备注
- 当前后端已具备 `GET /order/fetch?is_commission=true``POST /order/update` 能力,本轮优先复用现有接口,不新增后端 API。
- 若本地构建外存在后端联调缺口,需以 `admin-frontend` 构建结果作为本轮最低验证证据,并在交付中明确说明。
@@ -0,0 +1,11 @@
{
"status": "completed",
"completed": 5,
"failed": 0,
"pending": 0,
"total": 5,
"done": 5,
"percent": 100,
"current": "节点管理分页、置顶、批量修改与父子筛选已完成",
"updated_at": "2026-04-24 23:02:00"
}

Some files were not shown because too many files have changed in this diff Show More