Files
Pawer/docs/taro-miniapp-design.md
2026-06-18 14:33:50 +08:00

744 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 汪圈 HTML 转 Taro 微信小程序设计文档
## 1. 背景与目标
当前参考稿位于 `refrence_html/`,共 6 个 HTML 文件:
| HTML 文件 | 目标页面 | 说明 |
| --- | --- | --- |
| `plaza.html` | `pages/plaza` | 广场信息流、搜索、频道 Tab、话题 Chip、点赞动效 |
| `nearby.html` | `pages/nearby` | 附近地图、宠物 Pin、可拖拽底部 Sheet、匹配喜欢动效 |
| `messages.html` | `pages/messages` | 消息页、活跃用户横滑、会话列表、未读状态 |
| `profile.html` | `pages/profile` | 我的页面、资料卡、宠物档案、偏好设置 |
| `publish.html` | `pages/publish` | 发布动态、图片网格、话题、可见范围 Sheet、发布成功弹层 |
| `wangquan-ios-launcher.html` | `pages/launcher`,可选 | 设计总览页,仅用于开发预览或品牌落地页,不进入主 Tab |
迁移目标:
1. 使用 Taro + React + TypeScript 构建微信小程序。
2. 保持参考 HTML 的内屏视觉、色彩、间距、圆角、阴影、字体层级和动效一致。
3. 适配微信小程序运行环境,使用自定义导航、真实安全区和微信胶囊位置。
4. 页面拆成可维护组件,避免把 HTML 直接平铺到单个页面。
5. 使用微信云开发模式:页面通过云函数访问业务数据,云数据库和云存储承载帖子、宠物、消息和媒体。
6. 输出可直接落地的目录结构、组件边界、云函数规划和迁移步骤。
## 2. 视觉一致性边界
参考 HTML 是桌面浏览器里的 iPhone 预览稿,包含 `stage-wrap``.phone`、刘海、状态栏、底部 home indicator 等展示壳。
小程序实现时采用以下边界:
- 保留 `.screen` 内的产品视觉深紫背景、顶部内容、卡片、Tab、FAB、底部导航、Sheet、Toast、地图和发布页结构。
- 不把桌面预览用的外层 `.stage-wrap``.phone` 手机壳放进小程序页面,避免用户在微信里看到二次手机框。
- 使用 `navigationStyle: custom`,通过 `Taro.getSystemInfoSync()``Taro.getMenuButtonBoundingClientRect()` 计算状态栏、安全区和胶囊避让。
- 原 HTML 的 `status-bar` 抽象为 `CustomNavBar` 的安全区占位。正式小程序不模拟运营商、电量图标;视觉稿比对模式可通过 `VISUAL_PARITY_MODE` 开关显示模拟状态栏。
- 原 HTML 的 `home-indicator` 抽象为 `SafeAreaBottom`,在真机上优先使用系统安全区,视觉稿比对模式可显示白色横条。
## 3. 技术选型
| 层 | 选择 | 用途 |
| --- | --- | --- |
| 框架 | Taro 3.x/4.x | 编译到微信小程序 |
| UI | React + TypeScript | 页面和组件开发 |
| 样式 | SCSS + Taro pxTransform | 从 HTML CSS 迁移并统一设计 token |
| 状态 | React hooks + 轻量 store | 页面局部状态、用户会话、未读数量 |
| 数据 | 微信云开发云函数 + 云数据库 | Feed、宠物、消息、匹配、用户资料 |
| 媒体 | 云存储 | 图片、视频封面、头像 |
| 地图视觉 | CSS + 绝对定位,必要时 Canvas | 还原 `nearby.html` 的装饰地图 |
| 图标 | 原 SVG 路径资产化 | 统一转成 iconfont 或 PNG/SVG asset避免直接依赖 Web SVG DOM |
关键约束:
- Taro 页面只能使用小程序支持的组件和样式能力HTML 中的 `div/button/input/textarea/a` 需要迁移为 `View/Button/Input/Textarea/Navigator/Text/Image/ScrollView`
- 小程序没有 DOM API所有 `querySelector``classList``dataset` 直接操作改为 React state 驱动。
- `pointerdown/pointermove/pointerup` 改为 `onTouchStart/onTouchMove/onTouchEnd`
- `hover` 效果改为 `hoverClass``active` 状态或点击反馈。
- CSS 变量统一转 SCSS token减少不同基础库对 CSS custom properties 的兼容风险。
## 4. 小程序路由与页面
### 4.1 `app.config.ts`
```ts
export default defineAppConfig({
pages: [
'pages/plaza/index',
'pages/nearby/index',
'pages/publish/index',
'pages/messages/index',
'pages/profile/index'
],
window: {
navigationStyle: 'custom',
backgroundColor: '#14102b',
backgroundTextStyle: 'dark'
},
tabBar: {
custom: true,
color: '#8a7aab',
selectedColor: '#d8b4ff',
backgroundColor: '#14102b',
list: [
{ pagePath: 'pages/plaza/index', text: '广场' },
{ pagePath: 'pages/nearby/index', text: '附近' },
{ pagePath: 'pages/messages/index', text: '消息' },
{ pagePath: 'pages/profile/index', text: '我的' }
]
}
})
```
说明:
- `publish` 不是原生 tabBar 项,而是中间 FAB 跳转页。
- 使用自定义 `BottomTabBar` 实现 HTML 中间凸起发布按钮。
- `launcher` 可作为开发预览页放入 `subPackages/dev/pages/launcher`,不放入正式主包。
### 4.2 页面职责
| 页面 | 组件构成 | 主要状态 | 云函数 |
| --- | --- | --- | --- |
| `pages/plaza` | `CustomNavBar``SearchBar``SegmentedTabs``TopicChips``PostCard``FeedAdCard``LikeToast``BottomTabBar` | 当前频道、话题、帖子列表、点赞状态、toast 显示 | `feedList``postLike``postFavorite` |
| `pages/nearby` | `NearbyMap``PetPin``MapControls``LocationPill``NearbySheet``NearbyPetCard``MatchToast``BottomTabBar` | 选中宠物、Sheet 高度、筛选项、喜欢 toast | `nearbyPets``locationUpdate``matchLike` |
| `pages/messages` | `CustomNavBar``SearchBar``MessageTabs``ActiveUserRow``ConversationItem``BottomTabBar` | 消息分类、会话列表、未读状态 | `messageList``conversationRead` |
| `pages/profile` | `ProfileHero``StatsRow``ActionButtons``PetShelf``QuickGrid``PreferenceList``BottomTabBar` | 用户资料、宠物列表、开关状态 | `profileGet``profileUpdate``petList` |
| `pages/publish` | `PublishNav``ComposerAuthor``ComposerTextarea``MediaGrid``TopicSelector``PublishOptions``ComposerToolbar``VisibilitySheet``SuccessModal` | 文本、图片、话题、宠物、位置、可见范围、草稿 | `postCreate``draftSave``petList` |
## 5. 组件拆分
### 5.1 基础组件
| 组件 | 路径 | 说明 |
| --- | --- | --- |
| `PageShell` | `src/components/layout/PageShell` | 页面背景、滚动容器、安全区和底部留白 |
| `CustomNavBar` | `src/components/layout/CustomNavBar` | 自定义顶部栏,计算状态栏与胶囊避让 |
| `BottomTabBar` | `src/components/navigation/BottomTabBar` | 复刻 HTML 的底部 Tab 和中间发布 FAB |
| `Icon` | `src/components/ui/Icon` | 统一图标入口,映射原 SVG 到资产或 iconfont |
| `Avatar` | `src/components/ui/Avatar` | 渐变头像、在线点、宠物角标 |
| `Chip` | `src/components/ui/Chip` | 话题、筛选、标签选中态 |
| `SegmentedTabs` | `src/components/ui/SegmentedTabs` | 顶部频道切换和下划线 |
| `SearchBar` | `src/components/ui/SearchBar` | 搜索框视觉复用 |
| `ToastOverlay` | `src/components/feedback/ToastOverlay` | 点赞、匹配等居中放大 toast |
| `BottomSheet` | `src/components/feedback/BottomSheet` | 发布页可见范围选择、通用底部弹层 |
| `Switch` | `src/components/forms/Switch` | 复刻开关 knob 动效 |
### 5.2 业务组件
| 组件 | 路径 | 对应 HTML |
| --- | --- | --- |
| `PostCard` | `src/features/feed/components/PostCard` | `plaza.html``.post` |
| `FeedAdCard` | `src/features/feed/components/FeedAdCard` | `plaza.html``.ad-card` |
| `NearbyMap` | `src/features/nearby/components/NearbyMap` | `nearby.html` 的地图层、道路、水域、绿地 |
| `PetPin` | `src/features/nearby/components/PetPin` | `nearby.html``.pin` |
| `NearbySheet` | `src/features/nearby/components/NearbySheet` | `nearby.html` 的可拖拽 `.sheet` |
| `NearbyPetCard` | `src/features/nearby/components/NearbyPetCard` | `nearby.html` 的宠物卡片 |
| `ActiveUserRow` | `src/features/messages/components/ActiveUserRow` | `messages.html` 的活跃用户横向列表 |
| `ConversationItem` | `src/features/messages/components/ConversationItem` | `messages.html``.conv` |
| `ProfileHero` | `src/features/profile/components/ProfileHero` | `profile.html``.hero` |
| `PetShelf` | `src/features/profile/components/PetShelf` | `profile.html` 的毛孩子列表 |
| `PreferenceList` | `src/features/profile/components/PreferenceList` | `profile.html` 的设置列表 |
| `PublishComposer` | `src/features/publish/components/PublishComposer` | `publish.html` 的输入区 |
| `MediaGrid` | `src/features/publish/components/MediaGrid` | `publish.html` 的图片网格 |
| `PublishOptions` | `src/features/publish/components/PublishOptions` | `publish.html` 的关联宠物、位置、可见范围、草稿 |
| `ComposerToolbar` | `src/features/publish/components/ComposerToolbar` | `publish.html` 的底部工具栏 |
## 6. 动画与交互迁移方案
| 参考行为 | HTML 实现 | Taro 实现 |
| --- | --- | --- |
| 点赞爱心 toast | `.like-toast.show` + `scale` transition | `useToast()` 控制 `show` class`setTimeout` 480ms 隐藏 |
| 附近匹配 toast | `.match-toast.show` | 复用 `ToastOverlay`,传入 `heart` 图标 |
| 发布页底部 Sheet | `@keyframes slideUp` | `BottomSheet` 使用 `animation: slideUp 280ms cubic-bezier(0.2, 0, 0, 1)` |
| 附近 Sheet 拖拽 | `pointer` 事件 + CSS 变量 `--sheet-h` | `useDragSheet` 用 touch 事件维护高度snap 点按设计稿 60/220/420/620 px 等比转 rpx |
| 地图定位脉冲 | `@keyframes pulse` | 保留 WXSS keyframes`View` 伪元素改为子节点 |
| Tab/Chip 选中 | `classList.toggle('act')` | React state 控制 `activeKey``selectedIds` |
| 发布按钮启用 | `textarea input` + disabled | `content.length > 0 && content.length <= 2000` |
| 开关滑块 | `.switch.off``::after` | `Switch` 组件通过 `checked` class 驱动 knob 位移 |
| 图片删除 | DOM remove | `mediaIds.filter()` 更新列表 |
| 搜索区域点击缩放 | 直接写 `style.transform` | `pressed` state + class180ms 后还原 |
注意:
- 微信小程序不支持所有 Web 伪元素场景。复杂 `::before/::after` 需要改为显式 `View` 子节点,例如电池图标、地图 pulse、底部 home indicator。
- `position: sticky` 在发布页底部工具栏中改为 `position: fixed`,结合 `padding-bottom: env(safe-area-inset-bottom)` 避免被系统区域遮挡。
- `backdrop-filter` 兼容性需真机确认;无法完全稳定时,使用半透明背景 + 较高模糊感渐变替代。
## 7. 设计 Token
从 HTML 抽出统一 token放入 `src/styles/tokens.scss`
```scss
$bg: #14102b;
$bg-warm: #1c1442;
$surface: #1f1742;
$surface-2: #251c4a;
$surface-hi: #2d2255;
$fg: #f0e9ff;
$fg-2: #c7b9e0;
$muted: #8a7aab;
$border: #2e234a;
$border-soft: #251c40;
$accent: #d8b4ff;
$accent-2: #ffb3c8;
$primary: #ffd9a8;
$primary-on: #2a1d10;
$success: #8fe5b5;
$warn: #ffd166;
$danger: #ff8a9b;
$map-bg: #0e0a22;
$font-display: "Space Grotesk", "Inter", system-ui, sans-serif;
$font-body: "Inter", system-ui, -apple-system, "PingFang SC", "Microsoft YaHei", sans-serif;
$radius-sm: 10px;
$radius-md: 16px;
$radius-lg: 24px;
$radius-pill: 9999px;
```
迁移策略:
- 原样保留色值、透明度、渐变角度和阴影参数。
- Taro 构建配置按 390px 参考宽度做 px 到 rpx 的转换;如果当前 Taro 版本对自定义 `designWidth: 390` 支持不理想,则用 750 基准并执行 `750 / 390` 的机械转换。
- 字体在微信里不能稳定加载 Google Fonts。正式版以系统字体 + `PingFang SC` 为准;若必须完全还原 `Space Grotesk/Inter`,将字体文件放入云存储或本地资产并通过 `Taro.loadFontFace` 加载。
## 8. 数据模型
### 8.1 TypeScript 类型
```ts
export interface UserProfile {
_id: string
openid: string
nickname: string
avatarUrl?: string
location?: string
yearsWithPets?: number
level: number
stats: {
posts: number
following: number
followers: number
favorites: number
}
preferences: {
notifications: boolean
nearbyVisible: boolean
}
}
export interface Pet {
_id: string
ownerId: string
name: string
species: 'dog' | 'cat' | 'other'
breed: string
ageText: string
avatarFileId?: string
tags: string[]
location?: GeoPoint
online?: boolean
}
export interface Post {
_id: string
authorId: string
petId?: string
content: string
topics: string[]
media: MediaAsset[]
locationText?: string
visibility: 'public' | 'friends' | 'private'
counts: {
likes: number
comments: number
shares: number
favorites: number
}
likedByMe?: boolean
favoritedByMe?: boolean
createdAt: number
}
export interface Conversation {
_id: string
type: 'single' | 'group' | 'system'
title: string
avatarKey?: string
preview: string
unreadCount: number
pinned?: boolean
muted?: boolean
updatedAt: number
}
```
### 8.2 云数据库集合
| 集合 | 用途 | 关键索引 |
| --- | --- | --- |
| `users` | 用户基础资料、偏好、统计 | `openid` 唯一 |
| `pets` | 宠物档案 | `ownerId``location` |
| `posts` | 动态内容 | `visibility + createdAt``authorId + createdAt``topics` |
| `postLikes` | 点赞关系 | `postId + userId` 唯一 |
| `postFavorites` | 收藏关系 | `postId + userId` 唯一 |
| `comments` | 评论 | `postId + createdAt` |
| `locations` | 附近页定位快照 | `userId``geo` |
| `matches` | 附近喜欢/匹配 | `fromUserId + toPetId` |
| `conversations` | 会话元信息 | `memberIds``updatedAt` |
| `messages` | 消息内容 | `conversationId + createdAt` |
| `notifications` | 系统通知 | `userId + read + createdAt` |
| `drafts` | 发布草稿 | `userId + updatedAt` |
## 9. 云函数设计
统一入口原则:
- 小程序端通过 `Taro.cloud.callFunction` 调用云函数。
- 除云存储上传文件外,业务写操作都走云函数,云函数内校验 `openid`、参数、权限和数据归属。
- 查询函数返回页面所需 DTO减少小程序端多次拼接请求。
- 点赞、收藏、计数更新在云函数内用事务或幂等逻辑完成。
| 云函数 | 入参 | 出参 | 说明 |
| --- | --- | --- | --- |
| `login` | `{ userInfo? }` | `{ openid, user }` | 获取 openid初始化或更新用户 |
| `feedList` | `{ channel, topic?, cursor?, pageSize }` | `{ list, nextCursor }` | 广场/关注/附近信息流 |
| `postCreate` | `{ content, topics, media, petId?, location?, visibility }` | `{ postId }` | 发布动态并更新统计 |
| `postLike` | `{ postId, liked }` | `{ liked, likes }` | 幂等点赞/取消点赞 |
| `postFavorite` | `{ postId, favorited }` | `{ favorited, favorites }` | 幂等收藏 |
| `draftSave` | `{ draft }` | `{ draftId, updatedAt }` | 保存发布草稿 |
| `nearbyPets` | `{ location, filters }` | `{ list }` | 附近宠物列表和地图 pin |
| `locationUpdate` | `{ location, visible }` | `{ ok }` | 更新自己的附近可见状态 |
| `matchLike` | `{ petId }` | `{ matched }` | 附近页喜欢/匹配 |
| `messageList` | `{ tab, cursor? }` | `{ activeUsers, conversations, nextCursor }` | 消息页聚合数据 |
| `conversationRead` | `{ conversationId }` | `{ unreadCount }` | 标记会话已读 |
| `profileGet` | `{ userId? }` | `{ user, pets }` | 获取我的/他人资料 |
| `profileUpdate` | `{ patch }` | `{ user }` | 更新资料和偏好 |
| `petList` | `{ ownerId? }` | `{ list }` | 宠物列表 |
| `petSave` | `{ pet }` | `{ petId }` | 创建或更新宠物 |
### 9.1 云开发工程配置
`project.config.json` 需要显式声明 Taro 构建产物和云函数根目录:
```json
{
"miniprogramRoot": "dist/",
"cloudfunctionRoot": "cloudfunctions/",
"setting": {
"urlCheck": true,
"es6": true,
"postcss": true,
"minified": true
}
}
```
`src/app.tsx` 中初始化云开发环境:
```ts
import Taro from '@tarojs/taro'
const cloudEnv = process.env.TARO_APP_CLOUD_ENV
if (process.env.TARO_ENV === 'weapp' && cloudEnv) {
Taro.cloud.init({
env: cloudEnv,
traceUser: true
})
}
```
环境 ID 不写死在页面代码里,放到 `config/dev.ts``config/prod.ts``.env`,方便区分开发、测试和正式环境。
云函数目录采用单函数目录结构,便于微信开发者工具识别和单独部署:
```text
cloudfunctions/
login/
index.ts
package.json
feedList/
index.ts
package.json
postCreate/
index.ts
package.json
postLike/
index.ts
package.json
postFavorite/
index.ts
package.json
draftSave/
index.ts
package.json
nearbyPets/
index.ts
package.json
locationUpdate/
index.ts
package.json
matchLike/
index.ts
package.json
messageList/
index.ts
package.json
conversationRead/
index.ts
package.json
profileGet/
index.ts
package.json
profileUpdate/
index.ts
package.json
petList/
index.ts
package.json
petSave/
index.ts
package.json
```
## 10. 客户端服务层
客户端不在页面里直接散落 `callFunction`,统一封装:
```ts
export async function callCloud<TReq extends object, TRes>(
name: CloudFunctionName,
data: TReq
): Promise<TRes> {
const res = await Taro.cloud.callFunction({ name, data })
return res.result as TRes
}
```
服务分层:
```text
src/services/
cloud.ts # callCloud、错误归一化、loading guard
auth.service.ts # login
feed.service.ts # feedList/postLike/postFavorite
publish.service.ts # postCreate/draftSave/uploadMedia
nearby.service.ts # nearbyPets/locationUpdate/matchLike
message.service.ts # messageList/conversationRead
profile.service.ts # profileGet/profileUpdate/petList/petSave
```
页面只依赖 service 和 hooks不直接依赖云函数细节。
## 11. 完整目录结构
```text
Pet/
project.config.json
project.private.config.json
package.json
tsconfig.json
config/
index.ts
dev.ts
prod.ts
src/
app.config.ts
app.scss
app.tsx
assets/
icons/
compass.svg
heart.svg
message.svg
plus.svg
user.svg
search.svg
map-pin.svg
more.svg
close.svg
images/
README.md
components/
layout/
PageShell/
index.tsx
index.scss
CustomNavBar/
index.tsx
index.scss
SafeAreaBottom/
index.tsx
index.scss
navigation/
BottomTabBar/
index.tsx
index.scss
tabConfig.ts
ui/
Avatar/
index.tsx
index.scss
Chip/
index.tsx
index.scss
Icon/
index.tsx
iconMap.ts
index.scss
SearchBar/
index.tsx
index.scss
SegmentedTabs/
index.tsx
index.scss
Switch/
index.tsx
index.scss
feedback/
BottomSheet/
index.tsx
index.scss
ToastOverlay/
index.tsx
index.scss
features/
feed/
components/
FeedAdCard/
index.tsx
index.scss
PostCard/
index.tsx
index.scss
feed.types.ts
nearby/
components/
MapControls/
index.tsx
index.scss
NearbyMap/
index.tsx
index.scss
NearbyPetCard/
index.tsx
index.scss
NearbySheet/
index.tsx
index.scss
PetPin/
index.tsx
index.scss
nearby.types.ts
messages/
components/
ActiveUserRow/
index.tsx
index.scss
ConversationItem/
index.tsx
index.scss
message.types.ts
profile/
components/
PetShelf/
index.tsx
index.scss
PreferenceList/
index.tsx
index.scss
ProfileHero/
index.tsx
index.scss
QuickGrid/
index.tsx
index.scss
StatsRow/
index.tsx
index.scss
profile.types.ts
publish/
components/
ComposerToolbar/
index.tsx
index.scss
MediaGrid/
index.tsx
index.scss
PublishComposer/
index.tsx
index.scss
PublishOptions/
index.tsx
index.scss
VisibilitySheet/
index.tsx
index.scss
SuccessModal/
index.tsx
index.scss
publish.types.ts
hooks/
useCloudQuery.ts
useDragSheet.ts
useSystemLayout.ts
useToast.ts
useUploadMedia.ts
pages/
plaza/
index.config.ts
index.tsx
index.scss
nearby/
index.config.ts
index.tsx
index.scss
publish/
index.config.ts
index.tsx
index.scss
messages/
index.config.ts
index.tsx
index.scss
profile/
index.config.ts
index.tsx
index.scss
services/
auth.service.ts
cloud.ts
feed.service.ts
message.service.ts
nearby.service.ts
profile.service.ts
publish.service.ts
store/
session.store.ts
ui.store.ts
styles/
animations.scss
mixins.scss
tokens.scss
utilities.scss
types/
cloud.ts
domain.ts
global.d.ts
utils/
date.ts
px.ts
validators.ts
cloudfunctions/
login/
index.ts
package.json
feedList/
index.ts
package.json
postCreate/
index.ts
package.json
postLike/
index.ts
package.json
postFavorite/
index.ts
package.json
draftSave/
index.ts
package.json
nearbyPets/
index.ts
package.json
locationUpdate/
index.ts
package.json
matchLike/
index.ts
package.json
messageList/
index.ts
package.json
conversationRead/
index.ts
package.json
profileGet/
index.ts
package.json
profileUpdate/
index.ts
package.json
petList/
index.ts
package.json
petSave/
index.ts
package.json
docs/
taro-miniapp-design.md
refrence_html/
messages.html
nearby.html
plaza.html
profile.html
publish.html
wangquan-ios-launcher.html
```
## 12. 迁移步骤
### 第 1 阶段:工程初始化
1. 使用 Taro React TypeScript 模板初始化项目。
2. 配置微信小程序编译、`navigationStyle: custom`、自定义 tabBar。
3. 配置云开发环境 ID`app.tsx` 中初始化 `Taro.cloud.init({ env })`
4. 建立 `styles/tokens.scss``animations.scss` 和基础布局组件。
### 第 2 阶段:静态视觉还原
1. 先迁移 `plaza`,抽出全局 `PageShell``CustomNavBar``BottomTabBar``PostCard`
2. 再迁移 `messages``profile`复用头像、搜索、tab、switch。
3. 迁移 `publish`,重点处理 `Textarea`、底部 fixed toolbar、Sheet 和成功弹层。
4. 迁移 `nearby`重点处理地图层、pin 布局、底部拖拽 Sheet。
### 第 3 阶段:交互和动画
1. 全部 DOM 操作替换为 state。
2. 完整还原点赞 toast、匹配 toast、Sheet slideUp、地图 pulse、switch knob、FAB active。
3. 用微信开发者工具和真机分别确认 `backdrop-filter`、fixed 底部、safe-area、键盘弹起表现。
### 第 4 阶段:云函数接入
1. 先实现 `login``feedList``profileGet`,让页面能加载真实用户态。
2. 接入 `postLike``postFavorite`,验证计数幂等。
3. 接入 `postCreate` 和媒体上传,发布后跳转广场并展示新动态。
4. 接入 `nearbyPets``matchLike``messageList``conversationRead`
5. 补充数据库权限规则:客户端默认只读必要公开数据,写入走云函数。
### 第 5 阶段:验收
1. 与参考 HTML 做逐页截图对比,基准宽度 390px。
2. 检查 320/375/390/414 宽度下内容不重叠、不溢出。
3. 真机检查 iPhone 刘海屏、普通屏、安卓微信的状态栏、胶囊和底部安全区。
4. 云函数使用测试环境数据跑通发布、点赞、匹配、消息已读、资料更新。
## 13. 风险与处理
| 风险 | 影响 | 处理 |
| --- | --- | --- |
| HTML 使用大量 inline SVG | 微信小程序无法像 Web 一样直接渲染全部 SVG DOM | 将图标资产化为 iconfont 或图片资产;地图 SVG 改为 CSS/Canvas 组合 |
| Google Fonts 不可直接加载 | 字体观感略有差异 | 本地/云存储加载字体,或确认系统字体可接受 |
| `backdrop-filter` 兼容性 | 玻璃模糊效果可能变弱 | 半透明深色背景 + 渐变阴影兜底 |
| `position: sticky`/伪元素差异 | 发布页底部栏和装饰元素偏移 | fixed + safe area伪元素改显式节点 |
| 附近页拖拽性能 | touch move 频繁 setState 可能卡顿 | 用 `useRef` 缓存拖拽值,必要时节流,最终 snap 时 setState |
| 视觉 100% 与真实小程序系统 UI 冲突 | 状态栏/胶囊不可完全控制 | 明确只对产品内屏做 100% 还原;系统区域用真实安全区适配 |
## 14. 参考文档
- Taro 官方文档:`https://docs.taro.zone/`
- Taro 云开发 API`https://docs.taro.zone/docs/apis/cloud/`
- 微信小程序云开发文档:`https://developers.weixin.qq.com/miniprogram/dev/wxcloud/basis/getting-started.html`
- 微信云函数调用:`https://developers.weixin.qq.com/miniprogram/dev/wxcloud/reference-sdk-api/functions/callFunction/client.callFunction.html`