Wujies 无界平台
平台功能(自研)架构设计

设计与决策存档

这些是设计与方案文档:它们解释"为什么这么设计",以及有哪些备选方案被否掉了。 和文档站的其它页面不同,它们更接近工程日志 —— 包含实测记录、被推翻的假设、 以及踩过的坑。

这些文档不在本站正文里

它们不在本站的 website/ 目录中,而是散落在仓库外层的 docs/ 下 (wujies-platform/docs/ 里也有一份收录)。下面的路径是仓库内路径,不是本站链接。

外层 docs/ 在工作区根、与三个仓库并列,本身不在任何 git 仓库里 —— 写进那里的内容没有版本历史(正式收录看插件仓库的 wujies-plugins/docs/)。

什么时候看哪份

文档什么时候看
docs/开发指南.md想搞懂"这东西是什么、怎么跑、改哪里"。本站大量内容的第一手来源
docs/应用市场-插件打包与部署教程.md要打包 / 上架 / 安装 / 签名,照着手敲命令
wujies-platform/AGENTS.md改代码前扫一遍"不变量"和"已知坑"。人也能当速查表。权威来源,优先级最高
docs/应用市场改造方案.md想知道为什么这么设计、有哪些备选方案被否了
docs/应用市场-插件运行时探针报告.md想动插件加载机制(类加载器 / 子上下文),先看这份实测记录
docs/应用市场-竞品调研与差距分析.md想对齐 Halo 等系统的能力边界
docs/1Panel打包手册.md要把平台打成 1Panel 应用包
docs/1Panel部署与上架.md怎么装、怎么上架到官方商店、排障速查
docs/开发问题与解决方案.md本项目的踩坑总记录(2026-10):类加载器 / MyBatis 映射注册 / 序列化 / 前端远程产物 / 安装生命周期 / Windows 编码。想知道"这个坑怎么来的、怎么修的"看它
docs/插件开发详细教程.md从零到能做出来的详细版教程(16 章),以 wujies-quote 为骨架;★ 章节覆盖跨插件调用 / 开放接口 / Job / 系统服务
docs/AI-插件开发-SKILL.md给 AI 编码助手看的操作手册(不是教程):不变量、SOP、错误对照表、AI 特有的纪律
docs/1Panel手册-待改清单.md + 1Panel手册-改动diff.txt那次改名后对 1Panel 手册做的逐处改动与依据(含"哪些不该改"的判断)
docs/app-market/app.schema.json应用清单的 JSON Schema

几个"为什么"的答案

改造方案文档里有推导过程,这里给出结论:

为什么不做 fork(官方版 / 用户版同一份代码)

本项目有 3 个仓库、一批 SQL 迁移脚本、以及一堆构建期魔法 (远程应用必须复刻宿主的自动导入与组件解析器)。 fork 之后每次改公共逻辑都要改两遍,而且必然漂移。

一个 jar、一个前端、一个开关,便宜得多。

为什么不给 sys_menu 加 app_code 列

归属从 app_version_menu 反查即可,「不需要改表」。 加列要动框架的实体 / VO / Mapper XML / 菜单页面,代价大得多, 而且会和 app_version_menu 形成两份真相。

为什么迁移不做 down

MySQL 的 DDL 是隐式提交的,包在一个事务里是假的安全感。 所以设计上要求脚本幂等,把"能重跑"当作回滚能力的替代品。

为什么进程内隔离而不是进程外

决策是进程内(性能优先):绝大多数插件需要与宿主深度交互, 进程内是主流选择。不可信页面用 iframe 降级沙箱。

为什么目录远程读取不做缓存

频率很低(只在安装/升级时几次),而加缓存会遇到 "刚上架却装到旧版本"这种难以解释的问题。

为什么用过滤器挡上架端,而不是给接口逐个加注解

因为以后新增上架端接口会自动被挡住, 不会因为"忘了加开关"漏出去。

为什么目录实现用 @ConditionalOnProperty 而不是 @ConditionalOnMissingBean

后者依赖 bean 定义顺序,前者是显式的。

刻意不做的事(部分)

不做理由
不往宿主那个 HandlerMapping 里注册插件路由那是别人正在用的表,注销时键算错会连宿主接口一起摘掉
不让插件的 HandlerMapping 自动扫描上下文父类默认实现会把宿主控制器重复注册一遍,排查时极具误导性
不让插件类加载器"子优先"平台类必须由父加载器提供,否则出现"双 Class 世界"
不删任务历史它是审计线索
不删对象存储里的文件平台不知道它们属于谁,也不该替用户删文件
不做"上传即部署"上传只登记(解包读清单 + 落 OSS + 记校验和),产物释放是另一个动作
状态过滤放在前端状态 tab 的计数必须来自"不带状态过滤"的整份列表

相关阅读

目录