7. 社交动态应用(technical-architecture)

alt

1. 架构设计

alt

2. 技术栈描述

  • 前端框架: React@18 + Vite
  • 状态管理: Zustand@4
  • UI组件库: Ant Design@5 + TailwindCSS@3
  • 富文本编辑器: react-quill + quill-image-resize-module
  • 初始化工具: vite-init
  • 后端服务: Supabase(提供认证、数据库、存储)
  • 实时通信: Supabase Realtime
  • 图片处理: browser-image-compression

3. 路由定义

路由路径 页面用途
/ 动态首页,展示好友动态和推荐内容
/publish 发布动态页面,支持富文本编辑和媒体上传
/post/:id 动态详情页面,展示完整内容和评论区
/messages 消息列表页面,展示私信对话和通知
/chat/:userId 聊天页面,支持一对一实时对话
/friends 好友列表页面,支持搜索和分组管理
/profile/:userId 个人主页,展示用户信息和动态
/profile/settings 设置页面,账号和隐私设置
/login 登录页面,支持手机号/邮箱登录
/register 注册页面,新用户注册流程

4. 数据模型

4.1 数据库实体关系图

erDiagram
  USERS ||--o{ POSTS : creates
  USERS ||--o{ COMMENTS : writes
  USERS ||--o{ LIKES : gives
  USERS ||--o{ MESSAGES : sends
  USERS ||--o{ FRIENDSHIPS : has
  POSTS ||--o{ COMMENTS : receives
  POSTS ||--o{ LIKES : receives
  POSTS ||--o{ POST_MEDIA : contains
  
  USERS {
    uuid id PK
    string email UK
    string phone UK
    string username UK
    string password_hash
    string nickname
    string avatar_url
    string bio
    string background_image
    boolean is_verified
    timestamp created_at
    timestamp updated_at
  }
  
  POSTS {
    uuid id PK
    uuid user_id FK
    string content
    json media_urls
    string visibility
    json tags
    string location
    integer like_count
    integer comment_count
    timestamp created_at
    timestamp updated_at
  }
  
  COMMENTS {
    uuid id PK
    uuid post_id FK
    uuid user_id FK
    uuid parent_id FK
    string content
    integer like_count
    timestamp created_at
  }
  
  LIKES {
    uuid id PK
    uuid user_id FK
    uuid post_id FK
    uuid comment_id FK
    timestamp created_at
  }
  
  MESSAGES {
    uuid id PK
    uuid sender_id FK
    uuid receiver_id FK
    string content
    string message_type
    boolean is_read
    timestamp created_at
  }
  
  FRIENDSHIPS {
    uuid id PK
    uuid user_id FK
    uuid friend_id FK
    string status
    timestamp created_at
  }
  
  POST_MEDIA {
    uuid id PK
    uuid post_id FK
    string media_url
    string media_type
    integer sort_order
    timestamp created_at
  }

4.2 数据定义语言

用户表 (users)

-- 创建用户表
CREATE TABLE users (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  email VARCHAR(255) UNIQUE,
  phone VARCHAR(20) UNIQUE,
  username VARCHAR(50) UNIQUE NOT NULL,
  password_hash VARCHAR(255) NOT NULL,
  nickname VARCHAR(100) NOT NULL,
  avatar_url TEXT,
  bio TEXT,
  background_image TEXT,
  is_verified BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_users_username ON users(username);
CREATE INDEX idx_users_email ON users(email);
CREATE INDEX idx_users_phone ON users(phone);

动态表 (posts)

-- 创建动态表
CREATE TABLE posts (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  media_urls JSONB DEFAULT '[]',
  visibility VARCHAR(20) DEFAULT 'public' CHECK (visibility IN ('public', 'friends', 'private')),
  tags JSONB DEFAULT '[]',
  location VARCHAR(255),
  like_count INTEGER DEFAULT 0,
  comment_count INTEGER DEFAULT 0,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_posts_user_id ON posts(user_id);
CREATE INDEX idx_posts_created_at ON posts(created_at DESC);
CREATE INDEX idx_posts_visibility ON posts(visibility);

评论表 (comments)

-- 创建评论表
CREATE TABLE comments (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  parent_id UUID REFERENCES comments(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  like_count INTEGER DEFAULT 0,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_comments_post_id ON comments(post_id);
CREATE INDEX idx_comments_user_id ON comments(user_id);
CREATE INDEX idx_comments_parent_id ON comments(parent_id);

点赞表 (likes)

-- 创建点赞表
CREATE TABLE likes (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  post_id UUID REFERENCES posts(id) ON DELETE CASCADE,
  comment_id UUID REFERENCES comments(id) ON DELETE CASCADE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  UNIQUE(user_id, post_id),
  UNIQUE(user_id, comment_id)
);

-- 创建索引
CREATE INDEX idx_likes_user_post ON likes(user_id, post_id);
CREATE INDEX idx_likes_user_comment ON likes(user_id, comment_id);

消息表 (messages)

-- 创建消息表
CREATE TABLE messages (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  sender_id UUID REFERENCES users(id) ON DELETE CASCADE,
  receiver_id UUID REFERENCES users(id) ON DELETE CASCADE,
  content TEXT NOT NULL,
  message_type VARCHAR(20) DEFAULT 'text' CHECK (message_type IN ('text', 'image', 'video', 'audio')),
  is_read BOOLEAN DEFAULT FALSE,
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 创建索引
CREATE INDEX idx_messages_sender ON messages(sender_id);
CREATE INDEX idx_messages_receiver ON messages(receiver_id);
CREATE INDEX idx_messages_created_at ON messages(created_at DESC);

好友关系表 (friendships)

-- 创建好友关系表
CREATE TABLE friendships (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID REFERENCES users(id) ON DELETE CASCADE,
  friend_id UUID REFERENCES users(id) ON DELETE CASCADE,
  status VARCHAR(20) DEFAULT 'pending' CHECK (status IN ('pending', 'accepted', 'blocked')),
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  UNIQUE(user_id, friend_id)
);

-- 创建索引
CREATE INDEX idx_friendships_user_id ON friendships(user_id);
CREATE INDEX idx_friendships_friend_id ON friendships(friend_id);
CREATE INDEX idx_friendships_status ON friendships(status);

5. 权限配置

-- 基本权限授予
GRANT SELECT ON users TO anon;
GRANT SELECT ON posts TO anon;
GRANT SELECT ON comments TO anon;
GRANT SELECT ON likes TO anon;

-- 认证用户权限
GRANT ALL PRIVILEGES ON users TO authenticated;
GRANT ALL PRIVILEGES ON posts TO authenticated;
GRANT ALL PRIVILEGES ON comments TO authenticated;
GRANT ALL PRIVILEGES ON likes TO authenticated;
GRANT ALL PRIVILEGES ON messages TO authenticated;
GRANT ALL PRIVILEGES ON friendships TO authenticated;
GRANT ALL PRIVILEGES ON post_media TO authenticated;

-- RLS策略示例(posts表)
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;

-- 查看公开动态
CREATE POLICY "View public posts" ON posts
  FOR SELECT USING (visibility = 'public');

-- 查看好友动态
CREATE POLICY "View friends posts" ON posts
  FOR SELECT USING (
    visibility = 'friends' AND 
    user_id IN (
      SELECT friend_id FROM friendships 
      WHERE user_id = auth.uid() AND status = 'accepted'
    )
  );

-- 用户只能修改自己的动态
CREATE POLICY "Users can update own posts" ON posts
  FOR UPDATE USING (user_id = auth.uid());

-- 用户只能删除自己的动态
CREATE POLICY "Users can delete own posts" ON posts
  FOR DELETE USING (user_id = auth.uid());

6. 状态管理设计

6.1 Zustand Store结构

// 用户状态
interface UserStore {
  currentUser: User | null;
  isAuthenticated: boolean;
  login: (credentials) => Promise<void>;
  logout: () => void;
  updateProfile: (data) => Promise<void>;
}

// 动态状态
interface PostStore {
  posts: Post[];
  currentPost: Post | null;
  isLoading: boolean;
  fetchPosts: (page: number) => Promise<void>;
  createPost: (data) => Promise<void>;
  likePost: (postId: string) => void;
  addComment: (postId: string, content: string) => void;
}

// 消息状态
interface MessageStore {
  conversations: Conversation[];
  currentChat: Message[];
  unreadCount: number;
  fetchConversations: () => Promise<void>;
  fetchChatHistory: (userId: string) => Promise<void>;
  sendMessage: (receiverId: string, content: string) => void;
  markAsRead: (messageId: string) => void;
}

// 好友状态
interface FriendStore {
  friends: User[];
  pendingRequests: User[];
  searchResults: User[];
  fetchFriends: () => Promise<void>;
  sendFriendRequest: (userId: string) => void;
  acceptRequest: (requestId: string) => void;
  searchUsers: (query: string) => Promise<void>;
}

7. 实时功能实现

7.1 Supabase Realtime配置

// 消息实时订阅
const subscribeToMessages = (userId: string) => {
  return supabase
    .channel('messages')
    .on('postgres_changes', 
      { event: 'INSERT', schema: 'public', table: 'messages', 
        filter: `receiver_id=eq.${userId}` },
      (payload) => {
        // 处理新消息
        messageStore.addMessage(payload.new);
      }
    )
    .subscribe();
};

// 动态实时更新
const subscribeToPosts = () => {
  return supabase
    .channel('posts')
    .on('postgres_changes', 
      { event: 'INSERT', schema: 'public', table: 'posts' },
      (payload) => {
        // 添加新动态到列表
        postStore.addPost(payload.new);
      }
    )
    .subscribe();
};

8. 性能优化策略

8.1 前端优化

  • 虚拟滚动:动态列表使用react-window实现虚拟滚动
  • 图片懒加载:使用Intersection Observer实现图片懒加载
  • 代码分割:按路由进行代码分割,减少首屏加载时间
  • 缓存策略:利用Zustand持久化存储用户数据和常用状态

8.2 数据库优化

  • 索引优化:为常用查询字段创建复合索引
  • 分页查询:使用游标分页避免深度分页性能问题
  • 数据预加载:提前加载用户可能访问的数据
  • 连接池配置:合理配置数据库连接池参数
20大项目拆解:从PRD到架构 文章被收录于专栏

想独立做出一个完整的项目却不知从何下手?本专栏是你的终极路线图。我们由浅入深,通过20个经典项目案例,手把手带你走过产品构思、需求撰写、功能设计、技术选型、架构搭建的全过程。从&ldquo;音乐播放器&rdquo;到&ldquo;企业后台&rdquo;,你将逐步建立对软件系统的完整认知,完成从理论到实践、从单一技能到复合能力的飞跃。

全部评论

相关推荐

点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务