Skip to content

Commit a97cd31

Browse files
committed
Add data permission rule
1 parent 9b7584d commit a97cd31

File tree

17 files changed

+142
-151
lines changed

17 files changed

+142
-151
lines changed

backend/app/admin/api/v1/sys/data_rule.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ async def get_data_rule(pk: Annotated[int, Path(...)]) -> ResponseModel:
3030
DependsPagination,
3131
],
3232
)
33-
async def get_pagination_data_rule(db: CurrentSession) -> ResponseModel:
34-
data_rule_select = await data_rule_service.get_select()
33+
async def get_pagination_data_rule(db: CurrentSession, name: Annotated[str | None, Query()]) -> ResponseModel:
34+
data_rule_select = await data_rule_service.get_select(name=name)
3535
page_data = await paging_data(db, data_rule_select, GetDataRuleListDetails)
3636
return response_base.success(data=page_data)
3737

backend/app/admin/api/v1/sys/role.py

Lines changed: 0 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
from backend.app.admin.schema.role import (
88
CreateRoleParam,
99
GetRoleListDetails,
10-
UpdateRoleDataScopeParam,
11-
UpdateRoleDeptParam,
1210
UpdateRoleMenuParam,
1311
UpdateRoleParam,
1412
)
@@ -116,38 +114,6 @@ async def update_role_menus(
116114
return response_base.fail()
117115

118116

119-
@router.put(
120-
'/{pk}/data-scope',
121-
summary='更新角色数据范围',
122-
dependencies=[
123-
Depends(RequestPermission('sys:role:data_scope:edit')),
124-
DependsRBAC,
125-
],
126-
)
127-
async def update_role_data_scope(request: Request, pk: Annotated[int, Path(...)], data_scope: UpdateRoleDataScopeParam):
128-
count = await role_service.update_role_data_scope(request=request, pk=pk, data_scope=data_scope)
129-
if count > 0:
130-
return response_base.success()
131-
return response_base.fail()
132-
133-
134-
@router.put(
135-
'/{pk}/dept',
136-
summary='更新角色部门',
137-
dependencies=[
138-
Depends(RequestPermission('sys:role:dept:edit')),
139-
DependsRBAC,
140-
],
141-
)
142-
async def update_role_depts(
143-
request: Request, pk: Annotated[int, Path(...)], dept_ids: UpdateRoleDeptParam
144-
) -> ResponseModel:
145-
count = await role_service.update_role_dept(request=request, pk=pk, dept_ids=dept_ids)
146-
if count > 0:
147-
return response_base.success()
148-
return response_base.fail()
149-
150-
151117
@router.delete(
152118
'',
153119
summary='(批量)删除角色',

backend/app/admin/crud/crud_data_rule.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# -*- coding: utf-8 -*-
33
from typing import Sequence
44

5-
from sqlalchemy import Select
5+
from sqlalchemy import Select, desc, select
66
from sqlalchemy.ext.asyncio import AsyncSession
77
from sqlalchemy_crud_plus import CRUDPlus
88

@@ -13,25 +13,41 @@
1313
class CRUDDataRule(CRUDPlus[DataRule]):
1414
async def get(self, db: AsyncSession, pk: int) -> DataRule | None:
1515
"""
16-
获取 DataRule
16+
获取数据权限规则
1717
1818
:param db:
1919
:param pk:
2020
:return:
2121
"""
2222
return await self.select_model(db, pk)
2323

24-
async def get_list(self) -> Select:
24+
async def get_list(self, name: str = None) -> Select:
2525
"""
26-
获取 DataRule 列表
26+
获取数据权限规则列表
2727
2828
:return:
2929
"""
30-
return await self.select_order('created_time', 'desc')
30+
stmt = select(self.model).order_by(desc(self.model.created_time))
31+
where_list = []
32+
if name is not None:
33+
where_list.append(self.model.name.like(f'%{name}%'))
34+
if where_list:
35+
stmt = stmt.where(*where_list)
36+
return stmt
37+
38+
async def get_by_name(self, db: AsyncSession, name: str):
39+
"""
40+
通过 name 获取数据权限规则
41+
42+
:param db:
43+
:param name:
44+
:return:
45+
"""
46+
return await self.select_model_by_column(db, name=name)
3147

3248
async def get_all(self, db: AsyncSession) -> Sequence[DataRule]:
3349
"""
34-
获取所有 DataRule
50+
获取所有数据权限规则
3551
3652
:param db:
3753
:return:
@@ -40,7 +56,7 @@ async def get_all(self, db: AsyncSession) -> Sequence[DataRule]:
4056

4157
async def create(self, db: AsyncSession, obj_in: CreateDataRuleParam) -> None:
4258
"""
43-
创建 DataRule
59+
创建数据权限规则
4460
4561
:param db:
4662
:param obj_in:
@@ -50,7 +66,7 @@ async def create(self, db: AsyncSession, obj_in: CreateDataRuleParam) -> None:
5066

5167
async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleParam) -> int:
5268
"""
53-
更新 DataRule
69+
更新数据权限规则
5470
5571
:param db:
5672
:param pk:
@@ -61,7 +77,7 @@ async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleParam) -
6177

6278
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
6379
"""
64-
删除 DataRule
80+
删除数据权限规则
6581
6682
:param db:
6783
:param pk:

backend/app/admin/crud/crud_data_rule_type.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
class CRUDDataRuleType(CRUDPlus[DataRuleType]):
1414
async def get(self, db: AsyncSession, pk: int) -> DataRuleType | None:
1515
"""
16-
获取 DataRuleType
16+
获取数据权限规则类型
1717
1818
:param db:
1919
:param pk:
@@ -23,15 +23,25 @@ async def get(self, db: AsyncSession, pk: int) -> DataRuleType | None:
2323

2424
async def get_list(self) -> Select:
2525
"""
26-
获取 DataRuleType 列表
26+
获取数据权限规则类型列表
2727
2828
:return:
2929
"""
3030
return await self.select_order('created_time', 'desc')
3131

32+
async def get_by_name(self, db: AsyncSession, name: str) -> DataRuleType | None:
33+
"""
34+
通过 name 获取数据权限规则类型
35+
36+
:param db:
37+
:param name:
38+
:return:
39+
"""
40+
return await self.select_model_by_column(db, name=name)
41+
3242
async def get_all(self, db: AsyncSession) -> Sequence[DataRuleType]:
3343
"""
34-
获取所有 DataRuleType
44+
获取所有数据权限规则类型
3545
3646
:param db:
3747
:return:
@@ -40,7 +50,7 @@ async def get_all(self, db: AsyncSession) -> Sequence[DataRuleType]:
4050

4151
async def create(self, db: AsyncSession, obj_in: CreateDataRuleTypeParam) -> None:
4252
"""
43-
创建 DataRuleType
53+
创建数据权限规则类型
4454
4555
:param db:
4656
:param obj_in:
@@ -50,7 +60,7 @@ async def create(self, db: AsyncSession, obj_in: CreateDataRuleTypeParam) -> Non
5060

5161
async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleTypeParam) -> int:
5262
"""
53-
更新 DataRuleType
63+
更新数据权限规则类型
5464
5565
:param db:
5666
:param pk:
@@ -61,7 +71,7 @@ async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleTypePara
6171

6272
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
6373
"""
64-
删除 DataRuleType
74+
删除数据权限规则类型
6575
6676
:param db:
6777
:param pk:

backend/app/admin/crud/crud_role.py

Lines changed: 1 addition & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,12 @@
33
from typing import Sequence
44

55
from sqlalchemy import Select, desc, select
6-
from sqlalchemy.ext.asyncio import AsyncSession
76
from sqlalchemy.orm import selectinload
87
from sqlalchemy_crud_plus import CRUDPlus
98

10-
from backend.app.admin.model import Dept, Menu, Role, User
9+
from backend.app.admin.model import Menu, Role, User
1110
from backend.app.admin.schema.role import (
1211
CreateRoleParam,
13-
UpdateRoleDataScopeParam,
14-
UpdateRoleDeptParam,
1512
UpdateRoleMenuParam,
1613
UpdateRoleParam,
1714
)
@@ -129,32 +126,6 @@ async def update_menus(self, db, role_id: int, menu_ids: UpdateRoleMenuParam) ->
129126
current_role.menus = menus.scalars().all()
130127
return len(current_role.menus)
131128

132-
async def update_data_scope(self, db: AsyncSession, role_id: int, data_scope: UpdateRoleDataScopeParam):
133-
"""
134-
更新用户数据范围
135-
136-
:param db:
137-
:param role_id:
138-
:param data_scope:
139-
:return:
140-
"""
141-
return await self.update_model(db, role_id, data_scope)
142-
143-
async def update_depts(self, db, role_id: int, dept_ids: UpdateRoleDeptParam) -> int:
144-
"""
145-
更新角色部门
146-
147-
:param db:
148-
:param role_id:
149-
:param dept_ids:
150-
:return:
151-
"""
152-
stmt = select(Dept).where(Dept.id.in_(dept_ids.depts))
153-
depts = await db.execute(stmt)
154-
current_role = await self.get_with_relation(db, role_id)
155-
current_role.depts = depts.scalars().all()
156-
return len(current_role.depts)
157-
158129
async def delete(self, db, role_id: list[int]) -> int:
159130
"""
160131
删除角色
Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,31 @@
11
#!/usr/bin/env python3
22
# -*- coding: utf-8 -*-
3-
from sqlalchemy import String
4-
from sqlalchemy.orm import Mapped, mapped_column
3+
from sqlalchemy import ForeignKey, String
4+
from sqlalchemy.orm import Mapped, mapped_column, relationship
55

6+
from backend.app.admin.model.m2m import sys_role_data_rule
67
from backend.common.model import Base, id_key
78

89

910
class DataRule(Base):
1011
"""数据权限规则表"""
1112

12-
__tablename__ = 'data_rule'
13+
__tablename__ = 'sys_data_rule'
1314

1415
id: Mapped[id_key] = mapped_column(init=False)
15-
name: Mapped[str] = mapped_column(String(255), comment='规则名称')
16+
name: Mapped[str] = mapped_column(String(255), unique=True, comment='规则名称')
1617
model: Mapped[str] = mapped_column(String(50), comment='SQLA 模型类')
1718
column: Mapped[str] = mapped_column(String(20), comment='数据库字段')
18-
condition: Mapped[str] = mapped_column(String(20), comment='查询条件')
19+
operator: Mapped[int] = mapped_column(comment='运算符(0:and、1:or)')
20+
expression: Mapped[int] = mapped_column(
21+
comment='表达式(0:>、1:>=、2:<、3:<=、4:==、5:!=、6:in、7:not_in)'
22+
)
23+
24+
# 数据权限规则类型一对多
25+
type_id: Mapped[int] = mapped_column(
26+
ForeignKey('sys_data_rule_type.id', ondelete='CASCADE'), comment='数据权限规则类型关联ID'
27+
)
28+
type: Mapped['DataRuleType'] = relationship(init=False, back_populates='rules') # noqa: F821
29+
30+
# 角色规则多对多
31+
roles: Mapped[list['Role']] = relationship(init=False, secondary=sys_role_data_rule, back_populates='rules') # noqa: F821

backend/app/admin/model/data_rule_type.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22
# -*- coding: utf-8 -*-
33
from sqlalchemy import String
44
from sqlalchemy.dialects.mysql import LONGTEXT
5-
from sqlalchemy.orm import Mapped, mapped_column
5+
from sqlalchemy.orm import Mapped, mapped_column, relationship
66

77
from backend.common.model import Base, id_key
88

99

1010
class DataRuleType(Base):
1111
"""数据权限规则类型表"""
1212

13-
__tablename__ = 'data_rule_type'
13+
__tablename__ = 'sys_data_rule_type'
1414

1515
id: Mapped[id_key] = mapped_column(init=False)
16-
name: Mapped[str] = mapped_column(String(255), comment='规则类型名')
16+
name: Mapped[str] = mapped_column(String(255), unique=True, comment='规则类型名')
1717
status: Mapped[int] = mapped_column(default=1, comment='状态(0停用 1正常)')
1818
remark: Mapped[str | None] = mapped_column(LONGTEXT, default=None, comment='备注')
19+
20+
# 数据权限规则类型一对多
21+
data_rules: Mapped[list['DataRule']] = relationship(init=False, back_populates='type') # noqa: F821

backend/app/admin/model/m2m.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,17 @@
1919
Column('role_id', Integer, ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'),
2020
Column('menu_id', Integer, ForeignKey('sys_menu.id', ondelete='CASCADE'), primary_key=True, comment='菜单ID'),
2121
)
22+
23+
sys_role_data_rule = Table(
24+
'sys_role_data_rule',
25+
MappedBase.metadata,
26+
Column('id', INT, primary_key=True, unique=True, index=True, autoincrement=True, comment='主键ID'),
27+
Column('role_id', Integer, ForeignKey('sys_role.id', ondelete='CASCADE'), primary_key=True, comment='角色ID'),
28+
Column(
29+
'data_rule_id',
30+
Integer,
31+
ForeignKey('sys_data_rule.id', ondelete='CASCADE'),
32+
primary_key=True,
33+
comment='数据权限规则ID',
34+
),
35+
)

backend/app/admin/model/role.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
from sqlalchemy.dialects.mysql import LONGTEXT
55
from sqlalchemy.orm import Mapped, mapped_column, relationship
66

7-
from backend.app.admin.model.m2m import sys_role_menu, sys_user_role
7+
from backend.app.admin.model.m2m import sys_role_data_rule, sys_role_menu, sys_user_role
88
from backend.common.model import Base, id_key
99

1010

@@ -27,3 +27,6 @@ class Role(Base):
2727

2828
# 角色菜单多对多
2929
menus: Mapped[list['Menu']] = relationship(init=False, secondary=sys_role_menu, back_populates='roles') # noqa: F821
30+
31+
# 角色数据权限规则多对多
32+
rules: Mapped[list['DataRule']] = relationship(init=False, secondary=sys_role_data_rule, back_populates='roles') # noqa: F821

backend/app/admin/schema/data_rule.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,19 @@
22
# -*- coding: utf-8 -*-
33
from datetime import datetime
44

5-
from pydantic import ConfigDict
5+
from pydantic import ConfigDict, Field
66

7+
from backend.common.enums import RoleDataRuleExpressionType, RoleDataRuleOperatorType
78
from backend.common.schema import SchemaBase
89

910

1011
class DataRuleSchemaBase(SchemaBase):
12+
type_id: int
1113
name: str
1214
model: str
1315
column: str
14-
condition: str
16+
operator: RoleDataRuleOperatorType = Field(RoleDataRuleOperatorType.OR)
17+
expression: RoleDataRuleExpressionType = Field(RoleDataRuleExpressionType.eq)
1518

1619

1720
class CreateDataRuleParam(DataRuleSchemaBase):

0 commit comments

Comments
 (0)