西园寺预约微信小程序(xyxBooking-weapp)
将原有 H5 预约系统迁移至微信小程序的实现,基于 Taro 4 + Vue 3 + NutUI 开发,保留原有业务流程与 UI 风格,并补充了弱网/离线兜底能力。
功能概览
- 预约流程:须知 -> 日期/时段选择 -> 选择参观者 -> 提交订单 -> 支付 -> 查看预约码与记录
- 参观者管理:新增/删除参观者、证件号校验、脱敏展示
- 预约码展示:我的当日预约码、预约记录详情中的预约码
- 证件号查询:通过身份证号查询预约码(用于识别进闸机)
- 弱网/离线模式:弱网提示、离线预约记录列表/详情、离线预约码
- 义工核销:义工登录(权限预检)-> 扫码核销 -> 展示核销结果
技术栈
- 框架: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 默认)
开发命令
# 安装依赖
pnpm install
# 开发模式
pnpm dev:weapp # 微信小程序
pnpm dev:h5 # H5 端
# 构建
pnpm build:weapp # 微信小程序生产包
pnpm build:h5 # H5 端生产包
# 代码质量
pnpm lint # ESLint 检查并修复
pnpm format # Prettier 格式化
pnpm lint:no-fix # 仅检查不修复
代码质量保障
项目已配置完整的代码质量保障体系:
✅ 已配置工具
- ESLint:代码风格检查和潜在错误检测
- Prettier:代码格式化统一
- EditorConfig:编辑器配置统一
- Husky:Git Hooks 自动化
- lint-staged:提交前仅检查本次修改文件
📋 初始配置步骤
# 1. 安装代码质量相关依赖
pnpm add -D eslint prettier eslint-plugin-vue husky lint-staged
# 2. 初始化 Husky(自动设置 Git Hooks)
bash scripts/setup-husky.sh
# 3. 提交代码时会自动运行检查
git add .
git commit -m "feat: 添加新功能"
📚 详细配置文档
查看 docs/development-guide.md 获取完整的配置使用说明。
🎯 Claude Code 开发配置
项目配置了完善的 Claude Code 全局规则,支持:
- Vue 3 最佳实践
- Taro 开发规范
- 小程序特性适配
- 多端兼容处理
- 代码审查清单
全局规则位于 ~/.claude/rules/:
-
taro-patterns.md- Taro 开发规范 -
miniprogram-checklist.md- 小程序检查清单 -
taro-cross-platform.md- 多端兼容指南 -
vue-patterns.md- Vue 3 最佳实践 -
frontend-testing.md- 前端测试指南 -
code-review.md- 代码审查清单
项目结构
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 配置:
- @/utils -> src/utils
- @/components -> src/components
- @/assets -> src/assets
- @/api -> src/api
- @/stores -> src/stores
- @/hooks -> src/hooks
- @/composables -> src/composables
设计宽度体系
在 config/index.js 的 designWidth 做了双设计宽度:
- NutUI 组件按 375 设计稿计算
- 其他页面按 750(Taro 默认)计算
关键实现说明
认证与会话续期
- 启动时在 app.js 尝试静默授权:
silentAuth() - 会话凭证使用
sessionid存储在 Taro Storage(cookie 字符串) - 请求层在 utils/request.js 动态注入 cookie,并在 401 时触发刷新会话、重放原请求(配合 utils/authRedirect.js)
- 授权失败时跳转授权页,并保存来源页,授权成功后回跳(router store 持久化路径)
弱网/离线兜底
两处兜底入口:
- 启动阶段:在 app.js 检测网络类型,弱网/无网时提示并可一键进入离线列表
- 请求阶段:在 utils/request.js 捕获超时/网络错误,优先跳转离线列表;否则提示用户检查网络
离线数据来源:
- 离线预约记录缓存:
OFFLINE_BOOKING_DATA(见 useOfflineBookingCache.js) - 轮询刷新:见 useOfflineBookingCachePolling.js(引用计数 + 网络监听,避免重复启动)
离线页面:
- 离线预约记录列表:
pages/offlineBookingList/index - 离线预约记录详情:
pages/offlineBookingDetail/index - 离线预约码入口:
pages/offlineBookingCode/index
支付/退款(对接位)
- 支付拉起封装:见 utils/wechatPay.js 与 api/wx/pay.js
- 取消预约(退款接口):
icbcRefundAPI(见 api/index.js),在预约详情页调用并刷新离线缓存
义工核销
- 核销端 API:见 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)
- 优化轮询策略:已完成(二维码轮询按页面生命周期启停)
- 资源优化:CDN 图片策略、分包策略、首屏关键资源预加载
- 构建性能:评估开启 Webpack 持久化缓存,缩短二次编译时间