114 Commits

Author SHA1 Message Date
ageerle
8a12be349a docs: correct coding demo URL in READMEs 2026-10-22 01:04:05 +08:00
ageerle
f286f50bbe docs: update demo URLs and QR code login instructions 2026-10-21 06:43:05 +08:00
ageerle
5e66c7bd30 feat(short-drama): add director workspaces and refine video production
Add canvas and director APIs, production skill catalogs, prompt preservation, video references and Atlas H3 support. Include schema migrations, upload limits, regression coverage and the new demo URL.
2026-10-20 09:30:36 +08:00
ageerle
8ab3638012 fix(copilot): 对齐图片限制并修复 Doubao 模型与思考回放 2026-10-13 03:08:34 +08:00
ageerle
432fbb6ea4 fix(short-drama): enforce Atlas isolation and restore missing catalog routes 2026-10-10 10:22:33 +08:00
ageerle
ca6ef96200 feat: 完善短剧创作、技能目录与媒体任务恢复
保存原始创作输入,整合剧本打磨、分场规划与流式进度,接入审美及导演技能、角色声音和音乐;保持已批准媒体并完善请求去重与恢复。

统一增量 SQL 目录,补齐新安装字段并修正示例插入列,更新迁移说明;修复测试夹具与当前审阅、重启恢复行为的断言。验证:相关模块编译通过,短剧及 Atlas 回归 337 项、SSE 回归 3 项均通过。
2026-10-03 19:11:54 +08:00
ageerle
91b6b53ce9 feat: 增强短剧导演规则与素材生成及合成 2026-09-30 14:54:26 +08:00
ageerle
7c7e64311e Merge pull request #340 from ageerle/codex/mcp-remote-bearer-key
feat: support bearerKey in remote MCP tool JSON
2026-09-23 17:39:00 +08:00
ageerle
46714df604 feat: support bearer key in remote MCP tool config 2026-09-23 17:35:58 +08:00
ageerle
197dc40510 fix: return model keys in admin details and allow clearing 2026-09-22 23:05:59 +08:00
ageerle
8e3b286190 fix: restore admin-managed model keys and refresh cached clients 2026-09-21 11:08:05 +08:00
ageerle
91ca91571b test: cover external plan step visibility 2026-09-21 11:07:37 +08:00
ageerle
ce9228c5bb fix: preserve application Jackson settings for tenant requests 2026-09-21 11:07:36 +08:00
ageerle
6f19c86fe6 Merge pull request #337 from eroXianYin/main
知识库检索节点补齐严格模式、默认回复及节点注册
2026-09-21 11:02:32 +08:00
SUNLIZHAO\孙立钊
422d935b26 知识库检索节点补齐严格模式、默认回复及节点注册
- KnowledgeRetrievalNodeConfig 新增 is_strict / default_response 字段
- KnowledgeRetrievalNode 检索无结果时,严格模式开启返回默认回复,关闭返回空
- 检索模式优先级修正:节点明确选择覆盖知识库的混合检索配置
- 新增幂等注册 SQL(update 脚本 + 全量初始化),新老环境均可使用
2026-09-11 19:57:21 +08:00
ageerle
cca3090577 fix: support Atlas multimodal generation and media preview 2026-09-11 10:49:29 +08:00
ageerle
4766d2e628 docs: document URL management and local validation 2026-09-08 23:56:52 +08:00
ageerle
c9ca55b45b fix: preserve manual plan transitions during external verification 2026-09-08 23:48:59 +08:00
ageerle
bcff4fd9e3 feat: enhance coding harness, model security and system features 2026-09-08 23:33:29 +08:00
ageerle
d4ed2b8672 Merge pull request #326 from ansn366/docs/improve-windows-docker-setup
docs: improve Windows Docker deployment instructions
2026-09-05 22:27:32 +08:00
ageerle
ee838aa488 Merge pull request #328 from l-vM2k/fix-mainExecutor
fix: 修复 mainExecutor 线程池在高核CPU服务器上会空指针导致应用无法启动
2026-09-05 22:27:25 +08:00
ageerle
b27fa844e6 fix: handle missing Qdrant collections during deletion
Treat gRPC NOT_FOUND as an idempotent delete for collections, documents and fragments so first uploads can initialize their collection. Preserve other failures and add 19 regression cases.

Refs: https://gitee.com/ageerle/ruoyi-ai/issues/IKCTSX
2026-09-05 22:19:15 +08:00
Jiali
7f728c7a92 fix: 修复 mainExecutor 线程池在高核CPU服务器上会空指针导致应用无法启动
原配置从配置文件读取 corePoolSize 和 maxPoolSize,
当配置缺失时传入 null 导致 BeanCreationException。
现改为基于 CPU 核心数动态计算,并设置固定上限 100。
2026-08-26 19:10:39 +08:00
Ansn
15ffb4ec2e docs: improve Windows Docker deployment instructions 2026-08-21 11:54:57 +08:00
ageerle
f92e510665 chore: enable demo mode 2026-08-16 20:58:48 +08:00
ageerle@163.com
997548dd4b fix: expose builtin tools to LangChain4j agents 2026-08-15 23:14:08 +08:00
ageerle
25ab33c79c feat: add coding harness runtime and CMS module 2026-08-15 23:04:34 +08:00
ageerle
9d439d1dcf refactor: move RAG trace classes to argtrace package and update SQL schema
- Rename org.ruoyi.trace package to org.ruoyi.argtrace for RagTraceNodeTypes
  and RagTracePayloadBuilder; fix package declarations and update imports in
  ChatServiceFacade and KnowledgeRetrievalServiceImpl
- Remove obsolete RagTracePayloadBuilderTest
- Switch supervisor response strategy from SUMMARY to LAST in ChatServiceFacade
- Refresh docs/script/sql/ruoyi-ai.sql with the latest full schema dump
- Add live demo links (admin panel, user frontend, commercial edition) to
  README.md and README_ZH.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-04 17:44:39 +08:00
ageerle
0a08c489be docs: remove redundant registry commands 2026-08-04 15:57:32 +08:00
ageerle
038e7725f9 docs: add prebuilt image deployment guide 2026-08-04 15:55:17 +08:00
ageerle
4ccf249663 docs: remove obsolete WeChat image 2026-08-04 15:50:51 +08:00
ageerle
1d5b01f77f docs: remove obsolete Douyin image 2026-08-04 15:50:36 +08:00
ageerle
538dac3a46 docs: add Douyin tutorial QR code 2026-08-04 15:49:40 +08:00
ageerle
6c383dd9f5 fix: 修复智能体编辑时关联工具加载失败 (#320) 2026-08-04 15:38:25 +08:00
ageerle
9ae49f8797 fix: allow frontend dependency builds in image workflow 2026-08-04 15:30:34 +08:00
ageerle
3c175ba28d chore: sync pending project changes 2026-08-04 15:23:19 +08:00
ageerle
e34592c3d4 release: prepare v3.1.0 2026-08-04 15:18:57 +08:00
ageerle
fd044a4752 docs: align README badges in one row 2026-07-30 00:22:22 +08:00
ageerle
6e264ad500 feat: streamline workflow orchestration and chat routing
Add Zhipu web search integration, remove obsolete workflow nodes and resume handling, and separate model, agent, and workflow chat execution.
2026-07-30 00:15:44 +08:00
ageerle
83fd1ee983 fix: 移除FastJson 1.2.83严重安全漏洞,替换为Jackson
- 移除FastJson 1.2.83依赖(存在严重RCE漏洞CVE-2022-25845等)
- 替换为Spring Boot内置的Jackson 2.18.2
- 修改6个Java文件的JSON处理逻辑
- 所有模块编译验证通过

修改文件:
1. pom.xml - 移除fastjson依赖定义
2. ruoyi-common-chat/pom.xml - 替换为jackson-databind
3. QwenFileUploadUtils.java - 千问文件上传JSON解析
4. ChatRequest.java - 移除FastJson注解
5. MailSendNode.java - 邮件节点JSON处理
6. SwitcherNode.java - 条件分支JSON处理
7. AbstractAuthWeChatEnterpriseRequest.java - 企业微信登录
8. AuthDingTalkV2Request.java - 钉钉登录

安全提升:消除FastJson反序列化RCE漏洞攻击面

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 14:59:20 +08:00
ageerle
7640de34e5 Merge pull request #318 from ageerle/feat/register-default-role-and-misc
feat: 注册默认角色绑定 + 短剧流式超时兜底 + trace 测试适配
2026-07-28 11:25:37 +08:00
ageerle
77846601ee test(retrieval): 适配 KnowledgeRetrievalServiceImpl 新增 trace 依赖
构造测试实例时补上 TraceRecordService 与 TraceProperties 两个新参数,
修复编译/构造失败。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 11:22:26 +08:00
ageerle
b80dc6e23f fix(shortdrama): 流式生成增加首 token 90 秒超时兜底
部分聚合站对 stream=true 既不返回内容也不报错,外层 30 分钟总超时
才会失败,前端会长时间卡死。90 秒内未收到任何 token 时快速失败,
提示更换模型或使用同步生成。收到首 token 后取消兜底计时。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 11:22:19 +08:00
ageerle
176cc67a5c feat(register): 新用户注册成功后绑定默认角色并补齐缺失菜单权限
- SysRegisterService: 注册成功后读取 sys.register.defaultRoleId 配置,
  为新用户绑定默认角色;未配置则静默跳过,不影响注册流程
- SysUserServiceImpl.registerUser: insert 后回写 userId 主键,
  供调用方绑定默认角色或登录使用
- SQL: 修正 知识管理 父菜单 perms(knowledge:info:list -> system:info:list),
  新增 system:session:* / system:attach:* / system:fragment:* 菜单,
  新建 普通用户 角色(租户 000000,data_scope=5 仅本人)及角色-菜单关联,
  写入 sys.register.defaultRoleId 配置项

解决注册用户无默认角色导致无权限访问 AI 对话界面、以及菜单权限标识
与控制器不一致无法授权的问题。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-28 11:22:12 +08:00
ageerle
afaa86ef6e Merge branch 'fix/sse-session-trace-cleanup' 2026-07-23 15:38:50 +08:00
ageerle
d1a820728f fix(sse): SSE 改为按会话隔离 + 修 trace 租户 bug + 清理冗余
SSE 串台修复:
- SseEmitterManager 新增按 sessionId 维度的 connect/sendEvent/disconnect,
  每个会话一个 SSE 连接,替代原 userId+token 维度(同用户多会话串台)
- SseMessageDto 增加 sessionId + eventDto 字段,跨实例按会话路由
- SseTopicListener 优先按 sessionId 路由,回退原 userId/群发逻辑
- SseMessageUtils 增加 sessionId 重载,对话链路全部切换
- ChatServiceFacade / MyMcpClientListener / WorkflowStarter 切到 sessionId
- 通知/全局 /sse 端点保留 userId 模式(通知按用户)

trace 租户 bug 修复:
- trace_run / trace_node 加入 tenant.excludes,监控表跨租户全局可见,
  绕过异步线程租户上下文不传播导致 node 查不到的问题

冗余清理:
- 删除零使用的 @TraceNode 注解 + TraceNodeAspect 切面 + 对应单测
- TraceProperties 删除 recordDetail/maxInputLength/maxOutputLength
  (仅对已删切面生效,编程式埋点用 RagTracePayloadBuilder 不受影响)
- TracePayloadUtils 删除 input/output/asString 方法
- TraceConstants 删除无引用的 NODE_METHOD/HTTP/DB/CACHE/TASK/STREAM
- TraceContext 删除预留的 copyNodeStack
- TraceNodeVo 删除未用的 children 字段
- TraceRecordServiceImpl.getDetail 删除重复 enrich
- application.yml 删除 trace.payload 无效配置项
- RagTraceNodeTypes 删除无引用的 NODE_STREAM

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-23 15:35:10 +08:00
ageerle
11bb1dba0f Merge PR #308: 通用链路追踪模块与 RAG 对话全链路埋点 2026-07-23 15:10:40 +08:00
Obltv
345d2819d8 fix: 修复链路追踪输出记录及关闭追踪时的额外开销 2026-07-23 14:52:19 +08:00
Obltv
36e3cf8c52 fix: 修复链路追踪输出记录及关闭追踪时的额外开销 2026-07-23 14:45:43 +08:00
Obltv
06ff95cdc3 Merge upstream/main into feature/common-trace-rag-chat 2026-07-23 14:30:38 +08:00
ageerle
9adeee6c83 fix(short-drama): 修复角色形象跨分镜不一致
1. findRefImageIndex 补上 appearance 参数,与 findStoryboardReferenceImages
   的调用对齐。之前多形象角色(换装/青年老年)的 @imageN 绑定查的是
   默认形象 URL,和实际参考图列表对不上,导致 prompt 里没有 @imageN 标记
2. buildEnrichedVideoPrompt 角色段追加 visualDescription,
   文字 prompt 也承载外貌信息(发型/服装/体态),不能全靠参考图

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 16:06:06 +08:00
ageerle
e42d35f3bf fix: 工作流实体保留字转义 + 千问向量模型厂商映射
1. WorkflowRuntimeNode/WorkflowRuntime: input/output/status 字段加反引号,
   修复 MySQL 8.0 保留字导致 MyBatis-Plus SQL 解析异常 (#307)
2. EmbeddingModelFactory: 新增 providerCode→BeanName 映射,
   qianwen→alibailian,修复千问向量模型找不到 Bean 的问题 (#301)

Closes #307 #301

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 15:43:36 +08:00
ageerle
a69d1f51b9 feat: 打通 thinking 流式链路 + SqlAgent 表白名单校验
1. OllamaServiceImpl 补 .think() + .returnThinking(),对齐其他 provider (#306)
2. ChatServiceFacade.createCombinedHandler 新增 onPartialThinking,
   reasoning 内容经 SseMessageUtils.sendReasoning 流式推到前端 (#303)
3. SqlAgent 系统提示词追加无表时禁止执行 SQL 的规则 (#279)
4. ExecuteSqlQueryTool 代码层硬拦截:空白名单直接拒绝,
   有白名单则校验 SQL 中 FROM/JOIN 引用的表名 (#279)

Closes #303 #306 #279

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 15:31:32 +08:00
ageerle
911ae6cb1f fix: 修复 issue IJX5VV/IJPYWL/IHPUDA
- IJX5VV: 补全工作流 9 个节点消息模板 sys_config 配置(SQL 脚本合并重命名时遗失),
  附幂等增量脚本;此前节点执行会抛「请先配置该节点的响应模板」
- IJPYWL: 向量模型未配置维度时,Milvus/Qdrant 回退默认 1024,避免 Integer 拆箱 NPE
- IHPUDA: chat_provider.provider_icon 由 varchar(255) 加宽至 varchar(1000),
  容纳 minio 私有桶签名 URL,附增量脚本

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 15:28:28 +08:00
ageerle
9a2f326e42 fix(rag): 合并后修正-升级脚本兼容 MySQL 8、重解析按 docId 清理旧向量
1. 升级脚本 2026-07-20-knowledge-fragment-fid.sql 使用了 MySQL 8 不支持的
   ADD COLUMN IF NOT EXISTS(MariaDB 语法),在存量库执行会直接语法报错。
   改为与脚本内索引守卫一致的 information_schema 判断 + PREPARE 方式,保持幂等。

2. parse() 重新解析时按 fragment.fid 删除旧向量:存量数据的 fid 为迁移脚本
   回填的 MD5 值,与向量库中实际存储的随机 fid 不一致,首次重解析无法命中
   旧向量,导致新旧向量重复累积。改为写入新向量前先按 docId 清理(三种
   向量库策略均支持),写入失败时仍补偿删除新 fid。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-21 14:33:28 +08:00
ageerle@163.com
46a8d6b552 Merge pull request #315 from MuSan-Li/update/2026-07-19-fixes
修复RAG相关逻辑优化:统一文档切割配置、向量数据生命周期、
统一检索服务(阈值/重排/缓存)、按知识库路由向量库、重新解析支持
2026-07-21 14:33:11 +08:00
evo
cf5423f69f fix(rag): 统一文档切割配置并支持重新解析 2026-07-21 12:18:19 +08:00
evo
177375a7b7 docs(rag): 更新完整修复与验收报告 2026-07-21 09:35:56 +08:00
evo
016bdbdd94 test(rag): 增加三向量库 Docker 生命周期测试 2026-07-21 09:35:56 +08:00
evo
41e0dcb528 chore(rag): 对齐默认向量配置并启用测试 2026-07-21 09:35:56 +08:00
evo
787e447d09 fix(aiflow): 接入统一知识库检索服务 2026-07-21 09:35:33 +08:00
evo
9c092ae3bb fix(chat): 统一单轮检索并完善多库上下文 2026-07-21 09:35:26 +08:00
evo
42bc8fea95 fix(rag): 完善向量路由批量写入与数据生命周期 2026-07-21 09:35:18 +08:00
evo
c4fc1e6fcf fix(rag): 隔离模型实例并修正缓存刷新 2026-07-21 09:35:07 +08:00
evo
6f6d0893ec fix(rag): 统一检索阈值重排降级与缓存语义 2026-07-21 09:34:56 +08:00
evo
a6a55202a3 fix(rag): 修复文本分片边界与字面量分隔符 2026-07-21 09:34:47 +08:00
ageerle@163.com
24bee53f9e feat: 新增 ChitChatAgent 闲聊兜底子 Agent 并接入 supervisor
简单任务无专业子 Agent 可用时由闲聊 Agent 兜底,避免 supervisor 空转返回空内容;通过 supervisorContext 约束仅在问候/闲聊场景路由到该 Agent。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-20 16:08:48 +08:00
evo
afc9d3d17d fix: 修复本地启动、数据库初始化与构建问题 (#314)
* fix: 修复本地启动、数据库初始化与构建问题

* fix: 修复pr的一些问题提交
2026-07-19 13:42:43 +08:00
evo
97ce15d116 fix: 修复pr的一些问题提交 2026-07-19 13:30:09 +08:00
evo
879fe48945 fix: 修复本地启动、数据库初始化与构建问题 2026-07-19 12:20:22 +08:00
ageerle@163.com
5d834d924a feat: 编程助手按聊天模型过滤并补充 MCP 工具 thinking 事件,README 补充 copilot/uniapp 仓库
- CodingController.models 按 category=chat 过滤,编程对话只展示聊天模型
- 各 MCP 文件/命令工具在执行前推送 thinking 提示事件
- README/README_EN 项目源码表新增 ruoyi-copilot、ruoyi-uniapp 三端链接

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 14:47:18 +08:00
ageerle@163.com
fece90b307 feat: 新增短剧音频/编码模块、MCP 文件工具与 WebSocket 支持
- 短剧: 新增 ShortDramaAudio 实体/Mapper/BO/VO,扩展 ShortDramaServiceImpl
  合成逻辑与 FfmpegFilterGraphBuilder 滤镜图
- MCP: 新增 WriteFileTool/DeleteFileTool/ExecuteCommandTool,重构
  EditFileTool/ReadFileTool/ListDirectoryTool
- 编码: 新增 coding 模块(CodingAgent/WorkspaceService/SSE 事件通道)
- Atlas: 新增音频生成实现,扩展音视频/媒体实体与预测服务
- WebSocket: 新增公众号聊天 WebSocket 处理器与握手拦截
- 忽略 logs/ 目录,避免合成产物入库

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-17 11:52:53 +08:00
ageerle@163.com
06d110ed16 @docs: 修正 snailjob 注释里失效的 ry_job.sql 引用
实际建表脚本在 docs/script/sql/ruoyi-ai-v3_mysql8.sql(sj_ 前缀表),仓库中并无 ry_job.sql。
关联 issue #311。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-15 18:25:55 +08:00
ageerle@163.com
dfcadda2bb @style: 修正 QdrantVectorStoreStrategy 缩进为空格
createSchema 调用与文件其余代码保持 4 空格缩进统一,避免 checkstyle/spotless 报错。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-15 18:00:07 +08:00
Jack Jiang
3c9546ded9 fix: 修复 Qdrant 初始化创建集合问题 (#298) 2026-07-15 17:58:12 +08:00
Octopus
a3d82e092e Refresh MiniMax models and protocol support (#313)
Co-authored-by: octo-patch <266937838+octo-patch@users.noreply.github.com>
2026-07-15 17:43:51 +08:00
ageerle@163.com
96a1b741df fix: 兼容 Atlas 预测结果查询 404,避免前端轮询刷屏
Atlas /model/prediction/{id} 对已过期或不存在的任务返回 404
(常见于更换 API Key 后残留的旧任务)。原实现直接抛异常,前端
轮询反复触发错误提示。改为 404 时返回 status=failed 的响应,
让上层走正常失败分支落库,前端识别后终止轮询。

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-15 11:17:20 +08:00
ageerle@163.com
e7b7d1d084 更新README.md
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-15 10:52:15 +08:00
ageerle@163.com
efc30c3ac8 docs: README 新增短剧服务 ruoyi-drama 源码链接
Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-14 22:30:10 +08:00
ageerle@163.com
2ae13aafd4 feat: 新增短剧/媒体生成能力并脱敏数据库脚本
- 新增音频/视频/图片生成服务与 Atlas、OpenAI 实现
- 新增短剧脚本生成、分镜与 ffmpeg 合成模块
- 新增 Coze/Dify 聊天 provider 及 Agent 配置
- 脱敏 SQL 脚本:移除真实 DeepSeek API Key,掩码 COS 桶名
- 清理过期的 SQL update 脚本与 chat 文档

Co-Authored-By: Claude <noreply@anthropic.com>
2026-07-14 21:49:03 +08:00
Obltv
e925050207 feat: 新增通用链路追踪模块与 RAG 对话全链路埋点
- 新增 ruoyi-common-trace 模块:TraceContext 上下文、TraceNodeAspect 注解切面、数据库双表持久化
- ChatServiceFacade / KnowledgeRetrievalServiceImpl 完成 RAG 对话 retrieval → rerank → llm-call 全链路采集
- 新增 TraceController 提供列表/详情/节点查询 API 及数据统计
- 支持 trace.enabled 开关、payload 长度截断、错误安全降级
- TraceNodeTemplate 模板封装标准节点生命周期,减少重复样板代码
2026-06-16 10:14:35 +08:00
ageerle@163.com
7aa67cfc2f docs: 移除赞助商区块引用样式及多余换行
- 去掉 blockquote 引用块样式消除左侧竖线
- 去掉多余 <br> 避免链接文字断行

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 18:19:04 +08:00
ageerle@163.com
6d38e2bf25 docs: 赞助商图片改用本地路径并新增火山引擎 CodingPlan
- Atlas Cloud 图片从远程链接改为 docs/image/sponsor/ 本地路径
- 新增火山引擎 CodingPlan 开发者计划赞助商(中英文 README 同步)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-10 18:14:46 +08:00
ageerle@163.com
8ed5e61f63 docs: 添加微信技术交流群二维码
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-05 10:25:18 +08:00
ageerle@163.com
c3c89f8cc8 docs: 调整中文版赞助商图标大小
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:44:42 +08:00
ageerle@163.com
a3a6bdbc55 docs: 调整英文版赞助商图标大小与中文版一致
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:43:37 +08:00
ageerle@163.com
07d9fc1f45 docs: 同步英文版 README 与中文版保持一致
- 移除英文版 Quick Start/Live Demo 章节
- 移除 Ecosystem Partners 章节,合并到 Sponsors
- 更新赞助商格式为图片横幅样式
- 社区交流改为微信/QQ 二维码(替换 Telegram)
- 移除 Acknowledgments 中的 Spring AI Alibaba Copilot
- 修复 Technical Architecture 多余空行
- 更新文档链接域名(pandarobot -> ruoyiai)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-02 11:38:48 +08:00
ageerle@163.com
73a60e3591 docs: 更新 Atlas Cloud 赞助链接添加推荐参数
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 14:37:14 +08:00
ageerle@163.com
c79848c654 feat: 替换 PPIO 为 Atlas Cloud 并增强知识库功能
- 将 PPIO 服务提供商替换为 Atlas Cloud
- 更新 README 赞助商信息
- 删除 PPIOEmbeddingProvider 和相关测试
- 知识库新增重排序、混合检索、相似度阈值等字段
- 更新 SQL 初始化脚本

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 11:18:59 +08:00
ageerle@163.com
ec092a11c3 docs: 添加 web coding 快速部署说明
在 README 中新增使用 web coding 急速部署的章节,包含在线体验链接和部署截图展示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-30 17:45:16 +08:00
ageerle
9a7b727413 Merge pull request #293 from RobustH/main
升级RAG模块
2026-04-23 09:15:02 +08:00
RobustH
b8d16b7669 feat(rag): 对接用户端用户知识库对话,集成知识库配置应用 2026-04-23 00:52:53 +08:00
RobustH
058a4aee2a feat(rag): 新增测试配置应用的功能 2026-04-21 22:54:11 +08:00
RobustH
1b50c7f9f1 fix(rag): 修复合并重复,重排模型新增硅基流动供应商 2026-04-21 22:41:00 +08:00
RobustH
e7f53fd55f Merge remote-tracking branch 'origin/main'
# Conflicts:
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/bo/knowledge/KnowledgeInfoBo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/entity/knowledge/KnowledgeInfo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/domain/vo/knowledge/KnowledgeInfoVo.java
#	ruoyi-modules/ruoyi-chat/src/main/java/org/ruoyi/service/chat/impl/ChatServiceFacade.java
2026-04-21 21:41:51 +08:00
ageerle
07bdc5e585 Merge pull request #292 from yangzhen233/feature/rerank-model
Feature/rerank model
2026-04-20 21:06:27 +08:00
yangzhen
e1b8a5f011 新增千问3重排序模型,并附带新增sql文件 2026-04-20 16:07:02 +08:00
杨振
80ca76ea37 添加重排序功能 2026-04-20 01:02:09 +08:00
wangle
2c6ff66830 fix: 修正application.yml演示模式message缩进
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 13:42:39 +08:00
wangle
4f79a66559 feat: 添加小米MiMo、DeepSeek、自定义厂商等provider支持
- 新增小米MiMo服务实现类(MiMoServiceImpl)
- ChatModeType添加XIAOMI枚举
- 更新SQL初始化脚本,新增多家厂商(provider)和模型数据
- 添加2026-04-19数据库更新脚本
- application.yml演示模式排除路径增加attach/fragment/info接口
- 删除独立的minimax_provider.sql(数据已合并到主SQL)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 13:42:05 +08:00
wangle
22883b4334 Merge branch pr-280: 添加MiniMax作为LLM提供商
解决冲突:
- README: 保留Qdrant向量库信息 + 合并MiniMax模型接入
- pom.xml: 保留spring-boot-starter-test + 添加MiniMax测试依赖
- ChatModeType: 保留CUSTOM_API + 新增MINIMAX枚举
- MinimaxServiceImpl: 保留MyChatModelListener监听器

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-19 11:47:04 +08:00
wangle
081da6d18d feat: 添加MiniMax作为LLM提供商,合并PR#280并补充监听
合并PR#280的MiniMax provider实现,解决与main分支的冲突,
并在MinimaxServiceImpl中补充MyChatModelListener监听,
与其他provider保持一致。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-17 18:31:53 +08:00
ageerle
74eb5b2530 Merge pull request #290 from yangzhen233/feature/zhipu-embedding
添加智谱向量模型实现
2026-04-17 18:24:24 +08:00
ageerle
b0328fe0ef Merge pull request #291 from xiaonieli7/main
fate:增加自定义模型,调整前端模型选择下拉框
2026-04-17 18:16:59 +08:00
Administrator
2ee0aae57e fate:增加自定义模型,调整前端模型选择下拉框 2026-04-17 08:31:40 +08:00
杨振
d9c3de660a 添加智谱向量模型实现 2026-04-16 21:18:11 +08:00
RobustH
ccbf5c9520 feat(rag): 知识库检索测试新增混合检索 2026-04-14 23:18:29 +08:00
ageerle
c4f7c1f5d0 Merge pull request #283 from MrWws/fix/docker-compose-all.yaml
fix: 修复运行docker-compose-all.yaml报错的问题
2026-04-14 14:36:14 +08:00
RobustH
1208c46cca feat(rag): 集成硅基流动、阿里百炼重排模型并全方位增强检索测试体验 2026-04-14 01:40:28 +08:00
RobustH
06a63c377e feat: 新增检索测试相关接口
- 实现向量 L2 归一化,统一 Milvus/Qdrant/Weaviate 检索评分为 [0, 1] 空间
2026-04-13 23:33:56 +08:00
RobustH
0fa25032a3 feat(knowledge): 优化知识库文件状态枚举为"未解析,解析中,解析成功,解析失败",支持异步线程池解析文档 2026-04-13 00:15:01 +08:00
RobustH
28ad29d6ed feat(knowledge): 完善知识库及附件统计功能并修复分块数统计问题 2026-04-12 18:38:32 +08:00
MrWws
b9097b4989 fix: 修复运行docker-compose-all.yaml报错的问题 2026-03-31 22:59:26 +08:00
octopus
5d14eb20af feat: add MiniMax as first-class LLM provider
Add MiniMax AI as the 7th LLM provider, supporting chat (M2.7, M2.5,
M2.5-highspeed) and embedding (embo-01) models via OpenAI-compatible API.

Changes:
- Add MINIMAX enum to ChatModeType
- Add MinimaxServiceImpl chat provider (OpenAI-compat streaming)
- Add MinimaxEmbeddingProvider for vector embeddings
- Add SQL migration for provider and model registration
- Add 14 unit tests + 3 integration tests
- Update README/README_EN with MiniMax in provider list
2026-03-21 16:14:19 +08:00
957 changed files with 79324 additions and 4351 deletions

133
.github/workflows/publish-images.yml vendored Normal file
View File

@@ -0,0 +1,133 @@
name: Publish Docker Images
on:
push:
tags:
- 'v*.*.*'
workflow_dispatch:
inputs:
release_tag:
description: Release tag to rebuild
required: true
type: string
concurrency:
group: publish-images-${{ inputs.release_tag || github.ref_name }}
cancel-in-progress: false
env:
REGISTRY: ghcr.io
IMAGE_OWNER: ${{ github.repository_owner }}
RELEASE_TAG: ${{ inputs.release_tag || github.ref_name }}
jobs:
publish:
name: Publish ${{ matrix.image }}
runs-on: ubuntu-latest
permissions:
contents: read
packages: write
attestations: write
id-token: write
strategy:
fail-fast: false
matrix:
include:
- image: ruoyi-ai-backend
source: local
context: .
dockerfile: docs/docker/ruoyi-ai/Dockerfile.backend
- image: ruoyi-ai-mysql
source: local
context: .
dockerfile: docs/docker/ruoyi-ai/Dockerfile.mysql
- image: ruoyi-ai-admin
source: admin
context: build/ruoyi-admin
dockerfile: build/ruoyi-admin/apps/web-antd/Dockerfile
- image: ruoyi-ai-web
source: web
context: build/ruoyi-web
dockerfile: build/ruoyi-web/Dockerfile.frontend
steps:
- name: Checkout backend repository
uses: actions/checkout@v6
with:
ref: ${{ env.RELEASE_TAG }}
fetch-depth: 1
- name: Checkout admin repository
if: matrix.source == 'admin'
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/ruoyi-admin
ref: ${{ env.RELEASE_TAG }}
path: build/ruoyi-admin
fetch-depth: 1
- name: Checkout web repository
if: matrix.source == 'web'
uses: actions/checkout@v6
with:
repository: ${{ github.repository_owner }}/ruoyi-web
ref: ${{ env.RELEASE_TAG }}
path: build/ruoyi-web
fetch-depth: 1
- name: Configure frontend dependency builds
if: matrix.source == 'admin' || matrix.source == 'web'
shell: bash
run: |
python3 - "${{ matrix.dockerfile }}" <<'PY'
from pathlib import Path
import sys
dockerfile = Path(sys.argv[1])
content = dockerfile.read_text()
marker = "pnpm install --frozen-lockfile"
replacement = (
"pnpm install --frozen-lockfile "
"--config.dangerously-allow-all-builds=true"
)
if marker not in content:
raise SystemExit(f"pnpm install command not found in {dockerfile}")
dockerfile.write_text(content.replace(marker, replacement, 1))
PY
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Log in to GHCR
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_OWNER }}/${{ matrix.image }}
tags: |
type=raw,value=${{ env.RELEASE_TAG }}
type=raw,value=latest
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository }}
org.opencontainers.image.version=${{ env.RELEASE_TAG }}
- name: Build and push image
uses: docker/build-push-action@v6
with:
context: ${{ matrix.context }}
file: ${{ matrix.dockerfile }}
platforms: linux/amd64
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
cache-from: type=gha,scope=${{ matrix.image }}
cache-to: type=gha,mode=max,scope=${{ matrix.image }}
provenance: true
sbom: true

6
.gitignore vendored
View File

@@ -23,6 +23,9 @@ target/
.idea
.claude
.github
!.github/
!.github/workflows/
!.github/workflows/**
*.iws
*.iml
*.ipr
@@ -45,6 +48,7 @@ nbdist/
*.xml.versionsBackup
*.swp
data/
logs/
!*/build/*.java
!*/build/*.html
@@ -52,3 +56,5 @@ data/
.flattened-pom.xml
/.claude/settings.local.json
/docs/docker/milvus/volumes/
/.codex-runtime/

327
README.md
View File

@@ -2,11 +2,7 @@
<div align="center">
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
[![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![MIT License][license-shield]][license-url]
<p align="center">
@@ -17,226 +13,268 @@
<img src="docs/image/logo.png" alt="RuoYi AI Logo" width="120" height="120">
### 企业级AI助手平台
### Enterprise-Grade AI Assistant Platform
*开箱即用的全栈AI平台,支持多智能体协同、Supervisor模式编排、多种决策模式、RAG技术和流程编排能力*
*An out-of-the-box full-stack AI platform supporting multi-agent collaboration, Supervisor mode orchestration, and multiple decision models, with advanced RAG technology and visual workflow orchestration capabilities*
**[English](README_EN.md)** | **[📖 使用文档](https://doc.pandarobot.chat)** |
**[🚀 在线体验](https://web.pandarobot.chat)** | **[🐛 问题反馈](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 功能建议](https://github.com/ageerle/ruoyi-ai/issues)**
**[中文](README_ZH.md)** | **[📖 Documentation](https://doc.ruoyiai.chat/)** |
**[🚀 Live Demo](https://web.ruoyiai.chat/)** | **[🐛 Report Issues](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 Feature Requests](https://github.com/ageerle/ruoyi-ai/issues)**
</div>
## ✨ 核心亮点
## 🚀 Live Demo
| 模块 | 现有能力
|:----------:|---
| **模型管理** | 多模型接入(OpenAI/DeepSeek/通义/智谱)、多模态理解、Coze/DIFY/FastGPT平台集成
| **知识管理** | 本地RAG + 向量库(Milvus/Weaviate/Qdrant) + 文档解析
| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态
| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点
| **多智能体** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型
| Service | URL | Login Method |
|---|---|---|
| Short Drama Demo | [drama.ruoyiai.chat](https://drama.ruoyiai.chat/) | QR code login |
| User Frontend Demo | [web.ruoyiai.chat](https://web.ruoyiai.chat/) | QR code login |
| Coding Demo | [code.ruoyiai.chat](https://code.ruoyiai.chat/) | QR code login |
## 🚀 快速体验
## ✨ Core Features
### 在线演示
| Module | Current Capabilities |
|:---:|---|
| **Model Management** | Multi-model integration (DeepSeek/Zhipu/MIMO/Bailian/OpenAI), multi-modal understanding, Coze/DIFY/FastGPT/RAGFlow platform integration |
| **Knowledge Management** | Local RAG + Vector DB (Milvus/Weaviate/Qdrant) + Document parsing |
| **Tool Management** | MCP protocol integration, Skills capability + Extensible tool ecosystem |
| **Workflow Orchestration** | Visual workflow designer, drag-and-drop node orchestration, SSE streaming execution, currently supports model calls, email sending, manual review, and other nodes |
| **Multi-Agent** | Agent framework based on Langchain4j, Supervisor mode orchestration, supports multiple decision models, can flexibly combine tools and skills |
| 平台 | 地址 | 账号 |
|:------:|---|---|
| 用户端 | [web.pandarobot.chat](https://web.pandarobot.chat) | admin / admin123 |
| 管理后台 | [admin.pandarobot.chat](https://admin.pandarobot.chat) | admin / admin123 |
### Project Repositories
### 项目源码
| 项目模块 | GitHub 仓库 | Gitee 仓库 | GitCode 仓库 |
| Module | GitHub Repository | Gitee Repository | GitCode Repository |
|----------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
| 🔧 后端服务 | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
| 🎨 用户前端 | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
| 🛠️ 管理后台 | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
| 🔧 Backend | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
| 🎨 User Frontend | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
| 🛠️ Admin Panel | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
| 🎬 Drama | [ruoyi-drama](https://github.com/ageerle/ruoyi-drama) | [ruoyi-drama](https://gitee.com/ageerle/ruoyi-drama) | [ruoyi-drama](https://gitcode.com/ageerle/ruoyi-drama) |
| 🤖 Copilot | [ruoyi-copilot](https://github.com/ageerle/ruoyi-copilot) | [ruoyi-copilot](https://gitee.com/ageerle/ruoyi-copilot) | [ruoyi-copilot](https://gitcode.com/ageerle/ruoyi-copilot) |
| 📱 Mini-App | [ruoyi-uniapp](https://github.com/ageerle/ruoyi-uniapp) | [ruoyi-uniapp](https://gitee.com/ageerle/ruoyi-uniapp) | [ruoyi-uniapp](https://gitcode.com/ageerle/ruoyi-uniapp) |
### 合作项目
| 项目名称 | GitHub 仓库 | Gitee 仓库
### Partner Projects
| Project Name | GitHub Repository | Gitee Repository |
|----------------|-------------------------------------------------------|------------------------------------------------------|
| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
## 🛠️ 技术架构
## 🛠️ Technical Architecture
### 核心框架
- **后端架构**:Spring Boot 3.5.8 + Langchain4j
- **数据存储**:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate/Qdrant)
- **前端技术**:Vue 3 + Vben Admin + element-plus-x
- **安全认证**:Sa-Token + JWT 双重保障
### Core Framework
- **Backend**: Spring Boot 3.5.8 + Langchain4j
- **Data Storage**: MySQL 8.0 + Redis + Vector Databases (Milvus/Weaviate/Qdrant)
- **Frontend**: Vue 3 + Vben Admin + element-plus-x
- **Security**: Sa-Token + JWT dual-layer security
- **Document Processing**: PDF, Word, Excel parsing, intelligent image analysis
- **Real-time Communication**: WebSocket real-time communication, SSE streaming response
- **System Monitoring**: Comprehensive logging system, performance monitoring, service health checks
## 🐳 Docker Deployment
- **文档处理**:PDF、Word、Excel 解析,图像智能分析
- **实时通信**:WebSocket 实时通信,SSE 流式响应
- **系统监控**:完善的日志体系、性能监控、服务健康检查
This project provides two Docker deployment methods:
## 🐳 Docker 部署
### Method 1: One-click Start All Services (Recommended)
本项目提供两种 Docker 部署方式:
### 方式一:一键启动所有服务(推荐)
使用 `docker-compose-all.yaml` 可以一键启动所有服务(包括后端、管理端、用户端及依赖服务):
Use `docker-compose-all.yaml` to start all services at once (including backend, admin panel, user frontend, and dependencies):
#### Requirements
- Docker Engine(Linux/macOS)或 Docker Desktop(Windows)
- Docker Compose V2
#### Linux / macOS
```bash
# 克隆仓库
git clone https://github.com/ageerle/ruoyi-ai.git
# Clone the v3.1.0 release
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# 启动所有服务(从镜像仓库拉取预构建镜像)
docker-compose -f docker-compose-all.yaml up -d
# Pin the image version. Public GHCR images do not require docker login.
cp docs/docker/ruoyi-ai/.env.example docs/docker/ruoyi-ai/.env
sed -i 's/^RUIYI_VERSION=.*/RUIYI_VERSION=v3.1.0/' docs/docker/ruoyi-ai/.env
# 查看服务状态
docker-compose -f docker-compose-all.yaml ps
# Pull pre-built images from GHCR and start all services
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml pull
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml up -d
# 访问服务
# 管理端: http://localhost:25666 (admin / admin123)
# 用户端: http://localhost:25137
# 后端API: http://localhost:26039
# Check service status
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml ps
# Access services (replace SERVER_IP with the server address)
# Admin Panel: http://SERVER_IP:25666 (admin / admin123)
# User Frontend: http://SERVER_IP:25137
# Backend API: http://SERVER_IP:26039
```
### 方式二:分步部署(源码编译)
#### Windows PowerShell
If you are using Windows with Docker Desktop, you can use PowerShell to execute the following commands:
如果您需要从源码构建后端服务,请按照以下步骤操作:
```PowerShell
#### 第一步:部署后端服务
```bash
# 进入后端项目目录
# Clone the v3.1.0 release
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# 启动后端服务(源码编译构建)
# Create the environment configuration file
Copy-Item docs\docker\ruoyi-ai\.env.example docs\docker\ruoyi-ai\.env
# Pin the image version
(Get-Content docs\docker\ruoyi-ai\.env) `
-replace '^RUIYI_VERSION=.*', 'RUIYI_VERSION=v3.1.0' |
Set-Content docs\docker\ruoyi-ai\.env
# Check the environment configuration
Get-Content docs\docker\ruoyi-ai\.env
# Pull pre-built images from GHCR and start all services
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml pull
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml up -d
# Check service status
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml ps
```
The default Compose file also publishes MySQL (`23306`), Redis (`26379`),
Weaviate (`28080`), and MinIO (`29000`/`29090`). For production deployments,
change the default MySQL and MinIO passwords and expose only the application
ports through the firewall or a reverse proxy.
To upgrade to another published release, update `RUIYI_VERSION` in
`docs/docker/ruoyi-ai/.env`, then run `docker compose pull` and
`docker compose up -d` with the same `--env-file` and `-f` options. Do not use
`docker compose down -v` unless you intend to delete persistent data volumes.
### Method 2: Step-by-step Deployment (Source Build)
If you need to build backend services from source, follow these steps:
#### Step 1: Deploy Backend Service
```bash
# Enter backend project directory
cd ruoyi-ai
# Start backend service (build from source)
docker-compose up -d --build
# 等待后端服务启动完成
# Wait for backend service to start
docker-compose logs -f backend
```
#### 第二步:部署管理端
#### Step 2: Deploy Admin Panel
```bash
# 进入管理端项目目录
# Enter admin panel project directory
cd ruoyi-admin
# 构建并启动管理端
# Build and start admin panel
docker-compose up -d --build
# 访问管理端
# 地址: http://localhost:5666
# Access admin panel
# URL: http://localhost:5666
```
#### 第三步:部署用户端(可选)
#### Step 3: Deploy User Frontend (Optional)
```bash
# 进入用户端项目目录
# Enter user frontend project directory
cd ruoyi-web
# 构建并启动用户端
# Build and start user frontend
docker-compose up -d --build
# 访问用户端
# 地址: http://localhost:5137
# Access user frontend
# URL: http://localhost:5137
```
### 服务端口说明
### Service Ports
| 服务 | 一键启动端口 | 分步部署端口 | 说明 |
| Service | One-click Port | Step-by-step Port | Description |
|------|-------------|-------------|------|
| 管理端 | 25666 | 5666 | 管理后台访问地址 |
| 用户端 | 25137 | 5137 | 用户前端访问地址 |
| 后端服务 | 26039 | 6039 | 后端 API 服务 |
| MySQL | 23306 | 23306 | 数据库服务 |
| Redis | 26379 | 6379 | 缓存服务 |
| Weaviate | 28080 | 28080 | 向量数据库 |
| MinIO API | 29000 | 9000 | 对象存储 API |
| MinIO Console | 29090 | 9090 | 对象存储控制台 |
| Admin Panel | 25666 | 5666 | Admin backend access |
| User Frontend | 25137 | 5137 | User frontend access |
| Backend Service | 26039 | 6039 | Backend API service |
| MySQL | 23306 | 23306 | Database service |
| Redis | 26379 | 6379 | Cache service |
| Weaviate | 28080 | 28080 | Vector database |
| MinIO API | 29000 | 9000 | Object storage API |
| MinIO Console | 29090 | 9090 | Object storage console |
### 镜像仓库
## 📚 Documentation
所有镜像托管在阿里云容器镜像服务:
Want to learn more about installation, deployment, configuration, and secondary development?
```
crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
```
**👉 [Complete Documentation](https://doc.ruoyiai.chat/)**
可用镜像:
- `mysql:v3` - MySQL 数据库(包含初始化 SQL)
- `redis:6.2` - Redis 缓存
- `weaviate:1.30.0` - 向量数据库
- `minio:latest` - 对象存储
- `ruoyi-ai-backend:latest` - 后端服务
- `ruoyi-ai-admin:latest` - 管理端前端
- `ruoyi-ai-web:latest` - 用户端前端
- [Model and API Key configuration in ruoyi-admin (Chinese)](docs/model-configuration.md)
- [Dify Cloud setup for local development (Chinese)](docs/dify-cloud.md)
### 常用命令
## 🤝 Contributing
```bash
# 停止所有服务
docker-compose -f docker-compose-all.yaml down
We warmly welcome community contributions! Whether you are a seasoned developer or just getting started, you can contribute to the project 💪
# 查看服务日志
docker-compose -f docker-compose-all.yaml logs -f [服务名]
### How to Contribute
# 重启某个服务
docker-compose -f docker-compose-all.yaml restart [服务名]
```
1. **Fork** the project to your account
2. **Create a branch** (`git checkout -b feature/new-feature-name`)
3. **Commit your changes** (`git commit -m 'Add new feature'`)
4. **Push to the branch** (`git push origin feature/new-feature-name`)
5. **Create a Pull Request**
## 📚 使用文档
> 💡 **Tip**: We recommend submitting PRs to GitHub, we will automatically sync to other code hosting platforms
想要深入了解安装部署、功能配置和二次开发?
## 📄 License
**👉 [完整使用文档](https://doc.pandarobot.chat)**
This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
## 🤝 参与贡献
## 🙏 Acknowledgments
我们热烈欢迎社区贡献!无论您是资深开发者还是初学者,都可以为项目贡献力量 💪
Thanks to the following excellent open-source projects for their support:
- [Langchain4j](https://github.com/langchain4j/langchain4j) - Powerful Java LLM development framework
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - Mature enterprise-level rapid development framework
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - Modern Vue admin template
### 贡献方式
## 💎 Sponsors
1. **Fork** 项目到您的账户
2. **创建分支** (`git checkout -b feature/新功能名称`)
3. **提交代码** (`git commit -m '添加某某功能'`)
4. **推送分支** (`git push origin feature/新功能名称`)
5. **发起 Pull Request**
**Thanks to the following sponsors for supporting this project:**
> 💡 **小贴士**:建议将 PR 提交到 GitHub,我们会自动同步到其他代码托管平台
<a href="https://www.atlascloud.ai?ref=89F97E">
<img src="docs/image/sponsor/atlascloud_banner.png" alt="Atlas Cloud" width="160" height="80">
</a>
## 📄 开源协议
[Visit Atlas Cloud](https://www.atlascloud.ai?ref=89F97E&utm_source=github&utm_campaign=ruoyi-drama) · [Coding Plan Promotion](https://www.atlascloud.ai/console/coding-plan)
A full-modal AI inference platform that gives developers a unified AI API, supporting video generation, image generation, and LLMs. Connect once to access **300+ curated models**.
本项目采用 **MIT 开源协议**,详情请查看 [LICENSE](LICENSE) 文件。
<a href="https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai">
<img src="docs/image/sponsor/huoshan.png" alt="Volcengine CodingPlan" width="160" height="80">
</a>
## 🙏 特别鸣谢
[Sign up to claim 25 million tokens — go now](https://www.volcengine.com/activity/ai618?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai)
Enjoy ByteDance's in-house Doubao models plus full-power open-source SOTA models, covering text, VLM, and image generation — all modalities in one stop: Seed-2.1, Seedream-5.0, GLM-5.2, DeepSeek, and more. Not just for coding — it can also tackle complex long-horizon Agent tasks!
感谢以下优秀的开源项目为本项目提供支持:
- [Spring AI Alibaba Copilot](https://github.com/spring-ai-alibaba/copilot) - 基于spring-ai-alibaba
的智能编码助手
- [Langchain4j](https://github.com/langchain4j/langchain4j) - 强大的 Java LLM 开发框架
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - 成熟的企业级快速开发框架
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - 现代化的 Vue 后台管理模板
## 🌐 生态伙伴
- [PPIO 派欧云](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - 提供高性价比的 GPU
算力和模型 API 服务
- [优云智算](https://www.compshare.cn/?ytag=GPU_YY-gh_ruoyi) - 万卡RTX40系GPU+海内外主流模型API服务,秒级响应,按量计费,新客免费用。
## 💬 社区交流
## 💬 Community Chat
<div align="center">
<table>
<tr>
<td align="center">
<img src="docs/image/wx.png" alt="微信二维码" width="200" height="200"><br>
<strong>扫码添加作者微信</strong><br>
<em>邀请进群学习</em>
<img src="docs/image/wx.png" alt="WeChat QR Code" width="200" height="200"><br>
<strong>Scan to add author on WeChat</strong><br>
<em>Join group for learning</em>
</td>
<td align="center">
<img src="docs/image/qq.png" alt="QQ群二维码" width="200" height="200"><br>
<strong>QQ技术交流群</strong><br>
<em>技术讨论</em>
<img src="docs/image/douyin.png" alt="Douyin QR Code" width="200" height="200"><br>
<strong>Douyin Video Tutorials</strong><br>
<em>Open Douyin, scan & follow to watch video tutorials</em>
</td>
<td align="center">
<img src="docs/image/qq.png" alt="QQ Group QR Code" width="200" height="200"><br>
<strong>QQ Tech Exchange Group</strong><br>
<em>Technical discussion</em>
</td>
</tr>
@@ -245,11 +283,12 @@ docker-compose -f docker-compose-all.yaml restart [服务名]
</div>
---
<div align="center">
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-ai)** • **[ Fork 开始贡献](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 English](README_EN.md)** • **[📖 查看完整文档](https://doc.pandarobot.chat)**
**[⭐ Star to Support](https://github.com/ageerle/ruoyi-ai)** • **[Fork to Contribute](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 中文](README_ZH.md)** • **[📖 Complete Documentation](https://doc.ruoyiai.chat/)**
*用 ❤️ 打造,由 RuoYi AI 开源社区维护*
*Built with ❤️, maintained by the RuoYi AI open-source community*
</div>

View File

@@ -1,266 +0,0 @@
# RuoYi AI
<div align="center">
[![Contributors][contributors-shield]][contributors-url]
[![Forks][forks-shield]][forks-url]
[![Stargazers][stars-shield]][stars-url]
[![Issues][issues-shield]][issues-url]
[![MIT License][license-shield]][license-url]
<p align="center">
<a href="https://trendshift.io/repositories/13209">
<img src="https://trendshift.io/api/badge/repositories/13209" alt="GitHub Trending">
</a>
</p>
<img src="docs/image/logo.png" alt="RuoYi AI Logo" width="120" height="120">
### Enterprise-Grade AI Assistant Platform
*An out-of-the-box full-stack AI platform supporting multi-agent collaboration, Supervisor mode orchestration, and multiple decision models, with advanced RAG technology and visual workflow orchestration capabilities*
**[中文](README.md)** | **[📖 Documentation](https://doc.pandarobot.chat)** |
**[🚀 Live Demo](https://web.pandarobot.chat)** | **[🐛 Report Issues](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 Feature Requests](https://github.com/ageerle/ruoyi-ai/issues)**
</div>
## ✨ Core Features
| Module | Current Capabilities |
|:---:|---|
| **Model Management** | Multi-model integration (OpenAI/DeepSeek/Tongyi/Zhipu), multi-modal understanding, Coze/DIFY/FastGPT platform integration |
| **Knowledge Base** | Local RAG + Vector DB (Milvus/Weaviate/Qdrant) + Document parsing |
| **Tool Management** | MCP protocol integration, Skills capability + Extensible tool ecosystem |
| **Workflow Orchestration** | Visual workflow designer, drag-and-drop node orchestration, SSE streaming execution, currently supports model calls, email sending, manual review nodes |
| **Multi-Agent** | Agent framework based on Langchain4j, Supervisor mode orchestration, supports multiple decision models |
## 🚀 Quick Start
### Live Demo
| Platform | URL | Account |
|:------:|---|---|
| User Frontend | [web.pandarobot.chat](https://web.pandarobot.chat) | admin / admin123 |
| Admin Panel | [admin.pandarobot.chat](https://admin.pandarobot.chat) | admin / admin123 |
### Project Repositories
| Module | GitHub Repository | Gitee Repository | GitCode Repository |
|----------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
| 🔧 Backend | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
| 🎨 User Frontend | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
| 🛠️ Admin Panel | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
### Partner Projects
| Project Name | GitHub Repository | Gitee Repository |
|----------------|-------------------------------------------------------|------------------------------------------------------|
| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
## 🛠️ Technical Architecture
### Core Framework
- **Backend**: Spring Boot 3.5.8 + Langchain4j
- **Data Storage**: MySQL 8.0 + Redis + Vector Databases (Milvus/Weaviate/Qdrant)
- **Frontend**: Vue 3 + Vben Admin + element-plus-x
- **Security**: Sa-Token + JWT dual-layer security
- **Document Processing**: PDF, Word, Excel parsing, intelligent image analysis
- **Real-time Communication**: WebSocket real-time communication, SSE streaming response
- **System Monitoring**: Comprehensive logging system, performance monitoring, service health checks
## 🐳 Docker Deployment
This project provides two Docker deployment methods:
### Method 1: One-click Start All Services (Recommended)
Use `docker-compose-all.yaml` to start all services at once (including backend, admin panel, user frontend, and dependencies):
```bash
# Clone the repository
git clone https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# Start all services (pull pre-built images from registry)
docker-compose -f docker-compose-all.yaml up -d
# Check service status
docker-compose -f docker-compose-all.yaml ps
# Access services
# Admin Panel: http://localhost:25666 (admin / admin123)
# User Frontend: http://localhost:25137
# Backend API: http://localhost:26039
```
### Method 2: Step-by-step Deployment (Source Build)
If you need to build backend services from source, follow these steps:
#### Step 1: Deploy Backend Service
```bash
# Enter backend project directory
cd ruoyi-ai
# Start backend service (build from source)
docker-compose up -d --build
# Wait for backend service to start
docker-compose logs -f backend
```
#### Step 2: Deploy Admin Panel
```bash
# Enter admin panel project directory
cd ruoyi-admin
# Build and start admin panel
docker-compose up -d --build
# Access admin panel
# URL: http://localhost:5666
```
#### Step 3: Deploy User Frontend (Optional)
```bash
# Enter user frontend project directory
cd ruoyi-web
# Build and start user frontend
docker-compose up -d --build
# Access user frontend
# URL: http://localhost:5137
```
### Service Ports
| Service | One-click Port | Step-by-step Port | Description |
|------|-------------|-------------|------|
| Admin Panel | 25666 | 5666 | Admin backend access |
| User Frontend | 25137 | 5137 | User frontend access |
| Backend Service | 26039 | 6039 | Backend API service |
| MySQL | 23306 | 23306 | Database service |
| Redis | 26379 | 6379 | Cache service |
| Weaviate | 28080 | 28080 | Vector database |
| MinIO API | 29000 | 9000 | Object storage API |
| MinIO Console | 29090 | 9090 | Object storage console |
### Image Registry
All images are hosted on Alibaba Cloud Container Registry:
```
crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
```
Available images:
- `mysql:v3` - MySQL database (includes initialization SQL)
- `redis:6.2` - Redis cache
- `weaviate:1.30.0` - Vector database
- `minio:latest` - Object storage
- `ruoyi-ai-backend:latest` - Backend service
- `ruoyi-ai-admin:latest` - Admin frontend
- `ruoyi-ai-web:latest` - User frontend
### Common Commands
```bash
# Stop all services
docker-compose -f docker-compose-all.yaml down
# View service logs
docker-compose -f docker-compose-all.yaml logs -f [service-name]
# Restart a service
docker-compose -f docker-compose-all.yaml restart [service-name]
```
## 📚 Documentation
Want to learn more about installation, deployment, configuration, and secondary development?
**👉 [Complete Documentation](https://doc.pandarobot.chat)**
## 🤝 Contributing
We warmly welcome community contributions! Whether you are a seasoned developer or just getting started, you can contribute to the project 💪
### How to Contribute
1. **Fork** the project to your account
2. **Create a branch** (`git checkout -b feature/new-feature-name`)
3. **Commit your changes** (`git commit -m 'Add new feature'`)
4. **Push to the branch** (`git push origin feature/new-feature-name`)
5. **Create a Pull Request**
> 💡 **Tip**: We recommend submitting PRs to GitHub, we will automatically sync to other code hosting platforms
## 📄 License
This project is licensed under the **MIT License**. See the [LICENSE](LICENSE) file for details.
## 🙏 Acknowledgments
Thanks to the following excellent open-source projects for their support:
- [Spring AI Alibaba Copilot](https://github.com/spring-ai-alibaba/copilot) - Intelligent coding assistant based on spring-ai-alibaba
- [Langchain4j](https://github.com/langchain4j/langchain4j) - Powerful Java LLM development framework
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - Mature enterprise-level rapid development framework
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - Modern Vue admin template
## 🌐 Ecosystem Partners
- [PPIO Cloud](https://ppinfra.com/user/register?invited_by=P8QTUY&utm_source=github_ruoyi-ai) - Provides cost-effective GPU computing and model API services
- [Youyun Intelligent Computing](https://www.compshare.cn/?ytag=GPU_YY-gh_ruoyi) - Thousands of RTX40 series GPUs + mainstream models API services, second-level response, pay-per-use, free for new customers.
## 💬 Community Chat
<div align="center">
**[📱 Join Telegram Group](
https://t.me/+LqooQAc5HxRmYmE1)**
</div>
---
<div align="center">
**[⭐ Star to Support](https://github.com/ageerle/ruoyi-ai)** • **[Fork to Contribute](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 中文](README.md)** • **[📖 Complete Documentation](https://doc.pandarobot.chat)**
*Built with ❤️, maintained by the RuoYi AI open-source community*
</div>
<!-- Badge Links -->
[contributors-shield]: https://img.shields.io/github/contributors/ageerle/ruoyi-ai.svg?style=flat-square
[contributors-url]: https://github.com/ageerle/ruoyi-ai/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/ageerle/ruoyi-ai.svg?style=flat-square
[forks-url]: https://github.com/ageerle/ruoyi-ai/network/members
[stars-shield]: https://img.shields.io/github/stars/ageerle/ruoyi-ai.svg?style=flat-square
[stars-url]: https://github.com/ageerle/ruoyi-ai/stargazers
[issues-shield]: https://img.shields.io/github/issues/ageerle/ruoyi-ai.svg?style=flat-square
[issues-url]: https://github.com/ageerle/ruoyi-ai/issues
[license-shield]: https://img.shields.io/github/license/ageerle/ruoyi-ai.svg?style=flat-square
[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE

312
README_ZH.md Normal file
View File

@@ -0,0 +1,312 @@
# RuoYi AI
<div align="center">
[![Contributors][contributors-shield]][contributors-url] [![Forks][forks-shield]][forks-url] [![Stargazers][stars-shield]][stars-url] [![Issues][issues-shield]][issues-url] [![MIT License][license-shield]][license-url]
<p align="center">
<a href="https://trendshift.io/repositories/13209">
<img src="https://trendshift.io/api/badge/repositories/13209" alt="GitHub Trending">
</a>
</p>
<img src="docs/image/logo.png" alt="RuoYi AI Logo" width="120" height="120">
### 企业级AI助手平台
*开箱即用的全栈AI平台,支持多智能体协同、Supervisor模式编排、多种决策模式、RAG技术和流程编排能力*
**[English](README.md)** | **[📖 使用文档](https://doc.ruoyiai.chat/)** |
**[🚀 在线体验](https://web.ruoyiai.chat/)** | **[🐛 问题反馈](https://github.com/ageerle/ruoyi-ai/issues)** | **[💡 功能建议](https://github.com/ageerle/ruoyi-ai/issues)**
</div>
## 🚀 演示地址
| 服务 | 访问地址 | 登录方式 |
|---|---|---|
| 短剧演示环境 | [drama.ruoyiai.chat](https://drama.ruoyiai.chat/) | 扫码登录 |
| 用户端演示环境 | [web.ruoyiai.chat](https://web.ruoyiai.chat/) | 扫码登录 |
| 编程演示环境 | [code.ruoyiai.chat](https://code.ruoyiai.chat/) | 扫码登录 |
## ✨ 核心亮点
| 模块 | 现有能力
|:---------:|---
| **模型管理** | 多模型接入(DeepSeek/智谱/MIMO/百炼/OpenAI)、多模态理解、Coze/DIFY/FastGPT/RAGFlow平台集成
| **知识管理** | 本地RAG + 向量库(Milvus/Weaviate/Qdrant) + 文档解析
| **工具管理** | Mcp协议集成、Skills能力 + 可扩展工具生态
| **流程编排** | 可视化工作流设计器、节点拖拽编排、SSE流式执行,目前已经支持模型调用,邮件发送,人工审核等节点
| **智能体管理** | 基于Langchain4j的Agent框架、Supervisor模式编排,支持多种决策模型,可以灵活搭配工具,skills
### 项目源码
| 项目模块 | GitHub 仓库 | Gitee 仓库 | GitCode 仓库 |
|----------|-------------------------------------------------------|------------------------------------------------------|--------------------------------------------------------|
| 🔧 后端服务 | [ruoyi-ai](https://github.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitee.com/ageerle/ruoyi-ai) | [ruoyi-ai](https://gitcode.com/ageerle/ruoyi-ai) |
| 🎨 用户前端 | [ruoyi-web](https://github.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitee.com/ageerle/ruoyi-web) | [ruoyi-web](https://gitcode.com/ageerle/ruoyi-web) |
| 🛠️ 管理后台 | [ruoyi-admin](https://github.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitee.com/ageerle/ruoyi-admin) | [ruoyi-admin](https://gitcode.com/ageerle/ruoyi-admin) |
| 🎬 短剧平台 | [ruoyi-drama](https://github.com/ageerle/ruoyi-drama) | [ruoyi-drama](https://gitee.com/ageerle/ruoyi-drama) | [ruoyi-drama](https://gitcode.com/ageerle/ruoyi-drama) |
| 🤖 编程助手 | [ruoyi-copilot](https://github.com/ageerle/ruoyi-copilot) | [ruoyi-copilot](https://gitee.com/ageerle/ruoyi-copilot) | [ruoyi-copilot](https://gitcode.com/ageerle/ruoyi-copilot) |
| 📱 小程序端 | [ruoyi-uniapp](https://github.com/ageerle/ruoyi-uniapp) | [ruoyi-uniapp](https://gitee.com/ageerle/ruoyi-uniapp) | [ruoyi-uniapp](https://gitcode.com/ageerle/ruoyi-uniapp) |
### 合作项目
| 项目名称 | GitHub 仓库 | Gitee 仓库
|----------------|-------------------------------------------------------|------------------------------------------------------|
| element-plus-x | [element-plus-x](https://github.com/element-plus-x/Element-Plus-X) | [element-plus-x](https://gitee.com/he-jiayue/element-plus-x) |
## 🛠️ 技术架构
### 核心框架
- **后端架构**:Spring Boot 3.5.8 + Langchain4j
- **数据存储**:MySQL 8.0 + Redis + 向量数据库(Milvus/Weaviate/Qdrant)
- **前端技术**:Vue 3 + Vben Admin + element-plus-x
- **安全认证**:Sa-Token + JWT 双重保障
- **文档处理**:PDF、Word、Excel 解析,图像智能分析
- **实时通信**:WebSocket 实时通信,SSE 流式响应
- **系统监控**:完善的日志体系、性能监控、服务健康检查
## 🐳 Docker 部署
本项目提供两种 Docker 部署方式:
### 方式一:一键启动所有服务(推荐)
使用 `docker-compose-all.yaml` 可以一键启动所有服务(包括后端、管理端、用户端及依赖服务):
#### 环境要求
- Docker Engine(Linux/macOS)或 Docker Desktop(Windows)
- Docker Compose V2
#### Linux / macOS
```bash
# 克隆 v3.1.0 版本
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# 固定镜像版本。GHCR 镜像已公开,无需 docker login
cp docs/docker/ruoyi-ai/.env.example docs/docker/ruoyi-ai/.env
sed -i 's/^RUIYI_VERSION=.*/RUIYI_VERSION=v3.1.0/' docs/docker/ruoyi-ai/.env
# 从 GHCR 拉取预构建镜像并启动全部服务
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml pull
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml up -d
# 查看服务状态
docker compose --env-file docs/docker/ruoyi-ai/.env \
-f docs/docker/ruoyi-ai/docker-compose-all.yaml ps
# 访问服务(将 SERVER_IP 替换为服务器地址)
# 管理端: http://SERVER_IP:25666 (admin / admin123)
# 用户端: http://SERVER_IP:25137
# 后端API: http://SERVER_IP:26039
```
#### Windows PowerShell
如果您使用 Windows + Docker Desktop,可以使用 PowerShell 执行以下命令:
```PowerShell
# 克隆 v3.1.0 版本
git clone --depth 1 --branch v3.1.0 https://github.com/ageerle/ruoyi-ai.git
cd ruoyi-ai
# 创建环境配置文件
Copy-Item docs\docker\ruoyi-ai\.env.example docs\docker\ruoyi-ai\.env
# 固定镜像版本
(Get-Content docs\docker\ruoyi-ai\.env) `
-replace '^RUIYI_VERSION=.*', 'RUIYI_VERSION=v3.1.0' |
Set-Content docs\docker\ruoyi-ai\.env
# 查看环境配置
Get-Content docs\docker\ruoyi-ai\.env
# 从 GHCR 拉取预构建镜像并启动全部服务
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml pull
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml up -d
# 查看服务状态
docker compose --env-file docs\docker\ruoyi-ai\.env `
-f docs\docker\ruoyi-ai\docker-compose-all.yaml ps
```
默认 Compose 还会发布 MySQL(`23306`)、Redis(`26379`)、Weaviate(`28080`)和
MinIO(`29000`/`29090`)端口。生产环境请修改 MySQL 和 MinIO 默认密码,并通过防火墙或反向代理只开放应用端口。
升级到其他已发布版本时,修改 `docs/docker/ruoyi-ai/.env` 中的 `RUIYI_VERSION`,然后使用相同的
`--env-file` 和 `-f` 参数执行 `docker compose pull`、`docker compose up -d`。除非确定要删除持久化数据卷,
不要执行 `docker compose down -v`。
### 方式二:分步部署(源码编译)
如果您需要从源码构建后端服务,请按照以下步骤操作:
#### 第一步:部署后端服务
```bash
# 进入后端项目目录
cd ruoyi-ai
# 启动后端服务(源码编译构建)
docker-compose up -d --build
# 等待后端服务启动完成
docker-compose logs -f backend
```
#### 第二步:部署管理端
```bash
# 进入管理端项目目录
cd ruoyi-admin
# 构建并启动管理端
docker-compose up -d --build
# 访问管理端
# 地址: http://localhost:5666
```
#### 第三步:部署用户端(可选)
```bash
# 进入用户端项目目录
cd ruoyi-web
# 构建并启动用户端
docker-compose up -d --build
# 访问用户端
# 地址: http://localhost:5137
```
### 服务端口说明
| 服务 | 一键启动端口 | 分步部署端口 | 说明 |
|------|-------------|-------------|------|
| 管理端 | 25666 | 5666 | 管理后台访问地址 |
| 用户端 | 25137 | 5137 | 用户前端访问地址 |
| 后端服务 | 26039 | 6039 | 后端 API 服务 |
| MySQL | 23306 | 23306 | 数据库服务 |
| Redis | 26379 | 6379 | 缓存服务 |
| Weaviate | 28080 | 28080 | 向量数据库 |
| MinIO API | 29000 | 9000 | 对象存储 API |
| MinIO Console | 29090 | 9090 | 对象存储控制台 |
## 📚 使用文档
想要深入了解安装部署、功能配置和二次开发?
**👉 [完整使用文档](https://doc.ruoyiai.chat/)**
- [在 ruoyi-admin 中配置模型和 API Key](docs/model-configuration.md)
- [本地开发接入 Dify 官方云服务](docs/dify-cloud.md)
## 🤝 参与贡献
我们热烈欢迎社区贡献!无论您是资深开发者还是初学者,都可以为项目贡献力量 💪
### 贡献方式
1. **Fork** 项目到您的账户
2. **创建分支** (`git checkout -b feature/新功能名称`)
3. **提交代码** (`git commit -m '添加某某功能'`)
4. **推送分支** (`git push origin feature/新功能名称`)
5. **发起 Pull Request**
> 💡 **小贴士**:建议将 PR 提交到 GitHub,我们会自动同步到其他代码托管平台
## 📄 开源协议
本项目采用 **MIT 开源协议**,详情请查看 [LICENSE](LICENSE) 文件。
## 🙏 特别鸣谢
感谢以下优秀的开源项目为本项目提供支持:
- [Langchain4j](https://github.com/langchain4j/langchain4j) - 强大的 Java LLM 开发框架
- [RuoYi-Vue-Plus](https://gitee.com/dromara/RuoYi-Vue-Plus) - 成熟的企业级快速开发框架
- [Vben Admin](https://github.com/vbenjs/vue-vben-admin) - 现代化的 Vue 后台管理模板
## 💎 赞助商
**感谢以下赞助商对本项目的支持:**
<a href="https://www.atlascloud.ai?ref=89F97E">
<img src="docs/image/sponsor/atlascloud_banner.png" alt="Atlas Cloud" width="160" height="80">
</a>
[访问Atlas Cloud官网](https://www.atlascloud.ai?ref=89F97E&utm_source=github&utm_campaign=ruoyi-drama) · [编程计划优惠](https://www.atlascloud.ai/console/coding-plan)
全模态 AI 推理平台,为开发者提供统一的 AI API,支持视频生成、图像生成和大语言模型。一次接入,即可访问 **300+ 精选模型**。
<a href="https://www.volcengine.com/activity/codingplan?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai">
<img src="docs/image/sponsor/huoshan.png" alt="火山引擎 CodingPlan" width="160" height="80">
</a>
[注册即领2500万Tokens,立即前往](https://www.volcengine.com/activity/ai618?utm_campaign=hw&utm_content=hw&utm_medium=devrel_tool_web&utm_source=OWO&utm_term=ageerle-ruoyi-ai)
享字节自研豆包模型+满血版开源 SOTA模型,覆盖文本、VLM、图像生成,全模态一站配齐:Seed-2.1、Seedream-5.0、GLM-5.2、DeepSeek等。不止编程、更能解决 Agent 复杂长程任务!
## 💬 社区交流
<div align="center">
<table>
<tr>
<td align="center">
<img src="docs/image/wx.png" alt="微信二维码" width="200" height="200"><br>
<strong>扫码添加作者微信</strong><br>
<em>邀请进群学习</em>
</td>
<td align="center">
<img src="docs/image/douyin.png" alt="抖音二维码" width="200" height="200"><br>
<strong>抖音视频教程</strong><br>
<em>打开抖音扫一扫,关注查看视频教程</em>
</td>
<td align="center">
<img src="docs/image/qq.png" alt="QQ群二维码" width="200" height="200"><br>
<strong>QQ技术交流群</strong><br>
<em>技术讨论</em>
</td>
</tr>
</table>
</div>
---
<div align="center">
**[⭐ 点个Star支持一下](https://github.com/ageerle/ruoyi-ai)** • **[ Fork 开始贡献](https://github.com/ageerle/ruoyi-ai/fork)** • **[📚 English](README.md)** • **[📖 查看完整文档](https://doc.ruoyiai.chat/)**
*用 ❤️ 打造,由 RuoYi AI 开源社区维护*
</div>
<!-- Badge Links -->
[contributors-shield]: https://img.shields.io/github/contributors/ageerle/ruoyi-ai.svg?style=flat-square
[contributors-url]: https://github.com/ageerle/ruoyi-ai/graphs/contributors
[forks-shield]: https://img.shields.io/github/forks/ageerle/ruoyi-ai.svg?style=flat-square
[forks-url]: https://github.com/ageerle/ruoyi-ai/network/members
[stars-shield]: https://img.shields.io/github/stars/ageerle/ruoyi-ai.svg?style=flat-square
[stars-url]: https://github.com/ageerle/ruoyi-ai/stargazers
[issues-shield]: https://img.shields.io/github/issues/ageerle/ruoyi-ai.svg?style=flat-square
[issues-url]: https://github.com/ageerle/ruoyi-ai/issues
[license-shield]: https://img.shields.io/github/license/ageerle/ruoyi-ai.svg?style=flat-square
[license-url]: https://github.com/ageerle/ruoyi-ai/blob/main/LICENSE

50
docs/dify-cloud.md Normal file
View File

@@ -0,0 +1,50 @@
# Dify 官方云服务配置
本指南适用于本地运行 RuoYi-AI Java 后端、连接 Dify 官方云服务的场景。
## 准备 Dify 应用
在 Dify 中创建并发布聊天应用,先在 Dify 自己的调试页面确认可以正常回答。首次接入可以使用 Chatbot(聊天助手)。在该应用的 API 访问页面创建应用 API Key。
应用 Key 对应具体的 Dify 应用;知识库 Key 不能用于聊天。Dify 官方云服务的 API 基础地址为 `https://api.dify.ai/v1`。参见 [Dify API 入门](https://docs.dify.ai/en/api-reference/guides/get-started) 和 [聊天应用 API](https://docs.dify.ai/en/api-reference/guides/chat)。
## 在后台配置 Key
API Key 统一在 **ruoyi-admin → 对话管理 → 模型管理** 中直接填写并保存,无需配置后端环境变量。
## 模型管理填写示例
先确认厂商管理中的 `Dify` 已启用,再在模型管理中修改 Dify 模型:
| 字段 | 填写内容 |
| --- | --- |
| 模型分类 | 聊天(`chat`) |
| 模型供应商 | Dify(编码 `dify`) |
| 模型名称 | `dify-chat` |
| 模型描述 | Dify 聊天助手 |
| 请求地址 | `https://api.dify.ai/v1` |
| 密钥 | 从 Dify 应用复制的真实 API Key,如 `app-...` |
| 是否显示 | 是 |
直接填写真实应用 Key,不需要 `env:` 或 `Bearer ` 前缀。编辑时回显已保存的 Key,默认隐藏,点击眼睛可查看原文。输入内容原样保存,清空后保存会清除原 Key。保存后新的调用读取最新配置,无需重启后端。
请求地址填写到 `/v1`,不要追加 `/chat-messages`,也不要填写 Dify 应用的网页分享链接。模型名称是本系统的选择标识,可以取一个不重复的应用名称;实际调用哪个 Dify 应用由应用 Key 决定。
已有数据库直接在模型管理中按上述内容保存即可,无需重新导入全量 SQL。保存后在聊天页面选择该模型,发送一条简单消息验证。
## 适用范围
- 官方云服务使用 `https://api.dify.ai/v1`;自建 Dify 填写后端可以访问的服务 API 地址。
- 不同模型可以填写不同的应用 Key,分别连接对应的 Dify 应用。
- 当前适配器使用聊天消息接口,普通 Workflow 应用不能通过此模型配置调用。
- 当前请求的自定义 `inputs` 为空。接入的聊天应用应能在不提供额外必填输入变量的情况下运行。
- 当前聊天适配器没有实现 Dify 的 Human Input 表单交互和文件上传流程;首次验证请使用简单文本聊天应用。
## 常见情况
| 现象 | 检查方法 |
| --- | --- |
| 后台无法保存 | 检查厂商是否启用,以及模型分类、名称等必填项是否齐全。 |
| 查看已保存的密钥 | 编辑时默认隐藏,点击密钥框右侧的眼睛查看原文;清空后保存会清除密钥。 |
| Dify 返回鉴权失败 | 在模型管理中填写当前应用的有效 API Key,检查复制时是否带入空格或 `Bearer ` 前缀。 |
| Dify 返回应用类型或输入参数错误 | 检查是否使用聊天应用,以及应用是否要求额外输入变量;先在 Dify 中验证应用可以回答。 |

View File

@@ -1,8 +1,6 @@
version: '3.5'
services:
etcd:
container_name: milvus-etcd
container_name: ruoyi-rag-milvus-etcd
image: quay.io/coreos/etcd:v3.5.18
environment:
- ETCD_AUTO_COMPACTION_MODE=revision
@@ -19,14 +17,11 @@ services:
retries: 3
minio:
container_name: milvus-minio
container_name: ruoyi-rag-milvus-minio
image: minio/minio:RELEASE.2023-03-20T20-16-18Z
environment:
MINIO_ACCESS_KEY: minioadmin
MINIO_SECRET_KEY: minioadmin
ports:
- "9001:9001"
- "9000:9000"
volumes:
- ${DOCKER_VOLUME_DIRECTORY:-.}/volumes/minio:/minio_data
command: minio server /minio_data --console-address ":9001"
@@ -37,7 +32,7 @@ services:
retries: 3
standalone:
container_name: milvus-standalone
container_name: ruoyi-rag-milvus
image: milvusdb/milvus:v2.5.7
command: ["milvus", "run", "standalone"]
security_opt:
@@ -61,7 +56,7 @@ services:
- "minio"
attu:
container_name: attu
container_name: ruoyi-rag-attu
image: zilliz/attu:v2.5.7
environment:
MILVUS_URL: milvus-standalone:19530
@@ -72,4 +67,4 @@ services:
networks:
default:
name: milvus
name: ruoyi-rag-milvus

View File

@@ -1,12 +1,20 @@
---
services:
qdrant:
image: qdrant/qdrant:latest
container_name: ruoyi-rag-qdrant
image: qdrant/qdrant:v1.17.0
ports:
- 6333:6333
- 6334:6334
volumes:
- qdrant_data:/qdrant/storage
healthcheck:
test: ["CMD-SHELL", "bash -c 'exec 3<>/dev/tcp/127.0.0.1/6333 && printf \"GET /healthz HTTP/1.1\\r\\nHost: localhost\\r\\nConnection: close\\r\\n\\r\\n\" >&3 && grep -q \"200 OK\" <&3'"]
interval: 10s
timeout: 5s
retries: 12
start_period: 10s
restart: unless-stopped
volumes:
qdrant_data:
...

View File

@@ -0,0 +1,6 @@
# GitHub Container Registry namespace owner.
# For the upstream project this is ageerle; change it when using a fork.
IMAGE_OWNER=ageerle
# Use latest for convenience, or pin a release such as v3.1.0.
RUIYI_VERSION=latest

View File

@@ -20,6 +20,22 @@ RUN mvn clean package -Pprod -DskipTests
# 最终运行镜像
FROM eclipse-temurin:17-jre-alpine
RUN set -eux; \
apk add --no-cache ffmpeg; \
for filter in scale pad fps setsar format tpad trim settb setpts xfade \
aresample aformat apad atrim asetpts anullsrc concat acrossfade; do \
ffmpeg -hide_banner -filters 2>/dev/null | grep -Eq "[[:space:]]${filter}[[:space:]]"; \
done; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q dissolve; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q fadeblack; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q slideleft; \
ffmpeg -hide_banner -encoders 2>/dev/null | grep -Eq '[[:space:]]libx264[[:space:]]'; \
ffmpeg -hide_banner -encoders 2>/dev/null | grep -Eq '[[:space:]]aac[[:space:]]'; \
ffprobe -hide_banner -version >/dev/null
ENV FFMPEG_PATH=/usr/bin/ffmpeg \
FFPROBE_PATH=/usr/bin/ffprobe
# 设置工作目录
WORKDIR /app
@@ -27,10 +43,10 @@ WORKDIR /app
COPY --from=builder /build/ruoyi-admin/target/ruoyi-admin.jar ./ruoyi-admin.jar
# 创建日志目录
RUN mkdir -p /ruoyi/server/logs
RUN mkdir -p /ruoyi/server/logs /ruoyi/server/temp
# 暴露端口
EXPOSE 6039
# 启动命令
ENTRYPOINT ["java", "-jar", "ruoyi-admin.jar", "--spring.profiles.active=prod"]
ENTRYPOINT ["java", "-Djava.io.tmpdir=/ruoyi/server/temp", "-jar", "ruoyi-admin.jar", "--spring.profiles.active=prod"]

View File

@@ -1,16 +1,14 @@
# 基于官方MySQL 8.0镜像构建自定义镜像
# 构建命令: docker build -t registry.cn-hangzhou.aliyuncs.com/ruoyi-ai/mysql:v3 -f Dockerfile.mysql .
FROM mysql:8.0.33
FROM mysql:8.0
# 设置时区
ENV TZ=Asia/Shanghai
# 复制初始化脚本和SQL文件到镜像中
COPY docs/script/docker/mysql/init/init-db.sh /docker-entrypoint-initdb.d/init-db.sh
COPY docs/script/sql/ruoyi-ai-v3_mysql8.sql /docker-entrypoint-initdb.d/ruoyi-ai-v3_mysql8.sql
# 设置脚本可执行权限
RUN chmod +x /docker-entrypoint-initdb.d/init-db.sh
# MySQL 官方入口会按文件名顺序执行初始化目录中的 SQL。
# 主库统一为 ruoyi-ai,与初始化 SQL 和 Compose 中的数据库配置保持一致。
COPY docs/script/sql/ruoyi-ai.sql /docker-entrypoint-initdb.d/01-ruoyi-ai.sql
COPY docs/script/sql/snail_job_mysql.sql /docker-entrypoint-initdb.d/02-snail-job.sql
# MySQL启动参数
CMD ["--default-authentication-plugin=mysql_native_password", \
@@ -18,4 +16,4 @@ CMD ["--default-authentication-plugin=mysql_native_password", \
"--collation-server=utf8mb4_general_ci", \
"--explicit_defaults_for_timestamp=true", \
"--lower_case_table_names=1", \
"--skip-ssl"]
"--skip-ssl"]

View File

@@ -10,27 +10,28 @@
# - RuoYi-Admin (管理端前端)
# - RuoYi-Web (用户端前端)
#
# 镜像仓库地址: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai
version: '3.8'
# 镜像仓库地址: ghcr.io/ageerle
services:
# ==================== MySQL 数据库 ====================
mysql:
# 阿里云镜像地址(包含初始化SQL)
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/mysql:v3
# GHCR 镜像(包含初始化SQL)
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-mysql:${RUIYI_VERSION:-latest}
container_name: ruoyi-ai-mysql
restart: always
ports:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ruoyi-ai-agent
MYSQL_DATABASE: ruoyi-ai
TZ: Asia/Shanghai
volumes:
- mysql-data:/var/lib/mysql
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
# Force TCP: during first-time initialization MySQL exposes a temporary
# socket-only server. A socket ping would mark the service healthy before
# the real network listener (used by the backend) is ready.
test: ["CMD", "mysqladmin", "ping", "--protocol=tcp", "-h", "127.0.0.1", "-u", "root", "-proot"]
interval: 15s
timeout: 10s
retries: 10
@@ -40,7 +41,7 @@ services:
# ==================== Redis 缓存 ====================
redis:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/redis:6.2
image: redis:6.2
container_name: ruoyi-ai-redis
restart: always
ports:
@@ -58,14 +59,14 @@ services:
# ==================== Weaviate 向量数据库 ====================
weaviate:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/weaviate:1.30.0
image: semitechnologies/weaviate:1.30.0
container_name: ruoyi-ai-weaviate
restart: always
ports:
- "28080:8080"
environment:
QUERY_DEFAULTS_LIMIT: 25
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: true
AUTHENTICATION_ANONYMOUS_ACCESS_ENABLED: "true"
PERSISTENCE_DATA_PATH: /var/lib/weaviate
DEFAULT_VECTORIZER_MODULE: none
ENABLE_MODULES: text2vec-cohere,text2vec-huggingface,text2vec-palm,text2vec-openai,generative-openai,generative-cohere,generative-palm,ref2vec-centroid,reranker-cohere,qna-openai
@@ -77,7 +78,7 @@ services:
# ==================== MinIO 对象存储 ====================
minio:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/minio:latest
image: minio/minio:latest
container_name: ruoyi-ai-minio
restart: always
ports:
@@ -94,7 +95,7 @@ services:
# ==================== RuoYi-AI 后端服务 ====================
backend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-backend:latest
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-backend:${RUIYI_VERSION:-latest}
container_name: ruoyi-ai-backend
restart: always
ports:
@@ -104,13 +105,19 @@ services:
# MySQL 配置
SPRING_DATASOURCE_DYNAMIC_PRIMARY: master
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_DRIVERCLASSNAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL: jdbc:mysql://mysql:3306/ruoyi-ai-agent?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL: jdbc:mysql://mysql:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_USERNAME: root
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_PASSWORD: root
# Redis 配置
SPRING_DATA_REDIS_HOST: redis
SPRING_DATA_REDIS_PORT: 6379
SPRING_DATA_REDIS_DATABASE: 0
# Allow large presentation files for knowledge-base ingestion.
SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE: 600MB
SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE: 620MB
VECTOR_STORE_TYPE: weaviate
VECTOR_STORE_WEAVIATE_PROTOCOL: http
VECTOR_STORE_WEAVIATE_HOST: weaviate:8080
# 日志配置
LOGGING_LEVEL_ORG_RUOYI: info
LOGGING_LEVEL_ORG_SPRINGFRAMEWORK: warn
@@ -128,7 +135,7 @@ services:
# ==================== RuoYi-AI 管理端前端 ====================
admin-frontend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-admin:latest
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-admin:${RUIYI_VERSION:-latest}
container_name: ruoyi-ai-admin
restart: always
ports:
@@ -153,7 +160,7 @@ services:
# ==================== RuoYi-AI 用户端前端 ====================
web-frontend:
image: crpi-31mraxd99y2gqdgr.cn-beijing.personal.cr.aliyuncs.com/ruoyi_ai/ruoyi-ai-web:latest
image: ghcr.io/${IMAGE_OWNER:-ageerle}/ruoyi-ai-web:${RUIYI_VERSION:-latest}
container_name: ruoyi-ai-web
restart: always
ports:
@@ -177,4 +184,4 @@ volumes:
weaviate-data:
minio-data:
logs-data:
upload-data:
upload-data:

View File

@@ -18,11 +18,11 @@ services:
- "23306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: ruoyi-ai-agent
MYSQL_DATABASE: ruoyi-ai
TZ: Asia/Shanghai
volumes:
- ./docs/script/docker/mysql/init/init-db.sh:/docker-entrypoint-initdb.d/init-db.sh:ro
- ./docs/script/sql/ruoyi-ai-v3_mysql8.sql:/docker-entrypoint-initdb.d/ruoyi-ai-v3_mysql8.sql:ro
- ../../script/sql/ruoyi-ai.sql:/docker-entrypoint-initdb.d/01-ruoyi-ai.sql:ro
- ../../script/sql/snail_job_mysql.sql:/docker-entrypoint-initdb.d/02-snail-job.sql:ro
- mysql-data:/var/lib/mysql
command:
--default-authentication-plugin=mysql_native_password
@@ -32,7 +32,9 @@ services:
--lower_case_table_names=1
--skip-ssl
healthcheck:
test: ["CMD", "mysqladmin", "ping", "-h", "localhost", "-u", "root", "-proot"]
# Do not let the socket-only initialization server satisfy the check.
# The backend connects over TCP and must wait for that listener.
test: ["CMD", "mysqladmin", "ping", "--protocol=tcp", "-h", "127.0.0.1", "-u", "root", "-proot"]
interval: 15s
timeout: 10s
retries: 10
@@ -108,7 +110,7 @@ services:
# MySQL 配置
SPRING_DATASOURCE_DYNAMIC_PRIMARY: master
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_DRIVERCLASSNAME: com.mysql.cj.jdbc.Driver
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL: jdbc:mysql://mysql:3306/ruoyi-ai-agent?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_URL: jdbc:mysql://mysql:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_USERNAME: root
SPRING_DATASOURCE_DYNAMIC_DATASOURCE_MASTER_PASSWORD: root
# Redis 配置

View File

@@ -5,12 +5,12 @@ services:
- --host
- 0.0.0.0
- --port
- '6038'
- '8080'
- --scheme
- http
image: semitechnologies/weaviate:1.19.7
image: semitechnologies/weaviate:1.30.0
ports:
- 6038:6038
- 28080:8080
- 50051:50051
volumes:
- weaviate_data:/var/lib/weaviate

BIN
docs/image/01.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 298 KiB

BIN
docs/image/02.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

BIN
docs/image/03.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 316 KiB

BIN
docs/image/douyin.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 276 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

View File

@@ -0,0 +1,34 @@
# 模型与 API Key 配置
模型的 API Key 统一在 **ruoyi-admin → 对话管理 → 模型管理** 中配置。
1. 在“厂商管理”中选择并启用对应厂商,填写服务 API 地址。
2. 在“模型管理”中新建或编辑模型,选择厂商、分类,填写服务商提供的模型 ID。
3. 在“密钥”框直接粘贴真实 API Key,保存模型。
4. 在 `ruoyi-web` 中选择模型使用;向量和重排模型则在对应知识库配置中选择。
需要 API Key 的厂商适配器使用该模型保存的 Key,不要求固定的 Key 前缀或环境变量名称。自定义 OpenAI、Anthropic 服务的地址与 Key 也在模型管理中配置,无需设置配对环境变量。无需鉴权的本地模型可以不填 Key。
## 修改与批量更新
- 编辑模型时回显已保存的 Key,默认以密码形式隐藏,点击眼睛可查看原文;每次重新打开编辑框都会恢复隐藏。
- 密钥按输入内容原样保存,不限制前缀或格式,也不去除首尾空格。清空后保存会清除原 Key。
- 按厂商批量更新接口会将提交的 Key 保存到该厂商的模型中。
- 保存后新的模型调用会读取最新配置,无需重启后端。正在进行的请求继续使用开始时的配置。
- 模型列表、聊天用户端和导出文件不返回 Key。
## 已有模型
如果模型中原来保存的是 `env:ATLAS_API_KEY` 等文本,请在后台将其替换为真实 Key。密钥字段按填写内容直接使用,不解析 `env:` 引用。无需重新导入数据库。
## 示例
| 场景 | 厂商编码 | 密钥框填写内容 |
| --- | --- | --- |
| 千问聊天、向量或重排 | `qianwen` | 阿里云百炼的 API Key |
| DeepSeek | `deepseek` | DeepSeek 控制台创建的 API Key |
| Atlas 多媒体 | `atlas` | Atlas 控制台创建的 API Key |
| Dify 聊天应用 | `dify` | 对应应用的 `app-...` Key |
| 自定义 OpenAI / Anthropic | `custom_api` / `custom_anthropic` | 对应服务的 API Key |
填写的地址、模型 ID 和 Key 应对应同一个服务账号。模型是否可用、支持哪些能力以及额度限制,以服务商实际响应为准。

View File

@@ -1,10 +0,0 @@
#!/bin/bash
# 数据库初始化脚本
# 使用 --force 参数确保即使出错也继续执行
echo "开始初始化数据库..."
# 使用 --force 参数忽略错误继续执行
mysql -uroot -proot ruoyi-ai-agent --force < /docker-entrypoint-initdb.d/ruoyi-ai-v3_mysql8.sql
echo "数据库初始化完成"

View File

@@ -0,0 +1,86 @@
[CmdletBinding()]
param(
[switch]$Force
)
$ErrorActionPreference = 'Stop'
function Find-Executable([string]$Name) {
$command = Get-Command $Name -ErrorAction SilentlyContinue
if ($command) {
return $command.Source
}
$roots = @(
(Join-Path $env:LOCALAPPDATA 'Microsoft\WinGet\Packages'),
(Join-Path $env:USERPROFILE 'scoop\apps\ffmpeg'),
'C:\ProgramData\chocolatey\bin',
'C:\ffmpeg'
)
foreach ($root in $roots) {
if (-not (Test-Path $root)) { continue }
$match = Get-ChildItem -Path $root -Filter "$Name.exe" -Recurse -ErrorAction SilentlyContinue |
Select-Object -First 1 -ExpandProperty FullName
if ($match) { return $match }
}
return $null
}
$ffmpeg = Find-Executable 'ffmpeg'
$ffprobe = Find-Executable 'ffprobe'
if ($Force -or -not $ffmpeg -or -not $ffprobe) {
$winget = Get-Command winget -ErrorAction SilentlyContinue
if (-not $winget) {
throw '未找到 winget。请先从 Microsoft Store 安装“应用安装程序”,或使用项目 Dockerfile 运行后端。'
}
Write-Host '正在通过 winget 安装 FFmpeg...' -ForegroundColor Cyan
& winget install --id Gyan.FFmpeg --exact --source winget `
--accept-package-agreements --accept-source-agreements
if ($LASTEXITCODE -ne 0) {
throw "winget 安装失败,退出码: $LASTEXITCODE"
}
$ffmpeg = Find-Executable 'ffmpeg'
$ffprobe = Find-Executable 'ffprobe'
}
if (-not $ffmpeg -or -not $ffprobe) {
throw 'FFmpeg 已安装但未能定位 ffmpeg.exe 或 ffprobe.exe。请重新打开 PowerShell 后再次运行脚本。'
}
$binDirectory = Split-Path -Parent $ffmpeg
[Environment]::SetEnvironmentVariable('FFMPEG_PATH', $ffmpeg, 'User')
[Environment]::SetEnvironmentVariable('FFPROBE_PATH', $ffprobe, 'User')
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
$pathParts = @($userPath -split ';' | Where-Object { $_ })
if ($pathParts -notcontains $binDirectory) {
$newPath = (@($pathParts) + $binDirectory) -join ';'
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
}
$env:FFMPEG_PATH = $ffmpeg
$env:FFPROBE_PATH = $ffprobe
if (($env:Path -split ';') -notcontains $binDirectory) {
$env:Path = "$binDirectory;$env:Path"
}
Write-Host "ffmpeg: $ffmpeg" -ForegroundColor Green
Write-Host "ffprobe: $ffprobe" -ForegroundColor Green
& $ffmpeg -hide_banner -version | Select-Object -First 1
& $ffprobe -hide_banner -version | Select-Object -First 1
$encoders = & $ffmpeg -hide_banner -encoders 2>&1 | Out-String
if ($encoders -notmatch '\blibx264\b') {
throw '当前 FFmpeg 不包含 libx264 编码器,无法满足短剧合成配置。'
}
if ($encoders -notmatch '\baac\b') {
throw '当前 FFmpeg 不包含 AAC 编码器,无法满足短剧合成配置。'
}
Write-Host ''
Write-Host '安装与配置完成。请完全重启 IntelliJ IDEA 和 ruoyi-ai 后端服务。' -ForegroundColor Yellow
Write-Host '重启后,Spring 将从 FFMPEG_PATH 和 FFPROBE_PATH 读取绝对路径。'

60
docs/script/sql/README.md Normal file
View File

@@ -0,0 +1,60 @@
# SQL 脚本说明
## 全新安装
执行 [ruoyi-ai.sql](ruoyi-ai.sql) 即可创建 `ruoyi-ai` 主库和 `snail_job` 调度库,并导入初始化数据。
```sh
mysql -uroot -p < ruoyi-ai.sql
```
主 SQL 已合并下表列出的基础更新,以及原始想法、技能绑定、剧本打磨字段、模型优先级和 PC 登录超时结构。新安装仍需执行下面“后续功能更新”中注明的补充脚本。[snail_job_mysql.sql](snail_job_mysql.sql) 仅用于单独初始化调度库,执行主 SQL 后无需再执行它。
全量初始化包含 `DROP TABLE` 和调度库的 `DROP DATABASE`,已有数据库升级应使用对应的增量脚本。
## 已有数据库升级
连接目标主库后,按文件名升序执行尚未应用的更新脚本;不要根据文件重命名重复执行已应用的更新。
- `2026-06-15-trace.sql` 原名为 `update-0615-trace.sql`,内容未变;其中菜单插入没有判重,不应重复执行。
- `2026-08-30-mcp-market-tool-tenant.sql` 是一次性迁移,执行前检查脚本内的预检要求;部分执行失败后应按实际表结构续跑。
- 其余脚本包含重复执行保护,具体适用条件见各脚本注释。
## 命名约定
更新脚本统一采用 `YYYY-MM-DD-功能描述.sql`,功能描述使用小写英文和连字符,例如 `2026-09-01-sys-url.sql`。保留已有更新日期,同日脚本按文件名升序执行,并确保依赖顺序一致。
全量入口保留 `ruoyi-ai.sql`,独立调度库入口保留 `snail_job_mysql.sql`。
## 主 SQL 合并清单
截至 2026-09-01,`update` 目录的 9 个脚本均已体现在主 SQL 的最终表结构和初始化数据中。结构变更直接并入建表语句,重复配置按最终值保留一份;旧库回填及兼容逻辑保留在增量脚本中。
| 更新脚本 | 主 SQL 中对应内容 |
| --- | --- |
| [2026-06-15-trace.sql](update/2026-06-15-trace.sql) | `trace_run`、`trace_node` 表、租户字段和索引,以及链路追踪菜单 |
| [2026-07-20-knowledge-fragment-fid.sql](update/2026-07-20-knowledge-fragment-fid.sql) | 附件 `file_hash`、片段 `fid`、可空的 `doc_id` 和知识库租户索引 |
| [2026-07-21-chat-provider-icon-length.sql](update/2026-07-21-chat-provider-icon-length.sql) | `chat_provider.provider_icon` 扩展为 `varchar(1000)` |
| [2026-07-21-sys-config-node-template.sql](update/2026-07-21-sys-config-node-template.sql) | 7 个工作流节点消息模板配置 |
| [2026-07-24-register-default-role-and-missing-menus.sql](update/2026-07-24-register-default-role-and-missing-menus.sql) | 默认注册角色、角色菜单关联、默认角色配置,以及会话、附件和片段权限 |
| [2026-07-29-sys-config-node-template-all.sql](update/2026-07-29-sys-config-node-template-all.sql) | 工作流全部 8 个模板,前 7 个配置与上一批模板合并去重 |
| [2026-07-29-zhipu-web-search-node.sql](update/2026-07-29-zhipu-web-search-node.sql) | 智谱网络搜索节点及其消息模板;内部组件名保留 `Google` 以兼容已有流程 |
| [2026-08-30-mcp-market-tool-tenant.sql](update/2026-08-30-mcp-market-tool-tenant.sql) | `mcp_market_tool` 租户、审计字段和 `idx_tenant_market` 索引 |
| [2026-09-01-sys-url.sql](update/2026-09-01-sys-url.sql) | `sys_url` 表、5 个菜单权限和 2 条公开链接 |
后续增加更新脚本时,同步修改主 SQL 中对应的表结构或初始化数据,并更新本清单及主 SQL 文件头。
## 后续功能更新
以下脚本统一位于 `update/`。已有数据库按日期升级,保留原始输入、已批准媒体和提供商密钥;不要执行全量初始化。
| 脚本 | 内容与新安装要求 |
| --- | --- |
| [知识库检索节点](update/2026-09-11-knowledge-retrieval-node.sql) | 补充节点注册,新安装也需执行 |
| [短剧视觉资产](update/2026-09-30-short-drama-visual-asset.sql) | 补充异步视觉资产表,新安装也需执行 |
| [剧本打磨与 Seedance 2.5](update/2026-09-30-script-refinement-seedance-25.sql) | 打磨字段已并入全量结构;新安装执行以补充视频模型记录 |
| [技能绑定](update/2026-10-01-short-drama-skill-bindings.sql) | 项目审美与导演绑定,幂等;全量结构已包含 |
| [模型优先级](update/2026-10-02-chat-model-sort-order.sql) | 幂等增加优先级列,保留已自定义优先级;全量结构已包含 |
| [PC 登录空闲时间](update/2026-10-02-pc-login-idle-timeout.sql) | 仅调整原 30 分钟配置;全量默认已更新,已签发令牌需重新登录 |
| [文字模型默认优先级](update/2026-10-03-short-drama-flash-default.sql) | 先应用模型优先级迁移,再调整已有 Flash / Seed 模型排序,不新增模型或密钥 |
| [原始创作输入](update/2026-10-03-short-drama-original-idea.sql) | 幂等增加独立原文列,不用生成概要回填;全量结构已包含 |

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,128 @@
-- 链路追踪运行记录表
CREATE TABLE IF NOT EXISTS `trace_run` (
`id` bigint NOT NULL COMMENT '主键',
`trace_id` varchar(64) NOT NULL COMMENT '链路ID',
`trace_name` varchar(128) NOT NULL COMMENT '链路名称',
`business_type` varchar(64) NOT NULL COMMENT '业务类型',
`business_id` varchar(128) DEFAULT NULL COMMENT '业务ID',
`user_id` bigint DEFAULT NULL COMMENT '用户ID',
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
`status` varchar(32) NOT NULL COMMENT '状态',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`duration_ms` bigint DEFAULT NULL COMMENT '耗时毫秒',
`error_message` varchar(1000) DEFAULT NULL COMMENT '错误摘要',
`metadata` text DEFAULT NULL COMMENT '元数据JSON',
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
`create_by` bigint DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE KEY `uk_trace_run_trace_id` (`trace_id`) USING BTREE,
KEY `idx_trace_run_business` (`business_type`, `business_id`) USING BTREE,
KEY `idx_trace_run_status_time` (`status`, `start_time`) USING BTREE,
KEY `idx_trace_run_tenant_time` (`tenant_id`, `start_time`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='链路追踪运行记录表' ROW_FORMAT=DYNAMIC;
-- 链路追踪节点记录表
CREATE TABLE IF NOT EXISTS `trace_node` (
`id` bigint NOT NULL COMMENT '主键',
`trace_id` varchar(64) NOT NULL COMMENT '链路ID',
`node_id` varchar(64) NOT NULL COMMENT '节点ID',
`tenant_id` varchar(20) DEFAULT '000000' COMMENT '租户编号',
`parent_node_id` varchar(64) DEFAULT NULL COMMENT '父节点ID',
`node_name` varchar(128) NOT NULL COMMENT '节点名称',
`node_type` varchar(64) NOT NULL COMMENT '节点类型',
`depth` int DEFAULT 0 COMMENT '节点深度',
`sort_order` int DEFAULT 0 COMMENT '排序',
`class_name` varchar(255) DEFAULT NULL COMMENT '类名',
`method_name` varchar(128) DEFAULT NULL COMMENT '方法名',
`status` varchar(32) NOT NULL COMMENT '状态',
`start_time` datetime NOT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间',
`duration_ms` bigint DEFAULT NULL COMMENT '耗时毫秒',
`error_message` varchar(1000) DEFAULT NULL COMMENT '错误摘要',
`input_payload` text DEFAULT NULL COMMENT '输入JSON',
`output_payload` text DEFAULT NULL COMMENT '输出JSON',
`metadata` text DEFAULT NULL COMMENT '元数据JSON',
`create_dept` bigint DEFAULT NULL COMMENT '创建部门',
`create_by` bigint DEFAULT NULL COMMENT '创建者',
`create_time` datetime DEFAULT NULL COMMENT '创建时间',
`update_by` bigint DEFAULT NULL COMMENT '更新者',
`update_time` datetime DEFAULT NULL COMMENT '更新时间',
`del_flag` char(1) DEFAULT '0' COMMENT '删除标志(0代表存在 2代表删除)',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_trace_node_trace_id` (`trace_id`) USING BTREE,
KEY `idx_trace_node_parent` (`trace_id`, `parent_node_id`) USING BTREE,
KEY `idx_trace_node_time` (`trace_id`, `start_time`) USING BTREE,
KEY `idx_trace_node_tenant_time` (`tenant_id`, `start_time`) USING BTREE,
KEY `idx_trace_node_type_status` (`node_type`, `status`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='链路追踪节点记录表' ROW_FORMAT=DYNAMIC;
-- 兼容已存在的旧 trace 表:CREATE TABLE IF NOT EXISTS 不会给旧表补新字段
SET @trace_run_add_tenant_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `trace_run` ADD COLUMN `tenant_id` varchar(20) DEFAULT ''000000'' COMMENT ''租户编号'' AFTER `user_id`',
'SELECT 1'
)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'trace_run'
AND COLUMN_NAME = 'tenant_id'
);
PREPARE trace_run_add_tenant_stmt FROM @trace_run_add_tenant_sql;
EXECUTE trace_run_add_tenant_stmt;
DEALLOCATE PREPARE trace_run_add_tenant_stmt;
SET @trace_run_add_tenant_idx_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `trace_run` ADD INDEX `idx_trace_run_tenant_time` (`tenant_id`, `start_time`) USING BTREE',
'SELECT 1'
)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'trace_run'
AND INDEX_NAME = 'idx_trace_run_tenant_time'
);
PREPARE trace_run_add_tenant_idx_stmt FROM @trace_run_add_tenant_idx_sql;
EXECUTE trace_run_add_tenant_idx_stmt;
DEALLOCATE PREPARE trace_run_add_tenant_idx_stmt;
SET @trace_node_add_tenant_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `trace_node` ADD COLUMN `tenant_id` varchar(20) DEFAULT ''000000'' COMMENT ''租户编号'' AFTER `node_id`',
'SELECT 1'
)
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'trace_node'
AND COLUMN_NAME = 'tenant_id'
);
PREPARE trace_node_add_tenant_stmt FROM @trace_node_add_tenant_sql;
EXECUTE trace_node_add_tenant_stmt;
DEALLOCATE PREPARE trace_node_add_tenant_stmt;
SET @trace_node_add_tenant_idx_sql = (
SELECT IF(COUNT(*) = 0,
'ALTER TABLE `trace_node` ADD INDEX `idx_trace_node_tenant_time` (`tenant_id`, `start_time`) USING BTREE',
'SELECT 1'
)
FROM information_schema.STATISTICS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'trace_node'
AND INDEX_NAME = 'idx_trace_node_tenant_time'
);
PREPARE trace_node_add_tenant_idx_stmt FROM @trace_node_add_tenant_idx_sql;
EXECUTE trace_node_add_tenant_idx_stmt;
DEALLOCATE PREPARE trace_node_add_tenant_idx_stmt;
-- 链路追踪监控菜单 & 按钮权限
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), '链路追踪', 2, 7, 'trace', 'monitor/trace/index', '', 1, 0, 'C', '0', '0', 'monitor:trace:list', 'tabler:route', 103, 1, NOW(), '链路追踪监控菜单';
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), '链路追踪查询', (SELECT `menu_id` FROM `sys_menu` WHERE `perms` = 'monitor:trace:list' AND `menu_type` = 'C' LIMIT 1), 1, '#', '', '', 1, 0, 'F', '0', '0', 'monitor:trace:query', '#', 103, 1, NOW(), '';

View File

@@ -0,0 +1,58 @@
-- RAG metadata migration (MySQL 8). Safe to execute repeatedly.
-- 注意:MySQL 8 不支持 ALTER TABLE ... ADD COLUMN IF NOT EXISTS(仅 MariaDB 支持),
-- 因此列的增量添加统一用 information_schema 守卫 + PREPARE 实现幂等。
SET @add_file_hash_col = IF(EXISTS(
SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
AND table_name = 'knowledge_attach' AND column_name = 'file_hash'),
'SELECT 1',
'ALTER TABLE `knowledge_attach` ADD COLUMN `file_hash` varchar(64) NULL DEFAULT NULL COMMENT ''文件SHA-256摘要'' AFTER `doc_id`');
PREPARE stmt FROM @add_file_hash_col; EXECUTE stmt; DEALLOCATE PREPARE stmt;
ALTER TABLE `knowledge_attach`
MODIFY COLUMN `doc_id` varchar(32) NULL DEFAULT NULL COMMENT '文档ID';
SET @add_file_hash = IF(EXISTS(
SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE()
AND table_name = 'knowledge_attach' AND index_name = 'uk_knowledge_file_hash'),
'SELECT 1', 'ALTER TABLE `knowledge_attach` ADD UNIQUE INDEX `uk_knowledge_file_hash` (`knowledge_id`, `file_hash`)');
PREPARE stmt FROM @add_file_hash; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @add_fid_col = IF(EXISTS(
SELECT 1 FROM information_schema.columns WHERE table_schema = DATABASE()
AND table_name = 'knowledge_fragment' AND column_name = 'fid'),
'SELECT 1',
'ALTER TABLE `knowledge_fragment` ADD COLUMN `fid` varchar(32) NULL DEFAULT NULL COMMENT ''向量库片段ID'' AFTER `id`');
PREPARE stmt FROM @add_fid_col; EXECUTE stmt; DEALLOCATE PREPARE stmt;
ALTER TABLE `knowledge_fragment`
MODIFY COLUMN `doc_id` varchar(32) NULL DEFAULT NULL COMMENT '文档ID';
UPDATE `knowledge_fragment`
SET `fid` = LOWER(MD5(CONCAT('knowledge_fragment:', `id`)))
WHERE `fid` IS NULL OR `fid` = '';
SET @drop_idx_fid = IF(EXISTS(
SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE()
AND table_name = 'knowledge_fragment' AND index_name = 'idx_fid'),
'ALTER TABLE `knowledge_fragment` DROP INDEX `idx_fid`', 'SELECT 1');
PREPARE stmt FROM @drop_idx_fid; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @add_uk_fid = IF(EXISTS(
SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE()
AND table_name = 'knowledge_fragment' AND index_name = 'uk_fid'),
'SELECT 1', 'ALTER TABLE `knowledge_fragment` ADD UNIQUE INDEX `uk_fid` (`fid`)');
PREPARE stmt FROM @add_uk_fid; EXECUTE stmt; DEALLOCATE PREPARE stmt;
ALTER TABLE `knowledge_fragment` MODIFY COLUMN `fid` varchar(32) NOT NULL COMMENT '向量库片段ID';
SET @add_tenant_user = IF(EXISTS(
SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE()
AND table_name = 'knowledge_info' AND index_name = 'idx_tenant_user'),
'SELECT 1', 'ALTER TABLE `knowledge_info` ADD INDEX `idx_tenant_user` (`tenant_id`, `user_id`)');
PREPARE stmt FROM @add_tenant_user; EXECUTE stmt; DEALLOCATE PREPARE stmt;
SET @add_tenant_share = IF(EXISTS(
SELECT 1 FROM information_schema.statistics WHERE table_schema = DATABASE()
AND table_name = 'knowledge_info' AND index_name = 'idx_tenant_share'),
'SELECT 1', 'ALTER TABLE `knowledge_info` ADD INDEX `idx_tenant_share` (`tenant_id`, `share`)');
PREPARE stmt FROM @add_tenant_share; EXECUTE stmt; DEALLOCATE PREPARE stmt;

View File

@@ -0,0 +1,7 @@
-- 加宽 chat_provider.provider_icon 字段 (对应 issue IHPUDA)
-- 背景:文件系统使用 minio 私有桶时,厂商图标存的是带签名的临时访问 URL,
-- 长度常超过 255,导致「Data too long for column 'provider_icon'」。
-- MODIFY COLUMN 可重复执行。
ALTER TABLE `chat_provider`
MODIFY COLUMN `provider_icon` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '厂商图标';

View File

@@ -0,0 +1,33 @@
-- 补充工作流节点消息模板配置 (对应 issue IJX5VV)
-- 背景:NodeMessageTemplateEnum 依赖以下 7 个 sys_config 键,缺失时
-- WorkflowMessageUtil.getNodeMessageTemplate 会抛出「请先配置该节点的响应模板」。
-- 这批配置在历史提交 20d531c0 中存在,SQL 脚本合并重命名时遗失,此处恢复。
-- 幂等:按 config_key + tenant_id 判重,可重复执行。
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027192921483309058, '000000', 'HTTP请求节点响应模板', 'node.httpRequest.template', '✅ HTTP请求节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:23:51', 1, '2026-02-27 09:31:41', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.httpRequest.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027193296990957569, '000000', '文生图节点响应模板', 'node.image.template', '🎨 文生图节点:结束响应 - 图片URL: ', 'Y', 103, 1, '2026-02-27 09:25:20', 1, '2026-02-27 09:31:52', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.image.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027193820393959425, '000000', '发送邮箱节点响应模板', 'node.mailsend.template', '📧 发送邮箱节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:27:25', 1, '2026-02-27 09:32:05', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.mailsend.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027194134438277122, '000000', '结束节点响应模板', 'node.end.template', '🔚 流程已执行完毕,如果您有其他需求,请随时重新发起请求。', 'Y', 103, 1, '2026-02-27 09:28:40', 1, '2026-02-27 09:32:53', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.end.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027208880369647617, '000000', '条件分支节点响应模板', 'node.switch.template', '🔀 条件分支节点:触发 -> 跳转到节点 ', 'Y', 103, 1, '2026-02-27 10:27:15', 1, '2026-02-27 10:35:54', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.switch.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027213914603995137, '000000', '大模型回答节点响应模板', 'node.llmAnswer.template', '🤖 LLM 节点 生成回答:', 'Y', 103, 1, '2026-02-27 10:47:16', 1, '2026-02-27 10:52:40', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.llmAnswer.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027217577397391361, '000000', '工作流异常响应模板', 'node.exception.template', '🛑 工作流发生异常:', 'N', 103, 1, '2026-02-27 11:01:49', 1, '2026-02-27 11:02:01', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.exception.template' AND `tenant_id` = '000000');

View File

@@ -0,0 +1,119 @@
-- 注册链路修复:补齐缺失的菜单权限标识 + 新建注册默认角色
-- 关联问题:
-- #3 注册用户无默认角色 -> 无权限访问 AI 对话界面
-- #4 sys_menu 缺 system:session:* / system:attach:* / system:fragment:*,
-- 且 知识管理 父菜单 perms 为 knowledge:info:list,与控制器
-- KnowledgeInfoController 用的 system:info:list 对不上,:list 无法授权。
-- 本脚本幂等,可重复执行(INSERT IGNORE + UPDATE 天然幂等)。
-- 新增 menu_id / role_id / config_id 统一使用 2099010100000000xxx 段,
-- 与现有 snowflake id(2xxxxxxxxxxxxxxxxx)不冲突。
-- ============================================================
-- 1. 修正 知识管理 父菜单权限标识:knowledge:info:list -> system:info:list
-- ============================================================
UPDATE `sys_menu`
SET `perms` = 'system:info:list'
WHERE `menu_id` = 2006681261898813441 AND `perms` = 'knowledge:info:list';
-- ============================================================
-- 2. 新增 会话管理 菜单组(system:session:*)
-- 父菜单=对话管理(2000209300188356609)。
-- 管理端暂无 chat/session 页面,故 C 菜单设为隐藏(visible=1),
-- 权限标识仍可在角色管理中授权给用户端使用。
-- ============================================================
INSERT IGNORE INTO `sys_menu` VALUES
(2099010100000000001, '会话管理', 2000209300188356609, 6, 'session', NULL, NULL, 1, 0, 'C', '1', '0', 'system:session:list', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '会话管理菜单'),
(2099010100000000002, '会话管理查询', 2099010100000000001, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:session:query', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000003, '会话管理新增', 2099010100000000001, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:session:add', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000004, '会话管理修改', 2099010100000000001, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:session:edit', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000005, '会话管理删除', 2099010100000000001, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:session:remove', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000006, '会话管理导出', 2099010100000000001, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:session:export', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '');
-- ============================================================
-- 3. 新增 知识附件 菜单组(system:attach:*)
-- 父菜单=对话管理(2000209300188356609),组件对应管理端 knowledge/attach/index。
-- ============================================================
INSERT IGNORE INTO `sys_menu` VALUES
(2099010100000000010, '知识附件', 2000209300188356609, 7, 'attach', 'knowledge/attach/index', NULL, 1, 0, 'C', '0', '0', 'system:attach:list', 'ant-design:paper-clip-outlined', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '知识附件菜单'),
(2099010100000000011, '知识附件查询', 2099010100000000010, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:attach:query', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000012, '知识附件新增', 2099010100000000010, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:attach:add', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000013, '知识附件修改', 2099010100000000010, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:attach:edit', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000014, '知识附件删除', 2099010100000000010, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:attach:remove', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000015, '知识附件导出', 2099010100000000010, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:attach:export', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '');
-- ============================================================
-- 4. 新增 知识片段 菜单组(system:fragment:*)
-- 父菜单=对话管理(2000209300188356609),组件对应管理端 knowledge/fragment/index。
-- ============================================================
INSERT IGNORE INTO `sys_menu` VALUES
(2099010100000000020, '知识片段', 2000209300188356609, 8, 'fragment', 'knowledge/fragment/index', NULL, 1, 0, 'C', '0', '0', 'system:fragment:list', 'ant-design:file-text-outlined', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '知识片段菜单'),
(2099010100000000021, '知识片段查询', 2099010100000000020, 1, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:fragment:query', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000022, '知识片段新增', 2099010100000000020, 2, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:fragment:add', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000023, '知识片段修改', 2099010100000000020, 3, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:fragment:edit', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000024, '知识片段删除', 2099010100000000020, 4, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:fragment:remove', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, ''),
(2099010100000000025, '知识片段导出', 2099010100000000020, 5, '#', '', NULL, 1, 0, 'F', '0', '0', 'system:fragment:export', '#', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '');
-- ============================================================
-- 5. 新建 普通用户 角色(租户 000000,data_scope=5 仅本人)
-- ============================================================
INSERT IGNORE INTO `sys_role` VALUES
(2099010100000000030, '000000', '普通用户', 'user', 2, '5', 1, 1, '0', '0', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '注册用户默认角色');
-- ============================================================
-- 6. 角色-菜单关联:普通用户 拥有用户端 AI 对话所需权限
-- 会话管理(001-006) + 聊天消息(2000210914680823809 及 810-814)
-- + 知识管理(2006681261898813441 及 442-446)
-- + 知识附件(010-015) + 知识片段(020-025)
-- ============================================================
INSERT IGNORE INTO `sys_role_menu` (`role_id`, `menu_id`) VALUES
-- 会话管理
(2099010100000000030, 2099010100000000001),
(2099010100000000030, 2099010100000000002),
(2099010100000000030, 2099010100000000003),
(2099010100000000030, 2099010100000000004),
(2099010100000000030, 2099010100000000005),
(2099010100000000030, 2099010100000000006),
-- 聊天消息
(2099010100000000030, 2000210914680823809),
(2099010100000000030, 2000210914680823810),
(2099010100000000030, 2000210914680823811),
(2099010100000000030, 2000210914680823812),
(2099010100000000030, 2000210914680823813),
(2099010100000000030, 2000210914680823814),
-- 知识管理
(2099010100000000030, 2006681261898813441),
(2099010100000000030, 2006681261898813442),
(2099010100000000030, 2006681261898813443),
(2099010100000000030, 2006681261898813444),
(2099010100000000030, 2006681261898813445),
(2099010100000000030, 2006681261898813446),
-- 知识附件
(2099010100000000030, 2099010100000000010),
(2099010100000000030, 2099010100000000011),
(2099010100000000030, 2099010100000000012),
(2099010100000000030, 2099010100000000013),
(2099010100000000030, 2099010100000000014),
(2099010100000000030, 2099010100000000015),
-- 知识片段
(2099010100000000030, 2099010100000000020),
(2099010100000000030, 2099010100000000021),
(2099010100000000030, 2099010100000000022),
(2099010100000000030, 2099010100000000023),
(2099010100000000030, 2099010100000000024),
(2099010100000000030, 2099010100000000025);
-- ============================================================
-- 7. 注册默认角色配置项 sys.register.defaultRoleId
-- 后端 SysRegisterService 注册成功后读取此配置为新用户绑定角色;
-- 值为空字符串时不绑定(保留旧行为)。
-- ============================================================
INSERT IGNORE INTO `sys_config` VALUES
(2099010100000000031, '000000', '注册-默认角色ID', 'sys.register.defaultRoleId', '2099010100000000030', 'Y', 103, 1, '2026-07-24 00:00:00', NULL, NULL, '新注册用户绑定的默认角色ID,留空则不绑定');
-- ============================================================
-- 8. 前置条件(运营项,默认不执行):开启用户注册
-- sys.account.registerUser 默认 false,后端 AuthController.register
-- 会据此返回「当前系统没有开启注册功能」。若要开放注册,取消注释执行。
-- ============================================================
-- UPDATE `sys_config` SET `config_value` = 'true'
-- WHERE `config_key` = 'sys.account.registerUser' AND `tenant_id` = '000000';

View File

@@ -0,0 +1,39 @@
-- 一次性补全工作流节点消息模板配置 (NodeMessageTemplateEnum 全部 8 个键)
-- 背景:节点执行时 WorkflowMessageUtil.getNodeMessageTemplate 从 sys_config 读取展示模板,
-- 历史库中这批配置缺失, 导致运行工作流抛「请先配置该节点的响应模板」。
-- 其中前 7 个见 2026-07-21-sys-config-node-template.sql,
-- Google Search 为此前从未入库的节点模板。
-- 说明:代码已增加内置默认模板兜底, 本脚本为可选, 执行后模板可在 系统管理-配置管理 中自定义。
-- 幂等:按 config_key + tenant_id 判重, 可重复执行。
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027192921483309058, '000000', 'HTTP请求节点响应模板', 'node.httpRequest.template', '✅ HTTP请求节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:23:51', 1, '2026-02-27 09:31:41', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.httpRequest.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027193296990957569, '000000', '文生图节点响应模板', 'node.image.template', '🎨 文生图节点:结束响应 - 图片URL: ', 'Y', 103, 1, '2026-02-27 09:25:20', 1, '2026-02-27 09:31:52', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.image.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027193820393959425, '000000', '发送邮箱节点响应模板', 'node.mailsend.template', '📧 发送邮箱节点:结束响应 - ', 'Y', 103, 1, '2026-02-27 09:27:25', 1, '2026-02-27 09:32:05', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.mailsend.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027194134438277122, '000000', '结束节点响应模板', 'node.end.template', '🔚 流程已执行完毕,如果您有其他需求,请随时重新发起请求。', 'Y', 103, 1, '2026-02-27 09:28:40', 1, '2026-02-27 09:32:53', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.end.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027208880369647617, '000000', '条件分支节点响应模板', 'node.switch.template', '🔀 条件分支节点:触发 -> 跳转到节点 ', 'Y', 103, 1, '2026-02-27 10:27:15', 1, '2026-02-27 10:35:54', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.switch.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027213914603995137, '000000', '大模型回答节点响应模板', 'node.llmAnswer.template', '🤖 LLM 节点 生成回答:', 'Y', 103, 1, '2026-02-27 10:47:16', 1, '2026-02-27 10:52:40', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.llmAnswer.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2027217577397391361, '000000', '工作流异常响应模板', 'node.exception.template', '🛑 工作流发生异常:', 'N', 103, 1, '2026-02-27 11:01:49', 1, '2026-02-27 11:02:01', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.exception.template' AND `tenant_id` = '000000');
INSERT INTO `sys_config` (`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`, `config_type`, `create_dept`, `create_by`, `create_time`, `update_by`, `update_time`, `remark`)
SELECT 2084157200000000003, '000000', '网络搜索节点响应模板', 'node.googleSearch.template', '🔍 网络搜索节点处理完成:', 'Y', 103, 1, '2026-07-29 19:40:00', 1, '2026-07-29 19:40:00', NULL
FROM DUAL WHERE NOT EXISTS (SELECT 1 FROM `sys_config` WHERE `config_key` = 'node.googleSearch.template' AND `tenant_id` = '000000');

View File

@@ -0,0 +1,66 @@
-- 智谱 Web Search 工作流扩展节点
-- 内部组件名继续使用 Google,以兼容现有前端组件和已保存流程。
UPDATE `t_workflow_component`
SET `title` = '网络搜索',
`remark` = '调用智谱 Web Search 检索互联网信息',
`display_order` = 40,
`is_enable` = 1,
`is_deleted` = 0,
`update_time` = NOW()
WHERE `name` = 'Google'
AND `tenant_id` = '000000';
INSERT INTO `t_workflow_component`
(`uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`,
`create_time`, `update_time`, `is_deleted`, `tenant_id`)
SELECT
'a7f8c2d44e5b4c83a9d6f103c2b47e18',
'Google',
'网络搜索',
'调用智谱 Web Search 检索互联网信息',
40,
1,
NOW(),
NOW(),
0,
'000000'
FROM DUAL
WHERE NOT EXISTS (
SELECT 1
FROM `t_workflow_component`
WHERE `name` = 'Google'
AND `tenant_id` = '000000'
);
UPDATE `sys_config`
SET `config_name` = '网络搜索节点响应模板',
`config_value` = '🔍 网络搜索节点处理完成:',
`update_time` = NOW()
WHERE `config_key` = 'node.googleSearch.template'
AND `tenant_id` = '000000';
INSERT INTO `sys_config`
(`config_id`, `tenant_id`, `config_name`, `config_key`, `config_value`,
`config_type`, `create_dept`, `create_by`, `create_time`, `update_by`,
`update_time`, `remark`)
SELECT
2084157200000000003,
'000000',
'网络搜索节点响应模板',
'node.googleSearch.template',
'🔍 网络搜索节点处理完成:',
'Y',
103,
1,
NOW(),
1,
NOW(),
'智谱 Web Search 工作流扩展节点'
FROM DUAL
WHERE NOT EXISTS (
SELECT 1
FROM `sys_config`
WHERE `config_key` = 'node.googleSearch.template'
AND `tenant_id` = '000000'
);

View File

@@ -0,0 +1,41 @@
-- ----------------------------
-- MCP 市场工具租户与审计列补齐
-- 2026-08-30
-- ----------------------------
-- 本脚本只迁移结构和归属信息,不删除无法关联到市场的孤儿记录。
-- 孤儿记录的 tenant_id 保持 NULL,因此租户归属查询会 fail closed。
-- 这是一次性迁移脚本:两个 ALTER TABLE 都会隐式提交。若执行中断或仅完成部分 DDL,
-- 必须先核对实际表结构后逐句续跑,禁止直接重跑整个文件。
-- 本机受控执行入口为 scripts/apply-live-migrations.ps1;先使用 -PreflightOnly,
-- 再以同一个显式 DPAPI 备份路径执行正式迁移。生产环境仍需按自身发布流程审计后执行。
-- 首次 DDL 前预检;上线前应确认结果为 0,避免新增列后留下无法可信回填的归属。
SELECT COUNT(*) AS `preflight_invalid_market_owner_count`
FROM `mcp_market_tool` AS `tool`
LEFT JOIN `mcp_market_info` AS `market` ON `market`.`id` = `tool`.`market_id`
WHERE `market`.`id` IS NULL
OR `market`.`tenant_id` IS NULL;
ALTER TABLE `mcp_market_tool`
ADD COLUMN `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '租户编号' AFTER `local_tool_id`,
ADD COLUMN `create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门' AFTER `tenant_id`,
ADD COLUMN `create_by` bigint NULL DEFAULT NULL COMMENT '创建者' AFTER `create_dept`,
ADD COLUMN `update_by` bigint NULL DEFAULT NULL COMMENT '更新者' AFTER `create_time`,
ADD COLUMN `update_time` datetime NULL DEFAULT NULL COMMENT '更新时间' AFTER `update_by`;
UPDATE `mcp_market_tool` AS `tool`
INNER JOIN `mcp_market_info` AS `market` ON `market`.`id` = `tool`.`market_id`
SET `tool`.`tenant_id` = `market`.`tenant_id`;
ALTER TABLE `mcp_market_tool`
MODIFY COLUMN `tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '000000' COMMENT '租户编号',
ADD INDEX `idx_tenant_market` (`tenant_id`, `market_id`);
-- 上线前应确认结果为 0;统计覆盖父市场缺失、子表租户为空、父子租户为空或不一致。
SELECT COUNT(*) AS `invalid_market_tool_tenant_count`
FROM `mcp_market_tool` AS `tool`
LEFT JOIN `mcp_market_info` AS `market` ON `market`.`id` = `tool`.`market_id`
WHERE `market`.`id` IS NULL
OR `tool`.`tenant_id` IS NULL
OR `market`.`tenant_id` IS NULL
OR NOT (BINARY `tool`.`tenant_id` <=> BINARY `market`.`tenant_id`);

View File

@@ -0,0 +1,76 @@
-- ----------------------------------------------------------------------------
-- URL 管理模块增量脚本(可重复执行)
-- 1) 创建 sys_url 表
-- 2) 新增「系统管理 -> URL管理」菜单及 4 个按钮权限(按 perms 去重,幂等)
-- 3) 插入两条初始公开网站链接(按 name + url 去重,幂等)
-- 适用于已存在数据库的升级;全新安装请直接使用 ruoyi-ai.sql
-- ----------------------------------------------------------------------------
-- ----------------------------
-- 1. URL 管理表 sys_url
-- ----------------------------
CREATE TABLE IF NOT EXISTS `sys_url` (
`url_id` bigint NOT NULL AUTO_INCREMENT COMMENT '链接ID',
`tenant_id` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '000000' COMMENT '租户编号',
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT '链接名称',
`url` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL COMMENT 'HTTP(S) 地址',
`description` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '链接说明',
`sort_order` int NULL DEFAULT 0 COMMENT '显示顺序',
`status` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT '0' COMMENT '状态(0正常 1停用)',
`create_dept` bigint NULL DEFAULT NULL COMMENT '创建部门',
`create_by` bigint NULL DEFAULT NULL COMMENT '创建者',
`create_time` datetime NULL DEFAULT NULL COMMENT '创建时间',
`update_by` bigint NULL DEFAULT NULL COMMENT '更新者',
`update_time` datetime NULL DEFAULT NULL COMMENT '更新时间',
`remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`url_id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci COMMENT = 'URL 管理表' ROW_FORMAT = DYNAMIC;
-- ----------------------------
-- 2. 菜单 & 按钮权限(幂等:perms 不存在时才插入)
-- 父菜单 1 = 系统管理目录
-- ----------------------------
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), 'URL管理', 1, 12, 'url', 'system/url/index', '', 1, 0, 'C', '0', '0', 'system:url:list', 'mdi:link-variant', 103, 1, NOW(), 'URL管理菜单'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = 'system:url:list' AND `menu_type` = 'C');
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), 'URL查询', (SELECT `menu_id` FROM `sys_menu` WHERE `perms` = 'system:url:list' AND `menu_type` = 'C' LIMIT 1), 1, '#', '', '', 1, 0, 'F', '0', '0', 'system:url:query', '#', 103, 1, NOW(), ''
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = 'system:url:query' AND `menu_type` = 'F');
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), 'URL新增', (SELECT `menu_id` FROM `sys_menu` WHERE `perms` = 'system:url:list' AND `menu_type` = 'C' LIMIT 1), 2, '#', '', '', 1, 0, 'F', '0', '0', 'system:url:add', '#', 103, 1, NOW(), ''
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = 'system:url:add' AND `menu_type` = 'F');
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), 'URL修改', (SELECT `menu_id` FROM `sys_menu` WHERE `perms` = 'system:url:list' AND `menu_type` = 'C' LIMIT 1), 3, '#', '', '', 1, 0, 'F', '0', '0', 'system:url:edit', '#', 103, 1, NOW(), ''
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = 'system:url:edit' AND `menu_type` = 'F');
INSERT INTO `sys_menu`
(`menu_id`, `menu_name`, `parent_id`, `order_num`, `path`, `component`, `query_param`, `is_frame`, `is_cache`, `menu_type`, `visible`, `status`, `perms`, `icon`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT (SELECT COALESCE(MAX(`menu_id`), 0) + 1 FROM (SELECT `menu_id` FROM `sys_menu`) t), 'URL删除', (SELECT `menu_id` FROM `sys_menu` WHERE `perms` = 'system:url:list' AND `menu_type` = 'C' LIMIT 1), 4, '#', '', '', 1, 0, 'F', '0', '0', 'system:url:remove', '#', 103, 1, NOW(), ''
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_menu` WHERE `perms` = 'system:url:remove' AND `menu_type` = 'F');
-- ----------------------------
-- 3. 初始公开网站链接(幂等:name + url 均不存在时才插入)
-- ----------------------------
INSERT INTO `sys_url`
(`tenant_id`, `name`, `url`, `description`, `sort_order`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT '000000', '若依官网', 'https://ruoyi.vip', 'RuoYi 官方网站,提供文档、源码与社区支持', 1, '0', 103, 1, NOW(), '初始公开链接'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_url` WHERE `name` = '若依官网' AND `url` = 'https://ruoyi.vip');
INSERT INTO `sys_url`
(`tenant_id`, `name`, `url`, `description`, `sort_order`, `status`, `create_dept`, `create_by`, `create_time`, `remark`)
SELECT '000000', 'RuoYi-AI 开源仓库', 'https://github.com/ageerle/ruoyi-ai', 'RuoYi-AI 项目 GitHub 仓库', 2, '0', 103, 1, NOW(), '初始公开链接'
FROM DUAL
WHERE NOT EXISTS (SELECT 1 FROM `sys_url` WHERE `name` = 'RuoYi-AI 开源仓库' AND `url` = 'https://github.com/ageerle/ruoyi-ai');

View File

@@ -0,0 +1,24 @@
-- 知识库检索工作流节点注册
-- 为新安装和已有环境提供幂等的节点注册
INSERT INTO `t_workflow_component`
(`uuid`, `name`, `title`, `remark`, `display_order`, `is_enable`,
`create_time`, `update_time`, `is_deleted`, `tenant_id`)
SELECT
'b8e3c1d55f6a4d92b0e7f214d3c58a29',
'KnowledgeRetrieval',
'知识库检索',
'从知识库中检索相关内容,支持向量检索和混合检索',
30,
1,
NOW(),
NOW(),
0,
'000000'
FROM DUAL
WHERE NOT EXISTS (
SELECT 1
FROM `t_workflow_component`
WHERE `name` = 'KnowledgeRetrieval'
AND `tenant_id` = '000000'
);

View File

@@ -0,0 +1,19 @@
-- Run after the base ruoyi-ai.sql. Preserves existing scripts and provider keys.
DROP PROCEDURE IF EXISTS migrate_drama_preparation;
DELIMITER $$
CREATE PROCEDURE migrate_drama_preparation()
BEGIN
IF NOT EXISTS (SELECT 1 FROM information_schema.columns WHERE table_schema=DATABASE() AND table_name='short_drama_script' AND column_name='creation_mode') THEN
ALTER TABLE short_drama_script ADD creation_mode varchar(32) DEFAULT 'standard', ADD source_materials longtext, ADD worldbuilding longtext, ADD revision_notes longtext;
END IF;
END$$
DELIMITER ;
CALL migrate_drama_preparation();
DROP PROCEDURE migrate_drama_preparation;
INSERT INTO chat_model (id,category,model_name,provider_code,model_describe,model_show,api_host,api_key,create_dept,create_by,create_time,update_by,update_time,remark,tenant_id)
SELECT 2106002500000000001,'video','bytedance/seedance-2.5/reference-to-video','atlas','Seedance 2.5 多模态参考生视频(字节跳动)','Y',
COALESCE((SELECT api_host FROM (SELECT api_host FROM chat_model WHERE provider_code='atlas' AND category='video' AND tenant_id=0 ORDER BY id DESC LIMIT 1) h),'https://api.atlascloud.ai/api/v1'),
COALESCE((SELECT api_key FROM (SELECT api_key FROM chat_model WHERE provider_code='atlas' AND category='video' AND tenant_id=0 ORDER BY id DESC LIMIT 1) k),''),
103,1,NOW(),1,NOW(),'Atlas Seedance 2.5 reference-to-video; 4-30s, up to 30 images and 10 audio references',0
WHERE NOT EXISTS (SELECT 1 FROM chat_model WHERE model_name='bytedance/seedance-2.5/reference-to-video' AND tenant_id=0);

View File

@@ -0,0 +1,21 @@
CREATE TABLE IF NOT EXISTS short_drama_visual_asset (
id bigint NOT NULL PRIMARY KEY,
project_id bigint NOT NULL,
tenant_id varchar(20) NOT NULL DEFAULT '000000',
storyboard_id bigint DEFAULT NULL,
asset_key varchar(180) NOT NULL,
kind varchar(24) NOT NULL,
title varchar(255) NOT NULL,
prompt longtext,
reference_images longtext,
source_hash varchar(64),
status varchar(24) NOT NULL DEFAULT 'pending',
image_url text,
model varchar(255),
prediction_id varchar(255),
error_message text,
create_time datetime DEFAULT CURRENT_TIMESTAMP,
update_time datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
UNIQUE KEY uk_project_asset (project_id,asset_key),
KEY idx_storyboard (storyboard_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='道具资产和逐镜关键帧,可续跑';

View File

@@ -0,0 +1,13 @@
-- MySQL idempotent migration; run in the configured application database.
SET @skill_aesthetic_sql = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE short_drama_project ADD COLUMN aesthetic_skill_name VARCHAR(64) NULL COMMENT ''Selected aesthetic skill catalog name''',
'SELECT 1') FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'short_drama_project' AND column_name = 'aesthetic_skill_name');
PREPARE skill_aesthetic_stmt FROM @skill_aesthetic_sql;
EXECUTE skill_aesthetic_stmt;
DEALLOCATE PREPARE skill_aesthetic_stmt;
SET @skill_director_sql = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE short_drama_project ADD COLUMN director_skill_name VARCHAR(64) NULL COMMENT ''Selected director skill catalog name''',
'SELECT 1') FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'short_drama_project' AND column_name = 'director_skill_name');
PREPARE skill_director_stmt FROM @skill_director_sql;
EXECUTE skill_director_stmt;
DEALLOCATE PREPARE skill_director_stmt;

View File

@@ -0,0 +1,8 @@
-- Idempotent schema upgrade; preserve credentials and explicitly customized priorities.
SET @sort_order_sql = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE chat_model ADD COLUMN sort_order INT NOT NULL DEFAULT 100 COMMENT ''默认模型优先级,升序'' AFTER category',
'SELECT 1') FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'chat_model' AND column_name = 'sort_order');
PREPARE sort_order_stmt FROM @sort_order_sql;
EXECUTE sort_order_stmt;
DEALLOCATE PREPARE sort_order_stmt;
UPDATE chat_model SET sort_order = 0 WHERE provider_code = 'atlas' AND sort_order = 100 AND model_name IN ('bytedance/doubao-seed-2.1-pro-260628', 'openai/gpt-image-2.5-flare/text-to-image', 'bytedance/seedance-2.0-mini/reference-to-video');

View File

@@ -0,0 +1,7 @@
-- PC 管理后台和短剧工作台:无操作 12 小时后登录失效(单位:秒)。
-- 仅迁移原 30 分钟策略,保留已自定义的客户端设置。
UPDATE sys_client
SET active_timeout = 43200
WHERE device_type = 'pc' AND active_timeout = 1800;
-- 已部署环境通过 /system/client 更新相同字段以同步清理客户端缓存。
-- 已签发的令牌需重新登录后使用新策略。

View File

@@ -0,0 +1,6 @@
-- Existing Atlas keys/hosts remain intact. Default priority is maintained through model management.
-- Apply after 2026-10-02-chat-model-sort-order.sql.
UPDATE chat_model SET sort_order = 10
WHERE provider_code = 'atlas' AND category = 'chat' AND model_name = 'bytedance/doubao-seed-2.1-pro-260628' AND sort_order = 0;
UPDATE chat_model SET sort_order = 0
WHERE provider_code = 'atlas' AND category = 'chat' AND model_name = 'deepseek-ai/deepseek-v4.1-flash';

View File

@@ -0,0 +1,8 @@
-- Store the exact creation input separately from generated project descriptions.
-- Existing rows stay NULL unless their original request can be recovered.
SET @original_idea_sql = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE short_drama_project ADD COLUMN original_idea LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL COMMENT ''Original story creation input'' AFTER description',
'SELECT 1') FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'short_drama_project' AND column_name = 'original_idea');
PREPARE original_idea_stmt FROM @original_idea_sql;
EXECUTE original_idea_stmt;
DEALLOCATE PREPARE original_idea_stmt;

View File

@@ -0,0 +1,8 @@
-- Full image prompt histories can exceed TEXT's 65535 byte capacity after a few revisions.
-- Enlarge both the history and undo columns while retaining all earlier candidates.
ALTER TABLE short_drama_character_appearance
MODIFY COLUMN image_descriptions MEDIUMTEXT NULL COMMENT '每张图片对应的提示词(JSON数组)',
MODIFY COLUMN previous_descriptions MEDIUMTEXT NULL COMMENT '上一轮提示词列表(撤销用,JSON数组)';
ALTER TABLE short_drama_location
MODIFY COLUMN image_descriptions MEDIUMTEXT NULL COMMENT '每张图片对应的提示词(JSON数组)',
MODIFY COLUMN previous_descriptions MEDIUMTEXT NULL COMMENT '上一轮提示词列表(撤销用,JSON数组)';

View File

@@ -0,0 +1,7 @@
-- Add ordered multi-selection without rewriting existing project bindings.
SET @storyboard_skills_sql = (SELECT IF(COUNT(*) = 0,
'ALTER TABLE short_drama_project ADD COLUMN storyboard_skill_names TEXT NULL COMMENT ''Ordered storyboard skill catalog names as JSON''',
'SELECT 1') FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = 'short_drama_project' AND column_name = 'storyboard_skill_names');
PREPARE storyboard_skills_stmt FROM @storyboard_skills_sql;
EXECUTE storyboard_skills_stmt;
DEALLOCATE PREPARE storyboard_skills_stmt;

47
docs/tenant-management.md Normal file
View File

@@ -0,0 +1,47 @@
# 新增租户接口
开启 `tenant.enable: true` 后,超级管理员可通过 `POST /system/tenant` 创建租户。请求需要登录凭证和 `system:tenant:add` 权限;使用反向代理时,请按部署配置添加接口前缀。
## 请求参数
请求使用 `Content-Type: application/json`。
| 参数 | 说明 |
| --- | --- |
| `companyName` | 企业名称,必填且不能与已有租户重复。 |
| `contactUserName` | 联系人,必填。 |
| `contactPhone` | 联系电话,必填。 |
| `username` | 租户初始管理员用户名,必填。 |
| `password` | 租户初始管理员密码,必填。 |
| `packageId` | 已存在的租户套餐 ID,必填。建议使用字符串传输,避免浏览器对大整数的精度损失。 |
| `expireTime` | 过期时间,使用 `yyyy-MM-dd HH:mm:ss`,例如 `2027-09-11 00:00:00`;不传或传 `null` 表示不限制有效期。未带时区的时间按后端运行时区解释。 |
| `accountCount` | 可创建的用户数量,`-1` 表示不限制。 |
## 请求示例
请将套餐 ID 替换为当前系统中的有效套餐,并设置实际使用的管理员账号和密码。
```json
{
"companyName": "示例企业",
"contactUserName": "联系人",
"contactPhone": "13800000000",
"username": "tenant_admin",
"password": "ChangeMe_123456!",
"packageId": "2018611998196109314",
"expireTime": "2027-09-11 00:00:00",
"accountCount": -1
}
```
## 日期配置
后端默认日期格式配置位于 `ruoyi-admin/src/main/resources/application.yml`:
```yaml
spring:
jackson:
date-format: yyyy-MM-dd HH:mm:ss
```
扩展应用的 `ObjectMapper` 时,使用 Spring 注入的 `Jackson2ObjectMapperBuilder`,以保留全局日期格式、自定义 Jackson 模块和构建器配置。

35
docs/url-management.md Normal file
View File

@@ -0,0 +1,35 @@
# URL 管理
URL 管理用于维护 Copilot 新建编程任务页的常用链接。管理端入口为“系统管理 → URL管理”(`/system/url`),支持新增、编辑、批量删除、名称和状态筛选及分页。
## 安装与权限
已有数据库执行 [增量脚本](script/sql/update/2026-09-01-sys-url.sql),可重复执行。新安装使用包含 URL 表、菜单及初始链接的全量 `docs/script/sql/ruoyi-ai.sql`。脚本创建 `sys_url` 表和菜单;普通管理角色需分配对应菜单及按钮权限。
| 接口 | 权限 | 用途 |
| --- | --- | --- |
| `GET /system/url/list` | `system:url:list` | 名称、状态筛选和分页 |
| `GET /system/url/{urlId}` | `system:url:query` | 编辑回填 |
| `POST /system/url` | `system:url:add` | 新增 |
| `PUT /system/url` | `system:url:edit` | 编辑 |
| `DELETE /system/url/{urlIds}` | `system:url:remove` | 删除,多个 ID 以逗号分隔 |
| `GET /system/url/shortcuts` | `coding:harness:use` 或 `system:url:list` | 当前租户的已启用链接 |
链接地址仅允许带有效主机名的 HTTP(S) 地址。状态 `0` 表示启用,`1` 表示停用;列表和快捷入口按 `sortOrder`、`urlId` 升序排列。数据查询和修改遵循当前租户隔离。
## 使用
在管理端填写名称、地址、说明、顺序和状态后保存。Copilot 点击“新建编程任务”会刷新快捷入口;停用的链接不显示。卡片显示名称、说明和外链标识,并以 `noopener,noreferrer` 在新标签页打开。加载中、空列表和请求失败均有提示,失败时可重试。
后端实现位于 `ruoyi-modules/ruoyi-system` 的 `SysUrlController`、`SysUrlServiceImpl`;管理端位于 `ruoyi-admin/apps/web-antd/src/views/system/url`;Copilot 使用 `UrlShortcutCards.vue` 和 `useUrlShortcuts.ts`。
## 2026-09-08 最终验收
- 后端打包、管理端构建和 Copilot 构建通过;Copilot 构建包含类型检查。
- URL 接口 14/14,覆盖 CRUD、分页、排序、输入校验、权限和租户隔离。
- Copilot 单元测试 18/18,卡片状态与点击检查 7/7,EXTERNAL 计划工具回归 2/2。
- 增量 SQL 连续执行两次通过,全量 SQL 的 URL 模块在临时隔离库通过。
- 浏览器完成新增、编辑、筛选、停用隐藏、重新启用刷新和卡片说明检查;临时数据已清理。
- 管理端全项目仍有 103 项既有类型诊断,URL 模块为 0 项。
本轮还修复了 EXTERNAL 模式隐藏 `plan_step` 的框架问题,使模型能在证据校验后完成计划。原生运行和计划均已到达 `COMPLETED`。本轮为本地验收;未包含远程部署。新标签页打开参数通过组件测试确认,本轮未新增真实弹窗或手机尺寸实测结论。

47
pom.xml
View File

@@ -13,7 +13,7 @@
<description>全栈式AI开发平台</description>
<properties>
<revision>3.0.0</revision>
<revision>3.1.0</revision>
<spring-boot.version>3.5.8</spring-boot.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
@@ -43,8 +43,6 @@
<aws.sdk.version>2.28.22</aws.sdk.version>
<!-- SMS 配置 -->
<sms4j.version>3.3.5</sms4j.version>
<!-- 限制框架中的fastjson版本 -->
<fastjson.version>1.2.83</fastjson.version>
<!-- 面向运行时的D-ORM依赖 -->
<anyline.version>8.7.2-20250603</anyline.version>
<!-- 工作流配置 -->
@@ -54,18 +52,25 @@
<!-- Jackson XML -->
<jackson-dataformat-xml.version>2.18.2</jackson-dataformat-xml.version>
<!-- AI 相关依赖 -->
<langchain4j.version>1.13.0</langchain4j.version>
<langchain4j.community.version>1.13.0-beta23</langchain4j.community.version>
<langgraph4j.version>1.5.3</langgraph4j.version>
<langchain4j.version>1.17.2</langchain4j.version>
<langchain4j.beta.version>1.17.2-beta27</langchain4j.beta.version>
<langchain4j.community.version>1.17.0-beta27</langchain4j.community.version>
<langgraph4j.version>1.8.20</langgraph4j.version>
<weaviate.version>1.19.6</weaviate.version>
<dify.version>1.0.7</dify.version>
<dify.version>1.2.7</dify.version>
<coze.version>0.4.2</coze.version>
<!-- 智谱官方 Java SDK -->
<zai-sdk.version>0.3.5</zai-sdk.version>
<!-- gRPC 版本 - 解决 Milvus SDK 依赖冲突 -->
<grpc.version>1.62.2</grpc.version>
<!-- Apache Commons Compress - 用于POI处理ZIP格式 -->
<commons-compress.version>1.27.1</commons-compress.version>
<avatar-generator.version>1.1.0</avatar-generator.version>
<javassist.version>3.30.2-GA</javassist.version>
<jsoup.version>1.21.2</jsoup.version>
<knife4j.version>4.4.0</knife4j.version>
<swagger-annotations.version>2.2.8</swagger-annotations.version>
@@ -79,7 +84,7 @@
<maven-surefire-plugin.version>3.5.3</maven-surefire-plugin.version>
<flatten-maven-plugin.version>1.3.0</flatten-maven-plugin.version>
<!-- 打包默认跳过测试 -->
<skipTests>true</skipTests>
<skipTests>false</skipTests>
</properties>
<profiles>
@@ -342,6 +347,12 @@
<groupId>me.zhyd.oauth</groupId>
<artifactId>JustAuth</artifactId>
<version>${justauth.version}</version>
<exclusions>
<exclusion>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 离线IP地址定位库 ip2region -->
@@ -351,12 +362,6 @@
<version>${ip2region.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
</dependency>
<dependency>
<groupId>org.ruoyi</groupId>
<artifactId>ruoyi-system</artifactId>
@@ -499,20 +504,8 @@
<resources>
<resource>
<directory>src/main/resources</directory>
<!-- 关闭过滤 -->
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/resources</directory>
<!-- 引入所有 匹配文件进行过滤 -->
<includes>
<include>application*</include>
<include>bootstrap*</include>
<include>banner*</include>
</includes>
<!-- 启用过滤 即该资源中的变量将会被过滤器中的值替换 -->
<filtering>true</filtering>
</resource>
</resources>
</build>

View File

@@ -1,31 +1,59 @@
# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
# FFmpeg-enabled variant of ruoyi-admin/Dockerfile.
FROM bellsoft/liberica-openjdk-rocky:17.0.16-cds
#FROM bellsoft/liberica-openjdk-rocky:21.0.8-cds
#FROM findepi/graalvm:java17-native
LABEL maintainer="Lion Li"
# Rocky base repositories do not provide the full codec build. RPM Fusion Free
# supplies ffmpeg with libx264, while the checks below prevent a reduced build
# from reaching production unnoticed.
RUN set -eux; \
dnf -y install dnf-plugins-core epel-release; \
. /etc/os-release; \
rocky_major="${VERSION_ID%%.*}"; \
if [ "${rocky_major}" -ge 9 ]; then \
dnf config-manager --set-enabled crb; \
else \
dnf config-manager --set-enabled powertools; \
fi; \
dnf -y install "https://mirrors.rpmfusion.org/free/el/rpmfusion-free-release-${rocky_major}.noarch.rpm"; \
dnf -y install ffmpeg; \
for filter in scale pad fps setsar format tpad trim settb setpts xfade \
aresample aformat apad atrim asetpts anullsrc concat acrossfade; do \
ffmpeg -hide_banner -filters 2>/dev/null | grep -Eq "[[:space:]]${filter}[[:space:]]"; \
done; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q dissolve; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q fadeblack; \
ffmpeg -hide_banner -h filter=xfade 2>&1 | grep -q slideleft; \
ffmpeg -hide_banner -encoders 2>/dev/null | grep -Eq '[[:space:]]libx264[[:space:]]'; \
ffmpeg -hide_banner -encoders 2>/dev/null | grep -Eq '[[:space:]]aac[[:space:]]'; \
ffprobe -hide_banner -version >/dev/null; \
dnf clean all; \
rm -rf /var/cache/dnf
RUN mkdir -p /ruoyi/server/logs \
/ruoyi/server/temp \
/ruoyi/skywalking/agent
WORKDIR /ruoyi/server
ENV SERVER_PORT=8080 SNAIL_PORT=28080 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
ENV SERVER_PORT=8080 \
SNAIL_PORT=28080 \
LANG=C.UTF-8 \
LC_ALL=C.UTF-8 \
JAVA_OPTS="" \
FFMPEG_PATH=/usr/bin/ffmpeg \
FFPROBE_PATH=/usr/bin/ffprobe
EXPOSE ${SERVER_PORT}
# 暴露 snail job 客户端端口 用于定时任务调度中心通信
EXPOSE ${SNAIL_PORT}
ADD ./target/ruoyi-admin.jar ./app.jar
SHELL ["/bin/bash", "-c"]
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom \
-Djava.io.tmpdir=/ruoyi/server/temp \
-Dserver.port=${SERVER_PORT} \
-Dsnail-job.port=${SNAIL_PORT} \
# 应用名称 如果想区分集群节点监控 改成不同的名称即可
#-Dskywalking.agent.service_name=ruoyi-server \
#-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
-XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
-jar app.jar

Some files were not shown because too many files have changed in this diff Show More