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