feat(r2): 阶段4 store 降级为离线兜底缓存层
- designList/address 两页缓存优先渲染(冷启动不空屏),联网后以服务端为准覆盖 - store/design.ts、store/address.ts 文件头注明缓存层语义(回写/兜底/旧数据不合并) - 流程文档勾选阶段 1-4 进度 Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+10
-8
@@ -89,7 +89,7 @@
|
||||
`ordered` **不落库**,由 `orderId != null` 派生;前端不提交这个状态。
|
||||
3. 确认 Prisma `Address` / `DesignList` 模型字段与契约一致,缺字段先出迁移。
|
||||
|
||||
### 阶段 1:后端补齐 CRUD(先做,前端等它)
|
||||
### 阶段 1:后端补齐 CRUD(先做,前端等它)✅(2026-09-12,后端提交 0a3c8e8)
|
||||
|
||||
改动范围:`src/addresses/`、`src/design-list/`,两个模块均已注册,骨架已存在。
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
4. `findOne` 补归属校验(当前 TODO)。
|
||||
5. Swagger 补全以上全部接口。
|
||||
|
||||
### 阶段 2:前端 API 层(页面不动)
|
||||
### 阶段 2:前端 API 层(页面不动)✅(2026-09-12,前端提交 8438fea)
|
||||
|
||||
1. `src/utils/api/address.ts`(现为空占位):实现
|
||||
`fetchAddresses / createAddress / updateAddress / deleteAddress / setDefaultAddress`。
|
||||
@@ -126,7 +126,7 @@
|
||||
3. `src/types/index.ts`:`AddressItem` 增加服务端字段(服务端 id、`createdAt` 等);
|
||||
`DesignItem.status` 补 `'processing'`、`DesignItem.orderId` 派生 `ordered` 展示。
|
||||
|
||||
### 阶段 3:切换页面(两个页面 + 三个写入点)
|
||||
### 阶段 3:切换页面(两个页面 + 三个写入点)✅(2026-09-12,前端提交 e557dbc;WCD 红线已按上文落实)
|
||||
|
||||
| 文件 | 改动 |
|
||||
|---|---|
|
||||
@@ -136,16 +136,18 @@
|
||||
| `pages/diy/index.tsx`(保存 designData) | `updateDesign` 走 API;`designData.category` 裁剪为 `{id, mask, tone}`(决策#2);贴纸本地图路径允许暂存(R4 派单前才持久化,契约约束 #1)。**WCD 红线**:`category.mask` 必须保留;`stickers[].rotation/zIndex` 随保存持久化;items 是全量替换——提交前必须基于服务端最新 designData(含 R4 写入的 `wordcloud` 分组)合并改动后整包提交,不得只传改动片段(见「WCD 格式硬性规定」) |
|
||||
| `pages/diy/stickerEdit/index.tsx` | 同上,保存贴纸改动走 API;同样受 WCD 红线约束(合并后整包提交,rotation/zIndex 带全) |
|
||||
|
||||
### 阶段 4:本地 store 降级改造
|
||||
### 阶段 4:本地 store 降级改造 ✅(2026-09-12)
|
||||
|
||||
`utils/store/address.ts`、`design.ts` 保留,但语义变为"离线兜底缓存":
|
||||
`utils/store/address.ts`、`design.ts` 保留,但语义变为"离线兜底缓存"(文件头已注明):
|
||||
|
||||
- API 成功 → 把服务端数据写回本地缓存(下次冷启动先展示缓存再刷新);
|
||||
- API 成功 → 把服务端数据写回本地缓存(下次冷启动先展示缓存再刷新,designList/address
|
||||
两页已实现缓存优先渲染);
|
||||
**designData 原样存储**:不得清洗 `wxfile://` 等本地贴纸路径、不得裁剪任何字段
|
||||
(WCD 硬性规定 #4/#5);
|
||||
- API 失败/断网 → 页面读缓存并可正常浏览,写操作提示失败;
|
||||
- 登录后首次进入:只读服务端,**不自动合并**本地旧数据(`smart_design_list_<openid>`
|
||||
与服务端并存的问题按路线文档风险节处理:忽略或提供一次性导入,默认忽略)。
|
||||
- 登录后首次进入:只读服务端,**不自动合并**本地旧数据(联网刷新以服务端为准覆盖缓存,
|
||||
`smart_design_list_<openid>` 与服务端并存的问题按路线文档风险节处理:忽略或提供
|
||||
一次性导入,默认忽略)。
|
||||
|
||||
### 阶段 5:联调与验收
|
||||
|
||||
|
||||
@@ -28,7 +28,9 @@ export default function AddressPage() {
|
||||
const [isDefault, setIsDefault] = useState(false)
|
||||
|
||||
const load = () => {
|
||||
// API 优先,成功后回写本地缓存;失败降级读缓存
|
||||
// 缓存优先展示(冷启动不空屏),再拉服务端刷新;
|
||||
// 刷新成功回写缓存并以服务端为准覆盖(旧本地数据不自动合并,route-r2 风险节)
|
||||
setList(getAddressList())
|
||||
fetchAddresses()
|
||||
.then(data => {
|
||||
setList(data)
|
||||
|
||||
@@ -41,7 +41,9 @@ export default function DesignListPage() {
|
||||
const [selected, setSelected] = useState<Set<string>>(new Set())
|
||||
|
||||
const load = useCallback(() => {
|
||||
// API 优先,成功后回写本地缓存(checkout 等页面仍读缓存);失败降级读缓存
|
||||
// 缓存优先展示(冷启动不空屏),再拉服务端刷新;
|
||||
// 刷新成功回写缓存并以服务端为准覆盖(旧本地数据不自动合并,route-r2 风险节)
|
||||
setList(getDesignList())
|
||||
fetchDesignList()
|
||||
.then(data => {
|
||||
setList(data)
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* 收货地址本地存储 —— R2 后降级为「离线兜底缓存」层(按 openid 隔离,见 keys.ts)。
|
||||
* 真实 CRUD 已走 utils/api/address.ts;本层职责:
|
||||
* - 页面 API 成功 → 回写缓存,供冷启动先展示与未迁移页面(checkout 等)读取;
|
||||
* - API 失败/断网 → 页面读缓存正常浏览;
|
||||
* - 联网刷新以服务端为准覆盖缓存,旧本地数据不做自动合并(route-r2 风险节:默认忽略)。
|
||||
*/
|
||||
import Taro from '@tarojs/taro'
|
||||
import type { AddressItem } from '../../types'
|
||||
import { key } from './keys'
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* 设计清单本地存储 —— R2 后降级为「离线兜底缓存」层(按 openid 隔离,见 keys.ts)。
|
||||
* 真实 CRUD 已走 utils/api/design.ts;本层职责:
|
||||
* - 页面 API 成功 → 回写缓存,供冷启动先展示与未迁移页面(checkout 等)读取;
|
||||
* - API 失败/断网 → 页面读缓存正常浏览;
|
||||
* - 联网刷新以服务端为准覆盖缓存,旧本地数据不做自动合并(route-r2 风险节:默认忽略)。
|
||||
*/
|
||||
import Taro from '@tarojs/taro'
|
||||
import type { DesignItem } from '../../types'
|
||||
import { assetUrl } from '../asset'
|
||||
|
||||
Reference in New Issue
Block a user