完成匹配、跟价、权限部分
This commit is contained in:
@@ -17,4 +17,6 @@ public class PermissionMenuCreateRequest {
|
||||
|
||||
@NotBlank(message = "菜单路由不能为空")
|
||||
private String routePath;
|
||||
|
||||
private Integer sortOrder;
|
||||
}
|
||||
|
||||
@@ -17,4 +17,6 @@ public class PermissionMenuUpdateRequest {
|
||||
|
||||
@NotBlank(message = "菜单路由不能为空")
|
||||
private String routePath;
|
||||
|
||||
private Integer sortOrder;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.nanri.aiimage.modules.permission.model.entity;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.annotation.TableField;
|
||||
import com.baomidou.mybatisplus.annotation.TableId;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import lombok.Data;
|
||||
@@ -11,5 +12,8 @@ public class AdminUserEntity {
|
||||
|
||||
@TableId(type = IdType.AUTO)
|
||||
private Long id;
|
||||
private String username;
|
||||
private String role;
|
||||
@TableField("created_by_id")
|
||||
private Long createdById;
|
||||
}
|
||||
|
||||
@@ -17,5 +17,6 @@ public class PermissionMenuEntity {
|
||||
private String columnKey;
|
||||
private String menuType;
|
||||
private String routePath;
|
||||
private Integer sortOrder;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
|
||||
@@ -12,5 +12,6 @@ public class PermissionMenuItemVo {
|
||||
private String columnKey;
|
||||
private String menuType;
|
||||
private String routePath;
|
||||
private Integer sortOrder;
|
||||
private LocalDateTime createdAt;
|
||||
}
|
||||
|
||||
@@ -14,10 +14,16 @@ import java.util.List;
|
||||
public class PermissionMenuSchemaInitializer {
|
||||
|
||||
private final JdbcTemplate jdbcTemplate;
|
||||
|
||||
private static final List<DefaultAdminMenu> DEFAULT_ADMIN_MENUS = List.of(
|
||||
new DefaultAdminMenu("数据去重总数据", "admin_dedupe_total_data", "dedupe-total-data"),
|
||||
new DefaultAdminMenu("店铺管理", "admin_shop_manage", "shop-manage"),
|
||||
new DefaultAdminMenu("跳过跟价ASIN", "admin_skip_price_asin", "skip-price-asin")
|
||||
new DefaultAdminMenu("用户管理", "admin_users", "users", 10),
|
||||
new DefaultAdminMenu("栏目权限配置", "admin_columns", "columns", 20),
|
||||
new DefaultAdminMenu("数据去重总数据", "admin_dedupe_total_data", "dedupe-total-data", 30),
|
||||
new DefaultAdminMenu("店铺密钥管理", "admin_shop_keys", "shop-keys", 40),
|
||||
new DefaultAdminMenu("店铺管理", "admin_shop_manage", "shop-manage", 50),
|
||||
new DefaultAdminMenu("跳过跟价ASIN", "admin_skip_price_asin", "skip-price-asin", 60),
|
||||
new DefaultAdminMenu("查看生成记录", "admin_history", "history", 70),
|
||||
new DefaultAdminMenu("版本管理", "admin_version", "version", 80)
|
||||
);
|
||||
|
||||
@PostConstruct
|
||||
@@ -25,23 +31,19 @@ public class PermissionMenuSchemaInitializer {
|
||||
executeQuietly("""
|
||||
CREATE TABLE IF NOT EXISTS columns (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
||||
name VARCHAR(128) NOT NULL COMMENT '栏目名',
|
||||
column_key VARCHAR(64) NOT NULL COMMENT '栏目标识',
|
||||
name VARCHAR(128) NOT NULL COMMENT '菜单标题',
|
||||
column_key VARCHAR(64) NOT NULL COMMENT '菜单唯一标识',
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
|
||||
UNIQUE KEY uk_column_key (column_key)
|
||||
)
|
||||
""");
|
||||
executeQuietly("ALTER TABLE columns ADD COLUMN menu_type VARCHAR(20) NOT NULL DEFAULT 'app' COMMENT '菜单类型: app/admin' AFTER column_key");
|
||||
executeQuietly("ALTER TABLE columns ADD COLUMN route_path VARCHAR(255) NOT NULL DEFAULT '' COMMENT '菜单路由或页面标识' AFTER menu_type");
|
||||
executeQuietly("ALTER TABLE columns ADD COLUMN sort_order INT NOT NULL DEFAULT 0 COMMENT '菜单排序' AFTER route_path");
|
||||
executeQuietly("UPDATE columns SET menu_type = 'app' WHERE menu_type IS NULL OR menu_type = ''");
|
||||
executeQuietly("UPDATE columns SET sort_order = id WHERE sort_order IS NULL OR sort_order = 0");
|
||||
executeQuietly("ALTER TABLE columns ADD UNIQUE KEY uk_menu_type_route_path (menu_type, route_path)");
|
||||
ensureDefaultAdminMenus();
|
||||
executeQuietly("""
|
||||
INSERT INTO columns (name, column_key, menu_type, route_path)
|
||||
SELECT '店铺管理', 'admin_shop_manage', 'admin', 'shop-manage'
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM columns WHERE column_key = 'admin_shop_manage'
|
||||
)
|
||||
""");
|
||||
executeQuietly("""
|
||||
CREATE TABLE IF NOT EXISTS user_column_permission (
|
||||
user_id INT NOT NULL,
|
||||
@@ -56,12 +58,17 @@ public class PermissionMenuSchemaInitializer {
|
||||
private void ensureDefaultAdminMenus() {
|
||||
for (DefaultAdminMenu menu : DEFAULT_ADMIN_MENUS) {
|
||||
executeQuietly("""
|
||||
INSERT INTO columns (name, column_key, menu_type, route_path)
|
||||
SELECT '%s', '%s', 'admin', '%s'
|
||||
INSERT INTO columns (name, column_key, menu_type, route_path, sort_order)
|
||||
SELECT '%s', '%s', 'admin', '%s', %d
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1 FROM columns WHERE column_key = '%s'
|
||||
)
|
||||
""".formatted(menu.name(), menu.columnKey(), menu.routePath(), menu.columnKey()));
|
||||
""".formatted(menu.name(), menu.columnKey(), menu.routePath(), menu.sortOrder(), menu.columnKey()));
|
||||
executeQuietly("""
|
||||
UPDATE columns
|
||||
SET sort_order = %d
|
||||
WHERE column_key = '%s' AND (sort_order IS NULL OR sort_order = 0)
|
||||
""".formatted(menu.sortOrder(), menu.columnKey()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +80,6 @@ public class PermissionMenuSchemaInitializer {
|
||||
}
|
||||
}
|
||||
|
||||
private record DefaultAdminMenu(String name, String columnKey, String routePath) {
|
||||
private record DefaultAdminMenu(String name, String columnKey, String routePath, int sortOrder) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
@@ -41,6 +42,7 @@ public class PermissionMenuService {
|
||||
public List<PermissionMenuItemVo> list(String menuType) {
|
||||
LambdaQueryWrapper<PermissionMenuEntity> query = new LambdaQueryWrapper<PermissionMenuEntity>()
|
||||
.eq(isValidMenuType(menuType), PermissionMenuEntity::getMenuType, normalizeMenuType(menuType))
|
||||
.orderByAsc(PermissionMenuEntity::getSortOrder)
|
||||
.orderByAsc(PermissionMenuEntity::getId);
|
||||
return permissionMenuMapper.selectList(query).stream()
|
||||
.map(this::toItemVo)
|
||||
@@ -54,12 +56,14 @@ public class PermissionMenuService {
|
||||
String menuType = normalizeMenuTypeRequired(request.getMenuType());
|
||||
String routePath = normalizeRequired(request.getRoutePath(), "菜单路由不能为空");
|
||||
ensureUniqueColumnKey(columnKey, null);
|
||||
ensureUniqueRoutePath(menuType, routePath, null);
|
||||
|
||||
PermissionMenuEntity entity = new PermissionMenuEntity();
|
||||
entity.setName(name);
|
||||
entity.setColumnKey(columnKey);
|
||||
entity.setMenuType(menuType);
|
||||
entity.setRoutePath(routePath);
|
||||
entity.setSortOrder(resolveSortOrder(request.getSortOrder(), null));
|
||||
permissionMenuMapper.insert(entity);
|
||||
return toItemVo(getMenuById(entity.getId()));
|
||||
}
|
||||
@@ -72,11 +76,13 @@ public class PermissionMenuService {
|
||||
String menuType = normalizeMenuTypeRequired(request.getMenuType());
|
||||
String routePath = normalizeRequired(request.getRoutePath(), "菜单路由不能为空");
|
||||
ensureUniqueColumnKey(columnKey, id);
|
||||
ensureUniqueRoutePath(menuType, routePath, id);
|
||||
|
||||
entity.setName(name);
|
||||
entity.setColumnKey(columnKey);
|
||||
entity.setMenuType(menuType);
|
||||
entity.setRoutePath(routePath);
|
||||
entity.setSortOrder(resolveSortOrder(request.getSortOrder(), id));
|
||||
permissionMenuMapper.updateById(entity);
|
||||
return toItemVo(getMenuById(id));
|
||||
}
|
||||
@@ -141,6 +147,9 @@ public class PermissionMenuService {
|
||||
.map(menuMap::get)
|
||||
.filter(menu -> menu != null)
|
||||
.filter(menu -> safeMenuType == null || safeMenuType.equals(menu.getMenuType()))
|
||||
.sorted(Comparator
|
||||
.comparing(PermissionMenuEntity::getSortOrder, Comparator.nullsLast(Integer::compareTo))
|
||||
.thenComparing(PermissionMenuEntity::getId, Comparator.nullsLast(Long::compareTo)))
|
||||
.map(this::toItemVo)
|
||||
.toList();
|
||||
}
|
||||
@@ -196,6 +205,16 @@ public class PermissionMenuService {
|
||||
}
|
||||
}
|
||||
|
||||
private void ensureUniqueRoutePath(String menuType, String routePath, Long excludeId) {
|
||||
PermissionMenuEntity exists = permissionMenuMapper.selectOne(new LambdaQueryWrapper<PermissionMenuEntity>()
|
||||
.eq(PermissionMenuEntity::getMenuType, menuType)
|
||||
.eq(PermissionMenuEntity::getRoutePath, routePath)
|
||||
.last("LIMIT 1"));
|
||||
if (exists != null && (excludeId == null || !excludeId.equals(exists.getId()))) {
|
||||
throw new BusinessException("同一菜单类型下的菜单路由已存在");
|
||||
}
|
||||
}
|
||||
|
||||
private String normalizeRequired(String value, String message) {
|
||||
String normalized = value == null ? "" : value.trim();
|
||||
if (normalized.isEmpty() && !message.isEmpty()) {
|
||||
@@ -247,7 +266,21 @@ public class PermissionMenuService {
|
||||
vo.setColumnKey(entity.getColumnKey());
|
||||
vo.setMenuType(entity.getMenuType());
|
||||
vo.setRoutePath(entity.getRoutePath());
|
||||
vo.setSortOrder(entity.getSortOrder());
|
||||
vo.setCreatedAt(entity.getCreatedAt());
|
||||
return vo;
|
||||
}
|
||||
|
||||
private Integer resolveSortOrder(Integer sortOrder, Long excludeId) {
|
||||
if (sortOrder != null) {
|
||||
return sortOrder;
|
||||
}
|
||||
PermissionMenuEntity tail = permissionMenuMapper.selectOne(new LambdaQueryWrapper<PermissionMenuEntity>()
|
||||
.ne(excludeId != null, PermissionMenuEntity::getId, excludeId)
|
||||
.orderByDesc(PermissionMenuEntity::getSortOrder)
|
||||
.orderByDesc(PermissionMenuEntity::getId)
|
||||
.last("LIMIT 1"));
|
||||
int currentMax = tail == null || tail.getSortOrder() == null ? 0 : tail.getSortOrder();
|
||||
return currentMax + 1;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user