hookehuyr

docs: 重构 README 文档以提供更清晰的项目概览与架构说明

- 将项目介绍重构为更清晰的功能概览与技术栈说明
- 详细阐述项目结构、关键实现(如认证、离线兜底)与可复用能力
- 增加项目优缺点分析与明确的后续优化建议
- 移除过时的优化建议条目,更新为当前状态
Showing 1 changed file with 139 additions and 125 deletions
## 项目介绍
本项目是将原有H5预约系统迁移至微信小程序的实现。基于 Taro4 + Vue3 + NutUI 开发,保留了原有的功能和UI风格。
## 功能模块
1. **预约流程**
* 日期与时间段选择 (`pages/booking/index`)
* 预约信息确认与提交 (`pages/submit/index`)
* 预约记录查看 (`pages/bookingList/index`)
* 预约详情 (`pages/bookingDetail/index`)
2. **参观者管理**
* 参观者列表 (`pages/visitorList/index`)
* 添加/编辑参观者 (`pages/addVisitor/index`)
* 支持身份证号校验与脱敏显示
3. **个人中心**
* 预约码展示 (`pages/bookingCode/index`)
* 我的页面 (`pages/me/index`)
* 邀请码/证件号查询 (`pages/search/index`)
4. **弱网与离线模式**
* 弱网提示页 (`pages/weakNetwork/index`)
* 离线预约记录列表 (`pages/offlineBookingList/index`)
* 离线预约记录详情/离线二维码 (`pages/offlineBookingDetail/index`)
* 离线预约码入口页 (`pages/offlineBookingCode/index`)
* 离线预约缓存刷新与轮询 (`src/composables/useOfflineBookingCache.js`, `src/composables/useOfflineBookingCachePolling.js`)
* 网络从可用变为弱网/无网时,弹窗提示并可一键进入离线模式(`src/app.js`
5. **义工核销**
* 义工登录与权限预检 (`pages/volunteerLogin/index`)
* 核销页(扫码核销 + 结果展示)(`pages/verificationResult/index`)
6. **公共功能**
* 全局路由封装 (`hooks/useGo`)
* API 请求封装 (`utils/request`, `api/index`)
* 登录授权流程 (`pages/auth/index`)
* 弱网提示文案统一管理 (`utils/uiText.js`)
# 西园寺预约微信小程序(xyxBooking-weapp)
将原有 H5 预约系统迁移至微信小程序的实现,基于 Taro 4 + Vue 3 + NutUI 开发,保留原有业务流程与 UI 风格,并补充了弱网/离线兜底能力。
## 功能概览
- 预约流程:须知 -> 日期/时段选择 -> 选择参观者 -> 提交订单 -> 支付 -> 查看预约码与记录
- 参观者管理:新增/删除参观者、证件号校验、脱敏展示
- 预约码展示:我的当日预约码、预约记录详情中的预约码
- 证件号查询:通过身份证号查询预约码(用于识别进闸机)
- 弱网/离线模式:弱网提示、离线预约记录列表/详情、离线预约码
- 义工核销:义工登录(权限预检)-> 扫码核销 -> 展示核销结果
## 技术栈
* **框架**: Taro 4.x
* **UI库**: NutUI 4.x (Vue3)
* **语言**: JavaScript (Vue3 Setup 语法糖)
* **样式**: Less + TailwindCSS (部分)
* **状态管理**: Pinia
* **路由**: Taro Router + 自定义 Hooks
- 框架:Taro 4.1.9 + Vue 3(setup 语法糖)
- UI:NutUI 4(@nutui/nutui-taro + icons-vue-taro)
- 状态管理:Pinia(taro-plugin-pinia)
- 网络请求:axios-miniprogram(封装拦截器与认证续期)
- 样式:Less + TailwindCSS(小程序端通过 weapp-tailwindcss 兼容)
- 构建:Webpack 5(Taro 默认)
## 开发命令
```bash
pnpm install
pnpm dev:weapp
pnpm build:weapp
pnpm lint
```
## 项目结构
* `src/api`: 接口定义
* `src/assets`: 图片等静态资源
* `src/components`: 公共组件 (qrCode, qrCodeSearch, reserveCard等)
* `src/composables`: 组合式函数 (离线缓存/轮询等)
* `src/pages`: 页面文件
* `src/hooks`: 组合式函数 (useGo等)
* `src/stores`: Pinia 状态管理 (main/router 等)
* `src/utils`: 工具函数 (request, authRedirect, network, uiText 等)
## 项目运行
1. 安装依赖
```bash
pnpm install
```
2. 运行开发环境
```bash
pnpm dev:weapp
```
3. 打包构建
```bash
pnpm build:weapp
```
## 离线预约缓存轮询说明
### 目标
在「已授权 + 网络可用」时,定时刷新离线预约记录缓存(本地 storage:`OFFLINE_BOOKING_DATA`),用于弱网/离线兜底页面展示。
### 相关文件
* 离线缓存刷新:`src/composables/useOfflineBookingCache.js`
* 核心方法:`refresh_offline_booking_cache({ force })`
* 轮询与网络监听:`src/composables/useOfflineBookingCachePolling.js`
* 核心方法:`enable_offline_booking_cache_polling(options)` / `disable_offline_booking_cache_polling()`
* 启动入口:`src/app.js`
* 在授权成功后调用 `enable_offline_booking_cache_polling()`
### 启动条件
轮询启动需要同时满足:
1. `ref_count > 0`:表示当前确实有人需要轮询(应用级启用会占用 1 个引用)
2. `network_usable === true`:网络类型可用(由 `src/utils/network.js` 判定)
### 运行流程
1. `enable_offline_booking_cache_polling(options)`
* 缓存最后一次 `options`(用于网络恢复时重启轮询)
* 增加 `ref_count`
* 注册 `Taro.onNetworkStatusChange`(仅注册一次)
* 如果当前网络可用,则启动定时器,默认每 `60000ms` 刷新一次
2. 定时器 tick:
* 调用 `refresh_offline_booking_cache({ force: !!options?.force })`
* 内部会再次校验授权与网络,避免无效请求
3. 网络变更监听:
* 变为弱网/无网:立即停止轮询定时器
* 恢复为可用网络:若 `ref_count > 0`,用最后一次 `options` 重新启动轮询
4. `disable_offline_booking_cache_polling()`
* 释放一次 `ref_count`
*`ref_count === 0` 时:停止轮询并注销网络监听器
### options 说明
* `interval_ms`:轮询间隔(毫秒),默认 `60000`
* `immediate`:是否立即刷新一次,默认 `true`
* `force`:透传给 `refresh_offline_booking_cache`,用于强制刷新(默认 `false`
## 优化建议 (TODO)
* [x] 小程序授权流程有问题 - 已处理
* [ ] 完善支付流程(目前为模拟/H5跳转)- 后端配合联调
* [ ] 优化图片资源加载(考虑使用 CDN 或分包)- 有离线模式看情况处理
* [x] 弱网环境下的离线预约记录 - 已实现(本地缓存 + 离线列表/详情)
* [ ] 义工核销接口联调与核销结果字段展示优化(依赖后端返回结构稳定)
* [ ] 增强网络请求的错误处理与重试机制
* [ ] 补充单元测试
```text
config/ Taro 构建配置(alias、designWidth、tailwind 插件等)
doc/ 需求/说明文档(弱网离线、核销等)
src/
app.js 应用入口(启动授权、网络监听、离线缓存预加载/轮询)
app.config.js 小程序路由与窗口配置
api/ API 常量与封装(含 wx 支付、义工核销)
assets/ 静态资源(images、styles)
components/ 业务组件(预约码、预约记录卡、离线二维码等)
composables/ 组合式逻辑(离线缓存、轮询)
hooks/ 路由封装(useGo/useReplace)
pages/ 页面(按 pages/<name>/index.vue 组织)
stores/ Pinia store(router/main/host/counter)
utils/ 工具(request/authRedirect/network/uiText/wechatPay 等)
```
### 路径别名
[config/index.js](config/index.js) 配置:
- @/utils -> src/utils
- @/components -> src/components
- @/assets -> src/assets
- @/api -> src/api
- @/stores -> src/stores
- @/hooks -> src/hooks
- @/composables -> src/composables
### 设计宽度体系
[config/index.js](config/index.js) 的 designWidth 做了双设计宽度:
- NutUI 组件按 375 设计稿计算
- 其他页面按 750(Taro 默认)计算
## 关键实现说明
### 认证与会话续期
- 启动时在 [app.js](src/app.js) 尝试静默授权:`silentAuth()`
- 会话凭证使用 `sessionid` 存储在 Taro Storage(cookie 字符串)
- 请求层在 [utils/request.js](src/utils/request.js) 动态注入 cookie,并在 401 时触发刷新会话、重放原请求(配合 [utils/authRedirect.js](src/utils/authRedirect.js)
- 授权失败时跳转授权页,并保存来源页,授权成功后回跳(router store 持久化路径)
### 弱网/离线兜底
两处兜底入口:
- 启动阶段:在 [app.js](src/app.js) 检测网络类型,弱网/无网时提示并可一键进入离线列表
- 请求阶段:在 [utils/request.js](src/utils/request.js) 捕获超时/网络错误,优先跳转离线列表;否则提示用户检查网络
离线数据来源:
- 离线预约记录缓存:`OFFLINE_BOOKING_DATA`(见 [useOfflineBookingCache.js](src/composables/useOfflineBookingCache.js)
- 轮询刷新:见 [useOfflineBookingCachePolling.js](src/composables/useOfflineBookingCachePolling.js)(引用计数 + 网络监听,避免重复启动)
离线页面:
- 离线预约记录列表:`pages/offlineBookingList/index`
- 离线预约记录详情:`pages/offlineBookingDetail/index`
- 离线预约码入口:`pages/offlineBookingCode/index`
### 支付/退款(对接位)
- 支付拉起封装:见 [utils/wechatPay.js](src/utils/wechatPay.js)[api/wx/pay.js](src/api/wx/pay.js)
- 取消预约(退款接口):`icbcRefundAPI`(见 [api/index.js](src/api/index.js)),在预约详情页调用并刷新离线缓存
### 义工核销
- 核销端 API:见 [api/redeem.js](src/api/redeem.js)
- 页面:`pages/volunteerLogin/index`(权限预检/登录)与 `pages/verificationResult/index`(扫码核销与结果展示)
## 可复用能力(迁移到其他项目的价值)
- 请求层:`src/utils/request.js`
- 默认参数合并、cookie 注入、弱网降级
- 401 自动续期与原请求重放(与 authRedirect 配合)
- 认证/回跳:`src/utils/authRedirect.js` + `src/stores/router.js`
- 静默授权单例锁(避免并发登录)
- 保存来源页与授权后回跳
- 弱网/离线缓存:`src/composables/useOfflineBookingCache*.js`
- 离线数据结构抽取、缓存读写、轮询刷新、网络切换处理
- 路由工具:`src/hooks/useGo.js`
- 短路径补全、query 序列化、tabbar 兼容处理(可扩展)
- 弱网文案统一:`src/utils/uiText.js`
- 将 toast/modal 文案集中管理,避免页面散落硬编码
## 项目优缺点
### 优点
- 业务链路完整(预约、支付、预约码、记录、核销),页面目录清晰
- 认证流程健壮:会话续期、并发合并、授权回跳可控
- 弱网/离线兜底完善:启动检查 + 请求降级 + 离线列表/详情闭环
- 工具化程度高:request/authRedirect/useGo/uiText 等可复用模块明确
- 样式体系兼容小程序:Less + Tailwind(配合 weapp-tailwindcss)
### 不足
- 自动化测试缺失(暂无单元测试/集成测试与 CI 校验)
- 部分工具函数存在重复实现(例如证件号脱敏在多处出现)
- 轮询逻辑仅在卸载时清理,页面 onHide 场景可能仍在请求(可优化为按页面可见性启停)
- Webpack 持久化缓存未开启(`config/index.js` 中 cache.enable=false)
- 少量文件头部元信息/注释规范不一致(例如个别文件仍为“文件描述”占位)
## 优化建议(下一步)
- 补充测试:优先覆盖 request/authRedirect/offline cache 的关键边界
- 抽离通用工具:证件号脱敏、时间格式化、状态映射等统一放到 utils
- 优化轮询策略:结合页面生命周期 onShow/onHide 控制轮询启停
- 资源优化:CDN 图片策略、分包策略、首屏关键资源预加载
- 构建性能:评估开启 Webpack 持久化缓存,缩短二次编译时间
......