feat(navigation): 同步更新顶级栏目子级显示位置
- 在更新顶级栏目时,若top或bottom显示位置发生变更,递归同步所有子级(含孙级) - 新增syncChildrenPosition方法,递归收集并批量更新所有后代栏目的top和bottom字段 - 避免触发saveAsync,防止重复生成path和component - 在控制器层调用该同步方法保持栏目层级位置一致性
This commit is contained in:
@@ -121,6 +121,24 @@ public class CmsNavigationController extends BaseController {
|
||||
public ApiResult<?> update(@RequestBody CmsNavigation cmsNavigation) {
|
||||
// 单页模型绑定唯一性校验:同一租户下同一个单页只能绑定一个栏目
|
||||
checkPageBindingUnique(cmsNavigation);
|
||||
// 顶级栏目(parentId=0)的显示位置(top/bottom)发生变更时,
|
||||
// 递归同步所有子级(含孙级)的 top/bottom,保持层级一致。
|
||||
if (cmsNavigation.getParentId() != null && cmsNavigation.getParentId() == 0
|
||||
&& cmsNavigation.getNavigationId() != null
|
||||
&& (cmsNavigation.getTop() != null || cmsNavigation.getBottom() != null)) {
|
||||
CmsNavigation oldNav = cmsNavigationService.getById(cmsNavigation.getNavigationId());
|
||||
if (oldNav != null) {
|
||||
boolean topChanged = cmsNavigation.getTop() != null && !cmsNavigation.getTop().equals(oldNav.getTop());
|
||||
boolean bottomChanged = cmsNavigation.getBottom() != null && !cmsNavigation.getBottom().equals(oldNav.getBottom());
|
||||
if (topChanged || bottomChanged) {
|
||||
cmsNavigationService.syncChildrenPosition(
|
||||
cmsNavigation.getNavigationId(),
|
||||
cmsNavigation.getTop() != null ? cmsNavigation.getTop() : oldNav.getTop(),
|
||||
cmsNavigation.getBottom() != null ? cmsNavigation.getBottom() : oldNav.getBottom(),
|
||||
getTenantId());
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cmsNavigationService.updateById(cmsNavigation)) {
|
||||
// 修改成功事务处理
|
||||
cmsNavigationService.saveAsync(cmsNavigation);
|
||||
|
||||
@@ -42,4 +42,15 @@ public interface CmsNavigationService extends IService<CmsNavigation> {
|
||||
void saveAsync(CmsNavigation cmsNavigation);
|
||||
|
||||
CmsNavigation getByIdRelByCodeRel(String code);
|
||||
|
||||
/**
|
||||
* 递归同步顶级栏目所有子级(含孙级)的显示位置(top/bottom)。
|
||||
* 仅当顶级栏目位置发生变更时调用;只更新 top/bottom 字段,不触发 saveAsync。
|
||||
*
|
||||
* @param navigationId 顶级栏目ID
|
||||
* @param top 顶部显示标记(1/0)
|
||||
* @param bottom 底部显示标记(1/0)
|
||||
* @param tenantId 租户ID
|
||||
*/
|
||||
void syncChildrenPosition(Integer navigationId, Integer top, Integer bottom, Integer tenantId);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.gxwebsoft.cms.service.impl;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.core.util.StrUtil;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import com.gxwebsoft.cms.entity.CmsDesign;
|
||||
import com.gxwebsoft.cms.entity.CmsModel;
|
||||
@@ -23,6 +24,7 @@ import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -178,6 +180,40 @@ public class CmsNavigationServiceImpl extends ServiceImpl<CmsNavigationMapper, C
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* 递归同步顶级栏目所有子级(含孙级)的显示位置(top/bottom)。
|
||||
* 只更新 top/bottom 字段,不触发 saveAsync,避免重复生成 path/component。
|
||||
*/
|
||||
@Override
|
||||
public void syncChildrenPosition(Integer navigationId, Integer top, Integer bottom, Integer tenantId) {
|
||||
List<Integer> descendantIds = new ArrayList<>();
|
||||
collectDescendantIds(navigationId, tenantId, descendantIds);
|
||||
if (descendantIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
LambdaUpdateWrapper<CmsNavigation> updateWrapper = new LambdaUpdateWrapper<>();
|
||||
updateWrapper.in(CmsNavigation::getNavigationId, descendantIds)
|
||||
.set(CmsNavigation::getTop, top)
|
||||
.set(CmsNavigation::getBottom, bottom);
|
||||
update(updateWrapper);
|
||||
}
|
||||
|
||||
/** 递归收集某个栏目下所有后代栏目ID(含直接子级与更深层级) */
|
||||
private void collectDescendantIds(Integer parentId, Integer tenantId, List<Integer> result) {
|
||||
List<CmsNavigation> children = list(new LambdaQueryWrapper<CmsNavigation>()
|
||||
.eq(CmsNavigation::getParentId, parentId)
|
||||
.eq(CmsNavigation::getTenantId, tenantId)
|
||||
.eq(CmsNavigation::getDeleted, 0)
|
||||
.select(CmsNavigation::getNavigationId));
|
||||
if (children.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
for (CmsNavigation child : children) {
|
||||
result.add(child.getNavigationId());
|
||||
collectDescendantIds(child.getNavigationId(), tenantId, result);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CmsNavigation getByIdRelByCodeRel(String code) {
|
||||
CmsNavigationParam param = new CmsNavigationParam();
|
||||
|
||||
Reference in New Issue
Block a user