Skip to content

Commit 6670c64

Browse files
committed
update codes
1 parent fa94de7 commit 6670c64

File tree

6 files changed

+357
-6
lines changed

6 files changed

+357
-6
lines changed
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
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_scope import (
8+
CreateDataScopeParam,
9+
GetDataScopeDetail,
10+
GetDataScopeWithRelationDetail,
11+
UpdateDataScopeParam,
12+
UpdateDataScopeRuleParam,
13+
)
14+
from backend.app.admin.service.data_scope_service import data_scope_service
15+
from backend.common.pagination import DependsPagination, PageData, paging_data
16+
from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base
17+
from backend.common.security.jwt import DependsJwtAuth
18+
from backend.common.security.permission import RequestPermission
19+
from backend.common.security.rbac import DependsRBAC
20+
from backend.database.db import CurrentSession
21+
22+
router = APIRouter()
23+
24+
25+
@router.get('/{pk}', summary='获取数据范围详情', dependencies=[DependsJwtAuth])
26+
async def get_data_scope(
27+
pk: Annotated[int, Path(description='数据范围 ID')],
28+
) -> ResponseSchemaModel[GetDataScopeDetail]:
29+
data = await data_scope_service.get(pk=pk)
30+
return response_base.success(data=data)
31+
32+
33+
@router.get('/{pk}/rules', summary='获取数据范围所有规则', dependencies=[DependsJwtAuth])
34+
async def get_data_scope_rules(
35+
pk: Annotated[int, Path(description='数据范围 ID')],
36+
) -> ResponseSchemaModel[GetDataScopeWithRelationDetail]:
37+
data = await data_scope_service.get_rules(pk=pk)
38+
return response_base.success(data=data)
39+
40+
41+
@router.get(
42+
'',
43+
summary='分页获取所有数据范围',
44+
dependencies=[
45+
DependsJwtAuth,
46+
DependsPagination,
47+
],
48+
)
49+
async def get_pagination_data_scopes(
50+
db: CurrentSession,
51+
name: Annotated[str | None, Query(description='范围名称')] = None,
52+
status: Annotated[int | None, Query(description='状态')] = None,
53+
) -> ResponseSchemaModel[PageData[GetDataScopeDetail]]:
54+
data_scope_select = await data_scope_service.get_select(name=name, status=status)
55+
page_data = await paging_data(db, data_scope_select)
56+
return response_base.success(data=page_data)
57+
58+
59+
@router.post(
60+
'',
61+
summary='创建数据范围',
62+
dependencies=[
63+
Depends(RequestPermission('data:scope:add')),
64+
DependsRBAC,
65+
],
66+
)
67+
async def create_data_scope(obj: CreateDataScopeParam) -> ResponseModel:
68+
await data_scope_service.create(obj=obj)
69+
return response_base.success()
70+
71+
72+
@router.put(
73+
'/{pk}',
74+
summary='更新数据范围',
75+
dependencies=[
76+
Depends(RequestPermission('data:scope:edit')),
77+
DependsRBAC,
78+
],
79+
)
80+
async def update_data_scope(
81+
pk: Annotated[int, Path(description='数据范围 ID')], obj: UpdateDataScopeParam
82+
) -> ResponseModel:
83+
count = await data_scope_service.update(pk=pk, obj=obj)
84+
if count > 0:
85+
return response_base.success()
86+
return response_base.fail()
87+
88+
89+
@router.put(
90+
'/{pk}/rules',
91+
summary='更新数据范围规则',
92+
dependencies=[
93+
Depends(RequestPermission('data:scope:rule:edit')),
94+
],
95+
)
96+
async def update_data_scope_rules(
97+
pk: Annotated[int, Path(description='数据范围 ID')], rule_ids: UpdateDataScopeRuleParam
98+
):
99+
count = await data_scope_service.update_data_scope_rule(pk=pk, rule_ids=rule_ids)
100+
if count > 0:
101+
return response_base.success()
102+
return response_base.fail()
103+
104+
105+
@router.delete(
106+
'',
107+
summary='批量删除数据范围',
108+
dependencies=[
109+
Depends(RequestPermission('data:scope:del')),
110+
DependsRBAC,
111+
],
112+
)
113+
async def delete_data_scope(pk: Annotated[list[int], Query(description='数据范围 ID 列表')]) -> ResponseModel:
114+
count = await data_scope_service.delete(pk=pk)
115+
if count > 0:
116+
return response_base.success()
117+
return response_base.fail()
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from sqlalchemy import Select, and_, desc, select
4+
from sqlalchemy.ext.asyncio import AsyncSession
5+
from sqlalchemy.orm import noload, selectinload
6+
from sqlalchemy_crud_plus import CRUDPlus
7+
8+
from backend.app.admin.model import DataRule, DataScope
9+
from backend.app.admin.schema.data_scope import CreateDataScopeParam, UpdateDataScopeParam, UpdateDataScopeRuleParam
10+
11+
12+
class CRUDDataScope(CRUDPlus[DataScope]):
13+
"""数据范围数据库操作类"""
14+
15+
async def get(self, db: AsyncSession, pk: int) -> DataScope | None:
16+
"""
17+
获取数据范围详情
18+
19+
:param db: 数据库会话
20+
:param pk: 范围 ID
21+
:return:
22+
"""
23+
return await self.select_model(db, pk)
24+
25+
async def get_by_name(self, db: AsyncSession, name: str) -> DataScope | None:
26+
"""
27+
通过名称获取数据范围
28+
29+
:param db: 数据库会话
30+
:param name: 范围名称
31+
:return:
32+
"""
33+
return await self.select_model_by_column(db, name=name)
34+
35+
async def get_with_relation(self, db: AsyncSession, pk: int) -> DataScope:
36+
"""
37+
获取数据范围关联数据
38+
39+
:param db: 数据库会话
40+
:param pk: 范围 ID
41+
:return:
42+
"""
43+
stmt = select(self.model).options(selectinload(self.model.rules)).where(self.model.id == pk)
44+
data_scope = await db.execute(stmt)
45+
return data_scope.scalars().first()
46+
47+
async def get_list(self, name: str | None, status: int | None) -> Select:
48+
"""
49+
获取数据范围列表
50+
51+
:param name: 范围名称
52+
:param status: 范围状态
53+
:return:
54+
"""
55+
stmt = (
56+
select(self.model)
57+
.options(noload(self.model.rules), noload(self.model.roles))
58+
.order_by(desc(self.model.created_time))
59+
)
60+
61+
filters = []
62+
if name is not None:
63+
filters.append(self.model.name.like(f'%{name}%'))
64+
if status is not None:
65+
filters.append(self.model.status == status)
66+
67+
if filters:
68+
stmt = stmt.where(and_(*filters))
69+
70+
return stmt
71+
72+
async def create(self, db: AsyncSession, obj: CreateDataScopeParam) -> None:
73+
"""
74+
创建数据范围
75+
76+
:param db: 数据库会话
77+
:param obj: 创建数据范围参数
78+
:return:
79+
"""
80+
await self.create_model(db, obj)
81+
82+
async def update(self, db: AsyncSession, pk: int, obj: UpdateDataScopeParam) -> int:
83+
"""
84+
更新数据范围
85+
86+
:param db: 数据库会话
87+
:param pk: 范围 ID
88+
:param obj: 更新数据范围参数
89+
:return:
90+
"""
91+
return await self.update_model(db, pk, obj)
92+
93+
async def update_rules(self, db: AsyncSession, pk: int, rule_ids: UpdateDataScopeRuleParam) -> int:
94+
"""
95+
更新数据范围规则
96+
97+
:param db: 数据库会话
98+
:param pk: 范围 ID
99+
:param rule_ids: 数据规则 ID 列表
100+
:return:
101+
"""
102+
current_data_scope = await self.get_with_relation(db, pk)
103+
stmt = select(DataRule).where(DataRule.id.in_(rule_ids.rules))
104+
rules = await db.execute(stmt)
105+
current_data_scope.rules = rules.scalars().all()
106+
return len(current_data_scope.rules)
107+
108+
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
109+
"""
110+
删除数据范围
111+
112+
:param db: 数据库会话
113+
:param pk: 范围 ID 列表
114+
:return:
115+
"""
116+
return await self.delete_model_by_column(db, allow_multiple=True, id__in=pk)
117+
118+
119+
data_scope_dao: CRUDDataScope = CRUDDataScope(DataScope)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#!/usr/bin/env python3
2+
# -*- coding: utf-8 -*-
3+
from sqlalchemy import Select
4+
5+
from backend.app.admin.crud.crud_data_scope import data_scope_dao
6+
from backend.app.admin.model import DataScope
7+
from backend.app.admin.schema.data_scope import CreateDataScopeParam, UpdateDataScopeParam, UpdateDataScopeRuleParam
8+
from backend.common.exception import errors
9+
from backend.core.conf import settings
10+
from backend.database.db import async_db_session
11+
from backend.database.redis import redis_client
12+
13+
14+
class DataScopeService:
15+
"""数据范围服务类"""
16+
17+
@staticmethod
18+
async def get(*, pk: int) -> DataScope:
19+
"""
20+
获取数据范围详情
21+
22+
:param pk: 范围 ID
23+
:return:
24+
"""
25+
async with async_db_session() as db:
26+
data_scope = await data_scope_dao.get(db, pk)
27+
if not data_scope:
28+
raise errors.NotFoundError(msg='数据范围不存在')
29+
return data_scope
30+
31+
@staticmethod
32+
async def get_rules(*, pk: int) -> DataScope:
33+
"""
34+
获取数据范围规则
35+
36+
:param pk: 范围 ID
37+
:return:
38+
"""
39+
async with async_db_session() as db:
40+
data_scope = await data_scope_dao.get_with_relation(db, pk)
41+
if not data_scope:
42+
raise errors.NotFoundError(msg='数据范围不存在')
43+
return data_scope
44+
45+
@staticmethod
46+
async def get_select(*, name: str | None, status: int | None) -> Select:
47+
"""
48+
获取数据范围列表查询条件
49+
50+
:param name: 范围名称
51+
:param status: 范围状态
52+
:return:
53+
"""
54+
return await data_scope_dao.get_list(name, status)
55+
56+
@staticmethod
57+
async def create(*, obj: CreateDataScopeParam) -> None:
58+
"""
59+
创建数据范围
60+
61+
:param obj: 数据范围参数
62+
:return:
63+
"""
64+
async with async_db_session.begin() as db:
65+
data_scope = await data_scope_dao.get_by_name(db, obj.name)
66+
if data_scope:
67+
raise errors.ForbiddenError(msg='数据范围已存在')
68+
await data_scope_dao.create(db, obj)
69+
70+
@staticmethod
71+
async def update(*, pk: int, obj: UpdateDataScopeParam) -> int:
72+
"""
73+
更新数据范围
74+
75+
:param pk: 范围 ID
76+
:param obj: 数据范围更新参数
77+
:return:
78+
"""
79+
async with async_db_session.begin() as db:
80+
data_scope = await data_scope_dao.get(db, pk)
81+
if not data_scope:
82+
raise errors.NotFoundError(msg='数据范围不存在')
83+
count = await data_scope_dao.update(db, pk, obj)
84+
for role in await data_scope.awaitable_attrs.roles:
85+
for user in await role.awaitable_attrs.users:
86+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
87+
return count
88+
89+
@staticmethod
90+
async def update_data_scope_rule(*, pk: int, rule_ids: UpdateDataScopeRuleParam) -> int:
91+
"""
92+
更新数据范围规则
93+
94+
:param pk: 范围 ID
95+
:param rule_ids: 规则 ID 列表
96+
:return:
97+
"""
98+
async with async_db_session.begin() as db:
99+
count = await data_scope_dao.update_rules(db, pk, rule_ids)
100+
return count
101+
102+
@staticmethod
103+
async def delete(*, pk: list[int]) -> int:
104+
"""
105+
删除数据范围
106+
107+
:param pk: 范围 ID 列表
108+
:return:
109+
"""
110+
async with async_db_session.begin() as db:
111+
count = await data_scope_dao.delete(db, pk)
112+
for _pk in pk:
113+
data_rule = await data_scope_dao.get(db, _pk)
114+
if data_rule:
115+
for role in await data_rule.awaitable_attrs.roles:
116+
for user in await role.awaitable_attrs.users:
117+
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
118+
return count
119+
120+
121+
data_scope_service: DataScopeService = DataScopeService()

backend/plugin/data_permission/__init__.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

backend/plugin/data_permission/api/__init__.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

backend/plugin/data_permission/api/v1/__init__.py

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)