permission-system
13
总安装量
12
周安装量
#24975
全站排名
安装命令
npx skills add https://github.com/m19803261706/springboot-vben-admin --skill permission-system
Agent 安装分布
trae
10
claude-code
10
opencode
10
windsurf
7
codex
7
Skill 文档
æéç³»ç»å¼åè§è
æ¬é¡¹ç®éç¨ RBAC (åºäºè§è²çè®¿é®æ§å¶) æé模åï¼å å«èåæéãæé®æéåæ°æ®æéä¸ä¸ªç»´åº¦ã
æ ¸å¿åå
éè¦: æ¯æ¬¡å建æ°åè½æ¨¡åæ¶ï¼å¿ é¡» åæ¶å建对åºçèåæéè¿ç§» SQL æä»¶ï¼å¦ååè½å°æ æ³æ£å¸¸ä½¿ç¨ã
ä¸ãæéä½ç³»æ¶æ
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
â æéä½ç³»æ¶æ â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ¤
â â
â ç¨æ· (sys_user) â
â â â
â âââ æ¥æå¤ä¸ª âââ è§è² (sys_role) â
â â â
â âââ æ¥æå¤ä¸ª âââ èåæé (sys_menu) â
â â ââ ç®å½ (type=0) â
â â ââ èå (type=1) â
â â ââ æé® (type=2) â
â â â
â âââ æ°æ®æé (data_scope) â
â ââ å
¨é¨æ°æ® (1) â
â ââ æ¬é¨é¨ (2) â
â ââ æ¬é¨é¨åä¸çº§ (3) â
â ââ ä»
æ¬äºº (4) â
â ââ èªå®ä¹é¨é¨ (5) â
â â
âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
äºãæ°æ®åºè¡¨ç»æ
2.1 èå表 (sys_menu)
| åæ®µ | ç±»å | 说æ |
|---|---|---|
| id | bigint | ä¸»é® |
| parent_id | bigint | ç¶èåID (0=顶级) |
| menu_name | varchar(50) | èååç§° |
| menu_type | tinyint | ç±»å: 0=ç®å½, 1=èå, 2=æé® |
| path | varchar(200) | è·¯ç±è·¯å¾ |
| component | varchar(255) | ç»ä»¶è·¯å¾ |
| permission | varchar(100) | æéæ è¯ |
| icon | varchar(100) | 徿 |
| sort | int | æåº |
| visible | tinyint | æ¯å¦æ¾ç¤º: 0=éè, 1=æ¾ç¤º |
| status | tinyint | ç¶æ: 0=ç¦ç¨, 1=å¯ç¨ |
2.2 è§è²è¡¨ (sys_role)
| åæ®µ | ç±»å | 说æ |
|---|---|---|
| id | bigint | ä¸»é® |
| role_name | varchar(30) | è§è²åç§° |
| role_code | varchar(100) | è§è²ç¼ç |
| data_scope | tinyint | æ°æ®æéèå´ (1-5) |
| sort | int | æåº |
| status | tinyint | ç¶æ |
2.3 å ³è表
sys_user_role: ç¨æ·-è§è²å ³èsys_role_menu: è§è²-èåå ³èsys_role_dept: è§è²-é¨é¨å ³è (èªå®ä¹æ°æ®æé)
ä¸ãæéæ è¯å½åè§è
3.1 æ ¼å¼
{模å}:{å®ä½}:{æä½}
3.2 æ åæä½
| æä½ | æéæ è¯ | 说æ |
|---|---|---|
| å表 | xxx:entity:list |
æ¥çå表 |
| 详æ | xxx:entity:detail |
æ¥ç详æ |
| æ°å¢ | xxx:entity:add |
æ°å¢æ°æ® |
| ç¼è¾ | xxx:entity:edit |
ç¼è¾æ°æ® |
| å é¤ | xxx:entity:delete |
å 餿°æ® |
| å¯¼åº | xxx:entity:export |
å¯¼åºæ°æ® |
| å¯¼å ¥ | xxx:entity:import |
å¯¼å ¥æ°æ® |
3.3 示ä¾
# ç³»ç»ç®¡ç模å
sys:user:list # ç¨æ·å表
sys:user:add # æ°å¢ç¨æ·
sys:role:assign # åé
è§è²æé
# ä¸å¡æ¨¡å示ä¾
emergency:event:list # åºæ¥äºä»¶å表
emergency:event:handle # å¤çäºä»¶
emergency:plan:approve # 审æ¹é¢æ¡
åãæ°æ®æéç±»å
| ç±»å | å¼ | 说æ | å®ç°æ¹å¼ |
|---|---|---|---|
| å ¨é¨æ°æ® | 1 | æ éå¶ | 䏿·»å è¿æ»¤æ¡ä»¶ |
| æ¬é¨é¨ | 2 | åªçæ¬é¨é¨ | WHERE dept_id = ç¨æ·é¨é¨ID |
| æ¬é¨é¨åä¸çº§ | 3 | æ¬é¨é¨æ | WHERE dept_id IN (é¨é¨ååé¨é¨ID) |
| ä» æ¬äºº | 4 | åªçèªå·±å建ç | WHERE create_by = ç¨æ·ID |
| èªå®ä¹ | 5 | æå®é¨é¨ | WHERE dept_id IN (è§è²é
ç½®çé¨é¨) |
äºãCX å½ä»¤éæè§è
5.1 强å¶è¦æ±
彿§è¡ /cx:do æ /cx:plan å建æ°åè½æ¨¡åæ¶ï¼å¿
é¡» åæ¶ï¼
- å建 Flyway è¿ç§» SQL æä»¶
- å å«èåæ°æ®æå ¥è¯å¥
- å å«ç®¡çåè§è²èåæéåé è¯å¥
5.2 è¿ç§»æä»¶å½å
V{çæ¬å·}__{æè¿°}.sql
示ä¾:
V4__add_emergency_module_menu.sql
V5__add_monitor_module_menu.sql
5.3 è¿ç§» SQL 模æ¿
-- V{N}__add_{module}_menu.sql
-- ä½è
: CX
-- æ¥æ: {æ¥æ}
-- æè¿°: æ·»å {模åå}模åèååæé
-- =============================================
-- è·åå½åæå¤§èåID
-- =============================================
SET @max_menu_id = (SELECT COALESCE(MAX(id), 100) FROM sys_menu);
-- =============================================
-- æ·»å {模åå}ç®å½
-- =============================================
INSERT INTO sys_menu (id, parent_id, menu_name, menu_type, path, component, permission, icon, sort, visible, status) VALUES
(@max_menu_id + 1, 0, '{模å䏿å}', 0, '/{module}', NULL, NULL, '{icon}', {sort}, 1, 1);
-- =============================================
-- æ·»å {åè½å}èå
-- =============================================
INSERT INTO sys_menu (id, parent_id, menu_name, menu_type, path, component, permission, icon, sort, visible, status) VALUES
(@max_menu_id + 2, @max_menu_id + 1, '{åè½ä¸æå}', 1, '/{module}/{entity}', '/{module}/{entity}/index', '{module}:{entity}:list', '{icon}', 1, 1, 1),
(@max_menu_id + 3, @max_menu_id + 2, '{åè½}æ°å¢', 2, NULL, NULL, '{module}:{entity}:add', NULL, 1, 1, 1),
(@max_menu_id + 4, @max_menu_id + 2, '{åè½}ç¼è¾', 2, NULL, NULL, '{module}:{entity}:edit', NULL, 2, 1, 1),
(@max_menu_id + 5, @max_menu_id + 2, '{åè½}å é¤', 2, NULL, NULL, '{module}:{entity}:delete', NULL, 3, 1, 1);
-- =============================================
-- 为è¶
级管çååé
æ°èåæé
-- =============================================
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1, id FROM sys_menu WHERE id > @max_menu_id;
å ã宿´ç¤ºä¾ï¼æ·»å åºæ¥äºä»¶æ¨¡å
6.1 è¿ç§»æä»¶: V4__add_emergency_event_menu.sql
-- V4__add_emergency_event_menu.sql
-- ä½è
: CX
-- æ¥æ: 2026-01-13
-- æè¿°: æ·»å åºæ¥äºä»¶ç®¡ç模åèååæé
-- =============================================
-- è·åå½åæå¤§èåID (é¿å
IDå²çª)
-- =============================================
SET @max_menu_id = (SELECT COALESCE(MAX(id), 100) FROM sys_menu);
-- =============================================
-- æ·»å åºæ¥ç®¡çç®å½
-- =============================================
INSERT INTO sys_menu (id, parent_id, menu_name, menu_type, path, component, permission, icon, sort, visible, status) VALUES
(@max_menu_id + 1, 0, 'åºæ¥ç®¡ç', 0, '/emergency', NULL, NULL, 'ant-design:alert-outlined', 10, 1, 1);
-- =============================================
-- æ·»å äºä»¶ç®¡çèååæé®
-- =============================================
INSERT INTO sys_menu (id, parent_id, menu_name, menu_type, path, component, permission, icon, sort, visible, status) VALUES
-- äºä»¶ç®¡çèå
(@max_menu_id + 2, @max_menu_id + 1, 'äºä»¶ç®¡ç', 1, '/emergency/event', '/emergency/event/index', 'emergency:event:list', 'ant-design:file-exclamation-outlined', 1, 1, 1),
-- äºä»¶ç®¡çæé®
(@max_menu_id + 3, @max_menu_id + 2, 'äºä»¶æ°å¢', 2, NULL, NULL, 'emergency:event:add', NULL, 1, 1, 1),
(@max_menu_id + 4, @max_menu_id + 2, 'äºä»¶ç¼è¾', 2, NULL, NULL, 'emergency:event:edit', NULL, 2, 1, 1),
(@max_menu_id + 5, @max_menu_id + 2, 'äºä»¶å é¤', 2, NULL, NULL, 'emergency:event:delete', NULL, 3, 1, 1),
(@max_menu_id + 6, @max_menu_id + 2, 'äºä»¶å¤ç', 2, NULL, NULL, 'emergency:event:handle', NULL, 4, 1, 1),
(@max_menu_id + 7, @max_menu_id + 2, 'äºä»¶å¯¼åº', 2, NULL, NULL, 'emergency:event:export', NULL, 5, 1, 1);
-- =============================================
-- æ·»å 颿¡ç®¡çèååæé®
-- =============================================
INSERT INTO sys_menu (id, parent_id, menu_name, menu_type, path, component, permission, icon, sort, visible, status) VALUES
-- 颿¡ç®¡çèå
(@max_menu_id + 8, @max_menu_id + 1, '颿¡ç®¡ç', 1, '/emergency/plan', '/emergency/plan/index', 'emergency:plan:list', 'ant-design:solution-outlined', 2, 1, 1),
-- 颿¡ç®¡çæé®
(@max_menu_id + 9, @max_menu_id + 8, '颿¡æ°å¢', 2, NULL, NULL, 'emergency:plan:add', NULL, 1, 1, 1),
(@max_menu_id + 10, @max_menu_id + 8, '颿¡ç¼è¾', 2, NULL, NULL, 'emergency:plan:edit', NULL, 2, 1, 1),
(@max_menu_id + 11, @max_menu_id + 8, '颿¡å é¤', 2, NULL, NULL, 'emergency:plan:delete', NULL, 3, 1, 1),
(@max_menu_id + 12, @max_menu_id + 8, '颿¡å®¡æ¹', 2, NULL, NULL, 'emergency:plan:approve', NULL, 4, 1, 1);
-- =============================================
-- 为è¶
级管çåè§è²åé
æ°èåæé
-- =============================================
INSERT INTO sys_role_menu (role_id, menu_id)
SELECT 1, id FROM sys_menu WHERE id > @max_menu_id;
6.2 å端 Controller æé注解
@RestController
@RequestMapping("/api/emergency/event")
@RequiredArgsConstructor
@Tag(name = "åºæ¥äºä»¶ç®¡ç")
public class EmergencyEventController {
private final EmergencyEventService eventService;
@GetMapping
@SaCheckPermission("emergency:event:list")
@Operation(summary = "äºä»¶å表")
public ApiResponse<Page<EventVO>> list(EventQueryDTO query) {
return ApiResponse.success(eventService.findPage(query));
}
@PostMapping
@SaCheckPermission("emergency:event:add")
@Operation(summary = "æ°å¢äºä»¶")
public ApiResponse<EventVO> create(@Valid @RequestBody EventCreateDTO dto) {
return ApiResponse.success(eventService.create(dto));
}
@PutMapping("/{id}")
@SaCheckPermission("emergency:event:edit")
@Operation(summary = "ç¼è¾äºä»¶")
public ApiResponse<EventVO> update(@PathVariable Long id, @Valid @RequestBody EventUpdateDTO dto) {
return ApiResponse.success(eventService.update(id, dto));
}
@DeleteMapping("/{id}")
@SaCheckPermission("emergency:event:delete")
@Operation(summary = "å é¤äºä»¶")
public ApiResponse<Void> delete(@PathVariable Long id) {
eventService.delete(id);
return ApiResponse.success();
}
@PutMapping("/{id}/handle")
@SaCheckPermission("emergency:event:handle")
@Operation(summary = "å¤çäºä»¶")
public ApiResponse<EventVO> handle(@PathVariable Long id, @Valid @RequestBody EventHandleDTO dto) {
return ApiResponse.success(eventService.handle(id, dto));
}
}
6.3 å端路ç±é ç½® (ç±åç«¯å¨æè¿å)
å端æ éæå¨é
置路ç±ï¼èåæ°æ®ç±å端 /api/auth/routes æ¥å£å¨æè¿åã
ä¸ãæ°æ®æé使ç¨
7.1 Service 屿·»å æ°æ®æé注解
@Service
@RequiredArgsConstructor
public class EmergencyEventServiceImpl implements EmergencyEventService {
private final EmergencyEventRepository eventRepository;
private final DataScopeHelper dataScopeHelper;
@Override
@DataScope(deptAlias = "", userAlias = "")
public Page<EventVO> findPage(EventQueryDTO query) {
Specification<EmergencyEvent> spec = (root, criteriaQuery, cb) -> {
List<Predicate> predicates = new ArrayList<>();
// ä¸å¡æ¥è¯¢æ¡ä»¶...
// æ°æ®æéè¿æ»¤ (å¿
须添å )
Predicate dataScopePredicate = dataScopeHelper.buildDataScopePredicate(
root, cb, "deptId", "createBy");
if (dataScopePredicate != null) {
predicates.add(dataScopePredicate);
}
return cb.and(predicates.toArray(new Predicate[0]));
};
return eventRepository.findAll(spec, pageRequest).map(this::convertToVO);
}
}
å «ã常ç¨å¾æ åè
| 徿 | 徿 åç§° | éç¨åºæ¯ |
|---|---|---|
| âï¸ | ant-design:setting-outlined | ç³»ç»è®¾ç½® |
| ð¤ | ant-design:user-outlined | ç¨æ·ç®¡ç |
| ð¥ | ant-design:team-outlined | è§è²/å¢é |
| ð | ant-design:menu-outlined | èå管ç |
| ð¢ | ant-design:apartment-outlined | é¨é¨/ç»ç» |
| â ï¸ | ant-design:alert-outlined | åè¦/åºæ¥ |
| ð | ant-design:file-outlined | æä»¶/ææ¡£ |
| ð | ant-design:bar-chart-outlined | ç»è®¡/æ¥è¡¨ |
| ð | ant-design:bell-outlined | éç¥/æ¶æ¯ |
| ð | ant-design:folder-outlined | ç®å½/åç±» |
| ð | ant-design:safety-outlined | å®å ¨/æé |
| ð | ant-design:form-outlined | 表å |
ä¹ãæ£æ¥æ¸ å
å建æ°åè½æ¨¡åæ¶ï¼è¯·ç¡®è®¤ä»¥ä¸äºé¡¹ï¼
- å建 Flyway è¿ç§» SQL æä»¶ (V{N}_add{module}_menu.sql)
- èå ID 使ç¨
@max_menu_id + Né¿å å²çª - å å«ç®å½ãèåãæé®ä¸çº§ç»æ
- æéæ è¯ç¬¦å
{module}:{entity}:{action}è§è - ä¸ºè¶ çº§ç®¡çåè§è²åé æ°èåæé
- Controller æ¹æ³æ·»å
@SaCheckPermission注解 - éè¦æ°æ®æéçæ¥è¯¢æ·»å
DataScopeHelperè¿æ»¤ - å端页é¢ç»ä»¶è·¯å¾ä¸èå component åæ®µä¸è´
项ç®: åºæ¥ç®¡çç³»ç» å建æ¶é´: 2026-01-13 æ´æ°æ¶é´: 2026-01-13