9.0 KiB
9.0 KiB
后端功能实施方案
概述
以下功能需要后端服务支持,目前应用是纯前端应用(使用 IndexedDB 本地存储)。要实现这些功能,需要搭建后端服务。
1. 多用户系统
需求分析
- 支持多个用户注册和登录
- 每个用户可以创建和管理自己的家族树
- 用户可以邀请其他用户协作编辑同一个家族树
技术方案
后端技术栈选择
- Node.js + Express 或 Next.js API Routes
- 数据库: PostgreSQL / MongoDB
- 认证: NextAuth.js / Auth0 / Supabase Auth
数据模型
// 用户表
interface User {
id: string
email: string
name: string
avatar?: string
createdAt: string
updatedAt: string
}
// 家族树表
interface FamilyTree {
id: string
name: string // 家族名称,如"李氏家族"
ownerId: string // 创建者
rootMemberId: string
createdAt: string
updatedAt: string
}
// 家族成员表(扩展现有 FamilyMember)
interface FamilyMember {
// ... 现有字段
treeId: string // 所属家族树
}
// 用户-家族树关系表(协作者)
interface TreeCollaborator {
id: string
treeId: string
userId: string
role: 'owner' | 'editor' | 'viewer'
invitedBy: string
invitedAt: string
}
API 端点
// 用户认证
POST /api/auth/register
POST /api/auth/login
POST /api/auth/logout
GET /api/auth/me
// 家族树管理
GET /api/trees // 获取用户的所有家族树
POST /api/trees // 创建新家族树
GET /api/trees/:id // 获取家族树详情
PUT /api/trees/:id // 更新家族树
DELETE /api/trees/:id // 删除家族树
// 协作者管理
GET /api/trees/:id/collaborators
POST /api/trees/:id/invite // 邀请协作者
DELETE /api/trees/:id/collaborators/:userId
2. 云端同步
需求分析
- 数据自动同步到云端
- 多设备数据同步
- 离线编辑,在线时自动同步
- 冲突检测和解决
技术方案
同步策略
1. 实时同步(推荐)
- 使用 WebSocket 或 Server-Sent Events
- 每次操作立即同步到服务器
- 其他客户端实时接收更新
2. 定时同步
- 每隔一定时间(如 30 秒)同步一次
- 适合网络不稳定的场景
3. 混合模式
- 在线时实时同步
- 离线时本地存储
- 重新联网时批量同步
数据同步流程
// 同步记录表
interface SyncRecord {
id: string
treeId: string
userId: string
action: 'create' | 'update' | 'delete'
entityType: 'member' | 'photo' | 'story'
entityId: string
data: any
timestamp: string
synced: boolean
}
// 同步 API
POST /api/sync/push // 推送本地更改
GET /api/sync/pull // 拉取远程更改
GET /api/sync/status // 获取同步状态
冲突解决策略
-
最后写入优先(Last Write Wins)
- 简单但可能丢失数据
-
版本控制
- 每条记录有版本号
- 冲突时提示用户选择
-
操作转换(Operational Transformation)
- 复杂但最准确
- 类似 Google Docs 的协作编辑
实现示例(使用 Supabase)
// lib/sync.ts
import { createClient } from '@supabase/supabase-js'
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
// 推送本地更改到云端
export async function pushChanges(changes: SyncRecord[]) {
const { data, error } = await supabase
.from('sync_records')
.insert(changes)
if (error) throw error
return data
}
// 从云端拉取更改
export async function pullChanges(treeId: string, lastSyncTime: string) {
const { data, error } = await supabase
.from('sync_records')
.select('*')
.eq('treeId', treeId)
.gt('timestamp', lastSyncTime)
.order('timestamp', { ascending: true })
if (error) throw error
return data
}
// 实时订阅更改
export function subscribeToChanges(treeId: string, callback: (change: any) => void) {
return supabase
.channel(`tree:${treeId}`)
.on('postgres_changes', {
event: '*',
schema: 'public',
table: 'family_members',
filter: `treeId=eq.${treeId}`
}, callback)
.subscribe()
}
3. 权限管理
需求分析
- 不同用户有不同的操作权限
- 支持角色:所有者、编辑者、查看者
- 细粒度权限控制
权限模型
// 角色定义
enum Role {
OWNER = 'owner', // 所有者:完全控制
EDITOR = 'editor', // 编辑者:可以增删改
VIEWER = 'viewer' // 查看者:只读
}
// 权限定义
interface Permission {
canView: boolean
canCreate: boolean
canUpdate: boolean
canDelete: boolean
canInvite: boolean
canExport: boolean
canManageSettings: boolean
}
// 角色权限映射
const rolePermissions: Record<Role, Permission> = {
owner: {
canView: true,
canCreate: true,
canUpdate: true,
canDelete: true,
canInvite: true,
canExport: true,
canManageSettings: true,
},
editor: {
canView: true,
canCreate: true,
canUpdate: true,
canDelete: false,
canInvite: false,
canExport: true,
canManageSettings: false,
},
viewer: {
canView: true,
canCreate: false,
canUpdate: false,
canDelete: false,
canInvite: false,
canExport: true,
canManageSettings: false,
},
}
权限检查中间件
// middleware/auth.ts
import { NextRequest, NextResponse } from 'next/server'
export async function requireAuth(req: NextRequest) {
const token = req.headers.get('authorization')
if (!token) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
// 验证 token
const user = await verifyToken(token)
if (!user) {
return NextResponse.json({ error: 'Invalid token' }, { status: 401 })
}
return user
}
export async function requirePermission(
userId: string,
treeId: string,
permission: keyof Permission
) {
// 获取用户在该家族树的角色
const collaborator = await db.treeCollaborators.findFirst({
where: { userId, treeId }
})
if (!collaborator) {
throw new Error('No access to this tree')
}
const permissions = rolePermissions[collaborator.role]
if (!permissions[permission]) {
throw new Error(`Permission denied: ${permission}`)
}
return true
}
前端权限控制
// hooks/usePermissions.ts
import { useAuth } from './useAuth'
import { useFamilyTree } from './useFamilyTree'
export function usePermissions() {
const { user } = useAuth()
const { currentTree } = useFamilyTree()
const [permissions, setPermissions] = useState<Permission>()
useEffect(() => {
if (user && currentTree) {
fetchPermissions(user.id, currentTree.id).then(setPermissions)
}
}, [user, currentTree])
return permissions
}
// 使用示例
function MemberForm() {
const permissions = usePermissions()
if (!permissions?.canCreate) {
return <div>您没有权限添加成员</div>
}
return <form>...</form>
}
推荐的实施方案
方案 A:使用 Supabase(最简单)
优点:
- 开箱即用的认证、数据库、实时订阅
- 无需自己搭建后端
- 免费额度足够个人使用
- 自动处理权限和 RLS(Row Level Security)
步骤:
- 创建 Supabase 项目
- 设计数据库表结构
- 配置 RLS 规则
- 集成 Supabase 客户端
- 迁移现有 IndexedDB 数据
方案 B:使用 Next.js API Routes + PostgreSQL
优点:
- 完全控制后端逻辑
- 可以部署在 Vercel
- 适合需要复杂业务逻辑的场景
步骤:
- 添加 API Routes
- 配置数据库(Vercel Postgres / Neon)
- 实现认证逻辑(NextAuth.js)
- 实现同步 API
- 添加权限中间件
方案 C:使用 Firebase
优点:
- Google 生态系统
- 实时数据库
- 免费额度较大
步骤:
- 创建 Firebase 项目
- 配置 Firestore
- 设置 Firebase Auth
- 配置安全规则
- 集成 Firebase SDK
估算工作量
| 功能 | 使用 Supabase | 自建后端 |
|---|---|---|
| 多用户系统 | 2-3 天 | 5-7 天 |
| 云端同步 | 3-5 天 | 7-10 天 |
| 权限管理 | 2-3 天 | 5-7 天 |
| 总计 | 1-2 周 | 3-4 周 |
下一步行动
- 选择技术方案:推荐 Supabase(快速、简单)
- 数据迁移计划:设计从 IndexedDB 到云端的迁移方案
- 逐步实施:
- 第一阶段:多用户系统
- 第二阶段:云端同步
- 第三阶段:权限管理
注意事项
-
数据安全:
- 使用 HTTPS
- 加密敏感数据
- 定期备份
-
性能优化:
- 使用缓存
- 分页加载
- 图片 CDN
-
用户体验:
- 离线优先
- 乐观更新
- 友好的错误提示
建议:如果您想快速实现这些功能,我推荐使用 Supabase。我可以帮您:
- 设计 Supabase 数据库结构
- 实现认证和权限
- 添加实时同步功能
是否需要我开始实施?