task-275(验收反馈): 菜单权限标识/路由后台自动生成(menu_auto_/auto/ 前缀),表单移除两项输入;编辑缺省保持原值
This commit is contained in:
+2
-2
@@ -10,7 +10,7 @@ public class PermissionMenuCreateRequest {
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "菜单标识不能为空")
|
||||
/** 菜单标识;不传由后台自动生成(menu_auto_<类型>_<时间戳>)。 */
|
||||
@JsonAlias("column_key")
|
||||
private String columnKey;
|
||||
|
||||
@@ -22,7 +22,7 @@ public class PermissionMenuCreateRequest {
|
||||
@JsonAlias("menu_type")
|
||||
private String menuType;
|
||||
|
||||
@NotBlank(message = "菜单路由不能为空")
|
||||
/** 页面路由;不传由后台自动生成(auto/<菜单标识>)。 */
|
||||
@JsonAlias("route_path")
|
||||
private String routePath;
|
||||
|
||||
|
||||
+2
-2
@@ -10,7 +10,7 @@ public class PermissionMenuUpdateRequest {
|
||||
@NotBlank(message = "菜单名称不能为空")
|
||||
private String name;
|
||||
|
||||
@NotBlank(message = "菜单标识不能为空")
|
||||
/** 菜单标识;不传保持原值(表单不采集)。 */
|
||||
@JsonAlias("column_key")
|
||||
private String columnKey;
|
||||
|
||||
@@ -22,7 +22,7 @@ public class PermissionMenuUpdateRequest {
|
||||
@JsonAlias("menu_type")
|
||||
private String menuType;
|
||||
|
||||
@NotBlank(message = "菜单路由不能为空")
|
||||
/** 页面路由;不传保持原值(表单不采集)。 */
|
||||
@JsonAlias("route_path")
|
||||
private String routePath;
|
||||
|
||||
|
||||
+38
-4
@@ -74,9 +74,16 @@ public class PermissionMenuService {
|
||||
throw new BusinessException("菜单参数不能为空");
|
||||
}
|
||||
String name = normalizeRequired(request.getName(), "菜单名称不能为空");
|
||||
String columnKey = normalizeRequired(request.getColumnKey(), "菜单标识不能为空");
|
||||
String menuType = normalizeMenuTypeRequired(request.getMenuType());
|
||||
String routePath = normalizeRequired(request.getRoutePath(), "页面路径不能为空");
|
||||
// 权限标识/路由由后台自动生成:表单不采集,缺省时生成稳定唯一值。
|
||||
String columnKey = normalizeOptional(request.getColumnKey());
|
||||
if (columnKey == null) {
|
||||
columnKey = generateColumnKey(menuType);
|
||||
}
|
||||
String routePath = normalizeOptional(request.getRoutePath());
|
||||
if (routePath == null) {
|
||||
routePath = generateRoutePath(columnKey);
|
||||
}
|
||||
Long parentId = normalizeParentId(request.getParentId());
|
||||
ensureParentValid(parentId, null, menuType);
|
||||
ensureUniqueColumnKey(columnKey, null);
|
||||
@@ -107,9 +114,16 @@ public class PermissionMenuService {
|
||||
throw new BusinessException("菜单参数不能为空");
|
||||
}
|
||||
String name = normalizeRequired(request.getName(), "菜单名称不能为空");
|
||||
String columnKey = normalizeRequired(request.getColumnKey(), "菜单标识不能为空");
|
||||
String menuType = normalizeMenuTypeRequired(request.getMenuType());
|
||||
String routePath = normalizeRequired(request.getRoutePath(), "页面路径不能为空");
|
||||
// 编辑时未传权限标识/路由则保持原值(表单不采集,避免覆盖为自动值)。
|
||||
String columnKey = normalizeOptional(request.getColumnKey());
|
||||
if (columnKey == null) {
|
||||
columnKey = entity.getColumnKey();
|
||||
}
|
||||
String routePath = normalizeOptional(request.getRoutePath());
|
||||
if (routePath == null) {
|
||||
routePath = entity.getRoutePath();
|
||||
}
|
||||
Long parentId = normalizeParentId(request.getParentId());
|
||||
ensureParentValid(parentId, id, menuType);
|
||||
ensureMenuTypeChangeAllowed(entity, menuType);
|
||||
@@ -824,6 +838,26 @@ public class PermissionMenuService {
|
||||
return normalized;
|
||||
}
|
||||
|
||||
/** trim 后为空的返回 null(用于“后台自动生成/保持原值”的可选字段)。 */
|
||||
private String normalizeOptional(String value) {
|
||||
String normalized = value == null ? "" : value.trim();
|
||||
return normalized.isEmpty() ? null : normalized;
|
||||
}
|
||||
|
||||
/** 未传菜单标识时后台自动生成(menu_auto_<类型>_<毫秒时间戳>,唯一性由 ensureUniqueColumnKey 兜底)。 */
|
||||
private String generateColumnKey(String menuType) {
|
||||
String generated = "menu_auto_" + menuType + "_" + System.currentTimeMillis();
|
||||
log.info("[menu-auto-key] 未传菜单标识,后台自动生成 columnKey={}", generated);
|
||||
return generated;
|
||||
}
|
||||
|
||||
/** 未传页面路径时后台自动生成(auto/<菜单标识>,不与真实页面路由冲突)。 */
|
||||
private String generateRoutePath(String columnKey) {
|
||||
String generated = "auto/" + columnKey;
|
||||
log.info("[menu-auto-key] 未传页面路径,后台自动生成 routePath={}", generated);
|
||||
return generated;
|
||||
}
|
||||
|
||||
private Long normalizeParentId(Long value) {
|
||||
return value == null || value <= 0 ? null : value;
|
||||
}
|
||||
|
||||
+52
@@ -672,6 +672,58 @@ class PermissionMenuServiceTest {
|
||||
assertThat(inserted.getValue().getMenuType()).isEqualTo("admin");
|
||||
}
|
||||
|
||||
@Test
|
||||
void createWithoutColumnKeyAndRoutePathAutoGenerates() {
|
||||
PermissionMenuMapper menuMapper = mock(PermissionMenuMapper.class);
|
||||
UserColumnPermissionMapper permissionMapper = mock(UserColumnPermissionMapper.class);
|
||||
AdminUserMapper userMapper = mock(AdminUserMapper.class);
|
||||
PermissionMenuService service = new PermissionMenuService(menuMapper, permissionMapper, userMapper);
|
||||
|
||||
PermissionMenuEntity adminTail = menu(9L, null, "admin", 134);
|
||||
adminTail.setName("admin tail");
|
||||
when(menuMapper.selectOne(any())).thenReturn(null, null, adminTail);
|
||||
when(menuMapper.selectById(any())).thenReturn(adminTail);
|
||||
|
||||
PermissionMenuCreateRequest request = new PermissionMenuCreateRequest();
|
||||
request.setName("新菜单");
|
||||
request.setMenuType("admin");
|
||||
// 不传 columnKey / routePath:由后台自动生成。
|
||||
|
||||
service.create(request);
|
||||
|
||||
ArgumentCaptor<PermissionMenuEntity> inserted = ArgumentCaptor.forClass(PermissionMenuEntity.class);
|
||||
verify(menuMapper).insert(inserted.capture());
|
||||
assertThat(inserted.getValue().getColumnKey()).startsWith("menu_auto_admin_");
|
||||
assertThat(inserted.getValue().getRoutePath()).startsWith("auto/").contains(inserted.getValue().getColumnKey());
|
||||
}
|
||||
|
||||
@Test
|
||||
void updateWithoutColumnKeyAndRoutePathKeepsOriginal() {
|
||||
PermissionMenuMapper menuMapper = mock(PermissionMenuMapper.class);
|
||||
UserColumnPermissionMapper permissionMapper = mock(UserColumnPermissionMapper.class);
|
||||
AdminUserMapper userMapper = mock(AdminUserMapper.class);
|
||||
PermissionMenuService service = new PermissionMenuService(menuMapper, permissionMapper, userMapper);
|
||||
|
||||
PermissionMenuEntity current = menu(1L, null, "admin", 1);
|
||||
current.setName("原名");
|
||||
when(menuMapper.selectById(1L)).thenReturn(current);
|
||||
when(menuMapper.selectOne(any())).thenReturn(null, null, current);
|
||||
when(menuMapper.selectById(any())).thenReturn(current);
|
||||
|
||||
PermissionMenuUpdateRequest request = new PermissionMenuUpdateRequest();
|
||||
request.setName("改名");
|
||||
request.setMenuType("admin");
|
||||
// 不传 columnKey / routePath:保持原值。
|
||||
|
||||
service.update(1L, request);
|
||||
|
||||
ArgumentCaptor<PermissionMenuEntity> updated = ArgumentCaptor.forClass(PermissionMenuEntity.class);
|
||||
verify(menuMapper).updateById(updated.capture());
|
||||
assertThat(updated.getValue().getColumnKey()).isEqualTo("menu-1");
|
||||
assertThat(updated.getValue().getRoutePath()).isEqualTo("route-1");
|
||||
assertThat(updated.getValue().getName()).isEqualTo("改名");
|
||||
}
|
||||
|
||||
private PermissionMenuCreateRequest createRequest(Long parentId, String menuType) {
|
||||
PermissionMenuCreateRequest request = new PermissionMenuCreateRequest();
|
||||
request.setName("child");
|
||||
|
||||
Reference in New Issue
Block a user