# flutter_desen_chat
**Repository Path**: hlw422/flutter_desen_chat
## Basic Information
- **Project Name**: flutter_desen_chat
- **Description**: 基于 Flutter 开发的跨平台即时通讯应用,专注桌面端体验
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2026-07-06
- **Last Updated**: 2026-07-07
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ChatDesen - 即时通讯桌面应用
基于 Flutter 开发的跨平台即时通讯应用,专注桌面端体验
---
## 目录
- [功能特性](#功能特性)
- [技术栈](#技术栈)
- [项目结构](#项目结构)
- [快速开始](#快速开始)
- [功能详解](#功能详解)
- [API 接口](#api-接口)
- [架构设计](#架构设计)
---
## 功能特性
### 聊天核心
- **实时消息** — WebSocket 双向通信,支持心跳检测与自动重连
- **消息类型** — 文本、图片(预览/下载)、文件(上传/下载)
- **消息转发** — 支持文本/图片/文件转发给好友,自动区分消息类型
- **表情发送** — 80+ 表情,9 大分类(常用/微笑/爱心/手势/庆祝/情绪/动物/餐饮/自然)
- **图片预览** — 全屏查看器,支持左右切换、缩放、下载
### 好友系统
- **好友管理** — 搜索用户、添加好友、好友请求处理(接受/拒绝)
- **在线状态** — 实时显示好友在线/离线状态
- **智能判断** — 搜索时自动标记已是好友的用户,避免重复添加
- **通讯录** — 好友列表、待处理请求一目了然
### 桌面端优化
- **响应式布局** — 三栏自适应布局(侧导航 | 会话列表 | 聊天面板),最小宽度保护
- **右键菜单** — 统一的右键上下文菜单(复制、转发、下载、打开浏览器等)
- **文件选择器** — 使用系统原生目录选择器保存下载文件
- **紧凑模式** — 窗口缩小时自动隐藏非必要元素,防止溢出
### 其他特性
- **多端适配** — Mobile / Tablet / Desktop 三套 UI 自适应切换
- **离线消息** — 上线时自动拉取离线期间的消息
- **Token 持久化** — 自动登录,Token 本地安全存储
- **Material Design 3** — 全新视觉风格,跟随系统主题色
---
## 技术栈
| 类别 | 技术 | 版本 |
|------|------|------|
| 框架 | Flutter (SDK) | ^3.10.7 |
| 语言 | Dart | ^3.10 |
| HTTP | http | ^1.2.1 |
| WebSocket | web_socket_channel | ^2.4.5 |
| 状态管理 | Provider | ^6.1.2 |
| 本地存储 | shared_preferences | ^2.2.3 |
| 文件选择 | file_picker | ^8.0.0 |
| 链接启动 | url_launcher | ^6.3.0 |
| 路径服务 | path_provider | ^2.1.6 |
---
## 项目结构
```
lib/
├── main.dart # 应用入口 + MultiProvider 配置
├── config/
│ └── api_config.dart # API 基地址 / 接口路径 / 超时配置
├── models/ # 数据模型
│ ├── user.dart # 用户模型 (id, username, nickname, isOnline)
│ ├── chat.dart # 会话模型 (peer, lastMessage, unreadCount, isPinned)
│ └── message.dart # 消息模型 (MessageType: text/image/file; MessageOwner: self/other)
├── providers/
│ └── auth_provider.dart # 全局认证状态管理 (单例, 登录/注册/Token持久化)
├── services/ # 业务服务层
│ ├── api_client.dart # HTTP 客户端封装 (GET/POST/上传, Token注入, 统一错误处理)
│ ├── auth_service.dart # 认证服务 (登录/注册/Token管理)
│ ├── chat_service.dart # 聊天服务 (搜索用户/好友CRUD/消息收发/文件上传)
│ ├── websocket_service.dart # WebSocket 服务 (心跳/重连/消息广播流)
│ └── ws_service.dart # WebSocket 备用服务 (简化回调式 API)
└── pages/ # 页面层
├── main_layout.dart # 主布局 (三栏桌面布局, 最小宽度保护, 响应式导航)
├── loign_page.dart / regin_page.dart # 登录/注册路由入口
└── screens/
├── login/ # 登录页面 (mobile/tablet/desktop 三套适配)
├── chat/
│ ├── desktop_chat_list.dart # 桌面会话列表 (API实时加载)
│ ├── desktop_chat_panel.dart # ★ 核心聊天面板 (WS订阅+REST双发+附件+转发)
│ ├── mobile_chat_list.dart # 移动会话列表
│ └── ...
├── contacts/
│ ├── desktop_contacts.dart # 桌面通讯录 (搜索+好友请求+好友列表)
│ └── ...
├── profile/
│ ├── desktop_profile.dart # 桌面个人资料页
│ └── ...
└── widgets/ # 可复用组件
├── chat_bubble.dart # ★ 消息气泡 (文本/图片/文件/右键菜单/转发/全屏图)
├── chat_input_bar.dart # 输入栏 (文本+表情面板[8分类]+附件菜单)
└── add_friend_dialog.dart # 添加好友对话框 (搜索+去重+状态管理)
```
---
## 快速开始
### 环境要求
- Flutter SDK >= 3.10.7
- Dart SDK >= 3.10
- 支持 Windows / macOS / Linux 桌面平台
### 安装运行
```bash
# 1. 克隆项目
git clone
cd fluuter_desen
# 2. 安装依赖
flutter pub get
# 3. 运行项目 (桌面端)
flutter run -d windows # Windows
flutter run -d macos # macOS
flutter run -d linux # Linux
# 4. 或运行 Web 版
flutter run -d chrome
```
### 构建发布版本
```bash
# Windows
flutter build windows
# macOS
flutter build macos
# Linux
flutter build linux
```
---
## 功能详解
### 聊天系统
#### 消息收发流程
```
用户输入 → _sendMessage()
├─→ WebSocket.sendChatMessage() ← 实时推送(快)
├─→ ChatService.sendPrivateMessage() ← REST 保底(可靠)
└─→ 追加到 _items 列表 ← 本地即时显示
```
#### WebSocket 消息过滤逻辑
```dart
// 只接受两类消息:
// 1. 来自当前聊天对象的消息 (fromUserId == peerId) → 显示为对方消息
// 2. 自己发给聊天对象的消息回显 (fromUserId == myId) → 显示为自己的消息
// 同时校验 to_user_id 确保不混入其他会话
```
#### 图片/文件发送流程
```
选择文件 → FilePicker.pickFiles()
↓
上传到服务器 → ChatService.uploadFile()
↓
获取 URL → 构造 content JSON:
图片: {"url": "https://..."}
文件: {"filename":"a.pdf","url":"https://...", "size":1024}
↓
双通道发送:
WebSocket: sendChatMessage(msgType: 'image'/'file')
REST: sendPrivateImage() / sendPrivateFile()
```
#### 转发机制
```
右键/长按 → 转发对话框(好友列表)
↓ 选择目标好友
根据原消息类型分别调用接口:
文本 → sendPrivateMessage(content)
图片 → sendPrivateImage(url)
文件 → sendPrivateFile(name, url, size)
↓ 回调通知 DesktopChatPanel
追加到本地列表 (如果目标是当前聊天对象) ✓
```
### 表情系统
```
表情按钮点击 → 展开/收起 260px 高度面板
├── 分类标签栏 (9个分类横向滚动)
│ ├── 常用 | 😀 微笑 | 🎉 庆祝 | ❤️ 爱心
│ ├── 👍 手势 | 🤣 搞笑 | 😢 悲伤 | 😡 生气 | 🙏 其他
└── 表情网格 (8列 × 10行 = 80个表情)
点击 → 插入到光标位置 (TextEditingController.selection)
```
### 右键菜单体系
```
所有消息统一右键菜单:
├── 复制 (文本复制内容 / 图片复制链接 / 文件复制文件名)
├── [仅文本] 全选
├── 转发... → 弹出好友选择对话框
├── ──────────────
├── [仅图片] 在浏览器打开 / 下载图片 / 复制链接
└── [仅文件] 下载文件 (弹出目录选择器)
```
### 桌面端布局保护
```
主布局最小宽度计算:
导航栏(72px) + 会话列表(280px) + 分割线(1px) + 聊天面板(min 360px) = 713px
窗口 < 713px 时:
→ 启用水平滚动条 (Scrollbar + SingleChildScrollView)
→ 不再无限压缩右侧聊天面板
聊天面板内部:
→ 头部 LayoutBuilder: <200px 进入紧凑模式 (缩小头像/隐藏按钮)
→ ConstrainedBox minWidth: 360px
```
---
## API 接口
> 后端基础地址: `http://106.14.236.60:8091`
>
> WebSocket 地址: `ws://106.14.236.60:8091/ws`
### 认证接口
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/register` | 用户注册 |
| POST | `/api/login` | 用户登录 |
### 用户接口
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/users/search?keyword=xxx` | 搜索用户 |
| GET | `/api/friends` | 获取好友列表 |
| POST | `/api/friends/request` | 发送好友请求 |
| GET | `/api/friends/requests` | 获取待处理好友请求 |
| POST | `/api/friends/requests/{id}` | 处理好友请求 |
### 消息接口
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/messages/private/{userId}` | 获取私聊历史 |
| GET | `/api/messages/offline` | 获取离线消息 |
| POST | `/api/messages/send` | 发送消息 (支持 msg_type: text/image/file) |
### 文件接口
| 方法 | 路径 | 说明 |
|------|------|------|
| POST | `/api/upload` | 上传文件 (multipart/form-data) |
### 群组接口(预留)
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | `/api/groups` | 获取群组列表 |
| POST | `/api/groups` | 加入群组 |
| GET | `/api/groups/{id}/members` | 获取群成员 |
---
## 架构设计
### 数据流架构
```
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Widget层 │ ←──→ │ Provider层 │ ←──→ │ Service层 │
│ (UI展示) │ │ (状态管理) │ │ (业务逻辑) │
└──────────────┘ └──────────────┘ └──────┬───────┘
│
┌────────────────────┼────────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ HTTP API │ │WebSocket │ │ Local │
│ (REST) │ │ (实时) │ │ Storage │
└──────────┘ └──────────┘ └──────────┘
```
### 关键设计决策
1. **WebSocket + REST 双通道**: 消息通过 WS 实时推送 + REST 保底存储,确保消息送达
2. **Provider 单例模式**: AuthProvider 作为全局状态管理,登录态在所有页面共享
3. **响应式页面路由**: 每个功能模块有 mobile / tablet / desktop 三套实现,通过路由自动分发
4. **消息类型 JSON 编码**: 图片和文件消息的元信息以 JSON 格式存储在 content 字段中
5. **本地即时显示**: 发送消息后立即追加到列表,不等待服务器确认(乐观更新)
---
## 版本历史
### v1.0.0
- ✅ 用户注册/登录系统
- ✅ 好友管理(搜索/添加/请求处理)
- ✅ 私聊消息(文本/图片/文件)
- ✅ WebSocket 实时通信 + 心跳重连
- ✅ 表情包发送(8分类80+表情)
- ✅ 消息转发(支持全部消息类型)
- ✅ 右键上下文菜单
- ✅ 文件上传/下载(目录自选)
- ✅ 全屏图片预览(左右切换)
- ✅ 桌面端三栏自适应布局
- ✅ 最小宽度保护 + 紧凑模式
- ✅ 离线消息拉取
---
## License
MIT License
---
## 致谢
- [Flutter](https://flutter.dev/) - 跨平台 UI 框架
- [Material Design 3](https://m3.material.io/) - 设计规范