黑名单设计
如果用户在我们的网站里说了 一些不健康的内容,那么我们应该可以对其 进行拉黑或者封IP的操作。
数据库设计
CREATE TABLE `black` (
`id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'id',
`type` int(11) NOT NULL COMMENT '拉黑目标类型 1.ip 2uid',
`target` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '拉黑目标',
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
UNIQUE INDEX `idx_type_target`(`type`, `target`) USING BTREE
) COMMENT = '黑名单' ROW_FORMAT = Dynamic;
CREATE TABLE `role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`name` varchar(64) COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '角色名称',
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_create_time` (`create_time`) USING BTREE,
KEY `idx_update_time` (`update_time`) USING BTREE
) COMMENT='角色表';
CREATE TABLE `user_role` (
`id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT 'id',
`uid` bigint(20) NOT NULL COMMENT 'uid',
`role_id` bigint(20) NOT NULL COMMENT '角色id',
`create_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间',
`update_time` datetime(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '修改时间',
PRIMARY KEY (`id`) USING BTREE,
KEY `idx_uid` (`uid`) USING BTREE,
KEY `idx_role_id` (`role_id`) USING BTREE,
KEY `idx_create_time` (`create_time`) USING BTREE,
KEY `idx_update_time` (`update_time`) USING BTREE
) COMMENT='用户角色关系表';
insert into role(id,`name`) values(1,'超级管理员');
insert into role(id,`name`) values(2,'群聊管理员');
图如下:
一个用户可以有多个角色,一个角色也可以被多个用户拥有
user_role就相当于中间表
拉黑设计
拉黑主要体现在业务逻辑方面,没有什么特别难得地方,就是常规的增删改查
拉黑接口
UserController.java:
@PostMapping("/black")
@ApiOperation("拉黑用户")
public ApiResult<Void> black(@Valid @RequestBody BlackReq req) {
Long uid = RequestHolder.get().getUid();
boolean hasPower = userRoleService.hasPower(uid, RoleEnum.ADMIN);
AssertUtil.isTrue(hasPower, "您没有权限拉黑用户");
userService.black(req);
return ApiResult.success();
}
权限缓存
UserCache.java
@Component
public class UserCache {// todo 多级缓存
@Autowired
@Lazy
private UserRoleService userRoleService;
@Cacheable(cacheNames = "user", key = "'roles:'+#uid")
public Set<Long> getRoleSet(Long uid) {
List<UserRole> userRoles = userRoleService.listByUid(uid);
return userRoles.stream().map(UserRole::getRoleId).collect(Collectors.toSet());
}
}
权限(角色)判断
@Override
public boolean hasPower(Long uid, RoleEnum roleEnum) {
Set<Long> roleSet = userCache.getRoleSet(uid);
return (isAdmin(roleSet)) || roleSet.contains(roleEnum.getId());
}
private boolean isAdmin(Set<Long> roleSet) {
return roleSet.contains(RoleEnum.ADMIN.getId());
}
角色枚举RoleEnum.java:
@AllArgsConstructor
@Getter
public enum RoleEnum {
ADMIN(1L, "超级管理员"),
CHAT_MANAGER(2L, "云群聊管理"),
;
private final Long id;
private final String desc;
private static Map<Long, RoleEnum> cache;
static {
cache = Arrays.stream(RoleEnum.values()).collect(Collectors.toMap(RoleEnum::getId, Function.identity()));
}
public static RoleEnum of(Long type) {
return cache.get(type);
}
}