Skip to content

Commit 9b7584d

Browse files
committed
Refactor the data perms
1 parent 024beec commit 9b7584d

File tree

18 files changed

+514
-76
lines changed

18 files changed

+514
-76
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
from backend.app.admin.api.v1.sys.api import router as api_router
66
from backend.app.admin.api.v1.sys.casbin import router as casbin_router
77
from backend.app.admin.api.v1.sys.config import router as config_router
8+
from backend.app.admin.api.v1.sys.data_rule import router as data_rule_router
9+
from backend.app.admin.api.v1.sys.data_rule_type import router as data_rule_type_router
810
from backend.app.admin.api.v1.sys.dept import router as dept_router
911
from backend.app.admin.api.v1.sys.dict_data import router as dict_data_router
1012
from backend.app.admin.api.v1.sys.dict_type import router as dict_type_router
@@ -23,3 +25,5 @@
2325
router.include_router(menu_router, prefix='/menus', tags=['系统目录'])
2426
router.include_router(role_router, prefix='/roles', tags=['系统角色'])
2527
router.include_router(user_router, prefix='/users', tags=['系统用户'])
28+
router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据权限规则'])
29+
router.include_router(data_rule_type_router, prefix='/data-rule-types', tags=['系统数据权限类型'])
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from typing import Annotated
4+
5+
from fastapi import APIRouter, Depends, Path, Query
6+
7+
from backend.app.admin.schema.data_rule import CreateDataRuleParam, GetDataRuleListDetails, UpdateDataRuleParam
8+
from backend.app.admin.service.data_rule_service import data_rule_service
9+
from backend.common.pagination import DependsPagination, paging_data
10+
from backend.common.response.response_schema import ResponseModel, response_base
11+
from backend.common.security.jwt import DependsJwtAuth
12+
from backend.common.security.permission import RequestPermission
13+
from backend.common.security.rbac import DependsRBAC
14+
from backend.database.db_mysql import CurrentSession
15+
16+
router = APIRouter()
17+
18+
19+
@router.get('/{pk}', summary='获取数据规则详情', dependencies=[DependsJwtAuth])
20+
async def get_data_rule(pk: Annotated[int, Path(...)]) -> ResponseModel:
21+
data_rule = await data_rule_service.get(pk=pk)
22+
return response_base.success(data=data_rule)
23+
24+
25+
@router.get(
26+
'',
27+
summary='(模糊条件)分页获取所有数据规则',
28+
dependencies=[
29+
DependsJwtAuth,
30+
DependsPagination,
31+
],
32+
)
33+
async def get_pagination_data_rule(db: CurrentSession) -> ResponseModel:
34+
data_rule_select = await data_rule_service.get_select()
35+
page_data = await paging_data(db, data_rule_select, GetDataRuleListDetails)
36+
return response_base.success(data=page_data)
37+
38+
39+
@router.post(
40+
'',
41+
summary='创建数据规则',
42+
dependencies=[
43+
Depends(RequestPermission('data:rule:add')),
44+
DependsRBAC,
45+
],
46+
)
47+
async def create_data_rule(obj: CreateDataRuleParam) -> ResponseModel:
48+
await data_rule_service.create(obj=obj)
49+
return response_base.success()
50+
51+
52+
@router.put(
53+
'/{pk}',
54+
summary='更新数据规则',
55+
dependencies=[
56+
Depends(RequestPermission('data:rule:edit')),
57+
DependsRBAC,
58+
],
59+
)
60+
async def update_data_rule(pk: Annotated[int, Path(...)], obj: UpdateDataRuleParam) -> ResponseModel:
61+
count = await data_rule_service.update(pk=pk, obj=obj)
62+
if count > 0:
63+
return response_base.success()
64+
return response_base.fail()
65+
66+
67+
@router.delete(
68+
'',
69+
summary='(批量)删除数据规则',
70+
dependencies=[
71+
Depends(RequestPermission('data:rule:del')),
72+
DependsRBAC,
73+
],
74+
)
75+
async def delete_data_rule(pk: Annotated[list[int], Query(...)]) -> ResponseModel:
76+
count = await data_rule_service.delete(pk=pk)
77+
if count > 0:
78+
return response_base.success()
79+
return response_base.fail()
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from typing import Annotated
4+
5+
from fastapi import APIRouter, Depends, Path, Query
6+
7+
from backend.app.admin.schema.data_rule_type import (
8+
CreateDataRuleTypeParam,
9+
GetDataRuleTypeListDetails,
10+
UpdateDataRuleTypeParam,
11+
)
12+
from backend.app.admin.service.data_rule_type_service import data_rule_type_service
13+
from backend.common.pagination import DependsPagination, paging_data
14+
from backend.common.response.response_schema import ResponseModel, response_base
15+
from backend.common.security.jwt import DependsJwtAuth
16+
from backend.common.security.permission import RequestPermission
17+
from backend.common.security.rbac import DependsRBAC
18+
from backend.database.db_mysql import CurrentSession
19+
20+
router = APIRouter()
21+
22+
23+
@router.get('/{pk}', summary='获取数据规则类型详情', dependencies=[DependsJwtAuth])
24+
async def get_data_rule_type(pk: Annotated[int, Path(...)]) -> ResponseModel:
25+
data_rule_type = await data_rule_type_service.get(pk=pk)
26+
return response_base.success(data=data_rule_type)
27+
28+
29+
@router.get(
30+
'',
31+
summary='(模糊条件)分页获取所有数据规则类型',
32+
dependencies=[
33+
DependsJwtAuth,
34+
DependsPagination,
35+
],
36+
)
37+
async def get_pagination_data_rule_type(db: CurrentSession) -> ResponseModel:
38+
data_rule_type_select = await data_rule_type_service.get_select()
39+
page_data = await paging_data(db, data_rule_type_select, GetDataRuleTypeListDetails)
40+
return response_base.success(data=page_data)
41+
42+
43+
@router.post(
44+
'',
45+
summary='创建数据规则类型',
46+
dependencies=[
47+
Depends(RequestPermission('data:rule:type:add')),
48+
DependsRBAC,
49+
],
50+
)
51+
async def create_data_rule_type(obj: CreateDataRuleTypeParam) -> ResponseModel:
52+
await data_rule_type_service.create(obj=obj)
53+
return response_base.success()
54+
55+
56+
@router.put(
57+
'/{pk}',
58+
summary='更新数据规则类型',
59+
dependencies=[
60+
Depends(RequestPermission('data:rule:type:edit')),
61+
DependsRBAC,
62+
],
63+
)
64+
async def update_data_rule_type(pk: Annotated[int, Path(...)], obj: UpdateDataRuleTypeParam) -> ResponseModel:
65+
count = await data_rule_type_service.update(pk=pk, obj=obj)
66+
if count > 0:
67+
return response_base.success()
68+
return response_base.fail()
69+
70+
71+
@router.delete(
72+
'',
73+
summary='(批量)删除数据规则类型',
74+
dependencies=[
75+
Depends(RequestPermission('data:rule:type:del')),
76+
DependsRBAC,
77+
],
78+
)
79+
async def delete_data_rule_type(pk: Annotated[list[int], Query(...)]) -> ResponseModel:
80+
count = await data_rule_type_service.delete(pk=pk)
81+
if count > 0:
82+
return response_base.success()
83+
return response_base.fail()
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from typing import Sequence
4+
5+
from sqlalchemy import Select
6+
from sqlalchemy.ext.asyncio import AsyncSession
7+
from sqlalchemy_crud_plus import CRUDPlus
8+
9+
from backend.app.admin.model import DataRule
10+
from backend.app.admin.schema.data_rule import CreateDataRuleParam, UpdateDataRuleParam
11+
12+
13+
class CRUDDataRule(CRUDPlus[DataRule]):
14+
async def get(self, db: AsyncSession, pk: int) -> DataRule | None:
15+
"""
16+
获取 DataRule
17+
18+
:param db:
19+
:param pk:
20+
:return:
21+
"""
22+
return await self.select_model(db, pk)
23+
24+
async def get_list(self) -> Select:
25+
"""
26+
获取 DataRule 列表
27+
28+
:return:
29+
"""
30+
return await self.select_order('created_time', 'desc')
31+
32+
async def get_all(self, db: AsyncSession) -> Sequence[DataRule]:
33+
"""
34+
获取所有 DataRule
35+
36+
:param db:
37+
:return:
38+
"""
39+
return await self.select_models(db)
40+
41+
async def create(self, db: AsyncSession, obj_in: CreateDataRuleParam) -> None:
42+
"""
43+
创建 DataRule
44+
45+
:param db:
46+
:param obj_in:
47+
:return:
48+
"""
49+
await self.create_model(db, obj_in)
50+
51+
async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleParam) -> int:
52+
"""
53+
更新 DataRule
54+
55+
:param db:
56+
:param pk:
57+
:param obj_in:
58+
:return:
59+
"""
60+
return await self.update_model(db, pk, obj_in)
61+
62+
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
63+
"""
64+
删除 DataRule
65+
66+
:param db:
67+
:param pk:
68+
:return:
69+
"""
70+
return await self.delete_model_by_column(db, allow_multiple=True, id__in=pk)
71+
72+
73+
data_rule_dao: CRUDDataRule = CRUDDataRule(DataRule)
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from typing import Sequence
4+
5+
from sqlalchemy import Select
6+
from sqlalchemy.ext.asyncio import AsyncSession
7+
from sqlalchemy_crud_plus import CRUDPlus
8+
9+
from backend.app.admin.model import DataRuleType
10+
from backend.app.admin.schema.data_rule_type import CreateDataRuleTypeParam, UpdateDataRuleTypeParam
11+
12+
13+
class CRUDDataRuleType(CRUDPlus[DataRuleType]):
14+
async def get(self, db: AsyncSession, pk: int) -> DataRuleType | None:
15+
"""
16+
获取 DataRuleType
17+
18+
:param db:
19+
:param pk:
20+
:return:
21+
"""
22+
return await self.select_model(db, pk)
23+
24+
async def get_list(self) -> Select:
25+
"""
26+
获取 DataRuleType 列表
27+
28+
:return:
29+
"""
30+
return await self.select_order('created_time', 'desc')
31+
32+
async def get_all(self, db: AsyncSession) -> Sequence[DataRuleType]:
33+
"""
34+
获取所有 DataRuleType
35+
36+
:param db:
37+
:return:
38+
"""
39+
return await self.select_models(db)
40+
41+
async def create(self, db: AsyncSession, obj_in: CreateDataRuleTypeParam) -> None:
42+
"""
43+
创建 DataRuleType
44+
45+
:param db:
46+
:param obj_in:
47+
:return:
48+
"""
49+
await self.create_model(db, obj_in)
50+
51+
async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleTypeParam) -> int:
52+
"""
53+
更新 DataRuleType
54+
55+
:param db:
56+
:param pk:
57+
:param obj_in:
58+
:return:
59+
"""
60+
return await self.update_model(db, pk, obj_in)
61+
62+
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
63+
"""
64+
删除 DataRuleType
65+
66+
:param db:
67+
:param pk:
68+
:return:
69+
"""
70+
return await self.delete_model_by_column(db, allow_multiple=True, id__in=pk)
71+
72+
73+
data_rule_type_dao: CRUDDataRuleType = CRUDDataRuleType(DataRuleType)

backend/app/admin/crud/crud_user.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -303,7 +303,6 @@ async def get_with_relation(self, db: AsyncSession, *, user_id: int = None, user
303303
stmt = select(self.model).options(
304304
selectinload(self.model.dept),
305305
selectinload(self.model.roles).joinedload(Role.menus),
306-
selectinload(self.model.roles).joinedload(Role.depts),
307306
)
308307
filters = []
309308
if user_id:

backend/app/admin/model/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
from backend.app.admin.model.api import Api
44
from backend.app.admin.model.casbin_rule import CasbinRule
55
from backend.app.admin.model.config import Config
6+
from backend.app.admin.model.data_rule import DataRule
7+
from backend.app.admin.model.data_rule_type import DataRuleType
68
from backend.app.admin.model.dept import Dept
79
from backend.app.admin.model.dict_data import DictData
810
from backend.app.admin.model.dict_type import DictType
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from sqlalchemy import String
4+
from sqlalchemy.orm import Mapped, mapped_column
5+
6+
from backend.common.model import Base, id_key
7+
8+
9+
class DataRule(Base):
10+
"""数据权限规则表"""
11+
12+
__tablename__ = 'data_rule'
13+
14+
id: Mapped[id_key] = mapped_column(init=False)
15+
name: Mapped[str] = mapped_column(String(255), comment='规则名称')
16+
model: Mapped[str] = mapped_column(String(50), comment='SQLA 模型类')
17+
column: Mapped[str] = mapped_column(String(20), comment='数据库字段')
18+
condition: Mapped[str] = mapped_column(String(20), comment='查询条件')
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from sqlalchemy import String
4+
from sqlalchemy.dialects.mysql import LONGTEXT
5+
from sqlalchemy.orm import Mapped, mapped_column
6+
7+
from backend.common.model import Base, id_key
8+
9+
10+
class DataRuleType(Base):
11+
"""数据权限规则类型表"""
12+
13+
__tablename__ = 'data_rule_type'
14+
15+
id: Mapped[id_key] = mapped_column(init=False)
16+
name: Mapped[str] = mapped_column(String(255), comment='规则类型名')
17+
status: Mapped[int] = mapped_column(default=1, comment='状态(0停用 1正常)')
18+
remark: Mapped[str | None] = mapped_column(LONGTEXT, default=None, comment='备注')

backend/app/admin/model/dept.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
from sqlalchemy import ForeignKey, String
66
from sqlalchemy.orm import Mapped, mapped_column, relationship
77

8-
from backend.app.admin.model.m2m import sys_role_dept
98
from backend.common.model import Base, id_key
109

1110

@@ -33,6 +32,3 @@ class Dept(Base):
3332

3433
# 部门用户一对多
3534
users: Mapped[list['User']] = relationship(init=False, back_populates='dept') # noqa: F821
36-
37-
# 部门角色多对多
38-
roles: Mapped[list['Role']] = relationship(init=False, secondary=sys_role_dept, back_populates='depts') # noqa: F821

0 commit comments

Comments
 (0)