30 KiB
智绘微刻小程序 — 交付总结 v11
本文档供完全无上下文的新会话阅读,记录各轮重构的完整交付成果。
日期:2026-08-02(第十一批修改,Batch 11)
项目目录:F:\weixin_wordc\
技术栈:Taro 3.6.31 + React 18 + TypeScript + SCSS
一、历史修改回顾
Batch 1(已完成)
全局主题切换、字体系统、tabBar重组、商品详情页、设计清单、效果确认页、后端技术栈文档。
Batch 2(已完成)
全局Context主题同步、登录系统、贴纸DIY、订单详情、Profile 5状态、自动筛选、图片路径修复。
Batch 3(已完成)
完善个人主页功能(收货地址、设置页、协议页)、ThemeToggle点击修复、商品图片显示修复、Profile状态跳转修复、LoginGuard登录守卫、用户数据 openid 隔离。
Batch 4(已完成)
主题黑白切换彻底修复(删除eventCenter多余监听)、Profile菜单登录后无反应修复、本地用户数据库(密码保护zhihui2024)。
Batch 5(已完成)
Profile菜单登录后无反应最终修复(增加onShow同步)、全部emoji替换为icon图片、首页品类卡片icon化、成品展示轮播图替换为实物照片、设计确认页/订单详情页增加收货地址栏、LoginGuard空状态居中。
Batch 6(已完成)
设计清单/订单页未登录提示居中、icon尺寸统一缩小、底部tabBar图标图片化、删除首页标题栏旁多余icon、清单/订单页列表icon图片化。
Batch 7(已完成)
Service企业专属icon缩至28px、settings未登录头像icon缩至40px、首页轮播图文字与图片分离并适配昼夜主题。
二、本轮(Batch 6)修改任务 — 全部完成 ✅
| 序号 | 任务 | 状态 |
|---|---|---|
| 1 | 设计清单/订单页未登录提示居中修复:将 ThemeToggle + page-header 移入 LoginGuard 内部,未登录时只显示居中提示 |
✅ 完成 |
| 2 | icon 尺寸统一缩小:所有 icon 图片缩至与临近文字同高(约 28px–56px 区间),Profile 菜单 36px、tabBar 28px、品类 56px | ✅ 完成 |
| 3 | 底部 tabBar 图标图片化:4个导航 emoji → /icon/xxx.png,激活态放大 + 不透明 |
✅ 完成 |
| 4 | 删除首页标题栏旁的 首页.png:标题栏只保留纯文字"智绘微刻" | ✅ 完成 |
| 5 | 设计清单/订单列表 icon 图片化:design-icon / order-icon emoji 文字 → <Image>,空状态也替换 |
✅ 完成 |
三、文件变更清单
本轮修改的现有文件
| 文件 | 核心改动 |
|---|---|
src/pages/profile/index.tsx |
最终修复菜单点不开:① useEffect 增加 onShow 绑定,每次回到页面同步登录状态;② handleMenuClick 只对 designList/orders 做登录拦截,其他页面(设置/地址/客服/词云)登录与否均可进入;③ 全部 emoji 替换为 <Image> 引用 /icon/xxx.png;④ 状态栏增加图片 icon |
src/pages/profile/index.scss |
新增 .menu-icon-img、.status-icon-img、.enterprise-icon、.avatar-icon-img、.avatar-placeholder-img 等图片尺寸样式 |
src/pages/index/index.tsx |
① SHOWCASE_LIST 轮播图改用 img/ 实物照片;② 品类卡片 icon 字段改用 /icon/xxx.png;③ 搜索框/空状态图标改用 icon 图片 |
src/pages/checkout/index.tsx |
① 新增地址状态管理;② 展示默认收货地址;③ 新增"更改收货地址"按钮;④ 底部弹窗选择已有地址;⑤ 无地址时提示并引导添加 |
src/pages/checkout/index.scss |
新增 .checkout-address-card、.addr-picker-sheet 等地址弹窗样式 |
src/pages/orderDetail/index.tsx |
① 新增地址展示卡片;② 增加"更改收货地址"文字按钮;③ 底部弹窗选择地址 |
src/pages/orderDetail/index.scss |
新增 .address-change、.addr-picker-sheet 等底部弹窗样式 |
src/pages/settings/index.tsx |
4个菜单 emoji 全部替换为 /icon/xxx.png;未登录头像图标替换 |
src/pages/settings/index.scss |
新增 .settings-item-icon-img 样式 |
src/pages/service/index.tsx |
联系客服页全部 emoji 替换为 icon 图片 |
src/components/LoginGuard/index.tsx |
结构改为 .login-guard + .login-guard-inner,支持整体居中 |
src/components/LoginGuard/index.scss |
使用 justify-content: center; align-items: center; min-height: 80vh 实现整体垂直水平居中 |
config/index.js |
copy.patterns 增加 { from: 'src/icon', to: 'dist/icon' },确保图标资源被打包到小程序目录 |
src/app.config.ts |
页面列表保持不变(无需修改) |
Batch 6 新增/修改文件
| 文件 | 核心改动 |
|---|---|
src/pages/designList/index.tsx |
登录提示居中:ThemeToggle + page-header 移入 LoginGuard 内部;emoji 列表 icon → <Image src={item.productIcon}>;空状态 emoji → <Image src='/icon/调色盘.png'> |
src/pages/designList/index.scss |
新增 .design-icon-img(56×56);删除 .empty-icon 字体样式,改为 .empty-icon-img |
src/pages/orders/index.tsx |
登录提示居中:ThemeToggle + page-header 移入 LoginGuard 内部;emoji 订单 icon → <Image src={order.productIcon}>;空状态 emoji → <Image src='/icon/包裹.png'> |
src/pages/orders/index.scss |
新增 .order-icon-img(56×56);删除 .empty-icon 字体样式,改为 .empty-icon-img |
src/custom-tab-bar/index.tsx |
tabBar emoji 字符串 → <Image> 引用 /icon/xxx.png(首页/调色盘/包裹/个人) |
src/custom-tab-bar/index.scss |
.tab-icon(字体40px)→ .tab-icon-img(图片28px,未激活opacity:0.6,激活scale+opacity:1) |
src/pages/index/index.tsx |
删除标题栏旁 <Image className='header-icon' src='/icon/首页.png' /> |
src/pages/index/index.scss |
.search-icon-img → 28×28px;.category-icon-img → 56×56px |
src/pages/profile/index.scss |
.menu-icon-img 48→36px;.status-icon-img 40→28px;.enterprise-icon 40→28px;.avatar-icon-img 56→36px;.avatar-placeholder-img 80→56px |
src/pages/service/index.scss |
.service-hero-icon(图片)→ 56×56px;新增 .contact-icon-img 32×32px |
Batch 7 新增/修改文件
| 文件 | 核心改动 |
|---|---|
src/pages/service/index.scss |
.enterprise-icon 缺失定义补全 → 28×28px |
src/pages/settings/index.scss |
.settings-avatar-placeholder 改为 flex 居中容器;.settings-avatar-icon 缩至 40×40px |
src/pages/settings/index.tsx |
未登录头像 <Image className='settings-avatar-placeholder'> → <View className='settings-avatar-placeholder'> + 内部 <Image className='settings-avatar-icon'> |
src/pages/index/index.tsx |
轮播图 showcase-swiper-card 结构改为:Image 在上,showcase-text-area 白底区域在下,文字与图片分离 |
src/pages/index/index.scss |
轮播卡片重写:height: 520rpx;.showcase-image-wrapper 图片区 320rpx;新增 .showcase-text-area 文字区 background: var(--bg-card);文字颜色全部改为 CSS 变量 (--text-primary / --text-secondary);搜索框/结果提示/品类卡片/空状态也改为 CSS 变量适配主题 |
四、完整 Icon 映射表(供后续维护)
| 使用位置 | 图片路径 |
|---|---|
| Profile-我的设计 | /icon/调色盘.png |
| Profile-词云生成 | /icon/词云生成.png |
| Profile-收货地址 | /icon/地址.png |
| Profile-联系客服 | /icon/电话.png |
| Profile-使用帮助 | /icon/使用帮助.png |
| Profile-设置 | /icon/设置.png |
| Profile-待设计 | /icon/三角尺.png |
| Profile-待付款 | /icon/四角星.png |
| Profile-待发货 | /icon/包裹.png |
| Profile-待收货 | /icon/杯子.png |
| Profile-已完成 | /icon/书本.png |
| Profile-未登录头像 | /icon/个人.png |
| Profile-企业定制 | /icon/企业批量定制.png |
| Settings-个人信息 | /icon/个人.png |
| Settings-账号管理 | /icon/账号管理.png |
| Settings-定制协议 | /icon/定制协议.png |
| Settings-关于我们 | /icon/关于我们.png |
| 首页-笔记本(小) | /icon/书本.png |
| 首页-笔记本(大) | /icon/书本_大.png |
| 首页-杯垫 | /icon/杯子.png |
| 首页-笔盒 | /icon/笔盒.png |
| 首页-书灯 | /icon/书灯.png |
| 首页-搜索框 | /icon/搜索.png |
| Service-客服电话 | /icon/电话.png |
| Service-客服微信 | /icon/词云生成.png |
| Service-商务邮箱 | /icon/使用帮助.png |
| Service-企业专属 | /icon/企业批量定制.png |
| tabBar-首页 | /icon/首页.png |
| tabBar-设计清单 | /icon/调色盘.png |
| tabBar-订单 | /icon/包裹.png |
| tabBar-我的 | /icon/个人.png |
| designList-空状态 | /icon/调色盘.png |
| orders-空状态 | /icon/包裹.png |
| address-空状态 | /icon/地址.png |
五、编译验证结果
npx taro build --type weapp
- ✅ webpack 5.91.0 compiled successfully in ~21s
- ✅ 0 报错,0 ERROR
- ✅ 编译后
dist/总大小:1.2 MB(< 2MB,满足微信预览/上传限制) - 图片资源分布:
dist/img/:432 KB(8 张产品实物压缩图)dist/icon/:136 KB(19 个 icon 图标文件)
Batch 6 编译验证结果
npx taro build --type weapp
- ✅ webpack 5.91.0 compiled successfully in 18.58s
- ✅ 0 报错,0 ERROR
- ✅ 编译后
dist/总大小:约 361 KB(远小于 2MB 限制) - 图片资源分布:
dist/icon/:136 KB(19 个 icon 图标文件)dist/img/:432 KB(8 张产品实物压缩图)
六、关键踩坑记录(含本轮新增)
| 坑 | 现象 | 解法 |
|---|---|---|
| 全局主题不同步 | 切换后已打开页面不刷新 | React.createContext + eventCenter,各页面 onShow 时重新读取 Storage |
| 设计清单切页不刷新 | 加入清单后切换页面看不到新条目 | 用 Taro.getCurrentInstance().page.onShow 重写,保证每次页面展现必触发 |
| 图片显示纯空白 | 微信小程序编译后资源路径错乱 | productConfig.ts 的图片路径改为 /img/xxx 绝对路径;config/index.js copy 规则写为 to: 'dist/img' |
| ThemeToggle 点击无反应 | 在个人页点击主题按钮没有任何效果 | require('@tarojs/taro').default 在某些构建下不返回真实 Taro 对象,改为顶层 import Taro from '@tarojs/taro' |
| Profile 待设计未筛选 | 点击”待设计“跳到设计清单但显示全部条目 | 增加 designList:filter Storage 参数,设计清单 onShow 时读取并切换到 toDesign Tab(聚合未设计+设计中) |
| 用户数据未隔离 | 换账号登录后还能看到上一个用户的设计清单 | store.ts 重构为 DA 层,Storage key 按 openid 前缀隔离:design_list_${openid} |
| 收货地址省市区 | 不知如何实现三级联动 | 直接用微信原生组件 <Picker mode='region'>,无需自建数据 |
| 主题切换彻底崩溃(Batch 4) | 按下 ThemeToggle 后按钮卡死,无法回到白天主题 | ThemeContext 中 eventCenter.on('theme:change') 监听 undefined 参数导致 state 崩溃。删除 eventCenter 代码,纯 Context state 驱动 |
| Profile 菜单登录后无反应(Batch 4) | 未登录时菜单能点开,登录后完全点不开 | handleMenuClick 在未登录时对所有页面做了拦截,实际只有 designList/orders 需要登录,其余应开放 |
| Profile 菜单登录后仍无反应(Batch 5) | 登录后依然点不开常用功能 | 根因是 useEffect 没有绑定 onShow,登录后切回 Profile 时 isLoggedIn state 仍是 false。增加 page.onShow 同步登录状态解决 |
| Sass 编译报错(Batch 5) | 编辑 SCSS 时误删选择器名,导致 padding: 32px; 裸奔 |
重新整理 SCSS,确保每个属性都在正确选择器下 |
| icon 资源未打包 | 图标图片在开发者工具中报 404 | config/index.js 中增加 { from: 'src/icon', to: 'dist/icon' } copy 规则 |
七、核心业务流(完整链路)
首页浏览品类 → 商品详情页(轮播图+价格+介绍)
→ 加入设计清单(弹窗选数量)→ 设计清单页(需登录,支持自动筛选)
→ 立即下单 → DIY 工作台(直接进入,无需选品)
→ 添加贴纸(相册/相机)→ 拖动调整位置 → 碰撞检测
→ 预览效果 → 确认完成 → 设计效果确认页(含收货地址)
→ 弹窗确认下单 → 订单生成(需登录)→ 订单列表/订单详情(可改地址)
→ 物流时间轴追踪 → 确认收货 → 完成
个人主页
→ 待设计 / 待付款 / 待发货 / 待收货 / 已完成 → 自动跳转对应页面并筛选
→ 收货地址 → 增删改复 + 省市区选择 + 默认地址
→ 设置 → 修改信息 / 退出登录 / 定制协议 / 账号管理
→ 账号管理(密码保护:zhihui2024)→ 查看/切换/新建/删除本地用户
八、架构说明:前端 DA 层设计
所有数据操作通过 src/utils/store.ts 抽象为 Data Access 层:
pages/
└─ 调用 store.getDesignList() / addDesign() / designToOrder() 等业务接口
└─ store.ts 内封装 Taro.getStorageSync / setStorageSync
└─ key = `${scope}_${openid}` 实现多用户隔离
后端替换方案:上线时只需重写 store.ts 中的函数为 wx.request HTTP 调用,页面层零改动。
九、图片资源与 CDN 说明
⚠️ 当前状态:
- 实物照片已两轮压缩(最长边 800px、质量 60%),
dist/img/432 KB。- icon 图标 19 个,
dist/icon/136 KB。- 编译后总包体积 1.2 MB,满足微信 2MB 限制。
后续计划(上线前):
- 将实物照片上传到 腾讯云 COS 或 阿里云 OSS。
- 修改
productConfig.ts中images字段为网络 URL。- 移除
config/index.js中src/img的 copy 规则。- 小程序包体积可永久保持在 < 500KB。
新增:icon 图标均为小体积 PNG(平均 < 8KB),长期本地存放即可,无需 CDN。
十、下一步建议(可选)
- 后端接入:当前
openid为 mock 值,接入真实后端后替换wx.login的code换取真实openid。 - CDN 外链迁移:将
src/img/中的实物照片上传对象存储,productConfig.ts改为网络 URL。 - 真机预览:在微信开发者工具点击"预览",确认所有 icon 图标正常显示、无 404。
- 订单物流接口:当前为静态 mock,接入 backend 后可实现真实物流查询。
- 合并优化:检查是否还有遗漏 emoji 未替换为 icon 图片。
Batch 7 新增/修改文件
| 文件 | 核心改动 |
|---|---|
src/pages/service/index.scss |
.enterprise-icon 缺失定义补全 → 28×28px |
src/pages/settings/index.scss |
.settings-avatar-placeholder 改为 flex 居中容器;.settings-avatar-icon 缩至 40×40px |
src/pages/settings/index.tsx |
未登录头像 <Image className='settings-avatar-placeholder'> → <View className='settings-avatar-placeholder'> + 内部 <Image className='settings-avatar-icon'> |
src/pages/index/index.tsx |
轮播图 showcase-swiper-card 结构改为:Image 在上,showcase-text-area 白底区域在下,文字与图片分离 |
src/pages/index/index.scss |
轮播卡片重写:height: 520rpx;.showcase-image-wrapper 图片区 320rpx;新增 .showcase-text-area 文字区 background: var(--bg-card);文字颜色全部改为 CSS 变量 (--text-primary / --text-secondary);搜索框/结果提示/品类卡片/空状态也改为 CSS 变量适配主题 |
| Batch 7(17:10 批次)3 项优化目标全部完成,编译通过,包体积约 361 KB。 | |
| 累计完成:Batch 1 + Batch 2(12 项)+ Batch 3(6 项)+ Batch 4(3 项)+ Batch 5(6 项)+ Batch 6(5 项)+ Batch 7(3 项)= 38 项核心目标全部 ✅ |
Batch 8(2026-07-29 晚间)— Taro React 事件兼容修复 ✅
背景:微信基础库 3.17.0(灰度)+ Taro 3.6.31 + React 18 下,个人主页频繁出现 TypeError: Cannot read properties of undefined (reading '_num'),堆栈定位到 TaroElement.removeEventListener。
| 序号 | 任务 | 状态 |
|---|---|---|
| 1 | 全量 onClick → onTap:Taro 小程序端推荐 bindtap,onClick 在 React reconciler diff 时有概率触发 removeEventListener(undefined) |
✅ 完成 |
| 2 | Profile Fragment 消除:STATUS.map 中 <></> 包裹改为 <View className='status-group'>,避免 Taro diff 时 Fragment 内事件节点引用丢失 |
✅ 完成 |
| 3 | useEffect + page.onShow 重写:手动覆盖 page.onShow 在热更新时会重复叠加,改为 Taro 标准 useDidShow(() => sync()) |
✅ 完成 |
| 4 | 清理废弃 permission:删除 app.config.ts 中已废弃的 scope.writePhotosAlbum 配置 |
✅ 完成 |
文件变更:
| 文件 | 核心改动 |
|---|---|
src/components/ThemeToggle/index.tsx |
onClick → onTap |
src/pages/profile/index.tsx |
① useEffect → useDidShow;② STATUS_MAP.map 中 Fragment → View.status-group;③ 全部 onClick → onTap |
src/pages/profile/index.scss |
.status-row.row2/.row3 删除 grid;新增 .status-group flex 容器;.status-divider 增加 flex-shrink: 0 |
src/app.config.ts |
删除 permission.scope.writePhotosAlbum |
| 其他 12 个 .tsx 文件 | onClick → onTap(address、checkout、designList、diy、index、orderDetail、orders、product、service、settings、userDatabase、wordcloud) |
编译结果:webpack 5.91.0 compiled successfully in 27.13s,0 报错。
Batch 9(2026-07-29 晚间)— emoji → icon 图片彻底收尾 ✅
背景:商品详情页弹窗仍显示 emoji(如 📓、☕);设计清单/订单列表的 icon 图片不显示,因为 store.ts 存储的是旧 emoji 字符串而非图片路径。
| 序号 | 任务 | 状态 |
|---|---|---|
| 1 | productConfig.ts 增加 iconImg:每个产品新增 iconImg 字段(如 /icon/书本.png),不再用 emoji 作为展示资源 |
✅ 完成 |
| 2 | ** store 层写入逻辑修复**:addDesign() 存储 productIcon 时从 product.icon(emoji)改为 product.iconImg;designToOrder() 兼容旧数据 |
✅ 完成 |
| 3 | 运行时映射兼容旧数据:designList/index.tsx / orders/index.tsx 渲染时检测 productIcon 是否以 /icon/ 开头,否则通过 productId 查 PRODUCT_ICON_MAP |
✅ 完成 |
| 4 | 商品详情页弹窗去 emoji:Hero 无实物图时和弹窗中 <Text>{product.icon}</Text> → <Image src={getProductIconImg(product)} /> |
✅ 完成 |
文件变更:
| 文件 | 核心改动 |
|---|---|
src/utils/productConfig.ts |
5 个产品新增 iconImg;新增 PRODUCT_ICON_MAP;新增 getProductIconImg() 工具函数 |
src/types/index.ts |
ProductCategory 接口增加 iconImg?: string |
src/utils/store.ts |
addDesign() 存储 product.iconImg;designToOrder() 兼容旧数据(判断 /icon/ 前缀) |
src/pages/product/index.tsx |
Hero 无图时和弹窗中 emoji → Image + getProductIconImg() |
src/pages/product/index.scss |
新增 .hero-icon-img(100×100)、.modal-icon-img(48×48) |
src/pages/designList/index.tsx |
列表 item.productIcon 增加运行时映射兼容(旧数据查 PRODUCT_ICON_MAP) |
src/pages/orders/index.tsx |
同上,订单列表 icon 兼容旧数据 |
编译结果:webpack 5.91.0 compiled successfully in 23.03s,0 报错。
Batch 8 + 9 累计新增踩坑记录
| 坑 | 现象 | 解法 |
|---|---|---|
| Taro React onClick 事件崩溃 | 微信 3.17.0 灰度基础库下,点击 ThemeToggle 或菜单后控制台报 _num undefined,页面卡死 |
全量 onClick → onTap;Taro 小程序端 bindtap 比 onclick 稳定 |
| Fragment + map 导致事件引用丢失 | STATUS_MAP.map(() => <><View onTap={...}/><View/></>) 在 React diff 时 TaroElement 找不到对应事件对象 |
map 内不再使用 <>...</>,改用 <View className='status-group'> 包裹所有子节点 |
| 手动 page.onShow 热更新叠加 | useEffect 里 page.onShow = function(){...} 每次热重载都会多包一层,最终导致 onShow 无限递归或事件异常 |
改用 Taro React 标准 Hook useDidShow(() => sync()) |
| 旧数据 emoji 残留 | store.ts 之前存的是 product.icon(emoji),列表用 <Image src={item.productIcon}> 无法显示 |
① 写入层改为存 iconImg;② 渲染层增加运行时映射兜底 |
最终累计完成统计
| 批次 | 日期 | 完成项数 |
|---|---|---|
| Batch 1 | 早期 | 12 项 |
| Batch 2 | 早期 | 12 项 |
| Batch 3 | 早期 | 6 项 |
| Batch 4 | 2026-07-27 | 3 项 |
| Batch 5 | 2026-07-28 19:47 | 6 项 |
| Batch 6 | 2026-07-28 22:03 | 5 项 |
| Batch 7 | 2026-07-29 17:10 | 3 项 |
| Batch 8 | 2026-07-29 晚间 | 4 项 |
| Batch 9 | 2026-07-29 晚间 | 4 项 |
| Batch 10 | 2026-08-01 | 3 项 |
| 总计 | — | 58 项核心目标 ✅ |
Batch 10(2026-08-01)— 夜间模式字体 + 地址弹窗 + 空状态主题适配 ✅
背景:微信开发者工具夜间模式下订单详情页多处文字仍显示深色导致看不清;地址选择弹窗两侧间距不统一;收货地址空状态 emoji 未做夜间适配。
| 序号 | 任务 | 状态 |
|---|---|---|
| 1 | 订单详情页夜间模式文字颜色修复:补充 .status-text、.logistics-title/num、.meta-title/label/value、.timeline-status/time/desc 等 CSS 变量配色 |
✅ 完成 |
| 2 | 地址选择弹窗宽度统一:提取 .modal-overlay + .addr-picker-sheet 为 app.scss 全局统一样式;移除 checkout/orderDetail SCSS 中各自覆写的 width/radius 定义 |
✅ 完成 |
| 3 | 收货地址空状态主题适配:📍 emoji → <Image src='/icon/地址.png'>;空状态文字使用 CSS 变量;同步修复 orders/index.scss 中硬编码颜色 #5c3a3a / #b08d8d |
✅ 完成 |
文件变更:
| 文件 | 核心改动 |
|---|---|
src/app.scss |
新增全局 .modal-overlay(fixed 全屏遮罩)+ .addr-picker-sheet(底部圆角白底弹窗)统一样式 |
src/pages/orderDetail/index.scss |
新增 .status-text、.logistics-title/num、.meta-title/row/label/value、.timeline-status/time/desc 等 CSS 变量配色;移除旧 .addr-picker-sheet 覆写 |
src/pages/checkout/index.scss |
移除旧 .addr-picker-sheet 覆写,复用 app.scss 全局定义 |
src/pages/address/index.tsx |
空状态 📍 emoji → <Image src='/icon/地址.png' mode='aspectFit' /> |
src/pages/orders/index.scss |
.empty-text / .empty-sub 硬编码颜色改为 var(--text-primary) / var(--text-secondary) |
src/pages/address/index.scss |
新增 .empty-state/.empty-icon-img/.empty-text/.empty-sub 空状态样式(图标缩至 48px,文字使用 CSS 变量) |
编译结果:webpack 5.91.0 compiled successfully in 19.47s,0 报错。
一、历史修改回顾(Batch 1~10)
Batch 10(Completed)
夜间模式字体 + 地址弹窗统一 + 空状态主题适配。
Batch 11(2026-08-02)— 商品浏览页(Shop Page)沉浸式体验构建 ✅
背景:参考 ecommerce-demo.html 的交互式商品页设计(FLIP 转场 + 滚动驱动多阶段视差 + 主题色联动),为小程序新增独立「商品」tab,承担"看图种草→沉浸式详情→跳转购买链路"的推 discover 职能。
| 序号 | 任务 | 状态 |
|---|---|---|
| 1 | 新增「商品」tab 入口:底部导航从 4 tab 扩展为 5 tab(首页/商品/设计清单/订单/我的),新增 /icon/商品.png |
✅ 完成 |
| 2 | 构建 pages/shop/index.tsx:单页双容器结构(列表层 + 固定 overlay 详情层),点击卡片不走页面跳转,在当前页内完成沉浸式过渡 |
✅ 完成 |
| 3 | 滚动驱动视差动画:Hero 图上下边缘裁剪 → 整图上滑退出 → transition-band 吸顶显现 → 内容区延迟上浮淡入,全部绑定 ScrollView 进度 |
✅ 完成 |
| 4 | 产品主题色动态联动:每个产品新增 tone: [r,g,b],详情页背景、渐变遮罩、CTA 栏、吸顶条实时跟随产品色调变化(5 产品 5 色调) |
✅ 完成 |
| 5 | 商品文案全面升级:为 5 个产品补充 subtitle/story/scene/tags/specs/originalPrice,实现电商级长文案展示 |
✅ 完成 |
| 6 | 底部 CTA 衔接现有购买链路:"立即定制"按钮 navigateTo 到原有 /pages/product/index?id=xxx,不破坏已有业务流 |
✅ 完成 |
技术抉择与小程序适配:
| Demo 原版能力 | 小程序适配方案 | 原因 |
|---|---|---|
| FLIP 空间膨胀动画(卡片图直接膨胀到全屏) | B:卡片淡出 → Hero 淡入放大 | 小程序无实时 getBoundingClientRect FLIP 支持,且 position: fixed 在 ScrollView 内不稳定 |
window.scroll 驱动全局视差 |
<ScrollView scrollY> 内 onScroll 驱动 |
小程序页面级滚动不支持精细事件捕获,ScrollView 组件化更可控 |
CSS mask-image 渐变透明 |
伪元素 linear-gradient 遮罩 |
mask-image 在部分微信基础库/安卓机型支持不完整 |
| 统一深色沉浸式 | C:列表页走现有 Light/Dark 主题,详情 overlay 使用产品独立深色调 | 保持 tabBar / 状态栏在列表页与现有主题一致,详情页进入"画报模式" |
文件变更:
| 文件 | 核心改动 |
|---|---|
src/pages/shop/index.tsx |
新建:列表网格 + ScrollView 详情 overlay;useMemo 滚动进度映射多阶段动画;底部 CTA 跳转现有商品页 |
src/pages/shop/index.scss |
新建:2 列网格、Hero 固定层/裁剪/滑出、transition-band sticky、主题驱动色调、底部 CTA 毛玻璃栏 |
src/app.config.ts |
新增 pages/shop/index 路由;tabBar list 改为 5 项(首页/商品/设计清单/订单/我的) |
src/custom-tab-bar/index.tsx |
新增第 5 个 tab「商品」,icon: '/icon/商品.png' |
src/utils/productConfig.ts |
5 个产品全面升级:新增 subtitle / tone / story / scene / tags / specs / originalPrice;文案电商化 |
src/types/index.ts |
ProductCategory 接口扩展 8 个新字段:subtitle? / tone? / story? / scene? / tags? / specs? / originalPrice? |
src/icon/商品.png |
新增:底部导航「商品」tab 图标 |
踩坑记录(新增):
| 坑 | 现象 | 解法 |
|---|---|---|
| 小程序 inset 语法不支持 | SCSS 写 inset: 0 被直接透传,部分基础库不识别 |
显式写 top: 0; left: 0; right: 0; bottom: 0 |
| ScrollView 滚动事件不触发 | 默认 scrollEventThrottle 过大导致手感迟钝 |
显式声明 scrollEventThrottle={16} |
| tabBar 被详情 overlay 遮挡 | z-index: 200 不够,custom-tab-bar 为 z-index: 1000 |
详情 overlay 提升至 z-index: 1200 |
| 纯色背景 fallback | inset fallback 背景色叠加导致过渡不自然 |
overlay 使用 linear-gradient 伪元素实现边缘软化,兼容性更好 |
编译结果:webpack 5.91.0 compiled successfully in ~22s,0 报错。新增 icon 约 7KB,总包体积仍 < 2MB。
最终累计完成统计:
| 批次 | 日期 | 完成项数 |
|---|---|---|
| Batch 1 | 早期 | 12 项 |
| Batch 2 | 早期 | 12 项 |
| Batch 3 | 早期 | 6 项 |
| Batch 4 | 2026-07-27 | 3 项 |
| Batch 5 | 2026-07-28 19:47 | 6 项 |
| Batch 6 | 2026-07-28 22:03 | 5 项 |
| Batch 7 | 2026-07-29 17:10 | 3 项 |
| Batch 8 | 2026-07-29 晚间 | 4 项 |
| Batch 9 | 2026-07-29 晚间 | 4 项 |
| Batch 10 | 2026-08-01 | 3 项 |
| Batch 11 | 2026-08-02 | 6 项 |
| 总计 | — | 64 项核心目标 ✅ |
Batch 1(已完成)
全局主题切换、字体系统、tabBar重组、商品详情页、设计清单、效果确认页、后端技术栈文档。
Batch 2(已完成)
全局Context主题同步、登录系统、贴纸DIY、订单详情、Profile 5状态、自动筛选、图片路径修复。
Batch 3(已完成)
完善个人主页功能(收货地址、设置页、协议页)、ThemeToggle点击修复、商品图片显示修复、Profile状态跳转修复、LoginGuard登录守卫、用户数据 openid 隔离。
Batch 4(已完成)
主题黑白切换彻底修复(删除eventCenter多余监听)、Profile菜单登录后无反应修复、本地用户数据库(密码保护zhihui2024)。
Batch 5(已完成)
Profile菜单登录后无反应最终修复(增加onShow同步)、全部emoji替换为icon图片、首页品类卡片icon化、成品展示轮播图替换为实物照片、设计确认页/订单详情页增加收货地址栏、LoginGuard空状态居中。
Batch 6(已完成)
设计清单/订单页未登录提示居中、icon尺寸统一缩小、底部tabBar图标图片化、删除首页标题栏旁多余icon、清单/订单页列表icon图片化。
Batch 7(已完成)
Service企业专属icon缩至28px、settings未登录头像icon缩至40px、首页轮播图文字与图片分离并适配昼夜主题。
Batch 8(Completed)
Taro React 事件兼容修复:全量 onClick → onTap、Fragment 消除、useDidShow 替换、废弃 permission 清理。
Batch 9(Completed)
emoji → icon 图片彻底收尾:productConfig 增加 iconImg、store 写入层修复、运行时旧数据映射兼容、商品详情页弹窗去 emoji。
Batch 10(Completed)
夜间模式字体 + 地址弹窗统一 + 空状态主题适配。
Batch 11(Completed)
商品浏览页(Shop Page)沉浸式体验:新增「商品」tab(5 tab 架构)、单页双容器浏览页、滚动驱动视差动画、产品主题色联动、电商级长文案升级。