cbb
|
7ea80f01ef
|
fix(ui): 电机前端回滚到 P1 拆分前,恢复 STATUS 离线层契约
根因:拆分后 renderStatusPanel 操作 #statusOffline/#statusPanel,
HTML 实际 id 是 offlineOverlay/statusLive,遮罩永不摘掉。
CSS/HTML 结构本就未重写;本提交恢复完整 main.js 与 dual-link 传输层。
|
2026-09-21 03:04:09 +08:00 |
|
cbb
|
a797d5a8d6
|
docs(compose): host-code-quality 真机 e2e 27/0 通过记入 Verification
|
2026-09-21 02:57:00 +08:00 |
|
cbb
|
43b2d4bc13
|
fix(ui): 修复 HTML 中文编码损坏(PowerShell 默认编码误写)
从 2c6235d/261caf5 恢复 motor/index/can 页 UTF-8,
仅用 Python 以 UTF-8 重写 ?v= 缓存戳;boot_ecat 去掉误写问号。
勿再对 UTF-8 源文件用 Get-Content|Set-Content 默认编码。
|
2026-09-21 02:52:54 +08:00 |
|
cbb
|
34c3aebf6f
|
docs(compose): host-code-quality 记录最终提交区间 2c6235d..b215fdf
|
2026-09-21 02:32:25 +08:00 |
|
cbb
|
b215fdf966
|
docs(compose): host-code-quality delivered——R1–R16 整改收口与评审校准
|
2026-09-21 02:32:14 +08:00 |
|
cbb
|
c6510c1f00
|
docs+fix(quality): 更正 boot_ecat 代理注释;评审后校准 Verification 口径
|
2026-09-21 02:31:56 +08:00 |
|
cbb
|
fd98ad6864
|
docs(compose): host-code-quality delivered——R1–R16 整改与验证口径
|
2026-09-21 02:30:04 +08:00 |
|
cbb
|
06605067a5
|
fix(ota): boot_ecat 引入 ECAT_DEFAULT_ADAPTER 并更正代理重发注释
|
2026-09-21 02:28:47 +08:00 |
|
cbb
|
2304ed6999
|
refactor(motor+hygiene): P1 拆分 main.js 并收敛总线/toast + P3 卫生清理
R4: main.js 4647→1894 行,外提 scope/ota/seq/conn-poll
R5: waitVersion/queryNodeIdParam 下沉 transport
R6: ecat-bus.js 单点 bootstrap;repairEcatDc 缺 DC 字段不 motor/start
R7: toast-stack + utils 统一 DOM/quiet 助手
R12–R16: scripts 精简至正式清单、报告进 docs/reports、lab dump 清理、
README/CSS 所有权说明、网卡默认 I210 单点
|
2026-09-21 02:28:26 +08:00 |
|
cbb
|
d2b787761b
|
docs(compose): host-code-quality 记录 R1–R16 整改结果与验证口径
|
2026-09-21 02:28:05 +08:00 |
|
cbb
|
beeae8a382
|
chore(hygiene): P3 报告归档 docs/reports + scripts 收敛 + lab 清理 + CSS/README 约定
正式 scripts 仅保留 README 自测清单;根目录报告迁入 docs/reports;
lab 采样 dump 出库;CSS 注明 btn/toast 所有权并 bump ?v=。
|
2026-09-21 02:26:42 +08:00 |
|
cbb
|
261caf50b7
|
refactor(motor): P1 拆分 main.js + 收敛连接/总线状态机
R4 外提 scope/ota/seq/conn-poll;R5 waitVersion/queryNodeIdParam 下沉
transport;R6 ecat-bus 单点 bootstrap;R7 toast-stack + utils 去重。
main.js 4647→~1894 行。?v= 已 bump 20260924a。
|
2026-09-21 02:26:39 +08:00 |
|
cbb
|
b70f5ed0d6
|
refactor(server): P2 拆出 ecat_client/ecat_proc 并归一化桥路径
|
2026-09-21 02:22:32 +08:00 |
|
cbb
|
67dd1702f0
|
fix(server): P0 代理非幂等不重发 + 跨进程 native 互斥复用 + 默认网卡 I210
R1: autostart 后禁止自动重发 flash/motor/send 等副作用路径;
超时类失败也不再串打其它端口。
R2: README 默认网卡改为与代码一致的 I210。
R3: 命名互斥锁 + 先复用健康监听实例,避免 GUI/服务子进程互相 kill。
|
2026-09-21 02:14:16 +08:00 |
|
cbb
|
27a8fc1797
|
docs(compose): 上位机代码质量评估 host-code-quality + 积分耦合报告产物
全仓冗余/复杂度审计(3.5/5),交付重构清单 R1–R16;
附带入库 ecat 积分耦合 HTML 报告与 N2/N3 成对测试脚本。
|
2026-09-21 02:12:04 +08:00 |
|
cbb
|
2c6235d920
|
feat(ecat): PDO 快发 ESF1 桌面强制直通,堵死慢发回落
桌面 APP 下 ECAT motor 发送只走 pywebview ESF1→native TCP;
删除桥内 HTTP/JSON 回落。附延迟测量与 pack 自测脚本与规格文档。
|
2026-09-21 02:11:49 +08:00 |
|
cbb
|
383535bd1d
|
feat(web): 桌面原生桥 + 配置落盘 + 无设备静默态;排除调试脚本
变更点:
1. esp32_server.py
- /api/motor/ui-state、/api/lab/ui-state:配置原子落盘 data/*.json(WebView2 清存储仍在)
- _GuiApi.ecat_api/bridge_info:桌面壳经 GUI 进程裸 socket 直连 ecat_native,不经浏览器 HTTP
2. js/common/desktop-bridge.js(新)
- 探测 pywebview.api(含 iframe top/parent),transport-ecat 优先走原生桥
3. connection.js + responsive.css + components.css
- setQuietMode:离线且无传输时 html[data-dcu-calm=1] 掐常驻动画
- 进度条斜纹仅 .live 挂载,空闲不再按刷新率空转重绘
4. device-link.js
- 先查 native/health,已健康跳过 motor/start,避免 loop_stop 重进 OP 假超时
- 周期强制 0.25ms + DC SYNC0 对齐;轮询自愈被配错的 DC/周期
5. motor/main.js + transport-ecat.js
- 配置双写 localStorage + 磁盘 ui-state;pagehide/sendBeacon 刷盘;导入导出
- 探测代际 probeGen;ECAT 失败阈值 12;跟踪 bootActive/slaveAl/slaveOp
6. lab/spi_test.html、ota/boot_ecat.js、can_monitor 等跟随桥/静默态
7. .gitignore
- 排除 scripts/_* 与 anal/collect/measure/trace 等调试脚本、lab 产物、data/ 运行态
|
2026-09-20 22:58:00 +08:00 |
|
cbb
|
e91d53e0fc
|
feat(ecat): 启动后把 ecat_native 提到 RealTime;跳拍优化实验脚本与报告
- esp32_server: Popen 后外部 SetPriorityClass(RT/High),native 自设会被钳成 High
- 入库 skip_* 标定/实验脚本与 REPORT_ecat_skip_opt_20260917
- 前端 WIP:layout/app/polling/boot_ecat/index
- 不含 lab/skip_meter 原始采样与 preview 截图
|
2026-09-17 02:32:20 +08:00 |
|
cbb
|
b3a3a365bb
|
fix(conn): updateConnectionUi 判离线时同步清空运行指标
|
2026-09-16 20:47:57 +08:00 |
|
cbb
|
91a534514d
|
fix(conn): 拔线后不再永远「已连接」
1) pollStatus 把 5s 超时 AbortError / HTTP 非 2xx 计入失败,走离线+清指标
2) DeviceLink 快照不得把本页已判离线改回在线(Owner 连败 3 次前会盖绿灯)
|
2026-09-16 20:38:37 +08:00 |
|
cbb
|
5459bdeff7
|
fix(ui): 断线清指标加强——DeviceLink 离线也清 + 模块缓存版本戳
入口/stages/polling 带 ?v=20260916d,避免深层 import 被浏览器缓存成旧版;
外壳快照 ESP32 offline 时同样 clearLiveMetricsOnDisconnect。
|
2026-09-16 20:29:29 +08:00 |
|
cbb
|
d73e2fb5b8
|
chore: 入库 boot_ecat.js(app.js 已 import)
|
2026-09-16 12:32:02 +08:00 |
|
cbb
|
e98950cde2
|
chore: 解决 stash pop 与 device-link 合并冲突并收回本地 WIP
保留 ConnectionHub(deviceLink 导入/ECAT 自启/pmHold 幂等)与主线
WIP(断线清指标、AUTO_POLL=false、boot_ecat 等)。
|
2026-09-16 12:31:39 +08:00 |
|
cbb
|
0c772f5924
|
Merge branch 'feat/device-link'
|
2026-09-16 12:29:56 +08:00 |
|
cbb
|
6f1b3c2706
|
fix(pm): pmHold 幂等,清醒轮询不再每 2s 打「豁免解除」
pollOnce 每 2s 调 markAwake();原先无脑 pmHold(0) 会重复 POST 并刷日志。
现跟踪 pmHoldOn,仅在状态翻转时发请求并记一行。
|
2026-09-16 12:26:46 +08:00 |
|
cbb
|
f9502579ef
|
feat(link): 外壳启动强制 open+motor/start,不必等电机页切 EtherCAT
DeviceLink Owner 在控制台加载后自动 bootstrapEcatBus:status→open→
motor/start,沿用 hub 网卡与 period/spin 持久化。成功后不重复 start;
掉线 10s 退避重开。有线 ECAT 与 WiFi 不冲突。
|
2026-09-16 12:24:45 +08:00 |
|
cbb
|
4b4559e772
|
fix(server): worktree 启动时 ECAT_DIR 回指主检出 tools/ecat
从 .worktrees/<slug> 跑 esp32_server 时 join(BASE_DIR,'..','ecat') 会拼成
.worktrees/ecat,找不到 ecat_native.exe。先走出 .worktrees 再取兄弟目录。
|
2026-09-16 12:19:55 +08:00 |
|
cbb
|
0629bf0910
|
docs(compose): device-link ConnectionHub 扩展记入规格与报告
|
2026-09-16 12:12:36 +08:00 |
|
cbb
|
033ece2cca
|
feat(link): ConnectionHub 统一 WiFi/ECAT/BLE 端点与健康态
各页不再各自读写 dcu_esp_ip / dcu_ecat_adapter:deviceLink 提供
wifiBaseUrl/ecatPost/adapter API,OTA/CAN/motor/ecat_load/lab 走同一入口。
连接灯只覆盖在线布尔,保留调用方语义文案。
|
2026-09-16 12:12:24 +08:00 |
|
cbb
|
353d936abb
|
docs(compose): device-link 规格 delivered
|
2026-09-16 02:54:08 +08:00 |
|
cbb
|
6b5a9f9adc
|
fix(link): ECAT 轮询必重挂;连接灯不覆盖语义文案;BLE 通知成功后再上报
|
2026-09-16 02:53:53 +08:00 |
|
cbb
|
670b833dc6
|
feat(link): DeviceLink 外壳单例统一 ESP32/ECAT/BLE 健康态
各页只共用 IP、各自 fetch 导致同屏「已连接/连接失败」分裂。
外壳 Owner 轮询 /system/status 与 EtherCAT 状态,BroadcastChannel
广播快照;连接灯只认共享层,SPI 失败单独文案不覆盖设备离线。
|
2026-09-16 02:50:12 +08:00 |
|
cbb
|
be26f4daa2
|
docs(compose): tab-keepalive 规格标为 delivered 并写入验证报告
|
2026-09-16 02:41:13 +08:00 |
|
cbb
|
eaafee1312
|
feat(shell): tabs 多 iframe 常驻保活,切标签不再销毁功能页
单 iframe 换 src 会卸载文档,WebSocket/轮询/传输状态全灭。
改为一标签一懒创建 iframe,切换只改 visibility;F5/⟳ 只 reload 激活帧。
|
2026-09-16 02:37:18 +08:00 |
|
cbb
|
9bb804ec35
|
docs(lab): 更正 PRAM 写归因为从站侧成本;lan9252_pm 加 pmHold 看门狗豁免
|
2026-09-13 04:13:28 +08:00 |
|
cbb
|
209a869f96
|
feat(motor): 反馈刷新率 Hz 适配(0x0400/0x0401 扩展格式)+ ECAT 密排槽与判活自适应
反馈刷新率(配套电机固件 v0.4.1:0x0400 DLC4/0x0401 DLC2 扩展格式,
选择器 0x0100=STATUS · 0x0101=CONFIG 帧,协议值为周期 ms):
- 「节点 ID」页签新增 STATUS/CONFIG 刷新率读取/写入;界面单位一律 Hz
(写入按 周期ms=round(1000/Hz) 换算下发,读取反算 Hz 并附原始周期,
取整有损如实展示),0=停发,写入掉电保存;配置值以「读取」回读电机为准
- WiFi 应答回执走 0xC1 per-ID 快照(/can/feedback 全量 entries):
GD32 0xC0 ACK 仅 1 字节状态、不携带电机回帧;同 ID 回帧快照只存最新
一条,故一次快照只配一次请求(STATUS/CONFIG 分开读写)
- ECAT 回执走批量接收区 takeNodeIdReport,按长度分派 2B 旧格式/4B GET/5B SET ACK
- GET_NODE_ID 迁移到扩展选择器 0x0000,兼容旧固件 2B 节点 ID 应答
(SET DLC2 旧格式行为不变)
- transport-wifi 新增 fetchFeedbackFull(全量 CAN 反馈快照)
EtherCAT/基础设施(密排槽固件 1.6.21 配套):
- 快照槽位 5→9 一拍整轮(扫描周期数 6→1);判活阈值随实测 seq 间隔
自适应 clamp(3×EWMA, 2s, 30s),秒级回报档不再被固定 2s 误判离线;
STATUS 面板 Hz 明确为网页到达口径(按槽 seq 实测电机回报率的方案已否掉)
- esp32_server.py:ecat_native 单实例收紧(后起独占 + taskkill 残留实例,
双实例并存会抢 Npcap 致后起者抓不到从站)+ native stdout 落盘
- flash_gd32.py:刷写后校验「GD32 真的在跑新代码」(版本变化或 uptime 归零),
防"写入≠在跑"假台账
- lab:新增 LAN9252 电源诊断台、PDO 布局页;SPI 测速并入 EtherCAT 接收看板
并更名「SPI/ECAT 通信测速」;移除 continuity_test.html;新增 ECAT 单拍耗时
优化报告;/_local/ 排除入库;测试同步更新(62+58 项全过)
|
2026-09-12 20:10:47 +08:00 |
|
cbb
|
81096d0425
|
feat(motor): 新增 EtherCAT 周期速率扫描分析工具链,支持 sweep 脚本、指标校准、绘图与 HTML 报告生成
|
2026-09-10 03:02:14 +08:00 |
|
cbb
|
4e018af168
|
feat(motor): 序列每步新增绿色「单发」按钮,支持仅发送该步动作一次
|
2026-09-07 22:18:50 +08:00 |
|
cbb
|
3b156547bc
|
chore(gitignore): 为已入库的通用 ECAT 采样探针加白名单例外
|
2026-09-07 21:56:34 +08:00 |
|
cbb
|
03caa4acd4
|
chore: 采样/自测产物与一次性探针脚本移出版本库
- 删除已入库的 ecat_after*.csv 与 scripts/ecat_torn_hits.jsonl
- .gitignore 增加 *.csv / *.jsonl / scripts/_*_out.txt 与
scripts/probe_*.py / selftest_*.py 规则
- 保留 README 引用的回归自测 test_*.py|mjs 与 browser_check_*.mjs
|
2026-09-07 21:55:42 +08:00 |
|
cbb
|
ef9472334a
|
docs: 新增 .qoder Repowiki 知识库文档
|
2026-09-07 12:19:26 +08:00 |
|
cbb
|
43d42ad891
|
docs: 新增 CHANGELOG, 记录 2026-09-05 三项变更
app 窗口租约(关窗自动停从站)、首页 GD32 CPU 负载率指标、PDO 周期
缓存迁移与测试对齐; 面向使用者的视角, 实现细节指向 README 与提交。
|
2026-09-05 19:58:50 +08:00 |
|
cbb
|
12879aa81a
|
fix(motor): 清掉存量 4ms PDO 周期缓存, 测试对齐 pcore_mask
- transport-ecat: localStorage 的 dcu_ecat_period_ms 是 Python 时代默认
4ms 存进去的(browser_check_period.mjs 收尾也写 "4"), native 后端默认
已改小, 存量 "4" 会在每次 ensureStarted 把总线压回旧默认。加一次性
迁移标记 dcu_ecat_period_mig, 只删一次; 之后显式设 4 视为用户选择。
"恢复默认"从 setPdoPeriod(4) 改为删键跟随后端默认(固件修好前别低于
1ms)。
- test_motor_transport: 自旋钉核显示早已改用快照字段 pcore_mask(P 核),
测试还停在 ecore_mask 旧字段旧措辞, 本次对齐(含跨 32 位掩码、不连续
核号区间用例)。
验证: node scripts/test_motor_transport.mjs 66/66 通过。
|
2026-09-05 19:58:45 +08:00 |
|
cbb
|
9cbde690c6
|
feat(ota): 首页运行指标卡新增 GD32 CPU 负载率(EtherCAT 通道)
DCU_APP 固件 >=1.5.61 把"中断+非延迟处理段"占用率(1.5.63 收窄定义)
写进 EtherCAT 输入 PDO 段 5 诊断区(1s 滚动窗口, 0.1% 分辨率), native
经 /api/app/load 提供纯缓存读; 前端 js/ota/ecat_load.js 经同源代理
/ecat/api/app/* 轮询并渲染到 #mGd32Load。
- 与 /system/status 轮询完全独立: ESP32 离线互不影响, 失败不计入
ESP32 连接失败计数
- 失败静默退避 1s→5s→30s, 不用 EtherCAT 的用户不按 1Hz 触发 esp32_server
的自动拉起逻辑
- 无效显示 --: valid:false(总线未开/循环未跑/固件过旧)或 age_ms>3s
(PDO 循环已停, 值不再滚动); >=85% 琥珀色提示余量吃紧
- 页面上无 #mGd32Load 时自动空转(其他页共用 app.js 不受影响)
|
2026-09-05 19:58:36 +08:00 |
|
cbb
|
99fb9bcb4a
|
feat(server): app 窗口租约, 全部窗口关闭自动停 EtherCAT 循环
PDO 循环起来后 native 侧一直跑, 其 --parent-pid 自清理只覆盖"本服务拉起
的实例死掉"; 浏览器模式关窗后本服务还在、窗口模式复用现成 ecat_native
(parent 是别人)这两种常见离开方式都够不着 —— 从站卡在 OP、自旋节拍白占
一个核。现由每个 app 页面与页面服务器的 WebSocket 租约兜底:
- esp32_server.py: 新增 GET /ws/app-lease(手写 RFC6455 握手 + 帧泵)。
连接计数归零后隔 3s GRACE 调后端 /api/op/stop 停循环退回 INIT; 断开
感知靠 TCP FIN / Close 帧回显而非心跳(后台标签页节流不误停); 代理
透传时 _note_ecat_loop 记账"循环是否本服务跑起来的", 只停自己确认过
的; /api/shutdown 与 serve_forever 退出路径同步补停(定时器随进程死亡)。
- js/common/app-lease.js: 租约客户端, 3~30s 退避重连, file:// 静默跳过。
- 接入 tabs.html(外壳持有, 内部切标签不断连)与 pages/motor.html(单独
打开时页面自持)。
- 测试: scripts/test_app_lease.py(裸 TCP 全路径, 假 _ecat_post) +
scripts/test_app_lease_e2e.mjs(真 Edge headless + 假后端 8091, 不碰
真总线)。README 补设计动机与要点。
|
2026-09-05 19:58:25 +08:00 |
|
cbb
|
c189a8563e
|
feat(motor): ESP32 侧适配 EtherCAT native 后端, 清理 Python 时代残留
tools/ecat 后端已从 Python(ecat_server.py, 已删除)切到原生守护进程
build_native/ecat_native.exe。本仓(ESP32 电机控制台)的 EtherCAT 传输经
/ecat/api/* 代理打它, 这次把代理实现与全部相关措辞对齐到 native。
代理与自启(esp32_server.py):
- ECAT_ENTRY/ECAT_PYW(src/ecat_server.py + venv/pythonw) → ECAT_NATIVE_EXE
(build_native/ecat_native.exe); autostart 直接 Popen 单文件 exe, 不再经
venv/pythonw; 清场/--parent-pid/端口漂移三条契约 native 原样镜像, 注释同步
- 文件头与代理段里 ecat_server.py 措辞订正为 native
传输层注释(js/motor/*):
- main/transport/transport-ecat/refresh-rate 里"后端是 ecat_server.py /
用 venv 拉起"等 Python 时代说法统一改为 ecat_native.exe
- MOT_SLOTS_PER_PDO/MOTOR_SLOT_COUNT 引用改指 ecat_native.c(同名存在);
MOTOR_SCAN_CYCLES native 无此常量, 改按真实来源写 ⌈27/7⌉=4
- main.js 环境错误分类正则 /venv|pysoem|Npcap/ → /Npcap|build_native|
守护进程|全被占/: 前两者 native 永不吐给前端(死分支), 后者对齐 autostart
真实文案, 让"exe 没编译"这类错误不被 140 字截断
README/motor.html 同步; 新增 scripts/browser_check_period.mjs(内核级 PDO
周期热调的浏览器实测, 与既有 browser_check_*.mjs 同族)。
验证: py_compile esp32_server.py 通过; 6 个改动 JS + 新脚本 node --check
(ESM)全过; 正则对三类 native 错误命中、对废弃 venv/pysoem 不命中;
js/ 与 scripts/ 重扫 ecat_server|venv|pysoem 已空。
|
2026-09-05 03:56:52 +08:00 |
|
cbb
|
2d1743ca4f
|
feat(motor): 支持 WiFi 与 EtherCAT 双链路传输
- 抽象电机传输层,WiFi 与 EtherCAT 实现分离,解码、状态面板、波形和命令序列共用
- 新增 EtherCAT 后端反向代理与自动拉起,解决跨端口 CORS 与预检失败问题
- 刷新速度按链路独立存储,支持 EtherCAT 低延迟读取与 WiFi 稳定轮询
- 更新电机页链路选择、不支持页签置灰样式、README 说明及相关测试脚本
|
2026-09-04 12:18:06 +08:00 |
|
cbb
|
31b90f68b3
|
refactor: 按角色分层目录, HTML 不再平铺根目录
根目录原本平铺 7 个 HTML, 而 js/ 已按功能域分子目录, 两级结构不对称;
且自包含实验页与主功能页平级摆放, 看不出可随时删除。现按角色分三层:
tabs.html 标签外壳留在根 = 工具入口
pages/ index / can / can_monitor / motor 主功能页
lab/ continuity_test / spi_test 自包含实验页(零外部依赖)
scripts/ build_mem.bat
随迁修正(全部实跑验证):
- pages/ 下 4 页共 22 处 css/js 引用加 ../ 前缀; 页面互链同目录无需改
- js/motor/main.js 的 Worker URL 改用 import.meta.url 解析: 原文档相对
路径 "js/motor/tick.worker.js" 在 pages/ 下会解析成 /pages/js/... 而
404, 静默退化到 setTimeout 兜底、丢失后台不节流能力(已验证旧写法 404)
- tabs.html 的 TABS 登记新路径; pageToTab 改按文件名匹配, 旧版
localStorage 存的裸文件名(can.html)自动迁移到 pages/can.html
- esp32_server.py: GET / 与 /index.html 302 到 /tabs.html(根下已无
index.html); 注入脚本的 ⌂ 主页判定基准由 index.html 改为 tabs.html
- serve.bat 打印外壳与 OTA 页新地址; README 补目录结构与路径约定
验证: 39/39 静态资源 200, 7 页 200 且注入生效, 逐页解析引用 0 坏链,
路由 / 与 /index.html 302、未知页 404, node --check 与 py_compile 通过。
|
2026-09-03 21:51:17 +08:00 |
|
cbb
|
d2c86c425a
|
init: DCU ESP32 调试控制台前端与本地页面服务
纯前端上位机界面 + esp32_server.py 静态服务/桌面窗口外壳, 不含固件、
不直接访问硬件; 业务 API 由 ESP32_COMM 固件 80 端口跨域提供。
- tabs.html 单窗口多标签外壳, iframe 承载各功能页
- index.html OTA 中继(ESP32 WiFi / GD32 relay / BLE), js/ota + js/ble
- can.html / can_monitor.html CAN 通信与接收监控, js/can
- motor.html 电机 CAN FD 控制台, js/motor
- continuity_test.html LAN9252 通断测试, spi_test.html SPI 测速(临时, 自包含)
- 三入口: esp32_app.vbs 桌面窗口 / esp32_web.vbs 浏览器 / serve.bat 控制台调试
- 补 README(页面与目录约定、?v= 缓存版本等改动须知)、.gitignore、
.gitattributes(* -text 保持 Windows 换行原样)
|
2026-09-03 21:30:32 +08:00 |
|