# chatwithu **Repository Path**: zhengbaitech/chatwithu ## Basic Information - **Project Name**: chatwithu - **Description**: Stellar Chat · 极简玻璃态网页聊天应用 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-14 - **Last Updated**: 2026-10-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Stellar Chat · 极简玻璃态网页聊天应用 一个开箱即用的全栈聊天应用,包含 **Spring Boot 后端**、**React 用户端**、**Vue 管理端**,UI 走"极简主义玻璃态(Glassmorphism)+ 星空蓝紫渐变"路线。 ``` chat-app/ ├── backend/ # Spring Boot 3 + JPA + MySQL + Redis + WebSocket + JWT ├── user-web/ # React 18 + Vite + Tailwind + Zustand └── admin-web/ # Vue 3 + Vite + Tailwind + Pinia ``` --- ## ✨ 功能一览 ### 后端 (Spring Boot) - ✅ 用户端 / 管理端 双登录入口(JWT 鉴权,白名单放行登录/注册/验证码) - ✅ 图形验证码(**Redis**,一次性,5 分钟 TTL) - ✅ 用户注册 / 登录 / 获取当前用户(`/api/auth/*`) - ✅ 好友增删查(`/api/friends`) - ✅ 消息历史 / 标记已读(`/api/messages`) - ✅ 会话列表(最后一条消息 + 未读数)(`/api/conversations`) - ✅ WebSocket 实时聊天(`/ws/chat?token=xxx`),支持心跳 / 重连 / 已读回执 - ✅ 在线用户状态 **Redis 镜像**(`chat:online:user:{userId}`,TTL 60s,可跨实例查询) - ✅ 管理员登录、首页统计(总用户 / 今日新增 / 活跃 / 在线)、用户管理(列表 / 启停)(`/api/admin/*`) - ✅ 内置管理员账号 `admin / admin123`(启动时自动创建,不可新增/修改) - ✅ **MySQL 8** 数据库 + **HikariCP** 连接池 - ✅ **Redis** 缓存(Lettuce 客户端,自带连接池) ### 用户端 (React) - ✅ 玻璃态登录 / 注册页(渐变光晕背景、悬浮动效、涟漪按钮) - ✅ 头像上传 + 圆形裁剪(react-easy-crop,强制 100×100 base64) - ✅ 三栏聊天布局: 左侧 300px(对话/好友 Tab + 搜索) / 中间消息流 / 右侧 280px(资料,可折叠) - ✅ 气泡消息(自己渐变紫蓝 / 对方浅灰),时间戳分组,新消息从右滑入 - ✅ 在线状态点(绿色脉冲)、未读小红点 - ✅ WebSocket 实时收发 + 自动重连 + 心跳 - ✅ 滚动条紫条化、按钮涟漪 ### 管理端 (Vue) - ✅ 玻璃态登录页 - ✅ 首页概览: 总用户 / 今日新增 / 活跃 / 在线 + 在线用户列表(10s 自动刷新) - ✅ 用户管理: 分页、关键字搜索、启停账号 --- ## 🚀 快速启动 > 建议 Node ≥ 18,Java 17+,本地需先起 **MySQL 8** 和 **Redis 6+**。 ### 0. 准备 MySQL 和 Redis ```bash # 1) MySQL:创建库(密码按你本机改) mysql -uroot -proot -e "CREATE DATABASE IF NOT EXISTS chatdb DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" # 2) Redis:本地 6379 端口直接可用 redis-cli ping # 期待 PONG ``` > MySQL/Redis 地址和密码在 `backend/src/main/resources/application.yml` 顶部可改: > ```yaml > spring: > datasource: > url: jdbc:mysql://localhost:3306/chatdb?... > username: root > password: root # ← 改成你的 > data: > redis: > host: localhost > port: 6379 > password: # ← 没密码留空 > ``` ### 1. 启动后端 (端口 8080) ```bash cd backend mvn spring-boot:run ``` 首次启动会: - 自动在 MySQL `chatdb` 库建表(`t_user` / `t_friend` / `t_message`) - 自动初始化管理员账号 `admin / admin123` - 监听 `http://localhost:8080` 健康检查: ```bash curl http://localhost:8080/api/admin/captcha ``` 返回 `{"code":0, ...}` 即正常。验证码会进 Redis,可以用 `redis-cli KEYS 'chat:captcha:*'` 看到。 ### 2. 启动用户端 (端口 5173) ```bash cd user-web npm install npm run dev ``` 打开 http://localhost:5173 ### 3. 启动管理端 (端口 5174) ```bash cd admin-web npm install npm run dev ``` 打开 http://localhost:5174,使用 `admin / admin123` 登录。 --- ## 🧪 体验流程 1. 用户端注册两个账号(注意密码需含大小写字母 + 数字且 ≤ 20 位) 2. 用账号 A 登录,需要把账号 B 加为好友(目前 UI 暂只展示"好友",可在代码中通过接口 `POST /api/friends { targetId }` 添加,或等后续版本加搜索加好友 UI) 3. 双方互发消息,实时收到 4. 管理端 `admin/admin123` 登录,首页可看到在线用户,用户管理可启停账号 > 💡 想快速看效果?手动添加好友: 打开两个浏览器(一个无痕窗口),分别用 A、B 登录,从 A 浏览器控制台执行: > ```js > fetch('/api/friends', { method:'POST', headers:{'Content-Type':'application/json','Authorization':'Bearer '+localStorage.token}, body: JSON.stringify({ targetId: })}).then(r=>r.json()).then(console.log) > ``` > 然后在 A 的好友列表就能看到 B。 --- ## 📡 关键 API 一览 | 模块 | 方法 | 路径 | 说明 | | --- | --- | --- | --- | | 认证 | GET | `/api/auth/captcha` | 获取图形验证码 | | 认证 | POST | `/api/auth/register` | 用户注册(必填: 用户名/昵称/密码/确认密码 + 验证码) | | 认证 | POST | `/api/auth/login` | 用户端登录(返回 token + 用户信息) | | 认证 | GET | `/api/auth/me` | 当前登录用户 | | 好友 | GET/POST/DELETE | `/api/friends` | 好友增删查 | | 会话 | GET | `/api/conversations` | 会话列表(peer + lastMessage + unread) | | 消息 | GET | `/api/messages/{peerId}` | 拉历史消息(分页) | | 消息 | POST | `/api/messages/{peerId}/read` | 标记已读 | | 管理 | GET/POST | `/api/admin/captcha` `/api/admin/login` | 管理员登录 | | 管理 | GET | `/api/admin/overview` | 首页统计 | | 管理 | GET | `/api/admin/users` | 用户分页(关键字) | | 管理 | POST | `/api/admin/users/{id}/toggle-status` | 启停 | | WS | WS | `/ws/chat?token=...` | 实时消息通道 | ### WebSocket 协议 客户端发送: ```json { "type": "MSG", "toUserId": 2, "content": "hi", "msgType": "TEXT" } { "type": "READ", "peerId": 2 } { "type": "PING" } ``` 服务端推送: ```json { "type": "CONNECTED", "userId": 1 } { "type": "MSG", "id": 100, "conversationId": "1_2", "fromUserId": 1, "toUserId": 2, "content": "hi", "sendTime": "..." } { "type": "MSG_ACK", "data": { ...同上 } } { "type": "PONG", "ts": 1700000000000 } ``` --- ## 🎨 设计 Token (用户端 `src/styles/index.css` 集中定义) | 变量 | 含义 | | --- | --- | | `--color-primary` | 品牌主色 `#4F46E5` | | `--color-accent` | 品牌辅色 `#7C3AED` | | `--color-ink-50` | 卡片底色 `#F8FAFC` | | `--color-ink-200` | 对方气泡 `#E2E8F0` | | `--glass-blur` | 玻璃模糊半径 20px | | `--radius-xl` | 卡片圆角 24px | 动画:`blob`(光晕呼吸)、`fade-in`(登录卡片淡入)、`slide-in-right`(消息滑入)、`ripple`(按钮涟漪)。 --- ## 🔧 常见问题 - **WebSocket 连不上?** 确保 `vite.config.js` 的 `/ws` 代理正确,后端 `JwtHandshakeInterceptor` 需在 `URL ?token=` 传 JWT。 - **MySQL 密码不对?** 改 `backend/src/main/resources/application.yml` 的 `spring.datasource.password`。 - **Redis 验证码没生效?** 看后端启动日志是否连上 Redis(`LettuceConnectionFactory` 初始化),`redis-cli KEYS 'chat:captcha:*'` 应该能看到。 - **数据重置?** 清 MySQL 表 + 清 Redis: ```sql USE chatdb; TRUNCATE t_friend; TRUNCATE t_message; TRUNCATE t_user; ``` ```bash redis-cli --scan --pattern 'chat:*' | xargs -r redis-cli DEL ``` 然后重启后端,`admin` 账号会自动重建。 - **想跑集群(多实例 WS 路由)?** 当前实现是"本实例推送 + 跨实例靠下次上线拉历史补偿"。要真正跨实例实时推送,可以加 Redis Pub/Sub(`chat:ws:dispatch:{serverId}`),在 `WebSocketSessionManager` 里订阅 + publish。要的话告诉我,我加一版。 - **生产部署?** `mvn package` 生成 jar,然后 `user-web` / `admin-web` 用 `npm run build` 产 dist,nginx 反代即可。 --- ## 📁 目录速览 ``` chat-app/ ├── backend/ │ ├── pom.xml │ └── src/main/java/com/chat/ │ ├── ChatApplication.java # 启动类 │ ├── config/ # WebConfig / WebSocketConfig / DataInitializer / RedisConfig │ ├── controller/ # Auth / Friend / Message / Conversation / Admin / GlobalExceptionHandler │ ├── dto/ # 请求/响应对象 │ ├── entity/ # JPA 实体(User/Friend/Message) │ ├── repository/ # JPA Repository │ ├── security/ # JwtAuthFilter │ ├── service/ # 业务层 │ ├── util/ # JwtUtil / CaptchaUtil (Redis) / UserContext │ └── websocket/ # WebSocketAuthHandler / JwtHandshakeInterceptor / WebSocketSessionManager (Redis 在线状态) ├── user-web/ # React 18 用户端 │ ├── package.json │ ├── vite.config.js │ ├── tailwind.config.js │ ├── index.html │ └── src/ │ ├── main.jsx # 入口 │ ├── App.jsx # 路由 │ ├── api/ # axios 封装 │ ├── store/ # zustand │ ├── components/ # Avatar / AvatarCropper / RippleButton │ ├── pages/ # Login / Register / Chat │ ├── styles/index.css # ⭐ 所有颜色变量 / 玻璃 / 动画 │ └── utils/ # crop / ripple / ws └── admin-web/ # Vue 3 管理端 ├── package.json ├── vite.config.js ├── tailwind.config.js ├── index.html └── src/ ├── main.js ├── App.vue ├── api.js ├── store/auth.js ├── router/index.js ├── pages/ # Login / Layout / Dashboard / Users └── styles.css ``` Have fun 💫