明珠果苑网站部署手册
明珠果苑 · 网站文档
部署手册
重庆明珠果苑农业开发有限公司
一、架构与环境总览
1.1逻辑架构
用户浏览器 | +-- www.mzgarden.com / www.明珠果苑.com / www.明珠果苑.中国 / www.明珠果苑.网址 | -> Nginx(宝塔站点:Word Press) | -> WordPress /www/wwwroot/明珠果苑.com/ + MySQL(wordpress_sql) +-- sys.mzgarden.com / sys.明珠果苑.com / sys.明珠果苑.中国 / 117.50.73.149 | -> Nginx(宝塔站点:Ruoyi Office) | +-- 静态文件 /www/data/ruoyi/frontend/ | +-- /admin-api 反代 http://127.0.0.1:48080 |
后端 yudao 单体(fat jar 常驻) +-- 托管方式:宝塔「网站 -> Java项目 -> yudao-server」(唯一方式) +-- 端口:48080 应用端口、9999 xxl-job 执行器注册端口(同一进程监听) +-- jar:/www/data/ruoyi/backend/yudao-server.jar +-- 日志:/www/wwwlogs/java/springboot/yudao-server.log
Docker 容器 +-- ruoyi-postgres postgres:16 :5432 数据 /www/data/postgres 库 pgsql_mzgy、xxl_job +-- ruoyi-redis redis:8 :6379 数据 /www/data/redis +-- tdengine TDengine :16041(IoT 预留,当前未启用)
定时调度 xxl-job-admin 2.4.0(PG 改造版):systemd 托管,:9090 仅绑 127.0.0.1 内容管理系统数据库 MySQL:mysqld.service 正在运行(WordPress 依赖,勿停)
1.2一次请求的完整链路
1. 浏览器访问 http://sys.mzgarden.com,Nginx 收到请求后分两路:
2. 静态资源走 /www/data/ruoyi/frontend,返回 index.html 与 assets,前端路由由浏览器接管。
3. 接口走 /admin-api,反向代理到 127.0.0.1:48080,即 yudao-server.jar;后端再连 PostgreSQL 16(业务库 pgsql_mzgy)与 Redis 8。
4. 登录成功后返回的菜单来自数据库 system_menu 表(后端路由模式,accessMode=backend),因此改菜单是改库,不是改前端代码。
1.3站点与域名
| 站点(宝塔) | 绑定域名 | 指向 | nginx 配置 |
|---|---|---|---|
| 官方网站(WordPress) | www.mzgarden.com、www.明珠果苑.com、www.明珠果苑.中国、www.明珠果苑.网址 | /www/wwwroot/明珠果苑.com/ | /www/server/panel/vhost/nginx/xn--2hvo8ae1wg5o.com.conf 等 |
| 数字平台(Ruoyi Office) | sys.mzgarden.com、sys.明珠果苑.com、sys.明珠果苑.中国、117.50.73.149 | 静态 /www/data/ruoyi/frontend/ + /admin-api 反代 48080 | /www/server/panel/vhost/nginx/117.50.73.149.conf |
| 默认站 | 未匹配的 Host | /www/server/nginx/html | default.conf |
顺序约定:两站并列时官方网站在前、数字平台在后;域名重要性依次为 www.mzgarden.com > www.明珠果苑.com > www.明珠果苑.中国 > www.明珠果苑.网址。主域是 www.mzgarden.com,其余三个均 301 到主域。
注意:中文域名在 nginx 与宝塔底层一律是 punycode(xn-- 开头),界面看不到中文属正常。宝塔面板输入框会拦截中文域名,必须用命令行 sed 以 punycode 形式写入 server_name。
1.4端口清单
| 端口 | 归属进程 | 用途 | 对外 |
|---|---|---|---|
| 80 / 443 | nginx | 站点入口 | 是 |
| 48080 | yudao-server | 应用主端口(访问返回 401 即正常) | 是 |
| 9999 | yudao-server | xxl-job 执行器注册端口(与 48080 同一进程) | 否 |
| 9090 | xxl-job-admin | 调度中心控制台 | 仅 127.0.0.1 |
| 5432 | ruoyi-postgres 容器 | PostgreSQL | 否,容器内使用 |
| 6379 | ruoyi-redis 容器 | Redis | 否,容器内使用 |
| 16041 | tdengine 容器 | TDengine(IoT 预留) | 否 |
| 3306 | mysqld | 内容管理系统 WordPress 库 | 否 |
| 5151 | 宝塔面板 | 面板入口(https) | 按宝塔设置 |
| 22 | sshd | SSH | 按防火墙设置 |
1.5关键路径速查
| 内容 | 服务器位置 |
|---|---|
| 后端源码(含 mzgy 两个业务模块) | /www/data/ruoyi/ruoyi-office/ |
| 后端 fat jar | /www/data/ruoyi/backend/yudao-server.jar |
| 后端运行日志 | /www/wwwlogs/java/springboot/yudao-server.log |
| 前端静态产物 | /www/data/ruoyi/frontend/ |
| PostgreSQL 数据目录 | /www/data/postgres/ |
| Redis 数据目录 | /www/data/redis/ |
| 统一备份目录(上传、备份一律放这里) | /www/data/backup/ |
| 数据库每日备份产物 | /www/data/backup/db/ |
| 宝塔自带的计划任务备份 | /www/backup/(与上一行不是同一个目录,勿混) |
| 内容管理系统 WordPress 站点根 | /www/wwwroot/明珠果苑.com/ |
| nginx vhost 配置 | /www/server/panel/vhost/nginx/ |
| xxl-job 安装目录 | /www/data/xxl-job/ |
1.6后端与平台前端:H:\Ruoyi Office\
H:\Ruoyi Office\ ├─ ruoyi-office\ 后端源码工程 │ ├─ mzgy-module-base\ ★ 基地管理,25 个 Controller │ ├─ mzgy-module-channel\ ★ 渠道管理,4 个 Controller │ ├─ yudao-framework\ 框架层 │ ├─ yudao-module-system\ 系统、租户、权限、字典 │ ├─ yudao-module-erp\ 进销存财(渠道档案复用其客户表) │ ├─ yudao-module-bpm\ 工作流引擎 │ ├─ yudao-module-infra\ 基础设施(定时任务在此改造) │ ├─ yudao-module-iot\ 物联网原生模块(lot 用这个) │ ├─ yudao-module-oa / hrm / asset / wms / crm / ai 等 │ ├─ yudao-server\ 启动模块,打 jar 的入口 │ └─ pom.xml 根 POM,两个 mzgy 模块必须在这里注册 │ ├─ ruoyi-office-vben\ 前端源码(本项目唯一权威) │ ├─ apps\ │ │ ├─ web-antd\ ★ 本项目应用,所有前端改动都在这里 │ │ │ └─ src\ │ │ │ ├─ api\ 接口定义(base、channel、system 等) │ │ │ ├─ views\ 页面(base 25 个业务页、channel 等) │ │ │ ├─ router\ 路由(业务菜单走后端,路由文件较少) │ │ │ ├─ store\ 状态(auth.ts 登录逻辑) │ │ │ ├─ layouts\ 布局(auth.vue 登录页外壳) │ │ │ ├─ styles\ 自定义样式 │ │ │ ├─ preferences.ts 全局偏好(主题色、布局、首页) │ │ │ └─ bootstrap.ts 启动装配 │ │ └─ web-antdv-next / web-ele / web-naive / web-tdesign 模板自带,未使用 │ ├─ packages\ ★ 框架源码,不要改,升级会被覆盖 │ └─ package.json 根脚本,pnpm build 从这里执行 │ └─ xxl-job-2.4.0\ 调度中心源码(参考用)
1.7内容管理系统:H:\Word Press\
H:\Word Press\
├─ 原始代码\ WordPress 原始安装包
│ ├─ wordpress原始包.zip
│ └─ t9326+mysql\ 建站模板包(t9326.zip、t9326.sql、t9326.rar)
│
├─ 系统备份\ 素材与历史页面
│ ├─ 图片文件\ psd / png 素材(吴奶奶.psd、图片处理1.psd 等)
│ ├─ 官网建设中index.html
│ └─ 官网建设中的配置文件.txt
│
└─ 系统备忘\
├─ AI铁律.txt、栏目结构.txt、提示词01.txt 等 开发约定与备忘
├─ 首页修改要点.docx、登录相关页面修改要点.docx、维护页切换总结.docx
└─ 修改备忘\
└─ 20261020\ ★ 内容管理系统当前源码快照
├─ wp-content\themes\mzgy01\ 内容管理系统主题(自制)
├─ wp-content\plugins\mzgy-guard\ 安全插件(自制)
├─ wp-content\plugins\mzgy-maintenance\ 维护页插件(自制)
├─ index官网建设中.html
└─ favicon.ico
1.8备份与工作记录
H:\系统备份\新网云主机备份\YYYYMMDD\ 后端 jar(含 xxl-job 调度包)、前端 dist、数据库 dump、配置与安全包 H:\系统备忘\工作日志\ 工作日志 docx,按日期命名
1.9服务器目录结构
核心目录 /www/data/ruoyi,只放运行产物;服务器上不放任何源码。 /www/data/ruoyi/ ├─ backend/yudao-server.jar ★ 后端运行程序,宝塔 Java 项目指向此文件 └─ frontend/ ★ 前端静态产物,Nginx 指向这里
/www/data/xxl-job/ 调度中心(xxl-job-admin-2.4.0.jar 与配置) /www/data/backup/db/ 每日 PostgreSQL 备份(02:30 自动) /www/data/backup/site/ 宝塔站点备份(01:30 自动) /www/wwwlogs/java/springboot/yudao-server.log 后端运行日志(二进制,检索加 -a) /www/wwwroot/明珠果苑.com/ 内容管理系统 WordPress 站点根 /www/server/panel/ 宝塔面板 /etc/systemd/system/xxl-job-admin.service 调度中心服务定义
二、代码库规矩与本地工程
2.1六条铁律
1. 前端源码在本地 H:\Ruoyi Office\ruoyi-office-vben,服务器上只有编译后的静态产物,没有源码。
2. 后端源码在本地 H:\Ruoyi Office\ruoyi-office,服务器上不保留任何源码。
3. 前后端都在本地编译。本地改、本地打包;服务器只接收产物、重启服务,不在服务器上开发,也不在服务器上跑编译。
4. 编译完再上传。产物先落到 /www/data/backup/ 留档,再覆盖正式位置,出问题能随时退回上一版。
5. 内容管理系统是独立一套。WordPress 源码在本地 H:\Word Press,PHP 不需要编译,改完直接覆盖。
6. 数据库以服务器为准。任何结构或数据变更前先备份,脚本一律写成可重复执行。
2.2四方对照
| 项目 | 前端 | 后端 | 内容管理系统 | 数据库 |
|---|---|---|---|---|
| 源码在哪 | 本地 ruoyi-office-vben | 本地 H:\Ruoyi Office\ruoyi-office(唯一工作副本) | 本地 H:\Word Press | 服务器 pgsql_mzgy |
| 在哪改 | 本地 | 本地 | 本地或网站后台 | 服务器(SQL 脚本) |
| 在哪编译 | 本地 pnpm build:antd | 本地 mvn package | 不编译 | 不适用 |
| 产物 | apps/web-antd/dist.zip 约 10MB | yudao-server.jar 约 509MB | 主题、插件目录 | dump 文件 |
| 怎么上服务器 | 上传解压覆盖 frontend | 上传 jar 并重启 | 上传覆盖 wp-content | psql 执行 |
| 怎么生效 | 清缓存后刷新浏览器 | 宝塔 Java 项目页重启 | 覆盖即生效 | 执行即生效 |
2.3本地后端工程
本地 H:\Ruoyi Office\ruoyi-office 在官方芋道基础上承载两个业务模块,具备完整可编译条件,可直接编译出线上运行的那份 jar。相对原版芋道,工程上只有四处差别:
| 序号 | 项目 | 内容 |
|---|---|---|
| 1 | 业务模块目录 | mzgy-module-base、mzgy-module-channel 解压到工程根,共 244 个 java 文件,均为 api + server 双子模块 |
| 2 | 根 pom.xml | 在 <modules> 中注册 mzgy-module-base、mzgy-module-channel |
| 3 | yudao-server/pom.xml | 声明 mzgy-module-base-server、mzgy-module-channel-server 两个依赖(版本 ${revision}) |
| 4 | 依赖仓库 | 本机 ~/.m2 依赖仓库(勿删) |
基准值:产物 532,981,917 字节(约 509MB),构建耗时约 1 分钟(视机器而定)。与线上 jar 拆包比对,BOOT-INF/lib 中服务器有而本地没有的库为 0 个,说明本地装配与线上一致,产物可直接替换线上。
注意:本地 yudao-server/pom.xml 与 git 基线存在差异(asset、wms、member 等模块的依赖处于启用状态),与服务器那份一致。升级框架时不要用官方基线覆盖这两个 pom,否则业务模块依赖会丢失。根 pom 与服务器那份完全一致。
2.4工程本地化的五个步骤
后端走本地编译,本地这份工程必须是完整的。当前 H:\Ruoyi Office\ruoyi-office 已并入 mzgy-module-base、mzgy-module-channel 两个业务模块,编译产物与线上 jar 等价。换机器重建环境时,按下面五步做一次工程本地化:
1. 把 mzgy-module-base、mzgy-module-channel 两个模块放到工程根目录下(当前已就位)。
2. 根 pom.xml 的 modules 列表里加上这两个模块。
3. yudao-server/pom.xml 的 dependencies 里加上这两个模块依赖。
4. 确认本地 Maven 仓库可用(Windows 下为 C:\Users\<用户>\.m2);服务器上的 .m2 已清理,不再从服务器拷贝。
5. 本地跑一次完整打包,确认产物约 500MB 且能正常启动,再谈日常流程。
注意:根 pom.xml 与 yudao-server/pom.xml 以本地为准,服务器上已无源码,不要再从服务器拉这两份文件。
2.5两端源码漂移的风险与对策
本地打包会整体覆盖线上 jar,如果本地拿的是旧代码,重启后线上功能会莫名回退,而且日志里看不出原因。对策三条:
打包前先比对服务器与本地两个 mzgy 模块目录的文件时间与内容,确认无新改动。
本地工程纳入版本管理,每次上线前提交一次,留一个可回溯的代码快照。
每次上传的 jar 都带日期存一份到 /www/data/backup/,出问题时能在两分钟内退回上一版。
三、后端部署与运行
3.1运行方式:宝塔 Java 项目托管
后端以 fat jar 常驻方式运行,由宝塔面板的「Java项目」托管,随宝塔开机自启。项目关键信息如下:
| 项目 | 值 |
|---|---|
| 项目名 | yudao-server |
| 入口 jar | /www/data/ruoyi/backend/yudao-server.jar |
| 监听端口 | 9999,48080(9999 供 xxl-job 执行器注册,48080 为应用端口) |
| 启动参数 | /usr/bin/java -Xms256M -Xmx1024M -jar <jar> –spring.profiles.active=local |
| 启动耗时 | 约 108 秒,重启后耐心等待约 2 分钟再验证 |
| 日常操作 | 宝塔 → 网站 → Java项目 → 该项目行 → 停止 / 启动 / 重启 |
3.2两套托管并存的隐患与处置
3.2.1 识别特征
同一份 jar 若被启动两遍,会同时存在两个 java 进程,特征如下:
| 进程 | 托管方 | 启动时间 | 监听端口 | 实占内存 | 判定 |
|---|---|---|---|---|---|
| PID 16539 | 宝塔 Java 项目 | 2026-10-07 23:20:06 | 9999、48080 | 约 1.44GB | 真正在服务的是它 |
| PID 2605 | systemd(yudao-server.service) | 2026-10-07 12:41:51 | 无 | 约 1.19GB | 空转,堆已顶到 -Xmx1024M |
| PID 760 | 无主(10-17 启动) | 2026-10-17 | 无 | 约 337MB | 已自行退出 |
3.2.2 根因与后果
systemd 单元与宝塔项目指向同一份 jar,两套都配了开机自启。谁先抢到 48080 谁对外服务,另一套启动失败但进程不退。
后果一:白占约 1.2GB 内存,是内存占用偏高最常见的原因。
后果二:如果 systemd 那套抢先占了 48080,宝塔页面仍显示「运行中」,实际却不可用;反过来,用 systemctl restart 重启的是没在服务的那套,改了代码也不生效。
3.2.3 正确处置与校验
原则:只保留宝塔那套,停用并禁止 systemd 那套。执行:
systemctl disable yudao-server # 只摘开机自启,不影响运行中的服务 systemctl stop yudao-server # 释放那 1.19GB
处理后校验:
pgrep -af 'yudao-server\.jar' # 只能出现 1 行(宝塔那套) ss -tlnp | grep -E '9999|48080' # 必须仍归宝塔那套进程 free -h # used 应下降约 1.2GB
校验标准:pgrep 只剩一个进程,9999 与 48080 不中断,内存 used 应回落约 1.2GB,平台登录正常。
3.2.4 禁忌与回退
禁忌一:不要 systemctl enable / start yudao-server。要恢复,先停宝塔项目再启 systemd 那套,两者不可同时运行。
禁忌二:不要在没有确认端口归属的情况下 kill 任何 java 进程,杀错会立刻断服务。
回退路径:若确需回到 systemd 托管,顺序是:宝塔停项目 → systemctl enable –now yudao-server → 把宝塔项目设为不开机自启,避免再次双起。
3.3本地编译
在本地 H:\Ruoyi Office\ruoyi-office 工程根目录执行:
mvn package -P boot -Dmaven.test.skip=true
| 参数 | 为什么不能省 |
|---|---|
| -P boot | 不激活 boot profile 会走 cloud(微服务)分支,各模块各自打 fat jar,总量膨胀到 3.4GB 以上;正确产物约 509MB |
| -Dmaven.test.skip=true | 只写 -Dmaven.test.skip=true 仍会编译测试代码;yudao-module-iot-server 的测试类 import 的是 core.enums.IotDeviceStateEnum,而实际类在 core.enums.device 下,会直接编译失败 |
| 不要 mvn clean(运行期间) | clean 会删掉 target 下正在运行的 jar,线上进程虽然已被加载不受影响,但回滚文件没了 |
提示:在 PowerShell 里执行时,-D 参数要加双引号,例如 "-Dmaven.test.skip=true",否则点号会被拆开。
基准值:产物 532,981,917 字节(约 509MB);构建耗时约 1 分钟(视机器而定)。大小明显偏离这个数,先查 profile 是不是带错了。
禁忌:不要在 server 模块执行 mvn install。yudao-server 以及各 yudao-module-*-server 打出来的都是带 BOOT-INF 的 fat jar,install 会把它装进本地 ~/.m2 并覆盖同坐标的瘦包;此后任何一次再编译,引用这些模块的地方都会报找不到 Controller 或 Service 类,运行期则是 ClassNotFoundException。服务器上的 m2 同理,一样不能 install。
补救:从该模块 target/ 目录里取出 *.jar.original(install 之前那份瘦包),覆盖回 m2 仓库对应路径的同名 jar,再重新编译即可恢复。修定时任务时移植 infra-server 用的就是这条。
3.4上传与替换
以下步骤全程在宝塔里点,不需要命令行:
把新 jar 上传到 /www/data/backup/,重命名为 yudao-server-YYYYMMDD-HHMM.jar,作为留档与回滚点。
宝塔 → 网站 → Java项目 → yudao-server → 点「停止」。
把新 jar 上传覆盖 /www/data/ruoyi/backend/yudao-server.jar(同名覆盖)。
点「启动」,等待约 2 分钟。
验证:浏览器访问 http://117.50.73.149:48080 返回 {"code":401,"msg":"账号未登录"} 即正常;再看日志尾部无异常堆栈。
回滚:把 /www/data/backup/ 里上一版 jar 拷回原位置,再点重启,两分钟内可完成。
3.5重启后的验证
ss -tlnp | grep -E '9999|48080' # 端口在监听
curl -s http://127.0.0.1:48080/ -o /dev/null -w '%{http_code}\n' # 期望 401
tail -n 80 /www/wwwlogs/java/springboot/yudao-server.log
docker ps --format '{{.Names}}\t{{.Status}}'
提示:日志文件是二进制流,用 grep 时要加 -a,否则会被当成 binary file 跳过。
3.6重建时的已知问题与修复
| 问题 | 根因 | 修复 |
|---|---|---|
| fat jar 启动报 PermissionCommonApi 缺失 | 框架依赖未声明 + 实现类源码丢失 + 嵌套 jar 扫描不到 | yudao-server/pom.xml 显式补 13 个 cn.iocoder.cloud 框架依赖;实现类唯一保留在 yudao-module-system-server 的 framework/permission 下 |
| 启动报 ArraySchema 类冲突 | AI 模块传递引入 swagger-annotations 2.0.0,与 2.2.38 冲突 | 给 yudao-module-ai-server 依赖加 exclusion 排除 io.swagger.core.v3:swagger-annotations |
| 数据源连不上 | master/slave 指向连不通的 MySQL 33061 | 改为 PG 库 pgsql_mzgy(application-local.yaml) |
| 启动阻塞在 iotScheduler | iot 模块 Quartz 调度器阻塞 | iot 模块暂停启用(注释 pom 依赖);启用前需单独修调度器 |
| erp/wms Mapper 重名冲突 | 字段名 erpPurchaseOrderMapper 冲突 | 改 ErpPurchaseOrderServiceImpl 字段名 |
| 宝塔启动命令缺 profile | 未加 –spring.profiles.active=local | 启动命令补全,注意 -Xmx 位置 |
| 打包产物 3.4GB | 未带 -P boot | 固定命令 mvn package -P boot -Dmaven.test.skip=true |
3.7日常七步
| 步骤 | 在哪里做 | 做什么 | 命令或要点 |
|---|---|---|---|
| 1 | 本地 | 改代码 | 只改 mzgy-module-base、mzgy-module-channel 两个目录;官方模块不动 |
| 2 | 本地 | 编译 | 工程根目录执行 mvn clean package -P boot -Dmaven.test.skip=true |
| 3 | 本地 | 核对产物 | yudao-server\target\yudao-server.jar,正常约 500MB |
| 4 | 本地 | 算校验值 | sha256sum yudao-server.jar,把值记下来,上传后比对 |
| 5 | 服务器 | 接收上传 | 先传到 /www/data/backup/,不要直接盖正式目录 |
| 6 | 服务器 | 留档再覆盖 | 旧 jar 按日期改名留档,新 jar 覆盖 /www/data/ruoyi/backend/yudao-server.jar |
| 7 | 服务器 | 重启并验证 | 宝塔「网站 → Java项目 → yudao-server」点重启,再看日志确认启动成功 |
3.8具体命令
本地编译(Git Bash 或 CMD 均可):
cd "/h/Ruoyi Office/ruoyi-office" mvn clean package -P boot -Dmaven.test.skip=true ls -lh yudao-server/target/yudao-server.jar sha256sum yudao-server/target/yudao-server.jar
上传(先落备份目录):
scp yudao-server/target/yudao-server.jar root@117.50.73.149:/www/data/backup/yudao-server-new.jar
服务器覆盖并重启:
cd /www/data/ruoyi/backend cp yudao-server.jar /www/data/backup/yudao-server-$(date +%Y%m%d-%H%M).jar cp /www/data/backup/yudao-server-new.jar /www/data/ruoyi/backend/yudao-server.jar 宝塔「网站 → Java项目」点重启 tail -f /www/wwwlogs/java/springboot/yudao-server.log
关键:必须带 -P boot(单体模式)。漏掉会走微服务模式,各模块打成独立 fat jar,最终膨胀到 3.4G 以上,启动也会异常。这是本项目最硬的一条规矩。
提示:日志文件含二进制内容,用 grep 检索要加 -a,例如 grep -a "ERROR" yudao-server.log。
四、前端构建与部署
4.1构建命令
cd "H:\Ruoyi Office\ruoyi-office-vben" pnpm build:antd
产物为 apps/web-antd/dist.zip,约 10MB。必须走完整 turbo 流程:turbo 先对依赖包跑 unbuild 生成真实 dist,再编 web-antd;直接 vite build 会因依赖包还是 stub,把 jiti 拖进浏览器产物导致构建崩溃。二次构建约 1 分 24 秒。
4.2部署流程
宝塔上传 dist.zip 到 /tmp/。
发布写法:先清空 /www/data/ruoyi/frontend/ 再解压完整产物,不要用 unzip -o 覆盖式解压。覆盖式解压每发布一次都会留下上一版的 hash 文件,几轮下来目录里并存几套前端,浏览器拿着旧 index.html 还能把旧界面完整渲染出来,现象是「打开旧版、F5 变新版」。清空到解压之间会有短暂 404,放在低峰做。必须保持完整目录结构,jse 目录不要改名 js,否则主 JS 404 白屏。
注意:frontend/index.html 是手工改过的(去引导动画、改标题、内置自愈脚本,见 4.8),覆盖式解压会把它换回 dist.zip 里的同名文件,等于悄悄回退。发布前先确认源码模板 apps/web-antd/index.html 已同步。
菜单、权限类改动后清 Redis 缓存。
浏览器 Ctrl+F5 强刷,确认 index.html 引用的主 JS 哈希已变化。
顺序:必须先把 dist.zip 上传完,再执行解压。部署脚本首行是 set -e,zip 还没落到 /tmp 就执行 unzip,脚本会立即中止,后面的清缓存、重启都不会跑,现象很像部署失败,实际线上没有受影响。判断依据是 /tmp/dist.zip 不存在或大小为 0。
4.3必须保留的构建配置文件
| 文件 | 作用 |
|---|---|
| apps/web-antd/.env.production | VITE_APP_DOCALERT_ENABLE=false(关闭全局文档地址提示条);VITE_BASE=/web |
| apps/web-antd/vite.config.mts | resolve.alias:把 jiti 的 ESM 入口映射为浏览器 mock |
| apps/web-antd/scripts/jiti-browser-mock.mjs | jiti 浏览器侧空实现,属构建流程一部分 |
4.4Nginx 与静态资源要点
入口 JS 硬编码 /web/ 前缀,Nginx 需配 location ^~ /web/ rewrite,否则入口内部资源全 404。
品牌静态资源位置:/www/data/ruoyi/frontend/static/login-illustration.png(登录插图)、static/imgs/logo.png、favicon.ico。
反代 proxy_pass 尾部不能带斜杠,否则会吃掉 /admin-api 前缀,前端报「内部服务器错误」。
缓存按资源分六类,规则见下表。铁律:入口 HTML 绝不能回到 no-store——no-store 禁止浏览器把响应写盘,F5 拿到的新版存不回去,磁盘里那份旧 index.html 永远替换不掉,「F5 是新版、关掉重开又旧版」就是这么来的。
| 资源 | 缓存策略 | 为什么 |
|---|---|---|
| index.html、根路径、所有前端路由 | no-cache, must-revalidate | 可存盘,但每次使用前必须回源校验:没变 304,变了 200 并覆盖旧副本 |
| 带 hash 的 JS(jse/、js/) | public, max-age=31536000, immutable | 换版必换文件名,锁死一年安全;缺失时由刷新脚本接管 |
| 带 hash 的 CSS、字体、图片 | public, max-age=31536000, immutable | 同上,但缺失必须直接 404:CSS 上下文不执行脚本 |
| _app.config.js(固定名) | no-cache | 文件名固定、内容随版本变,绝不能长缓存 |
| 其他固定名资源(favicon、logo) | no-cache | 无 hash,改版后要能立刻看到 |
| 已删除的旧 hash JS | 200 + 刷新脚本 | 旧页面一旦请求旧 JS,静默重载到新版,最多跳一次 |
已删除的旧 hash JS 由 Nginx 返回一段刷新脚本兜底(保留原 query,最多跳一次);旧 CSS 必须直接 404,CSS 上下文不执行 JS,返回脚本既无效又污染样式。前端另有一层 vite:preloadError 自愈,两层各管一段、不能互相替代,分工见 4.8。
上线后按四条自检,中文域名走 punycode:
① 前端路由:curl.exe -I http://sys.xn--2hvo8ae1wg5o.com/web/auth/login 应见 Cache-Control: no-cache, must-revalidate
② 现行入口 JS(文件名以 index.html 引用为准):curl.exe -I http://sys.xn--2hvo8ae1wg5o.com/web/jse/<入口文件名> 应见 public, max-age=31536000, immutable
③ 已删除的旧 hash JS:curl.exe http://sys.xn--2hvo8ae1wg5o.com/web/jse/<已删的旧文件名> 应返回一小段 mz_stale 刷新脚本,类型 application/javascript
④ 已删除的旧 hash CSS:curl.exe -I http://sys.xn--2hvo8ae1wg5o.com/web/css/<已删的旧文件名> 必须是 404,不能是 200
4.5品牌定制源码位置(改皮必读)
| 定制项 | 源码位置 |
|---|---|
| 登录页标题 / 副标题 | packages/locales/src/langs/zh-CN/authentication.json |
| 登录页左侧插图 + 系统名称 | apps/web-antd/src/layouts/auth.vue + public/login-illustration.png |
| 默认主题(莫兰迪绿、浅色、侧边导航、深色顶栏) | apps/web-antd/src/preferences.ts |
| 全局背景色 #F5F7F5 | apps/web-antd/src/styles/antd-theme.css |
| 工作台欢迎语与快捷导航 | apps/web-antd/src/views/dashboard/workspace/index.vue(quickNavItems) |
| 页脚开关 / 高度 / 版权年份 | apps/web-antd/src/preferences.ts(footer 段) |
| 页脚版权样式(品牌绿 #5B7B5E) | packages/effects/layouts/src/basic/copyright/copyright.vue |
| 登录页底部链接 | packages/effects/common-ui/src/ui/authentication/doc-link.vue |
| favicon / logo | apps/web-antd/public/favicon.ico、public/static/imgs/logo.png |
界面上有三处固定文案,改皮时照抄,不要凭记忆写:主标题「明珠果苑数字管理平台」(必须带“管理”二字,此前漏写过)、副标题「公司管理·基地管理·渠道管理·智慧农业」、页脚「Copyright © 2026 | 重庆明珠果苑农业开发有限公司 | 技术开发:玉龙罡风」。框架自带的「RuoYi Office·企业管理一体化平台」字样一处都不能留,登录页、浏览器标题、页脚、关于页要逐一排查。
平台版本号随改动递进,当前 5.1。版本号由负责人确定,改版时页面显示与文档记录同步改,不要一处改一处不改。
Vben 的 CSS 变量用 hsl 三段式,不带 hsl() 包裹、不带逗号,例如 120 14% 96% 约等于 #F5F7F5。
注意:packages 目录是框架源码,不要改,升级会被覆盖;业务改动一律落在 apps/web-antd 下。
4.6偏好缓存坑
改了 preferences 的默认值并部署后,访问过旧版本的浏览器会用 localStorage 里的旧偏好覆盖新默认值,表现为页脚或主题不生效。这不是代码问题:在右上角偏好设置面板手动点一次,或用无痕窗口验证即可;新浏览器首次访问即生效。
4.7前端本地编译与上传七步
全部在本地完成,服务器只接收静态产物。
| 步骤 | 在哪里做 | 做什么 | 命令或要点 |
|---|---|---|---|
| 1 | 本地 | 改代码 | apps\web-antd\src 下改;常用四处:views 页面、api 接口、preferences.ts 偏好、styles 样式 |
| 2 | 本地 | 首次装依赖 | 在 ruoyi-office-vben 根目录执行 pnpm install |
| 3 | 本地 | 编译 | 根目录执行 pnpm build,产物在 apps\web-antd\dist |
| 4 | 本地 | 压缩产物 | 把 dist 内文件打成 zip,连同校验值一起上传 |
| 5 | 服务器 | 备份旧版 | 先打包现有 frontend 目录,按日期存到 /www/data/backup |
| 6 | 服务器 | 上传覆盖 | 宝塔上传 zip 解压,覆盖 /www/data/ruoyi/frontend |
| 7 | 浏览器 | 验证 | Ctrl+F5 强刷,避开缓存 |
注意:编译前先跟负责人确认,不擅自跑 pnpm build;每次产物按日期备份,出问题能退回上一版。
4.8产物级手工改动与前端自愈
index.html 有几处改动是直接改在构建产物上的:去启动引导动画、改标题、统一首屏背景、内联 vite:preloadError 自愈脚本。替换这个静态文件即生效,不必重新编译,也不用 reload Nginx;但 pnpm build 和覆盖式解压都会把它冲掉,源码模板必须同步。
发版后的白屏分两段,各由一层兜底,不能互相替代:
| 机制 | 覆盖场景 | 现状 |
|---|---|---|
| vite:preloadError(前端,内联在 index.html) | 用户已进入系统,发版后切到懒加载页面,chunk 已换名 404 | 已内置,由 Vite 运行时派发 |
| Nginx 刷新脚本(服务端,@mz_stale) | 用户拿着旧 index.html,入口 JS 直接 404,此时 Vite 运行时还没启动 | 已在运行,不能下掉,缓存规则见 4.4 |
| 两者关系 | 各管一段,互为双保险 | 入口 404 时无人派发事件,前端这层覆盖不到入口 |
自愈脚本四个要点:必须写在 <script type="module"> 之前,晚于入口注册就赶不上派发,等于没写;preventDefault() 阻止 Vite 默认抛错白屏,随后静默 reload 一次取新版;sessionStorage 标记防死循环,刷新后仍失败就停下;页面正常加载 4 秒后清标记,下次发版还能自愈。
去引导动画改四处:删 style[data-app-loading] 里的动画类,只留首屏背景;删 div#__app-loading__;title 改为「明珠果苑数字平台」;首屏背景 #F3F6F3、深色模式 #0d0d10,与登录页同色,加载前后不跳色。删 div 是安全的,入口里对应函数做过判空。
同步铁律:以上改动必须同步到 apps/web-antd/index.html,否则下次 pnpm build 静默丢失,现象与「从来没改过」完全一样,极难发现。编译前按 4.1 的约定先确认。
替换前先备份:cp /www/data/ruoyi/frontend/index.html /www/data/backup/index.html.bak-日期;回滚就用这份备份还原,不用改 Nginx。
五、数据库
5.1连接与操作模板
docker exec ruoyi-postgres psql -U pgsql_mzgy -d pgsql_mzgy -P pager=off -c "<SQL>"
# 查表结构用 information_schema(\d 不能通过 -c 传入) SELECT column_name, data_type FROM information_schema.columns WHERE table_name='xxx';
重要:宝塔「数据库」页只显示面板自己安装或登记过的库,看不到 Docker 容器里的 PG。判断后端到底连哪个库,以 docker ps 为准,别被面板误导。
5.2库与表现状
| 库 | 归属 | 规模 | 说明 |
|---|---|---|---|
| pgsql_mzgy | 业务主库 | 327 张表 | base_ 系列 26 张、channel_ 系列 4 张、system_* 系统表、erp/crm/bpm 等官方模块表 |
| xxl_job | 调度库 | 8 张表,数据仅 8 行 | 调度中心元数据;日志表会随调度增长 |
| postgres | 系统库 | — | 维护用 |
| wordpress_sql | MySQL | — | 内容管理系统 WordPress 库,在 mysqld 里,不在 PG |
建库:pgsql_mzgy 现有 327 张表,由本地 H:\Ruoyi Office\sql\pg语句\ 下 18 个脚本建成,按序全量执行即可重建。注意:这 18 个都是官方模块脚本,自研的 base_ 26 张、channel_ 4 张不在其中,重建时要单独补齐,否则后端启动即报缺表。
| 序号 | 脚本文件(sql\pg语句\) | 覆盖模块 |
|---|---|---|
| 1 | 00-基础框架-system-infra-pgsql.sql | 系统管理 + 基础设施(含 infra_job / infra_job_log) |
| 2 | 00-基础框架-quartz-pgsql.sql | 定时任务 Quartz 表(已停用) |
| 3 | yudao-module-ai-pgsql.sql | AI 大模型 |
| 4 | yudao-module-asset-pgsql.sql | 资产 |
| 5 | yudao-module-bpm-pgsql.sql | 工作流 |
| 6 | yudao-module-crm-pgsql.sql | 客户关系 |
| 7 | yudao-module-erp-pgsql.sql | ERP |
| 8 | yudao-module-hrm-pgsql.sql | 人事 |
| 9 | yudao-module-iot-pgsql.sql | 物联网 |
| 10 | yudao-module-member-pgsql.sql | 会员 |
| 11 | yudao-module-mp-pgsql.sql | 微信公众号 |
| 12 | yudao-module-oa-pgsql.sql | 办公 |
| 13 | yudao-module-pay-pgsql.sql | 支付 |
| 14 | yudao-module-product-pgsql.sql | 商品 |
| 15 | yudao-module-promotion-pgsql.sql | 营销 |
| 16 | yudao-module-report-pgsql.sql | 报表 |
| 17 | yudao-module-trade-pgsql.sql | 交易 |
| 18 | yudao-module-wms-pgsql.sql | 仓储 |
5.3SQL 规范
任何结构或数据变更前先备份,见第七章。
脚本一律幂等(可重复执行),执行后核对表数与行数。
SQL 只执行一次。重复执行菜单类脚本会重复插入,导致前端路由崩溃(menu name duplicate),出错要删干净重插。
多租户约定:业务表要有 tenant_id 列;布尔字段用 int2;json 字段按官方 PG 惯例用 text 而不是 jsonb。
官方 MySQL 脚本转 PG 的惯例:反引号去掉、LIMIT x,y 改 LIMIT y OFFSET x、DATE_ADD 改 interval 运算、! 取反改 NOT (…)、类型推断报错处显式 CAST。
5.4system_role_menu 特别注意
该表 id 列无自增、无默认值,由应用层填充。批量插入必须显式给 id,推荐 MAX(id) + ROW_NUMBER() OVER();直接插 null 会整批失败。
先 DELETE 后 INSERT 若中途失败,会造成角色菜单短暂为空,操作前先评估在线用户。
5.5数据隔离现状与隐患
平台是多租户系统,现有 6 个租户:明珠果苑(1)、伙伴1(121)、基地1(122)、渠道1(123)、单位1(124)、备用1(125)。租户之间硬隔离,登录页的租户下拉只决定登录入口,选错直接登录失败,不会串账。
隐患:但业务代码里 base_* 与 channel_* 共 31 个 DO 中有 26 个标了 @TenantIgnore,等于关闭了自动租户过滤,隔离目前靠菜单权限挡,接口层没有兜底。这是隐患,不是已成事实的安全事故,但需要收口。
5.6数据库与菜单变更
业务数据与菜单都在 PostgreSQL 16 的 pgsql_mzgy 库里,容器运行。
1. 业务表:base_ 开头 26 张(基地)、channel_ 开头 4 张(渠道),另有芋道自带的 system_、erp_、bpm_ 等。
2. 菜单:system_menu 表。父级用 parent_id 串起来,改菜单即改这张表;现有结构为三层——一级菜单、二级目录、页面,菜单类型与图标规范见《开发手册》3.7。
3. 改表原则:先备份表、再改数据;菜单改完需重新登录或清缓存才生效。
4. 落库做法:脚本整体放在一个事务里执行,任一步失败整体回滚。本次一次跑完 93 条新增、115 条更新,把旧的一级菜单归并、移动到新结构下。主脚本与补丁脚本分开,图标是独立补丁,便于单独核对与回退。
5. 前后各导一份单表快照做核对:重构后 system_menu 1311 个物理行(含表头),重构前 1218 行,差 93 行,正好等于新增菜单数。全库另用 pg_dump 导一份作基线。
6. 执行后当场数一级菜单:parent_id 为 0 的正好 8 个,依次为管理首页、内容管理、商城管理、公司管理、基地管理、渠道管理、系统管理、平台运维,与规划一致才算落库成功;数目不对就回滚,别在半成品上继续调。
7. 界面手改只进数据库,不进脚本。落库后有人在管理界面调过名称或排序,就不能再重跑主脚本——重跑会把界面上的修改覆盖回脚本里的值。
8. 菜单一移动,旧地址就失效。本次「代码生成」由 /web/infra/codegen 移到 /infra/dev/codegen,旧链接直接报错,原因是菜单挂到了新目录、路径随之改变。调整层级时要把路径变更一并列出核对,不能只改 parent_id。
9. 菜单数据上线时,配套两项要同时到位:新增目录补图标、未开发页面挂占位组件(common/coming-soon/index)。只上菜单不补这两项,点开就是空白图标和报错页。
六、定时任务调度
6.1部署现状
xxl-job-admin 2.4.0 经 PG 改造后部署在 9090,仅绑定 127.0.0.1,由 systemd 单元 xxl-job-admin.service 托管。改造内容包括:pom 加 postgresql 驱动、application.properties 改 PG 数据源(xxl_job 库)、7 个 mapper XML 转方言、修 timestamp < interval 与 ! 取反两处 SQL。
宇擎侧已接入:application-local.yaml 中 xxl.job.enabled 为 true,执行器以 yudao-server:9999 注册,心跳正常,相关 handler 已注册。注意这里的 9999 就是第四章那个执行器端口,与宝塔 Java 项目里填的端口一致。
6.2已知问题
宇擎的「定时任务」菜单从部署起就 404。根因是后端定时任务管理代码被裁剪:infra_job、infra_job_log 表在,前端菜单在,但 JobController、JobService、Mapper 都没有,属于版本不匹配。
修复方案(已定,未实施):从官方 yudao 源码移植约 15 个文件,编译 infra-server,用 .original 覆盖服务器 ~/.m2 中对应 jar,重启后端。
“建任务 → 9090 触发”的端到端链路尚未实测。
七、内容管理系统部署与改传
7.1现状
| 项目 | 值 |
|---|---|
| 程序 | WordPress(PHP 8.2) |
| 站点根 | /www/wwwroot/明珠果苑.com/ |
| 数据库 | MySQL 库 wordpress_sql(mysqld.service 正在运行) |
| 主域名 | www.mzgarden.com(主域)、www.明珠果苑.com、www.明珠果苑.中国、www.明珠果苑.网址;中文域名 punycode 为 xn--2hvo8ae1wg5o.xn--fiqs8s 与 xn--2hvo8ae1wg5o.com |
| 设计基调 | 艺术农业、莫兰迪绿:主绿 #5B7B5E、导航深色 #2D3A35、页面底 #F5F7F5 |
| 本地源码 | H:\Word Press\(原始代码、系统备份、系统备忘\修改备忘\20261020\wp-content) |
| 主题与插件 | 主题 mzgy01;插件 mzgy-guard、mzgy-maintenance(维护页) |
7.2改传流程
本地 H:\Word Press 改主题或插件文件。
上传覆盖服务器对应目录 /www/wwwroot/明珠果苑.com/wp-content/themes/mzgy01 或 plugins 下同名目录。
清缓存(插件或 CDN)后用无痕窗口验证;PHP 不需要编译,覆盖即生效。
7.3改在哪、传到哪
内容管理系统是独立一套,与数字平台没有代码关系,PHP 不需要编译,改完直接覆盖文件。
| 改什么 | 本地位置 | 服务器位置 | 怎么生效 |
|---|---|---|---|
| 文章、页面、菜单、图片 | WordPress 后台 | 不用碰文件 | 后台改完即生效 |
| 主题样式与模板 | H:\Word Press\系统备忘\修改备忘\20261020\wp-content\themes\mzgy01 | /www/wwwroot/明珠果苑.com/wp-content/themes/mzgy01 | 覆盖文件后清缓存 |
| 维护页插件 | …\wp-content\plugins\mzgy-maintenance | …\wp-content\plugins\mzgy-maintenance | 覆盖后后台停用再启用 |
| 安全插件 | …\wp-content\plugins\mzgy-guard | …\wp-content\plugins\mzgy-guard | 同上 |
| 新图片素材 | H:\Word Press\系统备份\图片文件 | 后台媒体库上传 | 直接后台上传 |
注意:改哪个文件就传哪个文件,不要整目录覆盖 wp-content,否则会把线上上传的图片和缓存一起冲掉。
7.4主题导航跟随分类
前台顶部菜单不再读「外观 → 菜单」里手工建的那套静态菜单,改由主题函数按分类目录树自动生成:后台新建一个分类,前台菜单就自动多出一项,不用再去外观里手工加。排序按分类建立顺序,未分类不显示,层级深度由主题里的常量控制,默认三层。
因此后台操作的顺序反过来了:先建分类、填好分类名和简介(分类描述会显示在前台分类页),前台菜单自动出现。「外观 → 菜单」里那套旧静态菜单只在主题回退到旧版本时才有用,不要两边同时改,免得两套菜单打架。
样式没动:菜单仍用原来的类名和 nav.css,改分类结构不影响前端样式。菜单项多了放不下一行时,在 nav.css 里调字号与间距,不要动主题函数。
7.5插件改传:文章访问权限
本节以 2026-10-31 上线的「文章访问权限」插件为例,记录一次完整的插件改传。插件与改主题文件不同:主题是覆盖已有文件,插件是新增目录,还要启用、还要留回退,所以次序不能反。以后再加插件,照本节的次序走。
7.5.1 规则口径
这套规则只作用在文章详情页这一处,全站默认是「仅登录」,与改传前的行为一致。判定顺序是:文章自己的设定优先,没设过才跟全站默认;「指定」档里角色与账号命中任一即放行。
| 情形 | 结果 |
|---|---|
| 管理员(manage_options) | 永远放行,不受任何设定影响 |
| 文章设为「公开(游客可看)」 | 未登录访客也能读 |
| 文章设为「仅登录」 | 任何已登录账号都能读 |
| 文章设为「指定」 | 角色或账号命中任一即放行,否则拦 |
| 文章未设过,或设为「跟随默认」 | 按全站默认,当前为「仅登录」 |
| 字段损坏、角色被删、数据缺失 | 一律按拦处理,宁可错拦不错放 |
| 只拦详情页 | 列表页、搜索、分类页、导航、站点地图照旧公开 |
7.5.2 传什么、传到哪里
站点根是 /www/wwwroot/明珠果苑.com/,插件在其下的 wp-content/plugins/。本次交付四个文件,要动的只有前两项。
| 文件 | 说明 |
|---|---|
| mzgy-access/ | 新插件目录,文章级访问权限,9 个文件约 1000 行 |
| mzgy-guard/mzgy-guard.php | 原内容卫士插件,只在拦截判断处加 3 行;水印与防复制一行未动 |
| mzgy-access_1.0.0.zip | 插件目录的压缩包,宝塔里可直接上传解压 |
| 部署说明.txt | 随附的上传次序与回退说明,内容已并入本节 |
落位一一对应,其余文件一律不传:
| 本地 | 服务器 |
|---|---|
| mzgy-access/(整个目录) | wp-content/plugins/mzgy-access/,新建目录 |
| mzgy-guard.php | wp-content/plugins/mzgy-guard/mzgy-guard.php,覆盖同名文件 |
不要整目录覆盖 wp-content(原因见 7.3),也不要顺手把 zip 留在服务器上,解压完即删。
7.5.3 分两步传
先传插件、验回归,再传守卫、才测放行。次序反了,中间任何一步出错都没有退路。
第一步,只传 mzgy-access:
一、把 mzgy-access_1.0.0.zip 上传到 plugins/ 目录,解压,得到 plugins/mzgy-access/。
二、后台插件页启用「明珠果苑访问权限」。
三、按 7.5.4 做回归验证,此时行为应与改前完全一致。
四、这一步做完,站点表现和原来一样,只是后台多了几个入口。
第二步,再传 mzgy-guard.php:
一、先把服务器上的 mzgy-guard/mzgy-guard.php 复制一份,改名 mzgy-guard.php_bak。
二、确认 _bak 就在同一目录里,再覆盖同名文件。
三、然后才去测「公开(游客可看)」是否真的放行。
为什么必须分两步:新插件启用后,守卫插件里那段旧的详情页判断仍会先接住所有请求。此时即便新插件写错,最坏结果是拦得更严,不会出现本该保护的文章被放出去。反过来先传守卫,判定就交给了还没验证过的新插件,一旦出错是直接放行。
7.5.4 回归验证
验收前先关掉维护模式。维护模式开着时,未登录访客看到的是建设中页(503),看不出访问权限的效果。
| 顺序 | 操作 | 应为 |
|---|---|---|
| a | 无痕窗口打开任一篇文章 | 仍返回 403「权限不足 · 该文章内容仅限注册用户查看」 |
| b | 登录一个普通账号再看同一篇 | 正常显示正文 |
| c | 看后台文章列表 | 多出「访问权限」一列,显示「跟随默认(仅登录)」 |
| d | 第二步之后:挑一篇设「公开(游客可看)」,无痕窗口打开 | 能直接看到正文 |
| e | 第二步之后:挑一篇设「指定」,勾一个角色 | 该角色账号能看,其他账号仍被拦 |
a、b、c 三条在第一步就要过,任何一条不对都停在这一步,不要继续传守卫。
7.5.5 出问题怎么退
一、后台停用「明珠果苑访问权限」:详情页立刻回到一律拦截,守卫里那段旧判断自动接管,不用改代码。
二、要连守卫一起退:把 mzgy-guard.php_bak 改回 mzgy-guard.php 原名。
三、停用插件不删任何文章数据,只是不生效,可随时再启用。
四、插件本身有语法错误时,后台会拒绝启用并给出提示,站点不会挂;守卫覆盖后若白屏,把 _bak 改回原名即可——这是本次唯一会碰到前台的改动。
7.5.6 已知边界
一、只拦文章详情页。列表页、搜索页、分类页、导航、站点地图照旧公开,这是现行口径。
二、图片是静态文件,知道图片地址仍能直接打开,插件拦不住;要拦得上 Nginx 层,另议。
三、被拦时返回 403,不跳转,搜索引擎会记为无法访问。
四、接口(/wp-json/)与 RSS 的正文输出由插件设置页的开关控制,默认开启:开启时这两个入口只给标题与摘要,关掉即恢复全文输出。
五、防复制与水印仍是守卫插件原样,本次未动一行。
六、若列表页或首页模板输出的是全文而不是摘要,详情页拦了也等于没拦,改传后要看一眼列表页有没有大段正文。
七、本次未做批量设置。要按「列表页全选设一次」还是「按分类自动继承」,待方案定后再加。
八、mzgy-guard 的版本号本次未改,仍为 1.2.0。
八、开机自启与服务恢复
8.1自启体系
| 组件 | 托管方式 | 开机自启 | 备注 |
|---|---|---|---|
| yudao-server(后端) | 宝塔 Java 项目 | 是(宝塔负责) | systemd 同名单元已 disable,切勿启用 |
| nginx | 宝塔 / systemd | 是 | 配置改动后 nginx -t 再 reload |
| PostgreSQL 16 | Docker 容器 ruoyi-postgres | 随 docker 服务 | 数据在 /www/data/postgres |
| Redis 8 | Docker 容器 ruoyi-redis | 随 docker 服务 | 数据在 /www/data/redis |
| xxl-job-admin | systemd xxl-job-admin.service | 是 | 9090 仅绑 127.0.0.1 |
| TDengine | Docker 容器 | 随 docker 服务 | IoT 预留,当前未启用 |
| MySQL | mysqld.service | 是 | 内容管理系统 WordPress 依赖,勿停 |
| 内容管理系统 WordPress | PHP-FPM + nginx | 是 | 无独立进程 |
九、本地编译再上传,六个必须盯住的地方
流程本身没问题,是标准做法。真正的风险不在流程,在两端一致性。
| 风险 | 会出什么事 | 怎么防 |
|---|---|---|
| 两端源码不一致(最要紧) | 本地编译用的是旧代码,上传后把新版本覆盖掉,功能凭空回退 | 编译前先确认版本管理里的代码是最新的;每次上线把产物与源码快照一并留档 |
| 本地缺依赖 | mvn 卡在拉包,或报找不到某个内部依赖,白等半天 | 本地 Maven 仓库已完整,无需再拷贝;服务器上的 .m2 已清理 |
| 配置文件不在 jar 里 | 以为改了配置会随 jar 生效,其实重启后读的还是服务器上的外部文件 | 改配置必须重新打包上传;只改服务器上的文件不会生效 |
| 漏掉 -P boot | 打成 3.4G 的微服务包,上传慢且启动失败 | 命令固定写全:mvn clean package -P boot -Dmaven.test.skip=true |
| 500MB 传输中断 | jar 只传了一半,服务起来直接报错 | 先传 /www/data/backup,比对 sha256 一致后再覆盖正式文件 |
| 停机与文件属主 | 重启期间约两分钟不可用;jar 属主与权限不对时服务起不来 | 挑低峰时段操作;覆盖后确认属主为 www(宝塔 Java 项目启动用户)且可读 |
附录 A常用命令速查
| 用途 | 命令 |
|---|---|
| 看后端日志 | tail -f /www/wwwlogs/java/springboot/yudao-server.log |
| 日志里搜报错(二进制安全) | grep -a -B3 -A8 "Caused by" /www/wwwlogs/java/springboot/yudao-server.log | tail -40 |
| 确认后端端口 | ss -tlnp | grep -E '9999|48080' |
| 确认后端进程数 | pgrep -af 'yudao-server\.jar' |
| 确认 systemd 是否还管着后端 | systemctl show -p MainPID –value yudao-server |
| 执行 SQL | docker exec ruoyi-postgres psql -U pgsql_mzgy -d pgsql_mzgy -P pager=off -c "<SQL>" |
| 查表数 | docker exec ruoyi-postgres psql -U pgsql_mzgy -d pgsql_mzgy -tc "select count(*) from information_schema.tables where table_schema='public'" |
| 手动跑一次数据库备份 | bash /www/data/backup/db/备份脚本路径 |
| 看备份日志 | tail -n 40 /www/data/backup/db/backup.log |
| 重载 nginx | nginx -t && nginx -s reload |
| 看磁盘占用 | du -sh /www/* | sort -rh; df -h / |
| 看内存与大户进程 | free -h; ps aux –sort=-%mem | head -12 |
| 本地打包(后端) | cd /d "H:\Ruoyi Office\ruoyi-office" && mvn package -P boot -Dmaven.test.skip=true |
| 本地构建(前端) | cd "H:\Ruoyi Office\ruoyi-office-vben" && pnpm build:antd |
| 部署前端 | unzip -o /tmp/dist.zip -d /www/data/ruoyi/frontend/ |
附录 B易混点速查
| 易混点 | 实际情况 | 正确做法 |
|---|---|---|
| 本地后端现在能直接编译吗 | 能。两个业务模块已并入本地工程,可编译出与线上等价的 jar | 打包命令必须带 -P boot 与 -Dmaven.test.skip=true,漏了会打错包 |
| 能不能直接在服务器上改后端代码 | 不能。服务器上已不保留后端源码,只在本地改 | 改动只在本地做,改完提交版本管理 |
| 服务器上能不能改前端 | 不能。服务器只有编译后的静态文件,没有源码 | 前端本地改、本地编译,上传产物覆盖 frontend |
| 改了前端没变化 | 多因浏览器缓存,或旧产物没覆盖干净 | 先 Ctrl+F5 强刷;仍不对则核对 Nginx root 是否指向 frontend、产物是否解压到位 |
| 内容管理系统要不要编译 | 不用。WordPress 是 PHP | 改完直接覆盖主题或插件文件 |
| 两份 pom 要不要同步 | 以本地为准。服务器已无源码,两份 pom 只在本地维护 | 随工程一起提交版本管理 |
附录 C生产环境软件与依赖清单
本附录列出生产服务器上实际运行的软件、版本与部署方式。版本以线上实际安装为准,调整环境或升级版本时请同步更新本表。开发机环境与框架版本见《明珠果苑网站开发手册》附录 C。
| 软件 | 版本 | 部署方式 | 用途 |
|---|---|---|---|
| Ubuntu | — | 新网云主机 | 操作系统,宝塔面板管理 |
| Nginx | 宝塔内置 | 系统服务 | 反向代理、静态资源、内容管理系统托管 |
| OpenJDK | 17 | 系统安装 | 后端服务运行时 |
| PostgreSQL | 16 | Docker 容器 | 业务库 pgsql_mzgy,94 张业务表 |
| Redis | 8 | Docker 容器 | 缓存、会话、字典数据 |
| XXL-Job | 2.4.0 | systemd(9090) | 定时任务调度中心,独立 xxl_job 库 |
| Docker | — | 系统安装 | 承载 PostgreSQL 与 Redis |
| PHP + WordPress | — | 宝塔站点 | 对外内容管理系统,自研主题 mzgy01 |
| 后端主服务 | Spring Boot 3.5.9 | Jar 运行,执行器 9999 | 业务主服务,令牌鉴权 |