From bc5b5bf8ffb305dcaf256b83b3fd0b96348e8182 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Tue, 11 Aug 2026 07:42:32 +0800 Subject: [PATCH] =?UTF-8?q?fix(cms):=20=E4=BF=AE=E5=A4=8D=E7=A9=BA?= =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=97=B6=E7=94=9F=E6=88=90=E9=9D=9E=E6=B3=95?= =?UTF-8?q?SQL=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 引入BeanUtil判断实体是否有除id和deleted外的非空字段 - 避免MyBatis-Plus在无可更新字段时生成缺SET子句的SQL - 防止多租户插件jsqlparser因SQL异常而失败 - 空更新场景返回幂等成功结果 - 保持原有代码逻辑,确保业务修改正确执行 --- .workbuddy/memory/2026-08-11.md | 17 +++++++++++++++++ .../cms/controller/CmsWebsiteController.java | 10 ++++++++++ 2 files changed, 27 insertions(+) create mode 100644 .workbuddy/memory/2026-08-11.md diff --git a/.workbuddy/memory/2026-08-11.md b/.workbuddy/memory/2026-08-11.md new file mode 100644 index 0000000..e340be9 --- /dev/null +++ b/.workbuddy/memory/2026-08-11.md @@ -0,0 +1,17 @@ +# 2026-08-11 工作记录 + +## 日志诊断:cms-api (websoft-modules) 报错 + +来源文件:/Users/gxwebsoft/Downloads/websoft-modules (1).log + +### 主报错(反复出现,需修复) +- 现象:`CmsWebsiteController.update()` → `updateById(cmsWebsite)` 生成非法 SQL + `UPDATE cms_website WHERE website_id=? AND deleted=0`(SET 子句为空) +- 抛错链:MyBatis-Plus `TenantLineInnerInterceptor` 用 jsqlparser 解析该空 SET SQL → `ParseException: Encountered unexpected token: "WHERE"` → `MybatisPlusException: Failed to process` +- 根因:`application.yml` 未设置全局 `field-strategy`,MP 3.4.x 默认 `NOT_NULL`。当 PUT /cms/website 的 body 只有 websiteId(websiteCode 被置 null,其余字段全 null)时,`updateById` 没有任何非空字段可写 → SET 为空 → SQL 非法。 +- 实体佐证:`CmsWebsite` 的 `@TableLogic deleted` 进 WHERE、`@TableId websiteId` 进 WHERE、`updateTime` 无 `@TableField(fill)` 自动填充 → 无字段兜底。 +- 已修复(2026-08-11):在 `CmsWebsiteController.update()` 调用 `updateById` 前,用 `BeanUtil.beanToMap` 判断是否存在非 id/deleted 的非空字段;为空则直接 `success` 跳过 DB 更新。已新增 import `cn.hutool.core.bean.BeanUtil`。 + +### 次要报错(非紧急) +- 01:44:17 MQTT:client `hjm_car_1786362857263` keepAlive=20s 超时,`MQTT连接丢失`(GPS 回调)。Paho 通常会自动重连,疑为 broker 网络/keepalive 问题。 +- 07:35:20 WARN Druid:`removeAbandoned is true, not use in production.` 连接池 abandoned 清理开启,Druid 不建议生产环境开启,属配置告警。 diff --git a/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java b/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java index de1e7bd..19a41e1 100644 --- a/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java +++ b/src/main/java/com/gxwebsoft/cms/controller/CmsWebsiteController.java @@ -2,6 +2,7 @@ package com.gxwebsoft.cms.controller; import cn.hutool.core.date.DateTime; import cn.hutool.core.date.DateUtil; +import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; @@ -151,6 +152,15 @@ public class CmsWebsiteController extends BaseController { // 不允许通过此接口清空或修改 websiteCode(设为 null 则 MP 不更新该字段) cmsWebsite.setWebsiteCode(null); } + // 修复:当实体没有任何非空(可更新)字段时,MyBatis-Plus 默认 NOT_NULL 策略会生成 + // 缺 SET 子句的非法 SQL(如 "UPDATE cms_website WHERE ..."),触发多租户插件 jsqlparser + // 解析异常。先判断是否存在 id / deleted 之外的非空字段,空更新视为幂等成功。 + boolean hasUpdatable = BeanUtil.beanToMap(cmsWebsite, false, false).entrySet().stream() + .anyMatch(e -> !"websiteId".equals(e.getKey()) && !"deleted".equals(e.getKey()) + && e.getValue() != null); + if (!hasUpdatable) { + return success("修改成功"); + } if (cmsWebsiteService.updateById(cmsWebsite)) { // 站点信息(含 domain / templateId 等)有 1 天 Redis 缓存,改完必须立刻失效, // 否则公开站与后台链接拼接最长 1 天读到旧值(与 CmsNavigationController 写操作保持一致)。