From ff432b82c0a32ba13aac9429b19dfdb658a085f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Mon, 3 Aug 2026 20:29:33 +0800 Subject: [PATCH] =?UTF-8?q?fix(cmsNavigation):=20=E8=A7=84=E8=8C=83code?= =?UTF-8?q?=E5=AD=97=E6=AE=B5=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=94=AF=E4=B8=80?= =?UTF-8?q?=E6=80=A7=E6=A0=A1=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 规范化code字段,trim并转为小写以保证唯一性校验一致 - 添加栏目code租户内唯一性校验逻辑,避免重复冲突 - 保留空或空串code时不进行唯一性校验 - 修改与新增操作均调用唯一性校验函数 - 避免触发数据库唯一索引导致操作失败异常 --- .../controller/CmsNavigationController.java | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/src/main/java/com/gxwebsoft/cms/controller/CmsNavigationController.java b/src/main/java/com/gxwebsoft/cms/controller/CmsNavigationController.java index 33c0841..68f1c5f 100644 --- a/src/main/java/com/gxwebsoft/cms/controller/CmsNavigationController.java +++ b/src/main/java/com/gxwebsoft/cms/controller/CmsNavigationController.java @@ -104,8 +104,14 @@ public class CmsNavigationController extends BaseController { } // 去除前面空格 cmsNavigation.setTitle(StrUtil.trimStart(cmsNavigation.getTitle())); + // code 规范化:trim + 转小写(唯一性以规范化后的值为准) + if (cmsNavigation.getCode() != null) { + cmsNavigation.setCode(cmsNavigation.getCode().trim().toLowerCase()); + } // 单页模型绑定唯一性校验:同一租户下同一个单页只能绑定一个栏目 checkPageBindingUnique(cmsNavigation); + // 栏目 code 租户内唯一性校验(code 为空/空串时不校验) + checkCodeUnique(cmsNavigation); if (cmsNavigationService.save(cmsNavigation)) { // 添加成功事务处理 cmsNavigationService.saveAsync(cmsNavigation); @@ -119,8 +125,14 @@ public class CmsNavigationController extends BaseController { @Operation(summary = "修改网站导航记录表") @PutMapping() public ApiResult update(@RequestBody CmsNavigation cmsNavigation) { + // code 规范化:trim + 转小写(唯一性以规范化后的值为准) + if (cmsNavigation.getCode() != null) { + cmsNavigation.setCode(cmsNavigation.getCode().trim().toLowerCase()); + } // 单页模型绑定唯一性校验:同一租户下同一个单页只能绑定一个栏目 checkPageBindingUnique(cmsNavigation); + // 栏目 code 租户内唯一性校验(code 为空/空串时不校验) + checkCodeUnique(cmsNavigation); // 顶级栏目(parentId=0)的显示位置(top/bottom)发生变更时, // 递归同步所有子级(含孙级)的 top/bottom,保持层级一致。 if (cmsNavigation.getParentId() != null && cmsNavigation.getParentId() == 0 @@ -160,6 +172,27 @@ public class CmsNavigationController extends BaseController { } @PreAuthorize("hasAuthority('cms:cmsNavigation:update')") + /** + * 校验栏目 code 租户内唯一:同一租户下 code 不可重复(code 为空/空串时不校验)。 + * 与单页绑定唯一性校验并列,避免触发 uk_navigation_tenant_code 唯一索引导致用户看到"操作失败"。 + */ + private void checkCodeUnique(CmsNavigation cmsNavigation) { + String code = cmsNavigation.getCode(); + if (code == null || code.trim().isEmpty()) { + return; + } + LambdaQueryWrapper wrapper = new LambdaQueryWrapper<>(); + wrapper.eq(CmsNavigation::getTenantId, getTenantId()) + .eq(CmsNavigation::getCode, code.trim()) + .eq(CmsNavigation::getDeleted, 0); + if (cmsNavigation.getNavigationId() != null) { + wrapper.ne(CmsNavigation::getNavigationId, cmsNavigation.getNavigationId()); + } + if (cmsNavigationService.count(wrapper) > 0) { + throw new BusinessException("栏目 code「" + code.trim() + "」已存在,请更换"); + } + } + @Operation(summary = "修改栏目状态") @PutMapping("/status") public ApiResult updateStatus(@RequestBody Map body) {