Java个人综合项目——萌部落社区V2.0

访问社区 · 项目结构 · [Java 业务](#Java 业务) · [AI 模块](#AI 模块) · 本地启动

萌部落是一个前后端分离的兴趣社区,把发帖、评论、收藏、聊天、成长、游戏和 AI 陪伴放在一套体系里。

https://github.com/pluchon/mengmeng_forum

核心功能展示

项目总览

#mermaid-svg-OFK9XZjOg6ff05dC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-OFK9XZjOg6ff05dC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-OFK9XZjOg6ff05dC .error-icon{fill:#552222;}#mermaid-svg-OFK9XZjOg6ff05dC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-OFK9XZjOg6ff05dC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-OFK9XZjOg6ff05dC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-OFK9XZjOg6ff05dC .marker.cross{stroke:#333333;}#mermaid-svg-OFK9XZjOg6ff05dC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-OFK9XZjOg6ff05dC p{margin:0;}#mermaid-svg-OFK9XZjOg6ff05dC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-OFK9XZjOg6ff05dC .cluster-label text{fill:#333;}#mermaid-svg-OFK9XZjOg6ff05dC .cluster-label span{color:#333;}#mermaid-svg-OFK9XZjOg6ff05dC .cluster-label span p{background-color:transparent;}#mermaid-svg-OFK9XZjOg6ff05dC .label text,#mermaid-svg-OFK9XZjOg6ff05dC span{fill:#333;color:#333;}#mermaid-svg-OFK9XZjOg6ff05dC .node rect,#mermaid-svg-OFK9XZjOg6ff05dC .node circle,#mermaid-svg-OFK9XZjOg6ff05dC .node ellipse,#mermaid-svg-OFK9XZjOg6ff05dC .node polygon,#mermaid-svg-OFK9XZjOg6ff05dC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-OFK9XZjOg6ff05dC .rough-node .label text,#mermaid-svg-OFK9XZjOg6ff05dC .node .label text,#mermaid-svg-OFK9XZjOg6ff05dC .image-shape .label,#mermaid-svg-OFK9XZjOg6ff05dC .icon-shape .label{text-anchor:middle;}#mermaid-svg-OFK9XZjOg6ff05dC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-OFK9XZjOg6ff05dC .rough-node .label,#mermaid-svg-OFK9XZjOg6ff05dC .node .label,#mermaid-svg-OFK9XZjOg6ff05dC .image-shape .label,#mermaid-svg-OFK9XZjOg6ff05dC .icon-shape .label{text-align:center;}#mermaid-svg-OFK9XZjOg6ff05dC .node.clickable{cursor:pointer;}#mermaid-svg-OFK9XZjOg6ff05dC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-OFK9XZjOg6ff05dC .arrowheadPath{fill:#333333;}#mermaid-svg-OFK9XZjOg6ff05dC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-OFK9XZjOg6ff05dC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-OFK9XZjOg6ff05dC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OFK9XZjOg6ff05dC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-OFK9XZjOg6ff05dC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OFK9XZjOg6ff05dC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-OFK9XZjOg6ff05dC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-OFK9XZjOg6ff05dC .cluster text{fill:#333;}#mermaid-svg-OFK9XZjOg6ff05dC .cluster span{color:#333;}#mermaid-svg-OFK9XZjOg6ff05dC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-OFK9XZjOg6ff05dC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-OFK9XZjOg6ff05dC rect.text{fill:none;stroke-width:0;}#mermaid-svg-OFK9XZjOg6ff05dC .icon-shape,#mermaid-svg-OFK9XZjOg6ff05dC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-OFK9XZjOg6ff05dC .icon-shape p,#mermaid-svg-OFK9XZjOg6ff05dC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-OFK9XZjOg6ff05dC .icon-shape .label rect,#mermaid-svg-OFK9XZjOg6ff05dC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-OFK9XZjOg6ff05dC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-OFK9XZjOg6ff05dC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-OFK9XZjOg6ff05dC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTPS / WSS
ai 域内部调用
用户 / 浏览器
forum-vue 用户端
Nginx

静态资源 + 反向代理
Spring Cloud Gateway
六个 Java 业务域

auth · content · im · game · economy · ai
Nacos

注册发现 / 配置
数据与消息

MySQL 六域库 · Redis · RabbitMQ
ai-server

审核 / 摘要 / 看板娘 / RAG
PostgreSQL

LangGraph 状态
外部模型与工具

请求路径是单向分层:用户端 → Nginx → Gateway → 对应业务域。六个 Java 域各自持有 api 契约和 server 实现,靠 Nacos 注册发现;MySQL 按域拆成六个库。AI 生成在 Python 服务,Java ai 域负责额度、会话和落库,普通社区功能不绑定具体模型。

项目结构

目录 负责什么
forum-vue 用户端页面、编辑器、社区互动与看板娘界面
java-cloud-standalone Gateway + 六域 api/server + 公共 common
ai-server 发帖检查、摘要、写作、生图、站内检索与看板娘
nginx 网站入口、Compose、打包和发布脚本
live2d 看板娘模型资源
migrate-online-db.sh 旧单库 forum_db 拆到六域库的迁移脚本

六域职责

进程 数据库 主要职责
auth forum-auth forum_auth_db 登录注册、账号资料、权限快照
content forum-content forum_content_db 帖子、板块、标签、评论、弹幕、推荐
im forum-im forum_im_db 私信、群聊、通知、语音信令
game forum-game forum_game_db 大厅、房间、对局、排行
economy forum-economy forum_economy_db 积分、签到、抽奖、会员
ai forum-ai forum_ai_db AI 额度、会话、漂流瓶、看板娘业务落库

跨域只依赖对方的 xxx-api,通过本地 Feign 客户端调用;不共享 Entity、Mapper、Service 实现。

单域内部分层

#mermaid-svg-bxHdkNzqYwKkYDiC{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-bxHdkNzqYwKkYDiC .error-icon{fill:#552222;}#mermaid-svg-bxHdkNzqYwKkYDiC .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-bxHdkNzqYwKkYDiC .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-bxHdkNzqYwKkYDiC .marker{fill:#333333;stroke:#333333;}#mermaid-svg-bxHdkNzqYwKkYDiC .marker.cross{stroke:#333333;}#mermaid-svg-bxHdkNzqYwKkYDiC svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-bxHdkNzqYwKkYDiC p{margin:0;}#mermaid-svg-bxHdkNzqYwKkYDiC .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster-label text{fill:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster-label span{color:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster-label span p{background-color:transparent;}#mermaid-svg-bxHdkNzqYwKkYDiC .label text,#mermaid-svg-bxHdkNzqYwKkYDiC span{fill:#333;color:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC .node rect,#mermaid-svg-bxHdkNzqYwKkYDiC .node circle,#mermaid-svg-bxHdkNzqYwKkYDiC .node ellipse,#mermaid-svg-bxHdkNzqYwKkYDiC .node polygon,#mermaid-svg-bxHdkNzqYwKkYDiC .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-bxHdkNzqYwKkYDiC .rough-node .label text,#mermaid-svg-bxHdkNzqYwKkYDiC .node .label text,#mermaid-svg-bxHdkNzqYwKkYDiC .image-shape .label,#mermaid-svg-bxHdkNzqYwKkYDiC .icon-shape .label{text-anchor:middle;}#mermaid-svg-bxHdkNzqYwKkYDiC .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-bxHdkNzqYwKkYDiC .rough-node .label,#mermaid-svg-bxHdkNzqYwKkYDiC .node .label,#mermaid-svg-bxHdkNzqYwKkYDiC .image-shape .label,#mermaid-svg-bxHdkNzqYwKkYDiC .icon-shape .label{text-align:center;}#mermaid-svg-bxHdkNzqYwKkYDiC .node.clickable{cursor:pointer;}#mermaid-svg-bxHdkNzqYwKkYDiC .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-bxHdkNzqYwKkYDiC .arrowheadPath{fill:#333333;}#mermaid-svg-bxHdkNzqYwKkYDiC .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-bxHdkNzqYwKkYDiC .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-bxHdkNzqYwKkYDiC .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bxHdkNzqYwKkYDiC .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-bxHdkNzqYwKkYDiC .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bxHdkNzqYwKkYDiC .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster text{fill:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC .cluster span{color:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-bxHdkNzqYwKkYDiC .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-bxHdkNzqYwKkYDiC rect.text{fill:none;stroke-width:0;}#mermaid-svg-bxHdkNzqYwKkYDiC .icon-shape,#mermaid-svg-bxHdkNzqYwKkYDiC .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-bxHdkNzqYwKkYDiC .icon-shape p,#mermaid-svg-bxHdkNzqYwKkYDiC .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-bxHdkNzqYwKkYDiC .icon-shape .label rect,#mermaid-svg-bxHdkNzqYwKkYDiC .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-bxHdkNzqYwKkYDiC .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-bxHdkNzqYwKkYDiC .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-bxHdkNzqYwKkYDiC :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} HTTP 请求
Controller
Service

权限 / 状态 / 业务规则
Mapper
本域 MySQL
Redis
Feign

调用其他域 api
RabbitMQ

按需

每个业务域都是同一套分层,只是落在不同进程和不同库上。同一条帖子无论从首页、搜索、收藏夹还是看板娘进入,数据都回到 content;账号身份由 auth 提供快照,其他域按需读取。

Java 业务模块

帖子发布与审核

#mermaid-svg-y1w6oEzbtiEQef23{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-y1w6oEzbtiEQef23 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-y1w6oEzbtiEQef23 .error-icon{fill:#552222;}#mermaid-svg-y1w6oEzbtiEQef23 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-y1w6oEzbtiEQef23 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-y1w6oEzbtiEQef23 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-y1w6oEzbtiEQef23 .marker.cross{stroke:#333333;}#mermaid-svg-y1w6oEzbtiEQef23 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-y1w6oEzbtiEQef23 p{margin:0;}#mermaid-svg-y1w6oEzbtiEQef23 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-y1w6oEzbtiEQef23 .cluster-label text{fill:#333;}#mermaid-svg-y1w6oEzbtiEQef23 .cluster-label span{color:#333;}#mermaid-svg-y1w6oEzbtiEQef23 .cluster-label span p{background-color:transparent;}#mermaid-svg-y1w6oEzbtiEQef23 .label text,#mermaid-svg-y1w6oEzbtiEQef23 span{fill:#333;color:#333;}#mermaid-svg-y1w6oEzbtiEQef23 .node rect,#mermaid-svg-y1w6oEzbtiEQef23 .node circle,#mermaid-svg-y1w6oEzbtiEQef23 .node ellipse,#mermaid-svg-y1w6oEzbtiEQef23 .node polygon,#mermaid-svg-y1w6oEzbtiEQef23 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-y1w6oEzbtiEQef23 .rough-node .label text,#mermaid-svg-y1w6oEzbtiEQef23 .node .label text,#mermaid-svg-y1w6oEzbtiEQef23 .image-shape .label,#mermaid-svg-y1w6oEzbtiEQef23 .icon-shape .label{text-anchor:middle;}#mermaid-svg-y1w6oEzbtiEQef23 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-y1w6oEzbtiEQef23 .rough-node .label,#mermaid-svg-y1w6oEzbtiEQef23 .node .label,#mermaid-svg-y1w6oEzbtiEQef23 .image-shape .label,#mermaid-svg-y1w6oEzbtiEQef23 .icon-shape .label{text-align:center;}#mermaid-svg-y1w6oEzbtiEQef23 .node.clickable{cursor:pointer;}#mermaid-svg-y1w6oEzbtiEQef23 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-y1w6oEzbtiEQef23 .arrowheadPath{fill:#333333;}#mermaid-svg-y1w6oEzbtiEQef23 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-y1w6oEzbtiEQef23 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-y1w6oEzbtiEQef23 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y1w6oEzbtiEQef23 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-y1w6oEzbtiEQef23 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y1w6oEzbtiEQef23 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-y1w6oEzbtiEQef23 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-y1w6oEzbtiEQef23 .cluster text{fill:#333;}#mermaid-svg-y1w6oEzbtiEQef23 .cluster span{color:#333;}#mermaid-svg-y1w6oEzbtiEQef23 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-y1w6oEzbtiEQef23 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-y1w6oEzbtiEQef23 rect.text{fill:none;stroke-width:0;}#mermaid-svg-y1w6oEzbtiEQef23 .icon-shape,#mermaid-svg-y1w6oEzbtiEQef23 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-y1w6oEzbtiEQef23 .icon-shape p,#mermaid-svg-y1w6oEzbtiEQef23 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-y1w6oEzbtiEQef23 .icon-shape .label rect,#mermaid-svg-y1w6oEzbtiEQef23 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-y1w6oEzbtiEQef23 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-y1w6oEzbtiEQef23 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-y1w6oEzbtiEQef23 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过与摘要
拒绝或异常
作者
编辑器

富文本或 Markdown
登录、参数与内容基础校验
保存为草稿
提交审核
Java 写入待审核帖子
审核任务队列
AI 审核图

文本、图片、视频
审核结果队列
Java 更新审核状态
公开帖子
驳回,作者可修改
首页、板块、搜索、推荐

帖子、问答、视频和弹幕都建立在内容社区模块上。发布时先保存必要内容,再进行检查;最终是否公开由 Java 后端决定,AI 只给出内容检查结果。

帖子互动与通知

#mermaid-svg-004xPuU2slleoX7W{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-004xPuU2slleoX7W .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-004xPuU2slleoX7W .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-004xPuU2slleoX7W .error-icon{fill:#552222;}#mermaid-svg-004xPuU2slleoX7W .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-004xPuU2slleoX7W .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-004xPuU2slleoX7W .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-004xPuU2slleoX7W .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-004xPuU2slleoX7W .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-004xPuU2slleoX7W .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-004xPuU2slleoX7W .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-004xPuU2slleoX7W .marker{fill:#333333;stroke:#333333;}#mermaid-svg-004xPuU2slleoX7W .marker.cross{stroke:#333333;}#mermaid-svg-004xPuU2slleoX7W svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-004xPuU2slleoX7W p{margin:0;}#mermaid-svg-004xPuU2slleoX7W .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-004xPuU2slleoX7W .cluster-label text{fill:#333;}#mermaid-svg-004xPuU2slleoX7W .cluster-label span{color:#333;}#mermaid-svg-004xPuU2slleoX7W .cluster-label span p{background-color:transparent;}#mermaid-svg-004xPuU2slleoX7W .label text,#mermaid-svg-004xPuU2slleoX7W span{fill:#333;color:#333;}#mermaid-svg-004xPuU2slleoX7W .node rect,#mermaid-svg-004xPuU2slleoX7W .node circle,#mermaid-svg-004xPuU2slleoX7W .node ellipse,#mermaid-svg-004xPuU2slleoX7W .node polygon,#mermaid-svg-004xPuU2slleoX7W .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-004xPuU2slleoX7W .rough-node .label text,#mermaid-svg-004xPuU2slleoX7W .node .label text,#mermaid-svg-004xPuU2slleoX7W .image-shape .label,#mermaid-svg-004xPuU2slleoX7W .icon-shape .label{text-anchor:middle;}#mermaid-svg-004xPuU2slleoX7W .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-004xPuU2slleoX7W .rough-node .label,#mermaid-svg-004xPuU2slleoX7W .node .label,#mermaid-svg-004xPuU2slleoX7W .image-shape .label,#mermaid-svg-004xPuU2slleoX7W .icon-shape .label{text-align:center;}#mermaid-svg-004xPuU2slleoX7W .node.clickable{cursor:pointer;}#mermaid-svg-004xPuU2slleoX7W .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-004xPuU2slleoX7W .arrowheadPath{fill:#333333;}#mermaid-svg-004xPuU2slleoX7W .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-004xPuU2slleoX7W .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-004xPuU2slleoX7W .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-004xPuU2slleoX7W .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-004xPuU2slleoX7W .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-004xPuU2slleoX7W .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-004xPuU2slleoX7W .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-004xPuU2slleoX7W .cluster text{fill:#333;}#mermaid-svg-004xPuU2slleoX7W .cluster span{color:#333;}#mermaid-svg-004xPuU2slleoX7W div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-004xPuU2slleoX7W .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-004xPuU2slleoX7W rect.text{fill:none;stroke-width:0;}#mermaid-svg-004xPuU2slleoX7W .icon-shape,#mermaid-svg-004xPuU2slleoX7W .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-004xPuU2slleoX7W .icon-shape p,#mermaid-svg-004xPuU2slleoX7W .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-004xPuU2slleoX7W .icon-shape .label rect,#mermaid-svg-004xPuU2slleoX7W .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-004xPuU2slleoX7W .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-004xPuU2slleoX7W .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-004xPuU2slleoX7W :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 公开帖子
点赞或取消点赞
发布评论
回复与楼中楼
收藏到文件夹
视频弹幕
互动记录
通知中心
实时提醒或未读数
相关用户

互动数据和帖子数据分开保存,但展示时会组合在一起。这样既能显示每个人的点赞、收藏和回复状态,也能让通知中心准确告诉用户发生了什么。

搜索、热帖与推荐

#mermaid-svg-alrGCznKVIw53kwb{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-alrGCznKVIw53kwb .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-alrGCznKVIw53kwb .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-alrGCznKVIw53kwb .error-icon{fill:#552222;}#mermaid-svg-alrGCznKVIw53kwb .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-alrGCznKVIw53kwb .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-alrGCznKVIw53kwb .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-alrGCznKVIw53kwb .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-alrGCznKVIw53kwb .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-alrGCznKVIw53kwb .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-alrGCznKVIw53kwb .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-alrGCznKVIw53kwb .marker{fill:#333333;stroke:#333333;}#mermaid-svg-alrGCznKVIw53kwb .marker.cross{stroke:#333333;}#mermaid-svg-alrGCznKVIw53kwb svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-alrGCznKVIw53kwb p{margin:0;}#mermaid-svg-alrGCznKVIw53kwb .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-alrGCznKVIw53kwb .cluster-label text{fill:#333;}#mermaid-svg-alrGCznKVIw53kwb .cluster-label span{color:#333;}#mermaid-svg-alrGCznKVIw53kwb .cluster-label span p{background-color:transparent;}#mermaid-svg-alrGCznKVIw53kwb .label text,#mermaid-svg-alrGCznKVIw53kwb span{fill:#333;color:#333;}#mermaid-svg-alrGCznKVIw53kwb .node rect,#mermaid-svg-alrGCznKVIw53kwb .node circle,#mermaid-svg-alrGCznKVIw53kwb .node ellipse,#mermaid-svg-alrGCznKVIw53kwb .node polygon,#mermaid-svg-alrGCznKVIw53kwb .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-alrGCznKVIw53kwb .rough-node .label text,#mermaid-svg-alrGCznKVIw53kwb .node .label text,#mermaid-svg-alrGCznKVIw53kwb .image-shape .label,#mermaid-svg-alrGCznKVIw53kwb .icon-shape .label{text-anchor:middle;}#mermaid-svg-alrGCznKVIw53kwb .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-alrGCznKVIw53kwb .rough-node .label,#mermaid-svg-alrGCznKVIw53kwb .node .label,#mermaid-svg-alrGCznKVIw53kwb .image-shape .label,#mermaid-svg-alrGCznKVIw53kwb .icon-shape .label{text-align:center;}#mermaid-svg-alrGCznKVIw53kwb .node.clickable{cursor:pointer;}#mermaid-svg-alrGCznKVIw53kwb .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-alrGCznKVIw53kwb .arrowheadPath{fill:#333333;}#mermaid-svg-alrGCznKVIw53kwb .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-alrGCznKVIw53kwb .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-alrGCznKVIw53kwb .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-alrGCznKVIw53kwb .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-alrGCznKVIw53kwb .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-alrGCznKVIw53kwb .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-alrGCznKVIw53kwb .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-alrGCznKVIw53kwb .cluster text{fill:#333;}#mermaid-svg-alrGCznKVIw53kwb .cluster span{color:#333;}#mermaid-svg-alrGCznKVIw53kwb div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-alrGCznKVIw53kwb .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-alrGCznKVIw53kwb rect.text{fill:none;stroke-width:0;}#mermaid-svg-alrGCznKVIw53kwb .icon-shape,#mermaid-svg-alrGCznKVIw53kwb .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-alrGCznKVIw53kwb .icon-shape p,#mermaid-svg-alrGCznKVIw53kwb .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-alrGCznKVIw53kwb .icon-shape .label rect,#mermaid-svg-alrGCznKVIw53kwb .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-alrGCznKVIw53kwb .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-alrGCznKVIw53kwb .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-alrGCznKVIw53kwb :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 新帖子、浏览与互动
内容与行为数据
定时计算热度
Redis 热帖缓存
首页与板块
用户关键词
帖子标题、正文与标签检索
帖子结果

高相似度作者结果
生成帖子特征

更新兴趣画像
推荐候选与排序
用户发现内容

发现模块不是另外复制一份帖子,而是根据已有内容、互动和兴趣帮助用户更快找到想看的内容。搜索优先找帖子本身;需要时也能找到与关键词高度相关的作者。

私信、群聊与实时互动

#mermaid-svg-wft350bA9z1GYc3P{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wft350bA9z1GYc3P .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wft350bA9z1GYc3P .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wft350bA9z1GYc3P .error-icon{fill:#552222;}#mermaid-svg-wft350bA9z1GYc3P .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wft350bA9z1GYc3P .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wft350bA9z1GYc3P .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wft350bA9z1GYc3P .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wft350bA9z1GYc3P .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wft350bA9z1GYc3P .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wft350bA9z1GYc3P .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wft350bA9z1GYc3P .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wft350bA9z1GYc3P .marker.cross{stroke:#333333;}#mermaid-svg-wft350bA9z1GYc3P svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wft350bA9z1GYc3P p{margin:0;}#mermaid-svg-wft350bA9z1GYc3P .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wft350bA9z1GYc3P .cluster-label text{fill:#333;}#mermaid-svg-wft350bA9z1GYc3P .cluster-label span{color:#333;}#mermaid-svg-wft350bA9z1GYc3P .cluster-label span p{background-color:transparent;}#mermaid-svg-wft350bA9z1GYc3P .label text,#mermaid-svg-wft350bA9z1GYc3P span{fill:#333;color:#333;}#mermaid-svg-wft350bA9z1GYc3P .node rect,#mermaid-svg-wft350bA9z1GYc3P .node circle,#mermaid-svg-wft350bA9z1GYc3P .node ellipse,#mermaid-svg-wft350bA9z1GYc3P .node polygon,#mermaid-svg-wft350bA9z1GYc3P .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wft350bA9z1GYc3P .rough-node .label text,#mermaid-svg-wft350bA9z1GYc3P .node .label text,#mermaid-svg-wft350bA9z1GYc3P .image-shape .label,#mermaid-svg-wft350bA9z1GYc3P .icon-shape .label{text-anchor:middle;}#mermaid-svg-wft350bA9z1GYc3P .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wft350bA9z1GYc3P .rough-node .label,#mermaid-svg-wft350bA9z1GYc3P .node .label,#mermaid-svg-wft350bA9z1GYc3P .image-shape .label,#mermaid-svg-wft350bA9z1GYc3P .icon-shape .label{text-align:center;}#mermaid-svg-wft350bA9z1GYc3P .node.clickable{cursor:pointer;}#mermaid-svg-wft350bA9z1GYc3P .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wft350bA9z1GYc3P .arrowheadPath{fill:#333333;}#mermaid-svg-wft350bA9z1GYc3P .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wft350bA9z1GYc3P .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wft350bA9z1GYc3P .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wft350bA9z1GYc3P .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wft350bA9z1GYc3P .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wft350bA9z1GYc3P .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wft350bA9z1GYc3P .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wft350bA9z1GYc3P .cluster text{fill:#333;}#mermaid-svg-wft350bA9z1GYc3P .cluster span{color:#333;}#mermaid-svg-wft350bA9z1GYc3P div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wft350bA9z1GYc3P .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wft350bA9z1GYc3P rect.text{fill:none;stroke-width:0;}#mermaid-svg-wft350bA9z1GYc3P .icon-shape,#mermaid-svg-wft350bA9z1GYc3P .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wft350bA9z1GYc3P .icon-shape p,#mermaid-svg-wft350bA9z1GYc3P .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wft350bA9z1GYc3P .icon-shape .label rect,#mermaid-svg-wft350bA9z1GYc3P .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wft350bA9z1GYc3P .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wft350bA9z1GYc3P .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wft350bA9z1GYc3P :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 发起方
发送私信或群消息
接收方或群成员
身份与成员关系校验
会话和消息记录
WebSocket 实时推送
未读数、已读状态、历史分页
消息中心与通知
语音邀请

私信、群聊和语音功能共用"消息先保存,再实时送达"的思路。用户重新进入页面后仍能看到历史消息;多人同时在线时也能及时收到新消息。

游戏中心

#mermaid-svg-brDQS1aZxvGyUQ8L{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-brDQS1aZxvGyUQ8L .error-icon{fill:#552222;}#mermaid-svg-brDQS1aZxvGyUQ8L .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-brDQS1aZxvGyUQ8L .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-brDQS1aZxvGyUQ8L .marker{fill:#333333;stroke:#333333;}#mermaid-svg-brDQS1aZxvGyUQ8L .marker.cross{stroke:#333333;}#mermaid-svg-brDQS1aZxvGyUQ8L svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-brDQS1aZxvGyUQ8L p{margin:0;}#mermaid-svg-brDQS1aZxvGyUQ8L .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster-label text{fill:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster-label span{color:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster-label span p{background-color:transparent;}#mermaid-svg-brDQS1aZxvGyUQ8L .label text,#mermaid-svg-brDQS1aZxvGyUQ8L span{fill:#333;color:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L .node rect,#mermaid-svg-brDQS1aZxvGyUQ8L .node circle,#mermaid-svg-brDQS1aZxvGyUQ8L .node ellipse,#mermaid-svg-brDQS1aZxvGyUQ8L .node polygon,#mermaid-svg-brDQS1aZxvGyUQ8L .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-brDQS1aZxvGyUQ8L .rough-node .label text,#mermaid-svg-brDQS1aZxvGyUQ8L .node .label text,#mermaid-svg-brDQS1aZxvGyUQ8L .image-shape .label,#mermaid-svg-brDQS1aZxvGyUQ8L .icon-shape .label{text-anchor:middle;}#mermaid-svg-brDQS1aZxvGyUQ8L .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-brDQS1aZxvGyUQ8L .rough-node .label,#mermaid-svg-brDQS1aZxvGyUQ8L .node .label,#mermaid-svg-brDQS1aZxvGyUQ8L .image-shape .label,#mermaid-svg-brDQS1aZxvGyUQ8L .icon-shape .label{text-align:center;}#mermaid-svg-brDQS1aZxvGyUQ8L .node.clickable{cursor:pointer;}#mermaid-svg-brDQS1aZxvGyUQ8L .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-brDQS1aZxvGyUQ8L .arrowheadPath{fill:#333333;}#mermaid-svg-brDQS1aZxvGyUQ8L .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-brDQS1aZxvGyUQ8L .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-brDQS1aZxvGyUQ8L .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-brDQS1aZxvGyUQ8L .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-brDQS1aZxvGyUQ8L .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-brDQS1aZxvGyUQ8L .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster text{fill:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L .cluster span{color:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-brDQS1aZxvGyUQ8L .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-brDQS1aZxvGyUQ8L rect.text{fill:none;stroke-width:0;}#mermaid-svg-brDQS1aZxvGyUQ8L .icon-shape,#mermaid-svg-brDQS1aZxvGyUQ8L .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-brDQS1aZxvGyUQ8L .icon-shape p,#mermaid-svg-brDQS1aZxvGyUQ8L .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-brDQS1aZxvGyUQ8L .icon-shape .label rect,#mermaid-svg-brDQS1aZxvGyUQ8L .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-brDQS1aZxvGyUQ8L .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-brDQS1aZxvGyUQ8L .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-brDQS1aZxvGyUQ8L :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 玩家
游戏大厅
创建、加入或匹配房间
校验人数、状态与游戏类型
房间实时连接
落子、操作、聊天、重连
对应游戏规则
广播最新房间状态
胜负、认输或结算
保存战绩与回放
积分、排行与个人资料

五子棋、井字棋和俄罗斯方块复用大厅、房间、实时连接和结算这套基本流程;每种游戏只保留各自的规则和画面,不重复建立一整套社交和排行系统。

AI 模块

AI 模块采用"统一入口、模块化处理"的方式。Java 后端不直接调用某一张图或某个模型,而是把请求交给 AI 服务入口;AI 服务按 taskType + intent + version 路由到已注册模块。当前的八个 Python 模块目录承载内容审核、摘要、创作、生图、游戏、搜索、RAG、推荐和看板娘九类 Gateway 能力;Java 始终负责权限、额度、持久化与最终业务状态。
#mermaid-svg-NiJX3saLJMAkNxGL{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NiJX3saLJMAkNxGL .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NiJX3saLJMAkNxGL .error-icon{fill:#552222;}#mermaid-svg-NiJX3saLJMAkNxGL .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NiJX3saLJMAkNxGL .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NiJX3saLJMAkNxGL .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NiJX3saLJMAkNxGL .marker.cross{stroke:#333333;}#mermaid-svg-NiJX3saLJMAkNxGL svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NiJX3saLJMAkNxGL p{margin:0;}#mermaid-svg-NiJX3saLJMAkNxGL .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-NiJX3saLJMAkNxGL .cluster-label text{fill:#333;}#mermaid-svg-NiJX3saLJMAkNxGL .cluster-label span{color:#333;}#mermaid-svg-NiJX3saLJMAkNxGL .cluster-label span p{background-color:transparent;}#mermaid-svg-NiJX3saLJMAkNxGL .label text,#mermaid-svg-NiJX3saLJMAkNxGL span{fill:#333;color:#333;}#mermaid-svg-NiJX3saLJMAkNxGL .node rect,#mermaid-svg-NiJX3saLJMAkNxGL .node circle,#mermaid-svg-NiJX3saLJMAkNxGL .node ellipse,#mermaid-svg-NiJX3saLJMAkNxGL .node polygon,#mermaid-svg-NiJX3saLJMAkNxGL .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NiJX3saLJMAkNxGL .rough-node .label text,#mermaid-svg-NiJX3saLJMAkNxGL .node .label text,#mermaid-svg-NiJX3saLJMAkNxGL .image-shape .label,#mermaid-svg-NiJX3saLJMAkNxGL .icon-shape .label{text-anchor:middle;}#mermaid-svg-NiJX3saLJMAkNxGL .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NiJX3saLJMAkNxGL .rough-node .label,#mermaid-svg-NiJX3saLJMAkNxGL .node .label,#mermaid-svg-NiJX3saLJMAkNxGL .image-shape .label,#mermaid-svg-NiJX3saLJMAkNxGL .icon-shape .label{text-align:center;}#mermaid-svg-NiJX3saLJMAkNxGL .node.clickable{cursor:pointer;}#mermaid-svg-NiJX3saLJMAkNxGL .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NiJX3saLJMAkNxGL .arrowheadPath{fill:#333333;}#mermaid-svg-NiJX3saLJMAkNxGL .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NiJX3saLJMAkNxGL .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NiJX3saLJMAkNxGL .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NiJX3saLJMAkNxGL .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NiJX3saLJMAkNxGL .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NiJX3saLJMAkNxGL .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NiJX3saLJMAkNxGL .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NiJX3saLJMAkNxGL .cluster text{fill:#333;}#mermaid-svg-NiJX3saLJMAkNxGL .cluster span{color:#333;}#mermaid-svg-NiJX3saLJMAkNxGL div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NiJX3saLJMAkNxGL .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NiJX3saLJMAkNxGL rect.text{fill:none;stroke-width:0;}#mermaid-svg-NiJX3saLJMAkNxGL .icon-shape,#mermaid-svg-NiJX3saLJMAkNxGL .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NiJX3saLJMAkNxGL .icon-shape p,#mermaid-svg-NiJX3saLJMAkNxGL .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NiJX3saLJMAkNxGL .icon-shape .label rect,#mermaid-svg-NiJX3saLJMAkNxGL .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NiJX3saLJMAkNxGL .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NiJX3saLJMAkNxGL .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NiJX3saLJMAkNxGL :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 用户端
Java AI 接口
校验用户、额度与内部密钥
AI Gateway
模块路由

taskType / intent / version
内容审核
帖子摘要
创作辅助

润色、封面提示
图片生成
五子棋 AI
站内搜索
RAG 索引
推荐特征与画像
看板娘 Agent
标准事件与结果

内容审核模块

#mermaid-svg-hJvt6mHtqfFVEOey{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-hJvt6mHtqfFVEOey .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-hJvt6mHtqfFVEOey .error-icon{fill:#552222;}#mermaid-svg-hJvt6mHtqfFVEOey .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-hJvt6mHtqfFVEOey .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-hJvt6mHtqfFVEOey .marker{fill:#333333;stroke:#333333;}#mermaid-svg-hJvt6mHtqfFVEOey .marker.cross{stroke:#333333;}#mermaid-svg-hJvt6mHtqfFVEOey svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-hJvt6mHtqfFVEOey p{margin:0;}#mermaid-svg-hJvt6mHtqfFVEOey .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-hJvt6mHtqfFVEOey .cluster-label text{fill:#333;}#mermaid-svg-hJvt6mHtqfFVEOey .cluster-label span{color:#333;}#mermaid-svg-hJvt6mHtqfFVEOey .cluster-label span p{background-color:transparent;}#mermaid-svg-hJvt6mHtqfFVEOey .label text,#mermaid-svg-hJvt6mHtqfFVEOey span{fill:#333;color:#333;}#mermaid-svg-hJvt6mHtqfFVEOey .node rect,#mermaid-svg-hJvt6mHtqfFVEOey .node circle,#mermaid-svg-hJvt6mHtqfFVEOey .node ellipse,#mermaid-svg-hJvt6mHtqfFVEOey .node polygon,#mermaid-svg-hJvt6mHtqfFVEOey .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-hJvt6mHtqfFVEOey .rough-node .label text,#mermaid-svg-hJvt6mHtqfFVEOey .node .label text,#mermaid-svg-hJvt6mHtqfFVEOey .image-shape .label,#mermaid-svg-hJvt6mHtqfFVEOey .icon-shape .label{text-anchor:middle;}#mermaid-svg-hJvt6mHtqfFVEOey .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-hJvt6mHtqfFVEOey .rough-node .label,#mermaid-svg-hJvt6mHtqfFVEOey .node .label,#mermaid-svg-hJvt6mHtqfFVEOey .image-shape .label,#mermaid-svg-hJvt6mHtqfFVEOey .icon-shape .label{text-align:center;}#mermaid-svg-hJvt6mHtqfFVEOey .node.clickable{cursor:pointer;}#mermaid-svg-hJvt6mHtqfFVEOey .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-hJvt6mHtqfFVEOey .arrowheadPath{fill:#333333;}#mermaid-svg-hJvt6mHtqfFVEOey .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-hJvt6mHtqfFVEOey .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-hJvt6mHtqfFVEOey .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hJvt6mHtqfFVEOey .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-hJvt6mHtqfFVEOey .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hJvt6mHtqfFVEOey .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-hJvt6mHtqfFVEOey .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-hJvt6mHtqfFVEOey .cluster text{fill:#333;}#mermaid-svg-hJvt6mHtqfFVEOey .cluster span{color:#333;}#mermaid-svg-hJvt6mHtqfFVEOey div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-hJvt6mHtqfFVEOey .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-hJvt6mHtqfFVEOey rect.text{fill:none;stroke-width:0;}#mermaid-svg-hJvt6mHtqfFVEOey .icon-shape,#mermaid-svg-hJvt6mHtqfFVEOey .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-hJvt6mHtqfFVEOey .icon-shape p,#mermaid-svg-hJvt6mHtqfFVEOey .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-hJvt6mHtqfFVEOey .icon-shape .label rect,#mermaid-svg-hJvt6mHtqfFVEOey .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-hJvt6mHtqfFVEOey .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-hJvt6mHtqfFVEOey .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-hJvt6mHtqfFVEOey :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 通过
拒绝
通过
拒绝
通过
拒绝
待审核帖子
Java 审核任务
审核任务队列
LangGraph 流程开始
validate_text

检查正文
validate_images

检查图片
reject_text
validate_video

检查视频
reject_image
summarize

Flash 摘要
reject_video
审核通过
finalize

汇总结果
审核结果队列
Java 更新帖子状态

内容审核走 RabbitMQ 异步链路,避免用户发帖时一直等待。审核模块也提供单独的文本、图片检查入口:文本优先命中语义缓存;图片先校验 Base64、体积与格式,再由视觉模型描述、文本模型判定。无论 AI 给出什么结论,Java 才能变更帖子审核状态。

帖子摘要模块

#mermaid-svg-K0Ww27twUJb15iem{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K0Ww27twUJb15iem .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K0Ww27twUJb15iem .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K0Ww27twUJb15iem .error-icon{fill:#552222;}#mermaid-svg-K0Ww27twUJb15iem .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K0Ww27twUJb15iem .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K0Ww27twUJb15iem .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K0Ww27twUJb15iem .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K0Ww27twUJb15iem .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K0Ww27twUJb15iem .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K0Ww27twUJb15iem .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K0Ww27twUJb15iem .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K0Ww27twUJb15iem .marker.cross{stroke:#333333;}#mermaid-svg-K0Ww27twUJb15iem svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K0Ww27twUJb15iem p{margin:0;}#mermaid-svg-K0Ww27twUJb15iem .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-K0Ww27twUJb15iem .cluster-label text{fill:#333;}#mermaid-svg-K0Ww27twUJb15iem .cluster-label span{color:#333;}#mermaid-svg-K0Ww27twUJb15iem .cluster-label span p{background-color:transparent;}#mermaid-svg-K0Ww27twUJb15iem .label text,#mermaid-svg-K0Ww27twUJb15iem span{fill:#333;color:#333;}#mermaid-svg-K0Ww27twUJb15iem .node rect,#mermaid-svg-K0Ww27twUJb15iem .node circle,#mermaid-svg-K0Ww27twUJb15iem .node ellipse,#mermaid-svg-K0Ww27twUJb15iem .node polygon,#mermaid-svg-K0Ww27twUJb15iem .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K0Ww27twUJb15iem .rough-node .label text,#mermaid-svg-K0Ww27twUJb15iem .node .label text,#mermaid-svg-K0Ww27twUJb15iem .image-shape .label,#mermaid-svg-K0Ww27twUJb15iem .icon-shape .label{text-anchor:middle;}#mermaid-svg-K0Ww27twUJb15iem .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-K0Ww27twUJb15iem .rough-node .label,#mermaid-svg-K0Ww27twUJb15iem .node .label,#mermaid-svg-K0Ww27twUJb15iem .image-shape .label,#mermaid-svg-K0Ww27twUJb15iem .icon-shape .label{text-align:center;}#mermaid-svg-K0Ww27twUJb15iem .node.clickable{cursor:pointer;}#mermaid-svg-K0Ww27twUJb15iem .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-K0Ww27twUJb15iem .arrowheadPath{fill:#333333;}#mermaid-svg-K0Ww27twUJb15iem .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K0Ww27twUJb15iem .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K0Ww27twUJb15iem .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K0Ww27twUJb15iem .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-K0Ww27twUJb15iem .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K0Ww27twUJb15iem .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-K0Ww27twUJb15iem .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K0Ww27twUJb15iem .cluster text{fill:#333;}#mermaid-svg-K0Ww27twUJb15iem .cluster span{color:#333;}#mermaid-svg-K0Ww27twUJb15iem div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K0Ww27twUJb15iem .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K0Ww27twUJb15iem rect.text{fill:none;stroke-width:0;}#mermaid-svg-K0Ww27twUJb15iem .icon-shape,#mermaid-svg-K0Ww27twUJb15iem .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K0Ww27twUJb15iem .icon-shape p,#mermaid-svg-K0Ww27twUJb15iem .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-K0Ww27twUJb15iem .icon-shape .label rect,#mermaid-svg-K0Ww27twUJb15iem .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K0Ww27twUJb15iem .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K0Ww27twUJb15iem .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K0Ww27twUJb15iem :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 否

详情页请求摘要
Java 校验登录、额度与可见性
POST_SUMMARY / GENERATE / v1
清理 HTML,校验正文
正文超过单段上限?
Flash 模型直接摘要
分块逐段摘要
合并各段结果
返回 summary / highlights / chunkCount
详情页展示,不修改原文

摘要模块使用 AiRuntime 调用快速文本模型;它仅输出内容理解结果,不修改帖子原文或审核状态。

创作与图片生成模块

#mermaid-svg-36yp413rEZHnuL00{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-36yp413rEZHnuL00 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-36yp413rEZHnuL00 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-36yp413rEZHnuL00 .error-icon{fill:#552222;}#mermaid-svg-36yp413rEZHnuL00 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-36yp413rEZHnuL00 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-36yp413rEZHnuL00 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-36yp413rEZHnuL00 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-36yp413rEZHnuL00 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-36yp413rEZHnuL00 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-36yp413rEZHnuL00 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-36yp413rEZHnuL00 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-36yp413rEZHnuL00 .marker.cross{stroke:#333333;}#mermaid-svg-36yp413rEZHnuL00 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-36yp413rEZHnuL00 p{margin:0;}#mermaid-svg-36yp413rEZHnuL00 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-36yp413rEZHnuL00 .cluster-label text{fill:#333;}#mermaid-svg-36yp413rEZHnuL00 .cluster-label span{color:#333;}#mermaid-svg-36yp413rEZHnuL00 .cluster-label span p{background-color:transparent;}#mermaid-svg-36yp413rEZHnuL00 .label text,#mermaid-svg-36yp413rEZHnuL00 span{fill:#333;color:#333;}#mermaid-svg-36yp413rEZHnuL00 .node rect,#mermaid-svg-36yp413rEZHnuL00 .node circle,#mermaid-svg-36yp413rEZHnuL00 .node ellipse,#mermaid-svg-36yp413rEZHnuL00 .node polygon,#mermaid-svg-36yp413rEZHnuL00 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-36yp413rEZHnuL00 .rough-node .label text,#mermaid-svg-36yp413rEZHnuL00 .node .label text,#mermaid-svg-36yp413rEZHnuL00 .image-shape .label,#mermaid-svg-36yp413rEZHnuL00 .icon-shape .label{text-anchor:middle;}#mermaid-svg-36yp413rEZHnuL00 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-36yp413rEZHnuL00 .rough-node .label,#mermaid-svg-36yp413rEZHnuL00 .node .label,#mermaid-svg-36yp413rEZHnuL00 .image-shape .label,#mermaid-svg-36yp413rEZHnuL00 .icon-shape .label{text-align:center;}#mermaid-svg-36yp413rEZHnuL00 .node.clickable{cursor:pointer;}#mermaid-svg-36yp413rEZHnuL00 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-36yp413rEZHnuL00 .arrowheadPath{fill:#333333;}#mermaid-svg-36yp413rEZHnuL00 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-36yp413rEZHnuL00 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-36yp413rEZHnuL00 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-36yp413rEZHnuL00 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-36yp413rEZHnuL00 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-36yp413rEZHnuL00 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-36yp413rEZHnuL00 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-36yp413rEZHnuL00 .cluster text{fill:#333;}#mermaid-svg-36yp413rEZHnuL00 .cluster span{color:#333;}#mermaid-svg-36yp413rEZHnuL00 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-36yp413rEZHnuL00 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-36yp413rEZHnuL00 rect.text{fill:none;stroke-width:0;}#mermaid-svg-36yp413rEZHnuL00 .icon-shape,#mermaid-svg-36yp413rEZHnuL00 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-36yp413rEZHnuL00 .icon-shape p,#mermaid-svg-36yp413rEZHnuL00 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-36yp413rEZHnuL00 .icon-shape .label rect,#mermaid-svg-36yp413rEZHnuL00 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-36yp413rEZHnuL00 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-36yp413rEZHnuL00 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-36yp413rEZHnuL00 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 作者
编辑器
Java 校验登录、额度与草稿归属
POST_CREATION / POLISH
POST_CREATION / COVER_HINTS
按体裁和编辑器模式

润色正文
从正文提取封面提示词
返回候选文本
IMAGE_GENERATION / GENERATE
校验提示词与质量参数

调用生图能力
图片地址与用量统计
用户确认后保存草稿或发布

创作模块只生成候选内容、提示词或图片 URL。草稿保存、发布、积分扣除与权限校验都留在 Java,AI 不会直接写入帖子状态。

游戏 AI 模块

#mermaid-svg-wVNferuT6IWcG2SH{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-wVNferuT6IWcG2SH .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-wVNferuT6IWcG2SH .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-wVNferuT6IWcG2SH .error-icon{fill:#552222;}#mermaid-svg-wVNferuT6IWcG2SH .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-wVNferuT6IWcG2SH .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-wVNferuT6IWcG2SH .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-wVNferuT6IWcG2SH .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-wVNferuT6IWcG2SH .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-wVNferuT6IWcG2SH .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-wVNferuT6IWcG2SH .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-wVNferuT6IWcG2SH .marker{fill:#333333;stroke:#333333;}#mermaid-svg-wVNferuT6IWcG2SH .marker.cross{stroke:#333333;}#mermaid-svg-wVNferuT6IWcG2SH svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-wVNferuT6IWcG2SH p{margin:0;}#mermaid-svg-wVNferuT6IWcG2SH .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-wVNferuT6IWcG2SH .cluster-label text{fill:#333;}#mermaid-svg-wVNferuT6IWcG2SH .cluster-label span{color:#333;}#mermaid-svg-wVNferuT6IWcG2SH .cluster-label span p{background-color:transparent;}#mermaid-svg-wVNferuT6IWcG2SH .label text,#mermaid-svg-wVNferuT6IWcG2SH span{fill:#333;color:#333;}#mermaid-svg-wVNferuT6IWcG2SH .node rect,#mermaid-svg-wVNferuT6IWcG2SH .node circle,#mermaid-svg-wVNferuT6IWcG2SH .node ellipse,#mermaid-svg-wVNferuT6IWcG2SH .node polygon,#mermaid-svg-wVNferuT6IWcG2SH .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-wVNferuT6IWcG2SH .rough-node .label text,#mermaid-svg-wVNferuT6IWcG2SH .node .label text,#mermaid-svg-wVNferuT6IWcG2SH .image-shape .label,#mermaid-svg-wVNferuT6IWcG2SH .icon-shape .label{text-anchor:middle;}#mermaid-svg-wVNferuT6IWcG2SH .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-wVNferuT6IWcG2SH .rough-node .label,#mermaid-svg-wVNferuT6IWcG2SH .node .label,#mermaid-svg-wVNferuT6IWcG2SH .image-shape .label,#mermaid-svg-wVNferuT6IWcG2SH .icon-shape .label{text-align:center;}#mermaid-svg-wVNferuT6IWcG2SH .node.clickable{cursor:pointer;}#mermaid-svg-wVNferuT6IWcG2SH .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-wVNferuT6IWcG2SH .arrowheadPath{fill:#333333;}#mermaid-svg-wVNferuT6IWcG2SH .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-wVNferuT6IWcG2SH .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-wVNferuT6IWcG2SH .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wVNferuT6IWcG2SH .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-wVNferuT6IWcG2SH .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wVNferuT6IWcG2SH .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-wVNferuT6IWcG2SH .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-wVNferuT6IWcG2SH .cluster text{fill:#333;}#mermaid-svg-wVNferuT6IWcG2SH .cluster span{color:#333;}#mermaid-svg-wVNferuT6IWcG2SH div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-wVNferuT6IWcG2SH .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-wVNferuT6IWcG2SH rect.text{fill:none;stroke-width:0;}#mermaid-svg-wVNferuT6IWcG2SH .icon-shape,#mermaid-svg-wVNferuT6IWcG2SH .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-wVNferuT6IWcG2SH .icon-shape p,#mermaid-svg-wVNferuT6IWcG2SH .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-wVNferuT6IWcG2SH .icon-shape .label rect,#mermaid-svg-wVNferuT6IWcG2SH .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-wVNferuT6IWcG2SH .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-wVNferuT6IWcG2SH .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-wVNferuT6IWcG2SH :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否或调用失败
五子棋房间
Java 校验回合、玩家与棋盘
GAME / GOBANG_MOVE / v1
校验落子位置合法性
规则层生成候选步
启用大模型规划?
大模型评估候选步
规则兜底选步
返回落子位置与用量
二次校验后落子并广播

游戏模块只建议一步棋;房间状态、胜负结算与 WebSocket 广播由 Java 游戏服务控制,模型不可绕过游戏规则。

推荐画像模块

#mermaid-svg-KI4BeyyaS5iw0p8F{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-KI4BeyyaS5iw0p8F .error-icon{fill:#552222;}#mermaid-svg-KI4BeyyaS5iw0p8F .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-KI4BeyyaS5iw0p8F .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-KI4BeyyaS5iw0p8F .marker{fill:#333333;stroke:#333333;}#mermaid-svg-KI4BeyyaS5iw0p8F .marker.cross{stroke:#333333;}#mermaid-svg-KI4BeyyaS5iw0p8F svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-KI4BeyyaS5iw0p8F p{margin:0;}#mermaid-svg-KI4BeyyaS5iw0p8F .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster-label text{fill:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster-label span{color:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster-label span p{background-color:transparent;}#mermaid-svg-KI4BeyyaS5iw0p8F .label text,#mermaid-svg-KI4BeyyaS5iw0p8F span{fill:#333;color:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F .node rect,#mermaid-svg-KI4BeyyaS5iw0p8F .node circle,#mermaid-svg-KI4BeyyaS5iw0p8F .node ellipse,#mermaid-svg-KI4BeyyaS5iw0p8F .node polygon,#mermaid-svg-KI4BeyyaS5iw0p8F .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-KI4BeyyaS5iw0p8F .rough-node .label text,#mermaid-svg-KI4BeyyaS5iw0p8F .node .label text,#mermaid-svg-KI4BeyyaS5iw0p8F .image-shape .label,#mermaid-svg-KI4BeyyaS5iw0p8F .icon-shape .label{text-anchor:middle;}#mermaid-svg-KI4BeyyaS5iw0p8F .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-KI4BeyyaS5iw0p8F .rough-node .label,#mermaid-svg-KI4BeyyaS5iw0p8F .node .label,#mermaid-svg-KI4BeyyaS5iw0p8F .image-shape .label,#mermaid-svg-KI4BeyyaS5iw0p8F .icon-shape .label{text-align:center;}#mermaid-svg-KI4BeyyaS5iw0p8F .node.clickable{cursor:pointer;}#mermaid-svg-KI4BeyyaS5iw0p8F .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-KI4BeyyaS5iw0p8F .arrowheadPath{fill:#333333;}#mermaid-svg-KI4BeyyaS5iw0p8F .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-KI4BeyyaS5iw0p8F .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-KI4BeyyaS5iw0p8F .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KI4BeyyaS5iw0p8F .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-KI4BeyyaS5iw0p8F .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KI4BeyyaS5iw0p8F .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster text{fill:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F .cluster span{color:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-KI4BeyyaS5iw0p8F .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-KI4BeyyaS5iw0p8F rect.text{fill:none;stroke-width:0;}#mermaid-svg-KI4BeyyaS5iw0p8F .icon-shape,#mermaid-svg-KI4BeyyaS5iw0p8F .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-KI4BeyyaS5iw0p8F .icon-shape p,#mermaid-svg-KI4BeyyaS5iw0p8F .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-KI4BeyyaS5iw0p8F .icon-shape .label rect,#mermaid-svg-KI4BeyyaS5iw0p8F .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-KI4BeyyaS5iw0p8F .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-KI4BeyyaS5iw0p8F .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-KI4BeyyaS5iw0p8F :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 行为与内容信号
事务提交后异步
事务提交后异步
事务提交后异步
帖子审核通过
点赞、收藏、回复、兴趣设置
标记不感兴趣 / 恢复
帖子特征提取任务
用户画像更新任务
反馈记录表
RECOMMENDATION / ARTICLE_FEATURE
RECOMMENDATION / USER_PROFILE
Gateway → LangChain → 模型
forum_article_ai_feature

topics / summary / fingerprint
forum_user_ai_profile_snapshot

topics / avoidTopics / summary
请求推荐流
Java 推荐规则

召回、可见性、关注、热度
硬过滤不感兴趣

兴趣加分、回避降分、后端分页

推荐 AI 只异步提炼公开帖主题与用户的聚合兴趣/回避主题,模型失败时使用规则兜底。推荐候选、帖子可见性、不感兴趣硬过滤和最终排序始终由 Java 完成;该模块不经过 RabbitMQ,也不需要 LangGraph。

看板娘助手模块

#mermaid-svg-xz8C3cBXwiI6a8Bh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-xz8C3cBXwiI6a8Bh .error-icon{fill:#552222;}#mermaid-svg-xz8C3cBXwiI6a8Bh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-xz8C3cBXwiI6a8Bh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .marker.cross{stroke:#333333;}#mermaid-svg-xz8C3cBXwiI6a8Bh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-xz8C3cBXwiI6a8Bh p{margin:0;}#mermaid-svg-xz8C3cBXwiI6a8Bh .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster-label text{fill:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster-label span{color:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster-label span p{background-color:transparent;}#mermaid-svg-xz8C3cBXwiI6a8Bh .label text,#mermaid-svg-xz8C3cBXwiI6a8Bh span{fill:#333;color:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .node rect,#mermaid-svg-xz8C3cBXwiI6a8Bh .node circle,#mermaid-svg-xz8C3cBXwiI6a8Bh .node ellipse,#mermaid-svg-xz8C3cBXwiI6a8Bh .node polygon,#mermaid-svg-xz8C3cBXwiI6a8Bh .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .rough-node .label text,#mermaid-svg-xz8C3cBXwiI6a8Bh .node .label text,#mermaid-svg-xz8C3cBXwiI6a8Bh .image-shape .label,#mermaid-svg-xz8C3cBXwiI6a8Bh .icon-shape .label{text-anchor:middle;}#mermaid-svg-xz8C3cBXwiI6a8Bh .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .rough-node .label,#mermaid-svg-xz8C3cBXwiI6a8Bh .node .label,#mermaid-svg-xz8C3cBXwiI6a8Bh .image-shape .label,#mermaid-svg-xz8C3cBXwiI6a8Bh .icon-shape .label{text-align:center;}#mermaid-svg-xz8C3cBXwiI6a8Bh .node.clickable{cursor:pointer;}#mermaid-svg-xz8C3cBXwiI6a8Bh .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .arrowheadPath{fill:#333333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xz8C3cBXwiI6a8Bh .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-xz8C3cBXwiI6a8Bh .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xz8C3cBXwiI6a8Bh .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster text{fill:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh .cluster span{color:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-xz8C3cBXwiI6a8Bh .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-xz8C3cBXwiI6a8Bh rect.text{fill:none;stroke-width:0;}#mermaid-svg-xz8C3cBXwiI6a8Bh .icon-shape,#mermaid-svg-xz8C3cBXwiI6a8Bh .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-xz8C3cBXwiI6a8Bh .icon-shape p,#mermaid-svg-xz8C3cBXwiI6a8Bh .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-xz8C3cBXwiI6a8Bh .icon-shape .label rect,#mermaid-svg-xz8C3cBXwiI6a8Bh .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-xz8C3cBXwiI6a8Bh .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-xz8C3cBXwiI6a8Bh .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-xz8C3cBXwiI6a8Bh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 历史过长
生图
对话
需要
不需要
用户消息
读取会话、记忆与上下文
MASCOT / CONTEXT_COMPRESS

将历史压缩为摘要
route_skill

识别请求类型
supervisor

选择生图还是对话路径
image

结合上下文生成图片
assess

判断是否需要联网搜索
tavily_search

搜索文字与图片
agent

快速或深度回答
保存消息、图片与状态
流式推送文本、图集或帖子按钮

看板娘会参考正在进行的对话。多数问题优先快速回答;只有需要复杂推理、规划或多步骤处理时才使用更强模型。长会话先压缩为摘要,检索到的帖子结果会保存到当前会话中,用户关闭再打开仍可以继续查看。

站内搜索模块

#mermaid-svg-VYYzOT8wEU8hhtWS{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VYYzOT8wEU8hhtWS .error-icon{fill:#552222;}#mermaid-svg-VYYzOT8wEU8hhtWS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VYYzOT8wEU8hhtWS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VYYzOT8wEU8hhtWS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VYYzOT8wEU8hhtWS .marker.cross{stroke:#333333;}#mermaid-svg-VYYzOT8wEU8hhtWS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VYYzOT8wEU8hhtWS p{margin:0;}#mermaid-svg-VYYzOT8wEU8hhtWS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster-label text{fill:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster-label span{color:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster-label span p{background-color:transparent;}#mermaid-svg-VYYzOT8wEU8hhtWS .label text,#mermaid-svg-VYYzOT8wEU8hhtWS span{fill:#333;color:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS .node rect,#mermaid-svg-VYYzOT8wEU8hhtWS .node circle,#mermaid-svg-VYYzOT8wEU8hhtWS .node ellipse,#mermaid-svg-VYYzOT8wEU8hhtWS .node polygon,#mermaid-svg-VYYzOT8wEU8hhtWS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-VYYzOT8wEU8hhtWS .rough-node .label text,#mermaid-svg-VYYzOT8wEU8hhtWS .node .label text,#mermaid-svg-VYYzOT8wEU8hhtWS .image-shape .label,#mermaid-svg-VYYzOT8wEU8hhtWS .icon-shape .label{text-anchor:middle;}#mermaid-svg-VYYzOT8wEU8hhtWS .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-VYYzOT8wEU8hhtWS .rough-node .label,#mermaid-svg-VYYzOT8wEU8hhtWS .node .label,#mermaid-svg-VYYzOT8wEU8hhtWS .image-shape .label,#mermaid-svg-VYYzOT8wEU8hhtWS .icon-shape .label{text-align:center;}#mermaid-svg-VYYzOT8wEU8hhtWS .node.clickable{cursor:pointer;}#mermaid-svg-VYYzOT8wEU8hhtWS .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-VYYzOT8wEU8hhtWS .arrowheadPath{fill:#333333;}#mermaid-svg-VYYzOT8wEU8hhtWS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-VYYzOT8wEU8hhtWS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-VYYzOT8wEU8hhtWS .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VYYzOT8wEU8hhtWS .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-VYYzOT8wEU8hhtWS .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VYYzOT8wEU8hhtWS .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster text{fill:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS .cluster span{color:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-VYYzOT8wEU8hhtWS .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-VYYzOT8wEU8hhtWS rect.text{fill:none;stroke-width:0;}#mermaid-svg-VYYzOT8wEU8hhtWS .icon-shape,#mermaid-svg-VYYzOT8wEU8hhtWS .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-VYYzOT8wEU8hhtWS .icon-shape p,#mermaid-svg-VYYzOT8wEU8hhtWS .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-VYYzOT8wEU8hhtWS .icon-shape .label rect,#mermaid-svg-VYYzOT8wEU8hhtWS .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-VYYzOT8wEU8hhtWS .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-VYYzOT8wEU8hhtWS .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-VYYzOT8wEU8hhtWS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是

搜索词
Java 提取公开候选与用户上下文
SEARCH / QUERY / v1
规范化搜索词与范围
向量检索帖子与用户
有向量命中?
候选 ID 与相关分数
关键词混合排序兜底
Java 过滤状态、作者与权限
后端分页返回

搜索模块只返回候选 ID 与分数,响应中明确标注仍需 Java 权限过滤。看板娘需要外部网页或地图信息时,才在自身 Agent 图中按需调用对应 MCP 工具。

RAG 索引模块

#mermaid-svg-cJZ9TVClf2me362a{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-cJZ9TVClf2me362a .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-cJZ9TVClf2me362a .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-cJZ9TVClf2me362a .error-icon{fill:#552222;}#mermaid-svg-cJZ9TVClf2me362a .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-cJZ9TVClf2me362a .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-cJZ9TVClf2me362a .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-cJZ9TVClf2me362a .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-cJZ9TVClf2me362a .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-cJZ9TVClf2me362a .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-cJZ9TVClf2me362a .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-cJZ9TVClf2me362a .marker{fill:#333333;stroke:#333333;}#mermaid-svg-cJZ9TVClf2me362a .marker.cross{stroke:#333333;}#mermaid-svg-cJZ9TVClf2me362a svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-cJZ9TVClf2me362a p{margin:0;}#mermaid-svg-cJZ9TVClf2me362a .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-cJZ9TVClf2me362a .cluster-label text{fill:#333;}#mermaid-svg-cJZ9TVClf2me362a .cluster-label span{color:#333;}#mermaid-svg-cJZ9TVClf2me362a .cluster-label span p{background-color:transparent;}#mermaid-svg-cJZ9TVClf2me362a .label text,#mermaid-svg-cJZ9TVClf2me362a span{fill:#333;color:#333;}#mermaid-svg-cJZ9TVClf2me362a .node rect,#mermaid-svg-cJZ9TVClf2me362a .node circle,#mermaid-svg-cJZ9TVClf2me362a .node ellipse,#mermaid-svg-cJZ9TVClf2me362a .node polygon,#mermaid-svg-cJZ9TVClf2me362a .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-cJZ9TVClf2me362a .rough-node .label text,#mermaid-svg-cJZ9TVClf2me362a .node .label text,#mermaid-svg-cJZ9TVClf2me362a .image-shape .label,#mermaid-svg-cJZ9TVClf2me362a .icon-shape .label{text-anchor:middle;}#mermaid-svg-cJZ9TVClf2me362a .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-cJZ9TVClf2me362a .rough-node .label,#mermaid-svg-cJZ9TVClf2me362a .node .label,#mermaid-svg-cJZ9TVClf2me362a .image-shape .label,#mermaid-svg-cJZ9TVClf2me362a .icon-shape .label{text-align:center;}#mermaid-svg-cJZ9TVClf2me362a .node.clickable{cursor:pointer;}#mermaid-svg-cJZ9TVClf2me362a .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-cJZ9TVClf2me362a .arrowheadPath{fill:#333333;}#mermaid-svg-cJZ9TVClf2me362a .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-cJZ9TVClf2me362a .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-cJZ9TVClf2me362a .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cJZ9TVClf2me362a .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-cJZ9TVClf2me362a .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cJZ9TVClf2me362a .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-cJZ9TVClf2me362a .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-cJZ9TVClf2me362a .cluster text{fill:#333;}#mermaid-svg-cJZ9TVClf2me362a .cluster span{color:#333;}#mermaid-svg-cJZ9TVClf2me362a div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-cJZ9TVClf2me362a .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-cJZ9TVClf2me362a rect.text{fill:none;stroke-width:0;}#mermaid-svg-cJZ9TVClf2me362a .icon-shape,#mermaid-svg-cJZ9TVClf2me362a .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-cJZ9TVClf2me362a .icon-shape p,#mermaid-svg-cJZ9TVClf2me362a .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-cJZ9TVClf2me362a .icon-shape .label rect,#mermaid-svg-cJZ9TVClf2me362a .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-cJZ9TVClf2me362a .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-cJZ9TVClf2me362a .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-cJZ9TVClf2me362a :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 帖子公开 / 作者资料更新
Java 确认业务状态已提交
RAG / INDEX_ARTICLE 或 INDEX_USER
规范化可检索字段
文本向量化
写入索引存储
帖子下架或删除
Java 触发删除
RAG / REMOVE_ARTICLE
供搜索模块召回

RAG 模块将文章与用户资料的索引写入、删除统一收敛到 Gateway;它不拥有帖子公开状态,索引命中后仍由 Java 过滤。

AI 使用的数据与记录

#mermaid-svg-CfMUZpWICpW74Xtt{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-CfMUZpWICpW74Xtt .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-CfMUZpWICpW74Xtt .error-icon{fill:#552222;}#mermaid-svg-CfMUZpWICpW74Xtt .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-CfMUZpWICpW74Xtt .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-CfMUZpWICpW74Xtt .marker{fill:#333333;stroke:#333333;}#mermaid-svg-CfMUZpWICpW74Xtt .marker.cross{stroke:#333333;}#mermaid-svg-CfMUZpWICpW74Xtt svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-CfMUZpWICpW74Xtt p{margin:0;}#mermaid-svg-CfMUZpWICpW74Xtt .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-CfMUZpWICpW74Xtt .cluster-label text{fill:#333;}#mermaid-svg-CfMUZpWICpW74Xtt .cluster-label span{color:#333;}#mermaid-svg-CfMUZpWICpW74Xtt .cluster-label span p{background-color:transparent;}#mermaid-svg-CfMUZpWICpW74Xtt .label text,#mermaid-svg-CfMUZpWICpW74Xtt span{fill:#333;color:#333;}#mermaid-svg-CfMUZpWICpW74Xtt .node rect,#mermaid-svg-CfMUZpWICpW74Xtt .node circle,#mermaid-svg-CfMUZpWICpW74Xtt .node ellipse,#mermaid-svg-CfMUZpWICpW74Xtt .node polygon,#mermaid-svg-CfMUZpWICpW74Xtt .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-CfMUZpWICpW74Xtt .rough-node .label text,#mermaid-svg-CfMUZpWICpW74Xtt .node .label text,#mermaid-svg-CfMUZpWICpW74Xtt .image-shape .label,#mermaid-svg-CfMUZpWICpW74Xtt .icon-shape .label{text-anchor:middle;}#mermaid-svg-CfMUZpWICpW74Xtt .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-CfMUZpWICpW74Xtt .rough-node .label,#mermaid-svg-CfMUZpWICpW74Xtt .node .label,#mermaid-svg-CfMUZpWICpW74Xtt .image-shape .label,#mermaid-svg-CfMUZpWICpW74Xtt .icon-shape .label{text-align:center;}#mermaid-svg-CfMUZpWICpW74Xtt .node.clickable{cursor:pointer;}#mermaid-svg-CfMUZpWICpW74Xtt .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-CfMUZpWICpW74Xtt .arrowheadPath{fill:#333333;}#mermaid-svg-CfMUZpWICpW74Xtt .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-CfMUZpWICpW74Xtt .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-CfMUZpWICpW74Xtt .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CfMUZpWICpW74Xtt .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-CfMUZpWICpW74Xtt .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CfMUZpWICpW74Xtt .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-CfMUZpWICpW74Xtt .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-CfMUZpWICpW74Xtt .cluster text{fill:#333;}#mermaid-svg-CfMUZpWICpW74Xtt .cluster span{color:#333;}#mermaid-svg-CfMUZpWICpW74Xtt div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-CfMUZpWICpW74Xtt .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-CfMUZpWICpW74Xtt rect.text{fill:none;stroke-width:0;}#mermaid-svg-CfMUZpWICpW74Xtt .icon-shape,#mermaid-svg-CfMUZpWICpW74Xtt .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-CfMUZpWICpW74Xtt .icon-shape p,#mermaid-svg-CfMUZpWICpW74Xtt .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-CfMUZpWICpW74Xtt .icon-shape .label rect,#mermaid-svg-CfMUZpWICpW74Xtt .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-CfMUZpWICpW74Xtt .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-CfMUZpWICpW74Xtt .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-CfMUZpWICpW74Xtt :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} Java 社区后端
MySQL

会话、额度、创作工作区、推荐结果
Redis

验证码、缓存、任务去重
RabbitMQ

审核任务与异步回调
AI Gateway
PostgreSQL

LangGraph 流程状态
向量检索与站内内容候选
Flash、深度推理与生图模型
搜索与地图工具

会话、额度和业务结果留在社区数据中;AI 流程本身保留必要的过程记录。这样既能让用户回到上次的对话,也能避免模型调用越过社区已有的账号和权限规则。

技术栈

Java 后端

依赖 版本 用途
Spring Boot 3.5.x Web、AMQP、Mail、Validation、WebSocket
MyBatis-Plus 3.5.15 Lambda API 查询,自带分页插件
JJWT 0.11.5 JWT 签发与解析
springdoc-openapi 2.8.0 开发期 Swagger UI
spring-security-crypto 随 Spring Boot BCrypt 密码加密,未引入完整 Security 框架
tianai-captcha 1.5.5 滑块拼图验证码
ip2region 2.7.0 离线 IP 归属地解析
Apache POI / PDFBox 5.2.5 / 3.0.5 Word、PDF 题库文档解析
阿里云 OSS SDK 3.17.4 图片、视频文件存储
阿里云短信 SDK 1.2.2 手机号验证码
thumbnailator 0.4.20 上传图片压缩与缩略图
Hutool 5.8.x 通用工具集

Python AI 服务

依赖 版本 用途
Flask 3.x HTTP Gateway 入口
LangChain Core 0.3.x 模型调用与链路封装
LangGraph 0.2.x 审核、看板娘等有状态 Agent 图
langgraph-checkpoint-postgres 2.x LangGraph 线程状态持久化到 PostgreSQL
dashscope ≥1.20 通义系列模型,含文本、视觉和生图
Pillow ≥10 图片格式校验与处理
pika 1.3.2 RabbitMQ 消费者,负责审核异步链路
psycopg3 ≥3.1 PostgreSQL 驱动
redis-py ≥5.0 语义缓存与状态去重
oss2 ≥2.18 阿里云 OSS 写入

前端

依赖 用途
Vue 3 + Vite SPA 框架与构建工具
Pinia + pinia-plugin-persistedstate 状态管理,支持本地持久化
Vue Router 客户端路由
Element Plus UI 组件库,配置中文语言包

基础设施

服务 镜像版本 用途
Nginx 1.30.1 反向代理、HTTPS 终止、静态资源分发
Nacos 3.1.1 服务注册发现与配置中心
MySQL 9.7.0 六个业务域独立库
Redis 8.0 缓存与排行榜,allkeys-lru 策略,限 256 MB
RabbitMQ 4.3-management 审核任务的异步消息队列
PostgreSQL 17 LangGraph checkpoint 持久化存储

本地启动

准备 Java 17、Python 3.11、Node.js、Docker Desktop。中间件(含与线上同镜像的 Nacos)由开发 Compose 拉起。

powershell 复制代码
# 中间件(开发 Compose:Nacos / MySQL / Redis / RabbitMQ / PostgreSQL / FFmpeg)
cd nginx
docker compose -f docker-compose.dev.yaml up -d
# IDEA 连接 Nacos 客户端:127.0.0.1:8848;浏览器控制台:http://127.0.0.1:8080/index.html
# (勿再启动仓库内本机独立 Nacos,避免端口冲突)

# 用户端
cd ..\forum-vue\front
npm install
npm run dev

# Java 微服务(IDEA 推荐按模块启动,或根目录 reactor 打包后分别启动)
cd ..\..\java-cloud-standalone
mvn -DskipTests package
# 依次启动:gateway、auth、content、im、game、economy、ai

# AI 服务
cd ..\ai-server
python main.py

若本地仍是旧的单库 forum_db,可先执行:

bash 复制代码
bash migrate-online-db.sh migrate-data

本地构建和 Docker 构建会通过本机 7897 代理访问外部依赖。密钥和环境差异只放在环境变量或本地配置中,不放入仓库。

分工nginx/.env 只给 Docker Compose / up.sh 部署用;本地 IDEA 启动的 Java 不再 读取该文件,只使用系统环境变量与各模块 application.yml 默认值。

环境变量说明

参考 nginx/.env.example(部署用),主要配置项:

变量 说明
JWT_SECRET JWT 签名密钥,生产必须替换
PII_CRYPTO_SECRET 手机号等敏感字段对称加密密钥
MYSQL_ROOT_PASSWORD MySQL root 密码
FORUM_*_DB_USERNAME / FORUM_*_DB_PASSWORD 六个业务域数据库账号
NACOS_ADDR Nacos 地址,生产默认 nacos:8848
REDIS_PASSWORD Redis 认证密码
RABBITMQ_USER / RABBITMQ_PASSWORD / RABBITMQ_VHOST MQ 账号与虚拟主机
DASHSCOPE_API_KEY 通义大模型 API Key
TAVILY_API_KEY 看板娘联网搜索 Key
HUANAPI_IMAGE_KEY 图片生成服务 Key
ALIYUN_ACCESS_KEY_ID/SECRET 阿里云 OSS / 短信公共凭据
FORUM_MASCOT_INTERNAL_KEY Java ↔ Python 内部鉴权密钥,两侧须一致
FORUM_VOICE_TURN_* 语音通话用的 TURN 服务器地址和凭据

打包发布

#mermaid-svg-MU3M8slIuUiVO32I{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MU3M8slIuUiVO32I .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MU3M8slIuUiVO32I .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MU3M8slIuUiVO32I .error-icon{fill:#552222;}#mermaid-svg-MU3M8slIuUiVO32I .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MU3M8slIuUiVO32I .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MU3M8slIuUiVO32I .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MU3M8slIuUiVO32I .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MU3M8slIuUiVO32I .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MU3M8slIuUiVO32I .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MU3M8slIuUiVO32I .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MU3M8slIuUiVO32I .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MU3M8slIuUiVO32I .marker.cross{stroke:#333333;}#mermaid-svg-MU3M8slIuUiVO32I svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MU3M8slIuUiVO32I p{margin:0;}#mermaid-svg-MU3M8slIuUiVO32I .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-MU3M8slIuUiVO32I .cluster-label text{fill:#333;}#mermaid-svg-MU3M8slIuUiVO32I .cluster-label span{color:#333;}#mermaid-svg-MU3M8slIuUiVO32I .cluster-label span p{background-color:transparent;}#mermaid-svg-MU3M8slIuUiVO32I .label text,#mermaid-svg-MU3M8slIuUiVO32I span{fill:#333;color:#333;}#mermaid-svg-MU3M8slIuUiVO32I .node rect,#mermaid-svg-MU3M8slIuUiVO32I .node circle,#mermaid-svg-MU3M8slIuUiVO32I .node ellipse,#mermaid-svg-MU3M8slIuUiVO32I .node polygon,#mermaid-svg-MU3M8slIuUiVO32I .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MU3M8slIuUiVO32I .rough-node .label text,#mermaid-svg-MU3M8slIuUiVO32I .node .label text,#mermaid-svg-MU3M8slIuUiVO32I .image-shape .label,#mermaid-svg-MU3M8slIuUiVO32I .icon-shape .label{text-anchor:middle;}#mermaid-svg-MU3M8slIuUiVO32I .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MU3M8slIuUiVO32I .rough-node .label,#mermaid-svg-MU3M8slIuUiVO32I .node .label,#mermaid-svg-MU3M8slIuUiVO32I .image-shape .label,#mermaid-svg-MU3M8slIuUiVO32I .icon-shape .label{text-align:center;}#mermaid-svg-MU3M8slIuUiVO32I .node.clickable{cursor:pointer;}#mermaid-svg-MU3M8slIuUiVO32I .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MU3M8slIuUiVO32I .arrowheadPath{fill:#333333;}#mermaid-svg-MU3M8slIuUiVO32I .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MU3M8slIuUiVO32I .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MU3M8slIuUiVO32I .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MU3M8slIuUiVO32I .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MU3M8slIuUiVO32I .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MU3M8slIuUiVO32I .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MU3M8slIuUiVO32I .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MU3M8slIuUiVO32I .cluster text{fill:#333;}#mermaid-svg-MU3M8slIuUiVO32I .cluster span{color:#333;}#mermaid-svg-MU3M8slIuUiVO32I div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MU3M8slIuUiVO32I .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MU3M8slIuUiVO32I rect.text{fill:none;stroke-width:0;}#mermaid-svg-MU3M8slIuUiVO32I .icon-shape,#mermaid-svg-MU3M8slIuUiVO32I .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MU3M8slIuUiVO32I .icon-shape p,#mermaid-svg-MU3M8slIuUiVO32I .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MU3M8slIuUiVO32I .icon-shape .label rect,#mermaid-svg-MU3M8slIuUiVO32I .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MU3M8slIuUiVO32I .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MU3M8slIuUiVO32I .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MU3M8slIuUiVO32I :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 当前源码
make-package.ps1
Vite 构建用户端
构建 Java、AI、FFmpeg 镜像
nginx dist
离线镜像 tar
nginx package
sql 中的初始化与增量脚本
verify-package.ps1
仅上传 package 目录
up.sh 启动线上容器

nginx 目录执行:

powershell 复制代码
.\scripts\make-package.ps1

默认只显示简洁的构建结果。需要查看镜像构建详情时,再使用:

powershell 复制代码
.\scripts\make-package.ps1 -ShowBuildDetails

完整发布包会生成在 nginx\package\。上传前可校验:

powershell 复制代码
.\scripts\verify-package.ps1

发布包以六个 server 模块各自的 src/main/resources/db/create.sql 作为独立数据库初始化基线。已有旧单库 forum_db 的环境,上线前用包内 migrate-online-db.sh migrate-data 建六域结构并搬迁数据,默认保留 forum_db。旧会话清理默认关闭,只有明确把脚本中的开关改为 1 才会执行清理。

核心设计思路

权限边界放在各 Java 业务域的 Service 层。前端的登录拦截只是减少无效请求;跨域调用通过 auth-api 等契约获取身份快照,AI 服务也只接受附带内部密钥的请求。

帖子有一套严格的状态流转:草稿 → 待审核 → 已发布,每一步只能由 Java Service 推进。审核期间字段锁定,前端拿不到直接改状态的入口。每次提交审核都会生成一个任务 ID 写入 article.audit_task_id,和 AI 侧 LangGraph 的 thread_id 对应,审核过程可以完整追溯。

AI 服务只管生成,不管写入。审核结论、摘要、推荐特征都由模型给出,但落库的动作始终在 Java 完成。这样换模型或 AI 服务临时挂掉,不会影响发帖、聊天这些核心功能。

消息的逻辑是先存后推。WebSocket 断线重连后,未读内容从数据库补全,不依赖连接状态。私信、群聊、语音邀请和系统通知走同一套流程,差别只在消息类型字段。

游戏的实时状态放在内存里,结束后再写库。对局中的每一步通过 WebSocket 广播给房间成员,游戏结束才把战绩和回放写进数据库,不做高频持久化。

站内搜索优先走向量召回,没命中再退回关键词排序。搜索模块只返回候选 ID 和相关分数,权限过滤和分页由 Java 完成,搜索结果不会泄露无权查看的内容。

数据表概览

业务表按六个独立库拆分:forum_auth_dbforum_content_dbforum_im_dbforum_game_dbforum_economy_dbforum_ai_db。每张表都有 create_timeupdate_timedelete_state 三个基础字段,主键统一用 BIGINT AUTO_INCREMENT

分组 主要表
用户与账号 useruser_login_loguser_followuser_interest_preference
帖子内容 articlearticle_imagearticle_replyarticle_sub_replyarticle_video_danmakuforum_article_tag
互动行为 article_likearticle_reply_likearticle_favoriteuser_favorite_folder
私信与群聊 messagegroup_chatgroup_chat_membergroup_chat_message
漂流瓶 drift_bottledrift_bottle_commentdrift_bottle_pick_log
游戏 game_definitiongame_gobang_match_recordgame_jinzi_match_recordgame_tetris_pk_match_recordgame_user_profile
成长与积分 user_growth_profilegrowth_experience_loggrowth_challengepoints_log
抽奖 lottery_activitylottery_prizelottery_draw_record
AI 相关 forum_ai_task_sessionforum_ai_usage_logforum_ai_creation_workspaceforum_user_ai_profile_snapshotforum_article_ai_featureforum_companion_session
通知 forum_noticesystem_messageforum_outbox_message

容器服务说明

生产栈由 nginx/docker-compose.yaml 定义。服务都在 forum-net 内网互通,对外只开放 Nginx 的 80 / 443;Nacos 不对外暴露。
#mermaid-svg-40EMeppkF31HnJKu{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-40EMeppkF31HnJKu .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-40EMeppkF31HnJKu .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-40EMeppkF31HnJKu .error-icon{fill:#552222;}#mermaid-svg-40EMeppkF31HnJKu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-40EMeppkF31HnJKu .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-40EMeppkF31HnJKu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-40EMeppkF31HnJKu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-40EMeppkF31HnJKu .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-40EMeppkF31HnJKu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-40EMeppkF31HnJKu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-40EMeppkF31HnJKu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-40EMeppkF31HnJKu .marker.cross{stroke:#333333;}#mermaid-svg-40EMeppkF31HnJKu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-40EMeppkF31HnJKu p{margin:0;}#mermaid-svg-40EMeppkF31HnJKu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-40EMeppkF31HnJKu .cluster-label text{fill:#333;}#mermaid-svg-40EMeppkF31HnJKu .cluster-label span{color:#333;}#mermaid-svg-40EMeppkF31HnJKu .cluster-label span p{background-color:transparent;}#mermaid-svg-40EMeppkF31HnJKu .label text,#mermaid-svg-40EMeppkF31HnJKu span{fill:#333;color:#333;}#mermaid-svg-40EMeppkF31HnJKu .node rect,#mermaid-svg-40EMeppkF31HnJKu .node circle,#mermaid-svg-40EMeppkF31HnJKu .node ellipse,#mermaid-svg-40EMeppkF31HnJKu .node polygon,#mermaid-svg-40EMeppkF31HnJKu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-40EMeppkF31HnJKu .rough-node .label text,#mermaid-svg-40EMeppkF31HnJKu .node .label text,#mermaid-svg-40EMeppkF31HnJKu .image-shape .label,#mermaid-svg-40EMeppkF31HnJKu .icon-shape .label{text-anchor:middle;}#mermaid-svg-40EMeppkF31HnJKu .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-40EMeppkF31HnJKu .rough-node .label,#mermaid-svg-40EMeppkF31HnJKu .node .label,#mermaid-svg-40EMeppkF31HnJKu .image-shape .label,#mermaid-svg-40EMeppkF31HnJKu .icon-shape .label{text-align:center;}#mermaid-svg-40EMeppkF31HnJKu .node.clickable{cursor:pointer;}#mermaid-svg-40EMeppkF31HnJKu .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-40EMeppkF31HnJKu .arrowheadPath{fill:#333333;}#mermaid-svg-40EMeppkF31HnJKu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-40EMeppkF31HnJKu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-40EMeppkF31HnJKu .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-40EMeppkF31HnJKu .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-40EMeppkF31HnJKu .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-40EMeppkF31HnJKu .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-40EMeppkF31HnJKu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-40EMeppkF31HnJKu .cluster text{fill:#333;}#mermaid-svg-40EMeppkF31HnJKu .cluster span{color:#333;}#mermaid-svg-40EMeppkF31HnJKu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-40EMeppkF31HnJKu .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-40EMeppkF31HnJKu rect.text{fill:none;stroke-width:0;}#mermaid-svg-40EMeppkF31HnJKu .icon-shape,#mermaid-svg-40EMeppkF31HnJKu .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-40EMeppkF31HnJKu .icon-shape p,#mermaid-svg-40EMeppkF31HnJKu .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-40EMeppkF31HnJKu .icon-shape .label rect,#mermaid-svg-40EMeppkF31HnJKu .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-40EMeppkF31HnJKu .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-40EMeppkF31HnJKu .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-40EMeppkF31HnJKu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 浏览器
nginx :80 / :443
gateway
Java 业务容器

auth · content · im · game · economy · ai
中间件

nacos · mysql · redis · rabbitmq
ai-server
ffmpeg
postgres

Gateway 与六个 Java 业务容器共用 forum-backend 镜像,靠不同 jar 入口区分进程。ffmpeg 负责视频转码,经内部密钥与 Java / AI 通信。

开发约定

  • 内容、权限和数据由对应业务域的 Java 服务决定,页面只负责展示和提交操作。
  • AI 只通过统一入口接入,页面不直接调用具体模型。
  • 新的数据库变更只追加新脚本,不修改已经执行过的历史脚本。
  • 密码、密钥、验证码或本地环境配置不提交仓库。
相关推荐
张小凡vip1 小时前
python--爬虫--成熟的爬虫框架Scrapy
爬虫·python·scrapy
梦雨生生2 小时前
java开发工具(学习第一天)
java·开发语言·学习
不瘦80斤不改名2 小时前
01-vibe-coding-起源与本质
人工智能·python
夜雪一千2 小时前
如何对新闻数据进行模糊去重
python
她说可以呀2 小时前
Spring-ai-alibaba文生图
java·人工智能·spring
oyguyteggytrrwwwrt4 小时前
3dgs渲染部分详细注释
python
松仔log4 小时前
Java中级——组合和继承
android·java·开发语言
不才不才不不才4 小时前
Spring 源码系列(16): doDispatch 全流程——一次请求的主干链路
java·后端·spring
snow@li4 小时前
HikariCP:高性能数据库连接池全景深入梳理
java·数据库