Henry_Du
1179130656
fix(cablemanager): 修复线缆分组详情编辑时成员被自动刷新打回且保存无效的问题
...
根因:
- cablemanager 每 900ms scheduleAutoReload() 通过 WS state_update 触发 reloadAll({silent:true}),之前 reloadAll 在 detail-view 场景下每次都会无条件把 detailTempMembers 从服务器读回、selectedAvailable/selectedMembers 清空,所以用户刚把某站台 » 加进成员,下一次被动刷新到了就立刻还原(视觉上就是「点过去又跳回来」)
- 保存 saveDetail() PUT 本身是能成功的(server PUT /api/audio-cable-groups/:id 的 stationNames 接口契约没问题),但保存之后 loadGroups() 拉完数据又立刻触发 broadcastUpdate()→WS state_update→scheduleAutoReload→又一次 reloadAll()→把刚保存的 detailTempMembers 用服务器值覆盖掉,用户看起来就是「保存无效」
修复 (cablemanager.html reloadAll):
1. 保存 refresh 前后的 prevGroups/prevStations 快照,只有 name/color/description 或站台列表真的变了(groupListChanged/ stationListChanged)才重绘列表和快选,避免心跳、lastSeen、tokenHolder 这些纯瞬时字段反复重绘
2. 区分 silent (被动自动刷) vs 非 silent (用户手动点刷新):
- 非 silent:保持原语义,完全用服务器值覆盖所有本地编辑(用户主动点刷新就是要回到当前后台状态)
- silent:
* 只在 metaChanged 时同步 name/description/color(并且不抢焦点的 input,避免正在打字被重置)
* 只在 membersChanged(后台 stationNames 真的跟上次不一样)时才同步成员到 detailTempMembers,否则保持用户未保存的成员编辑不变;同时清理 selected 中已不存在的名字
* renderDualLists 仅在 membersChanged || stationListChanged || metaChanged 才调用,其余时间完全不重绘详情
3. 服务器 PUT 端再验证过 stationNames 接口契约没问题:前端 saveDetail 发 {name,color,description,stationNames} 对得上 server PUT handler,保存完 /api/audio-cable-groups 读回 stationNames 正确
APP_VERSION_TEXT bump 到 v1.0.111
2026-08-17 18:11:57 +08:00
Henry_Du
fb17de6493
fix(cablemanager): 修复 cablemanager 无法操作 + 一直刷新的问题
...
- 根因1: GET /api/audio-cable-groups 服务端返回 {groups: list},但前端 loadGroups() 读 data.audioCableGroups → 永远读到 undefined → 始终空列表
修复: 服务端 L3447 同时返回 groups 和 audioCableGroups 两个别名;前端 loadGroups() 优先读 audioCableGroups,不存在则回退 groups
- 根因2: WebSocket onmessage 收到 init_state/state_update 立即 reloadAll(带 toast),若事件频繁会反复 re-render + 连弹『数据已刷新』toast → 看起来一直刷新且输入框总被重置
修复: 新增 scheduleAutoReload() 节流(两次自动刷新之间至少间隔 900ms);且自动刷新统一走 reloadAll({silent:true}) 不弹成功/失败 toast;仅用户点刷新按钮才弹提示
- 本地实测: PORT=8999 启动 server 后 /api/stations → {success:true, stations:[]},/api/audio-cable-groups → {success:true, groups:[], audioCableGroups:[]},两个端点均 200 且响应结构含双别名 key
- APP_VERSION_TEXT bump 到 v1.0.109
2026-08-17 17:55:09 +08:00
Henry_Du
5e466f4553
fix(ui): 补齐 generator.html 和 listmanager.html 的问号剥离兜底
...
- generator.html: 新增 ds() 钩子,在 renderList / batch 预览 / showToast 三个渲染点统一问号剥离
- listmanager.html: 新增 ds() 钩子,在 renderList / renderSequence / 自定义 select 选项 / showToast 四个点统一问号剥离
- APP_VERSION_TEXT bump 到 v1.0.107
2026-08-17 17:32:01 +08:00
Henry_Du
4c049050ce
feat(ui): 显示层去问号化 + 网页统一 CableManager 风格 + 补齐 select 下拉样式
...
需求:
1. 客户端与网页端所有展示到屏幕上的内容,去掉 ???、Unknown、未知版本、未选择、未合成、暂无在线 等占位问号/疑问式字符;
2. 网页端所有页面统一 cablemanager.html 那套风格(色板、硬边边框、圆角 6/8、顶栏渐变字/下边框分隔、shadow、body 径向渐变);
3. 补齐 <select>/option 下拉样式(appearance none、内联 SVG 箭头、padding-right 留位、ring focus、option 背景与主色一致),不再沿用系统默认。
改动:
1. station_broadcast.lua:
- 新增 Utils.sanitizeDisplay:统一把任意显示字符串内的 ? 全部剥离并 trim 空白,空串返回 '-'
- Display.render 里 truncL / truncR 从直接 tostring 改为走 sanitizeDisplay,保证所有监视器内容 0 问号
- Display.render 底部 3 条日志(drawLeft)和 Display.renderTerminal 顶部日志全部走 sanitizeDisplay
2. CloudServer/public/:
- index.html:
* :root 色板对齐 cablemanager(--bg-panel #121214、--text-primary #f4f4f5、--text-muted #a1a1aa、加 --bg-input/--ring-color、radius 8px)
* body 改 radial-gradient 背景
* .btn / .btn-primary / .btn-danger 统一成 cablemanager 同款尺寸(10x14、radius 6、font-weight 500/600)
* 新增 input[type=text|number|password] + textarea + select + option 完整样式组(cablemanager 同款)
* 清理 display 层的 Unknown/未知/未发布:
- stationVersion || '未知版本' 改为 || ''(空版本号直接省略,不写未知)
- seqHtml fallback 从 'Unknown sequence' 改为 ''
- localVersion 从 '未知' 改为 '-',targetVersion/publishedAt 从 '未发布' 改为 ''(空即省略)
- infoboard.html:
* :root 对齐 cablemanager,加 --bg-input、--ring-color、加 body radial-gradient
* 车次目的地 fallback 从 '未知终点' 改为 ''(没终点就空白)
- music.html:
* :root / body / layout-wrapper / topbar / title / btn / panel / card-title / badge / input+select+textarea 全对齐 cablemanager
* track_badge 默认占位从 '未选择' 改空(badge:empty 直接不显示)
* 空站台列表占位从 '暂无在线/已注册站台' 改为 '-'
* 补了完整 scrollbar 样式
* 最外层 body 内加 .layout-wrapper(对齐 cablemanager max-width 1280 + 居中)
- tempbroadcast.html:
* 所有风格同步 music.html(与 cablemanager 一致)
* build_badge 默认 '未合成' 改为空,失败分支也清空(只在合成成功/合成中写入),同时 .badge:empty {display:none}
* 空站台列表占位 '-'
* 补 select 下拉外观样式
客户端 bump v1.0.105 -> v1.0.106。
server.js node -c 通过;所有修改 HTML 仅改 style 段与少量占位文本,不影响 API 契约。
2026-08-17 16:17:38 +08:00
Henry_Du
e0a1252db6
chore(ui): 首页导航黄色按钮从 Full Info Board 换成 Cable Manager 入口
...
把 index.html 文件管理器工具栏的黄色 var(--warning) 按钮:
- href: /infoboard.html -> /cablemanager.html
- 文案: Full Info Board -> Cable Manager
- 保留 target=_blank(新标签打开线缆分组管理页,避免丢当前文件视图)
客户端 bump v1.0.104 -> v1.0.105
2026-08-17 15:53:13 +08:00
Henry_Du
4c7d94f2c9
feat(A1+B1): 引入站台多主机识别、音频线缆分组互斥令牌、本地Modem仲裁、线缆分组管理WebUI
...
服务端 A1 改动(CloudServer/server.js):
- stations 改为 nodes[] 多连接存储,同站台名的多台 CC 主机归入同一组(纯 stationName 精确分组)
- 新增 getStationMaster():hasStationPeripheral + lastSeen 加权选 Master,音频只下发给 Master
- 新增 audioCableGroups 数据结构(持久化到 server-data.json)
- 新增 acquireCableToken/releaseCableToken:同线缆组全局互斥,高优先级发送 audio_preempt 抢占
- 新增 7 路由 REST API:/api/audio-cable-groups CRUD + 批量/单个站台成员管理 + PUT /stations/:name/cable-group 直接改组
- sendAudioControl 给同站组所有节点全量下发(stop/状态同步)
- init_state / state_update 携带 audioCableGroups 给前端
- WS close 自动 removeStationWs 清理节点 + 释放令牌
客户端 B1 改动(station_broadcast.lua v1.0.99):
- Peripherals 新增 wiredModems 扫描(排除无线),自动 rednet.open
- 新增 LocalBus 命名空间:
- station_hello 每 10s 广播 + 30s 超时清理邻居
- 同站台名自动组 stationGroup,按 hasStationPeripheral + nodeId 升序选 Master
- 新增 Utils.isLocalStationMaster(),所有列车上报(arrival/approaching/alert/departure/schedule_sync)仅 Master 执行,彻底解决重复广播
- acquireLocalToken:audio_probe -> 80ms 收响应 -> 必要时 audio_preempt 抢占 -> token_grant
- 令牌持有期间每 2s 广播 audio_playing 心跳,30s 超时自动判死回收
- Audio.playerLoop 在 playItem 前获取本地令牌,失败则跳过该音频
- Audio.stop() 自动释放本地令牌
- WS 新增下行处理:audio_preempt / cable_token_denied / station_group_state
- station_identity.cfg 支持 audio_cable_group= 字段,saveStationIdentity 写回
- Network.register/heartbeat 携带 cableGroup 供服务端回填分组
Web 管理端(CloudServer/public/cablemanager.html,单文件无外部依赖):
- 极简硬边风格,对齐 listmanager.html 配色和字体
- 分组网格卡片:色标/名称/描述/成员数/当前令牌持有者 + 编辑删除
- 新增/编辑 Modal:名称+描述+8色预设色板+自定义#RRGGBB
- 分组详情双栏 Dual List:左栏全部站台(搜索+在线状态+在其他组标签)/ 右栏成员,中间批量添加移除按钮
- 顶部快捷操作:站台下拉+组下拉+确认,直接 PUT /stations/:name/cable-group
- WebSocket 监听 state_update 实时刷新,Toast 提示反馈
2026-08-17 15:32:20 +08:00
Henry_Du
55f0312314
feat(audio): 支持斜杠格式的车站编号和模糊搜索匹配
...
- 修改TTS音频导入逻辑,保留编号中的斜杠(/)格式(如 CH-01/CE-12),自动创建子目录
- 移除generator.html中单文件和批量导入时的斜杠转横杠逻辑
- 新增sanitizeStationCode和ensureDirForFile辅助函数,确保路径安全
- 重写findFileCaseInsensitive,支持递归子目录搜索与末尾段模糊匹配
- 新增listAllFilesRecursive和resolveAudioPathWithFuzzy工具函数
- 修改getPlaybackAudioByBaseName/findWavByBaseName支持模糊搜索查找
- 修改resolveManagedPath允许子路径访问,getManagedFiles递归扫描子目录
- 媒体路由从:file参数改为通配符/*形式,safeRelativeToBase确保路径安全
- 升级版本号至v1.0.98
2026-08-17 14:54:21 +08:00
Henry_Du
b74eb252e3
feat: 在后端增加解析远程 Gitea 最新版本号的接口并展示在前端
2026-08-16 11:40:47 +08:00
Henry_Du
10d15dfddc
feat: add station auto update publishing
...
Publish the latest station script from the console so online hosts download and reboot immediately while offline hosts update on their next load.
2026-08-02 20:04:55 +08:00
Henry_Du
2741b2d321
Revert TTS generation to backend with fixed local proxy 127.0.0.1:7890
2026-08-01 18:25:50 +08:00
Henry_Du
c76538e4bd
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
2026-08-01 17:58:20 +08:00
Henry_Du
038662c15e
Revert "feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions"
...
This reverts commit dedb37e22b .
2026-08-01 17:49:57 +08:00
Henry_Du
dedb37e22b
feat: switch to client-side fetch for Fish Audio API to bypass server network restrictions
2026-08-01 17:45:48 +08:00
Henry_Du
e3a88acf9b
Revert "feat: migrate TTS generation to frontend to utilize local browser proxy"
...
This reverts commit 5e600bb75d .
2026-08-01 11:58:20 +08:00
Henry_Du
5e600bb75d
feat: migrate TTS generation to frontend to utilize local browser proxy
2026-08-01 11:55:31 +08:00
Henry_Du
c0f100a833
fix(console): map Beep files to Audio/beep
...
Store and present Beep assets under Audio/beep while keeping legacy Audio/general reads working so existing files remain accessible during the directory transition.
2026-08-01 11:42:38 +08:00
Henry_Du
e66f39284f
feat: Add Line Audio Generation and Line List Manager
2026-08-01 11:20:58 +08:00
Henry_Du
a990a2da0c
fix(console): align music upload field name
...
Use the musicAudioFiles form field on music.html so the page matches the multer configuration for /api/upload/music-audio and stops returning Unexpected field.
2026-08-01 11:04:13 +08:00
Henry_Du
f7de7717dc
fix(tts): rename japanese station audio suffix to ja
...
Switch generated station audio entries from en-* to ja-* and update the generator flow so Chinese plus Japanese audio imports use the new suffix consistently.
2026-08-01 09:02:18 +08:00
Henry_Du
a2408da417
feat(tts): switch broadcast generation to s2.1-pro-free
...
Update the generator and temp broadcast flows to send the new Fish Audio model and reference IDs so Chinese and secondary-language audio use the latest requested voice configuration.
2026-08-01 08:50:13 +08:00
Henry_Du
69badb6853
feat(console): adapt main console for mobile screens
...
Stack the console layout vertically on smaller screens, wrap the action toolbar, collapse file rows into compact mobile cards, and make the bottom console, modal, and toast areas usable on phones without desktop splitters.
2026-08-01 08:26:50 +08:00
Henry_Du
304d413482
feat(station): group slave nodes by station target
...
Merge stations with the same station code and platform into one logical target, and expand music and temp broadcast playback to all online slave nodes while the console and picker UIs show grouped station entries with node counts.
2026-08-01 07:44:38 +08:00
Henry_Du
fd53eaef97
feat(console): add voice folder to file manager
...
Add an Audio/voice directory with upload and preview support, and expose it in the console file manager so the structure now shows Configuration, Music, Voice, Beep, and Station.
2026-08-01 07:21:47 +08:00
Henry_Du
1f4be7c10b
feat(console): split audio files into music and beep folders
...
Add an Audio/music path for uploaded music, keep the existing general audio directory as the Beep group, and update the console and music page so the file manager now shows Configuration, Music, Beep, and Station with matching upload and preview routes.
2026-08-01 07:18:14 +08:00
Henry_Du
1554adf5f1
feat(audio): support more upload and music formats
...
Allow the console and music page to upload common audio formats, expand music track detection and playback source selection beyond wav/dfpwm, and update station list name normalization so common extensions resolve consistently. Bump the station build to v1.0.6.
2026-08-01 06:39:18 +08:00
Henry_Du
f530d7e045
refactor: 重构文件存储路径并清理冗余代码
...
- 将项目文件存储从 public/uploads 迁移至项目根目录专用目录
- 更新所有前端页面的路径提示文本与API请求路径
- 移除冗余的列车详情展开收起功能及相关代码
- 重构服务器端文件路径处理逻辑,增强路径访问安全性
- 清理旧注释和未使用的变量与函数
2026-07-31 19:41:26 +08:00
Henry_Du
e4b4fa5cdb
Remove CTM and inbound prediction
2026-07-31 18:23:24 +08:00