分析日期:2026-09-07
分析范围:lc_garage实际源码、配置、前端构建、项目文档与 Git 历史
结论性质:代码与配置静态审查 + 可执行构建验证,不替代真实闸机、打印机、摄像头和支付终端的现场验收。
项目已经完成从旧的 GIN-VUE-ADMIN 服务端形态向 Wails 单进程桌面应用的主要迁移,并具备停车场配置、停车会话、数字票、支付流水、月卡、交接班、报表、打印和异常处置等基础模块。当前代码也已经出现 internal/modules 领域模块化结构,说明迁移正在持续进行。
距离可稳定交付仍有三类问题:
AGENTS.md、旧版 PROJECT.md、lc_garage/README.md、doc/PROJECT.md 和 doc/功能缺失.md 的架构、数据库和完成状态描述不完全一致。lc_garage/,根目录是项目文档工作区。lc_garage/main.go,通过 //go:embed all:frontend/dist 嵌入前端,并将 /api/* 反向代理到 Gin :8888。lc_garage/internal/,不存在文档中曾描述的 lc_garage/server/ 主目录。frontend/ 和 web/ 两套目录;Wails 配置明确使用 frontend,web 更像历史遗留或兼容目录。parking-session、digital-ticket、payment、monthly、shift、report、printer、incident、central-payment、deviceprovisioning 等。frontend: npm run build 成功,Vite 生成生产包;构建有 Sass 弃用提示及两个超过 500 KB 的 chunk 警告。go test ./...: 当前环境失败在 Go 构建缓存目录 C:\Users\longc\AppData\Local\go-build 的访问权限,输出为 Access is denied,不能视为代码测试失败。GOCACHE,并在 CI 中固定执行,避免环境权限造成误判。证据:internal/initialize/router.go:70-92。
Router.StaticFS(global.GVA_CONFIG.Local.StorePath, ...) 直接提供本地上传目录;车牌抓拍、头像等文件可通过可预测路径访问。:swagger/*any 直接注册,未看到生产环境开关。dashboardRouter.InitDashboardRouter(PublicGroup) 将监控接口放在公开组;CPU、内存等运行信息不应默认匿名暴露。PublicGroup.POST("/device-images/upload", deviceimage.Upload) 公开注册,上传接口应明确鉴权、文件类型、大小、路径和访问权限。修复方案:
system.expose-swagger、system.expose-monitor 等显式配置,生产默认关闭。证据:internal/initialize/seed.go 包含固定 bcrypt 密码和 README.md:32-35 公开写出 admin/123456;config.yaml 还保留对象存储示例密钥字段。
修复方案:
证据:internal/initialize/gorm_sqlite.go:47-53 只设置连接池,没有设置 WAL、busy_timeout 或备份策略;config.yaml:185-199 允许 max-open-conns: 100。
风险:设备事件、支付、操作日志和定时任务并发写入时可能出现 database is locked;进程或磁盘损坏会导致本地运营数据丢失。
修复方案:
PRAGMA journal_mode=WAL、PRAGMA busy_timeout=5000、合理的 synchronous 设置,并将写并发控制在可验证范围。证据:internal/core/server.go:34-40 调用 s.ListenAndServe().Error();internal/initialize/gorm.go:77-84 在迁移失败时使用 os.Exit(0)。
风险:监听失败可能触发 nil error 解引用;数据库迁移失败却以成功码退出,Windows 启动器和发布脚本无法正确识别失败。
修复方案:
err := s.ListenAndServe(),对 http.ErrServerClosed 单独处理,其余错误记录并以失败状态退出或通知 Wails 主进程。os.Exit(0) 改为错误返回/受控退出码 1,并在启动错误日志中写明迁移步骤和恢复建议。证据:doc/功能缺失.md 和 internal/modules/payment 的现状说明;当前 payment_record 主要记录本地业务结果,POS、扫码和中央缴费机仍需真实设备或网关确认。
修复方案:
现状记录见 doc/功能缺失.md:117-139。读卡器、闸机控制器、连接管理器和运行时状态存在多套来源;串口/TCP 的 ACK、分片、超时、重连和落杆反馈还需要现场验证。
修复方案:拆分设备类型与通道拓扑,统一 DeviceRuntime 状态源;所有开闸/关闸命令落 device_command_log,校验 ACK、超时和重试,增加地感、防砸、落杆确认和人工兜底测试。
config.yaml:210 当前为 gate-simulator: false,默认值正确;但仍应在启动时显示运行模式,并在生产构建或生产配置中拒绝开启模拟模式。模拟模式下的“开闸成功”不能被当作真实硬件确认。
修复方案:增加 environment=production 与 gate-simulator 互斥校验;模拟模式所有指令标记 simulated=true,前端和审计记录明确显示。
现状:票机打印仍以同步硬件调用为主,失败重试、重打、作废和异常处置尚未形成完整任务模型。
修复方案:新增打印任务表和状态机,先创建任务再执行硬件动作;记录短写、串口错误、设备离线和重试次数,允许受权限控制的重打/作废,并与数字票和停车会话建立补偿规则。
现状:月卡退款缺少完整退款流水和审批;自然月/季/年、并发办理、人工白名单保护需要继续完善;交接班和报表还需要覆盖所有支付方式、退款和差异。
修复方案:
doc/功能缺失.md 指出 ExpireAt 自动执行和状态不一致检测仍不完整。应明确待支付票、已支付未离场票的过期规则,并由定时任务执行状态迁移和异常告警。
@import/legacy API 弃用警告。PROJECT.md 仍描述 server/ 独立后端、MySQL 和旧 Electron 结构,与实际 Wails + SQLite 代码不符。AGENTS.md、lc_garage/README.md 和 doc/PROJECT.md 对结构的描述不一致:前者较旧,后两者基本反映当前布局。doc/功能缺失.md 中部分安全问题已在提交 8cca42f 修复,例如注册角色层级校验、操作日志脱敏、模拟闸机告警,但文档仍把它们写成当前漏洞。doc/项目进度.md 更新日期早于最近代码提交,完成状态与后续新增的中央缴费机、设备接入模块没有完全同步。修复方案:
lc_garage/doc/PROJECT.md 作为唯一项目说明,以 lc_garage/README.md 作为快速开始文档。PROJECT.md 标记为历史文档或删除,避免新成员误用 MySQL/server 启动方式。doc/功能缺失.md 增加“已修复/仍存在”分栏、代码版本和验证命令;删除已完成项的当前时态描述。项目进度.md、流程文档和测试记录,并在 CI 检查文档中的路径是否存在。Wails 使用 frontend,但 web 仍保留完整 Vue 源码和 Vite 配置。双目录会导致修复只落在一处、构建结果与开发结果不一致。
修复方案:短期在 README 和 wails.json 中明确 frontend 为唯一构建源;中期归档或删除 web,若必须兼容则用脚本从唯一源生成,不允许手工双写。
frontend/src/view/report/enter.vue:222-224 的异常处理调用 t.value.getListFail,文件中没有对应的 t 定义。接口失败时会再次触发 ReferenceError,原始错误信息被覆盖。
修复方案:改为已有的 $t/语言包访问方式,或定义统一的 useI18n 实例;补充请求失败分支测试。
frontend/src/pinia/modules/user.js:91-98 只有黑名单接口返回成功才清理 token;而 frontend/src/utils/request.js:147-162 的 401 处理依赖用户确认。
修复方案:登出无论服务端结果如何都清理本地 token;401 统一立即清理并跳转登录,弹窗只用于提示,不应让失效凭据继续留存。
| 顺序 | 优先级 | 工作包 | 完成标准 |
|---|---|---|---|
| 1 | P0 | 路由、上传、Swagger、监控和设备接口安全边界 | 匿名访问测试通过;上传不可猜测读取;生产 Swagger/监控默认关闭 |
| 2 | P0 | 默认凭据、密钥和配置校验 | 首次启动强制改密;仓库不含可用生产密钥;非法端口/路径拒绝启动 |
| 3 | P0 | SQLite WAL、锁等待、备份恢复 | 并发写压测通过;备份可校验;恢复演练有记录 |
| 4 | P0 | 启动失败和进程退出语义 | 迁移/监听失败返回非零并写清晰诊断,不出现 nil error panic |
| 5 | P0 | 支付订单、回调幂等和财务对账 | 成功/失败/不确定/退款/冲正可追溯,重复通知不重复收费 |
| 6 | P1 | 道闸、读卡器、打印机现场闭环 | ACK、超时、重试、离线、落杆和打印补偿均有集成测试 |
| 7 | P1 | 月卡、交接班、报表和数字票过期 | 事务、并发、退款、班次和跨表对账规则明确并覆盖测试 |
| 8 | P1 | 摄像头、设备告警和 LED | 设备状态、事件、恢复和余位推送可在现场验收 |
| 9 | P2 | 文档收敛、双前端归档和前端性能 | 唯一开发入口,文档路径与状态可由 CI 校验 |
发布前至少执行:
cd D:\lq\Smart Parking\lc_garage
$env:GOCACHE = "D:\lq\Smart Parking\lc_garage\build\gocache-ci"
go test ./... -count=1
cd frontend
npm run build
另外需要单独保留以下验收记录:真实闸机开/关及断网、真实打印机短写和重打、摄像头重复识别、POS/中央缴费机回调幂等、SQLite 备份恢复、管理员和操作员越权测试。只有代码、权限、自动化测试和现场流程同时通过,相关功能才应标记为“已完成”。