Optimize the userinfo cache cleaning logic (#586)

This commit is contained in:
Wu Clan
2025-04-23 12:40:27 +08:00
committed by GitHub
parent e8c844ead7
commit 0833cd5443
17 changed files with 109 additions and 110 deletions
+1 -1
View File
@@ -17,7 +17,7 @@ router.include_router(dept_router, prefix='/depts', tags=['系统部门'])
router.include_router(menu_router, prefix='/menus', tags=['系统菜单'])
router.include_router(role_router, prefix='/roles', tags=['系统角色'])
router.include_router(user_router, prefix='/users', tags=['系统用户'])
router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据权限规则'])
router.include_router(data_rule_router, prefix='/data-rules', tags=['系统数据规则'])
router.include_router(token_router, prefix='/tokens', tags=['系统令牌'])
router.include_router(upload_router, prefix='/upload', tags=['系统上传'])
router.include_router(plugin_router, prefix='/plugin', tags=['系统插件'])
+10 -12
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
from typing import Annotated
from fastapi import APIRouter, Depends, Path, Query, Request
from fastapi import APIRouter, Depends, Path, Query
from backend.app.admin.schema.data_rule import CreateDataRuleParam, GetDataRuleDetail, UpdateDataRuleParam
from backend.app.admin.service.data_rule_service import data_rule_service
@@ -16,13 +16,13 @@ from backend.database.db import CurrentSession
router = APIRouter()
@router.get('/models', summary='获取支持过滤的数据库模型', dependencies=[DependsJwtAuth])
@router.get('/models', summary='获取数据规则可用模型', dependencies=[DependsJwtAuth])
async def get_data_rule_models() -> ResponseSchemaModel[list[str]]:
models = await data_rule_service.get_models()
return response_base.success(data=models)
@router.get('/model/{model}/columns', summary='获取支持过滤的数据库模型列', dependencies=[DependsJwtAuth])
@router.get('/model/{model}/columns', summary='获取数据规则可用模型列', dependencies=[DependsJwtAuth])
async def get_data_rule_model_columns(
model: Annotated[str, Path(description='模型名称')],
) -> ResponseSchemaModel[list[str]]:
@@ -36,7 +36,7 @@ async def get_all_data_rules() -> ResponseSchemaModel[list[GetDataRuleDetail]]:
return response_base.success(data=data)
@router.get('/{pk}', summary='获取数据权限规则详情', dependencies=[DependsJwtAuth])
@router.get('/{pk}', summary='获取数据规则详情', dependencies=[DependsJwtAuth])
async def get_data_rule(
pk: Annotated[int, Path(description='数据规则 ID')],
) -> ResponseSchemaModel[GetDataRuleDetail]:
@@ -46,7 +46,7 @@ async def get_data_rule(
@router.get(
'',
summary='分页获取所有数据权限规则',
summary='分页获取所有数据规则',
dependencies=[
DependsJwtAuth,
DependsPagination,
@@ -62,7 +62,7 @@ async def get_pagination_data_rules(
@router.post(
'',
summary='创建数据权限规则',
summary='创建数据规则',
dependencies=[
Depends(RequestPermission('data:rule:add')),
DependsRBAC,
@@ -75,7 +75,7 @@ async def create_data_rule(obj: CreateDataRuleParam) -> ResponseModel:
@router.put(
'/{pk}',
summary='更新数据权限规则',
summary='更新数据规则',
dependencies=[
Depends(RequestPermission('data:rule:edit')),
DependsRBAC,
@@ -92,16 +92,14 @@ async def update_data_rule(
@router.delete(
'',
summary='批量删除数据权限规则',
summary='批量删除数据规则',
dependencies=[
Depends(RequestPermission('data:rule:del')),
DependsRBAC,
],
)
async def delete_data_rule(
request: Request, pk: Annotated[list[int], Query(description='数据规则 ID 列表')]
) -> ResponseModel:
count = await data_rule_service.delete(request=request, pk=pk)
async def delete_data_rule(pk: Annotated[list[int], Query(description='数据规则 ID 列表')]) -> ResponseModel:
count = await data_rule_service.delete(pk=pk)
if count > 0:
return response_base.success()
return response_base.fail()
+3 -3
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
from typing import Annotated, Any
from fastapi import APIRouter, Depends, Path, Query, Request
from fastapi import APIRouter, Depends, Path, Query
from backend.app.admin.schema.dept import CreateDeptParam, GetDeptDetail, UpdateDeptParam
from backend.app.admin.service.dept_service import dept_service
@@ -67,8 +67,8 @@ async def update_dept(pk: Annotated[int, Path(description='部门 ID')], obj: Up
DependsRBAC,
],
)
async def delete_dept(request: Request, pk: Annotated[int, Path(description='部门 ID')]) -> ResponseModel:
count = await dept_service.delete(request=request, pk=pk)
async def delete_dept(pk: Annotated[int, Path(description='部门 ID')]) -> ResponseModel:
count = await dept_service.delete(pk=pk)
if count > 0:
return response_base.success()
return response_base.fail()
+2 -2
View File
@@ -71,8 +71,8 @@ async def update_menu(pk: Annotated[int, Path(description='菜单 ID')], obj: Up
DependsRBAC,
],
)
async def delete_menu(request: Request, pk: Annotated[int, Path(description='菜单 ID 列表')]) -> ResponseModel:
count = await menu_service.delete(request=request, pk=pk)
async def delete_menu(pk: Annotated[int, Path(description='菜单 ID 列表')]) -> ResponseModel:
count = await menu_service.delete(pk=pk)
if count > 0:
return response_base.success()
return response_base.fail()
+8 -8
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*-
from typing import Annotated, Any
from fastapi import APIRouter, Depends, Path, Query, Request
from fastapi import APIRouter, Depends, Path, Query
from backend.app.admin.schema.role import (
CreateRoleParam,
@@ -116,9 +116,9 @@ async def update_role(pk: Annotated[int, Path(description='角色 ID')], obj: Up
],
)
async def update_role_menus(
request: Request, pk: Annotated[int, Path(description='角色 ID')], menu_ids: UpdateRoleMenuParam
pk: Annotated[int, Path(description='角色 ID')], menu_ids: UpdateRoleMenuParam
) -> ResponseModel:
count = await role_service.update_role_menu(request=request, pk=pk, menu_ids=menu_ids)
count = await role_service.update_role_menu(pk=pk, menu_ids=menu_ids)
if count > 0:
return response_base.success()
return response_base.fail()
@@ -126,16 +126,16 @@ async def update_role_menus(
@router.put(
'/{pk}/rule',
summary='更新角色数据权限规则',
summary='更新角色数据规则',
dependencies=[
Depends(RequestPermission('sys:role:rule:edit')),
DependsRBAC,
],
)
async def update_role_rules(
request: Request, pk: Annotated[int, Path(description='角色 ID')], rule_ids: UpdateRoleRuleParam
pk: Annotated[int, Path(description='角色 ID')], rule_ids: UpdateRoleRuleParam
) -> ResponseModel:
count = await role_service.update_role_rule(request=request, pk=pk, rule_ids=rule_ids)
count = await role_service.update_role_rule(pk=pk, rule_ids=rule_ids)
if count > 0:
return response_base.success()
return response_base.fail()
@@ -149,8 +149,8 @@ async def update_role_rules(
DependsRBAC,
],
)
async def delete_role(request: Request, pk: Annotated[list[int], Query(description='角色 ID 列表')]) -> ResponseModel:
count = await role_service.delete(request=request, pk=pk)
async def delete_role(pk: Annotated[list[int], Query(description='角色 ID 列表')]) -> ResponseModel:
count = await role_service.delete(pk=pk)
if count > 0:
return response_base.success()
return response_base.fail()
+1 -1
View File
@@ -12,7 +12,7 @@ from backend.app.admin.schema.data_rule import CreateDataRuleParam, UpdateDataRu
class CRUDDataRule(CRUDPlus[DataRule]):
"""数据权限规则数据库操作类"""
"""数据规则数据库操作类"""
async def get(self, db: AsyncSession, pk: int) -> DataRule | None:
"""
+1 -1
View File
@@ -15,7 +15,7 @@ if TYPE_CHECKING:
class DataRule(Base):
"""数据权限规则表"""
"""数据规则表"""
__tablename__ = 'sys_data_rule'
+1 -1
View File
@@ -30,6 +30,6 @@ sys_role_data_rule = Table(
Integer,
ForeignKey('sys_data_rule.id', ondelete='CASCADE'),
primary_key=True,
comment='数据权限规则ID',
comment='数据规则ID',
),
)
+1 -1
View File
@@ -34,5 +34,5 @@ class Role(Base):
# 角色菜单多对多
menus: Mapped[list[Menu]] = relationship(init=False, secondary=sys_role_menu, back_populates='roles')
# 角色数据权限规则多对多
# 角色数据规则多对多
rules: Mapped[list[DataRule]] = relationship(init=False, secondary=sys_role_data_rule, back_populates='roles')
+16 -10
View File
@@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
from typing import Sequence
from fastapi import Request
from sqlalchemy import Select
from backend.app.admin.crud.crud_data_rule import data_rule_dao
@@ -17,7 +16,7 @@ from backend.utils.import_parse import dynamic_import_data_model
class DataRuleService:
"""数据权限规则服务类"""
"""数据规则服务类"""
@staticmethod
async def get(*, pk: int) -> DataRule:
@@ -50,19 +49,19 @@ class DataRuleService:
@staticmethod
async def get_models() -> list[str]:
"""获取所有数据模型"""
"""获取所有数据规则可用模型"""
return list(settings.DATA_PERMISSION_MODELS.keys())
@staticmethod
async def get_columns(model: str) -> list[str]:
"""
获取数据模型的字段列表
获取数据规则可用模型的字段列表
:param model: 模型名称
:return:
"""
if model not in settings.DATA_PERMISSION_MODELS:
raise errors.NotFoundError(msg='数据模型不存在')
raise errors.NotFoundError(msg='数据规则可用模型不存在')
model_ins = dynamic_import_data_model(settings.DATA_PERMISSION_MODELS[model])
model_columns = [
key for key in model_ins.__table__.columns.keys() if key not in settings.DATA_PERMISSION_COLUMN_EXCLUDE
@@ -97,7 +96,7 @@ class DataRuleService:
async with async_db_session.begin() as db:
data_rule = await data_rule_dao.get_by_name(db, obj.name)
if data_rule:
raise errors.ForbiddenError(msg='数据权限规则已存在')
raise errors.ForbiddenError(msg='数据规则已存在')
await data_rule_dao.create(db, obj)
@staticmethod
@@ -112,22 +111,29 @@ class DataRuleService:
async with async_db_session.begin() as db:
data_rule = await data_rule_dao.get(db, pk)
if not data_rule:
raise errors.NotFoundError(msg='数据权限规则不存在')
raise errors.NotFoundError(msg='数据规则不存在')
count = await data_rule_dao.update(db, pk, obj)
for role in await data_rule.awaitable_attrs.roles:
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
async def delete(*, request: Request, pk: list[int]) -> int:
async def delete(*, pk: list[int]) -> int:
"""
删除数据规则
:param request: FastAPI 请求对象
:param pk: 规则 ID 列表
:return:
"""
async with async_db_session.begin() as db:
count = await data_rule_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
for _pk in pk:
data_rule = await data_rule_dao.get(db, _pk)
if data_rule:
for role in await data_rule.awaitable_attrs.roles:
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
+4 -7
View File
@@ -2,8 +2,6 @@
# -*- coding: utf-8 -*-
from typing import Any
from fastapi import Request
from backend.app.admin.crud.crud_dept import dept_dao
from backend.app.admin.model import Dept
from backend.app.admin.schema.dept import CreateDeptParam, UpdateDeptParam
@@ -93,24 +91,23 @@ class DeptService:
return count
@staticmethod
async def delete(*, request: Request, pk: int) -> int:
async def delete(*, pk: int) -> int:
"""
删除部门
:param request: FastAPI 请求对象
:param pk: 部门 ID
:return:
"""
async with async_db_session.begin() as db:
dept = await dept_dao.get_with_relation(db, pk)
dept_user = dept.users
if dept_user:
if dept.users:
raise errors.ForbiddenError(msg='部门下存在用户,无法删除')
children = await dept_dao.get_children(db, pk)
if children:
raise errors.ForbiddenError(msg='部门下存在子部门,无法删除')
count = await dept_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
for user in dept.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
+9 -3
View File
@@ -123,14 +123,16 @@ class MenuService:
if obj.parent_id == menu.id:
raise errors.ForbiddenError(msg='禁止关联自身为父级')
count = await menu_dao.update(db, pk, obj)
for role in await menu.awaitable_attrs.roles:
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
async def delete(*, request: Request, pk: int) -> int:
async def delete(*, pk: int) -> int:
"""
删除菜单
:param request: FastAPI 请求对象
:param pk: 菜单 ID
:return:
"""
@@ -138,8 +140,12 @@ class MenuService:
children = await menu_dao.get_children(db, pk)
if children:
raise errors.ForbiddenError(msg='菜单下存在子菜单,无法删除')
menu = await menu_dao.get(db, pk)
count = await menu_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
if menu:
for role in await menu.awaitable_attrs.roles:
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
+17 -15
View File
@@ -2,7 +2,6 @@
# -*- coding: utf-8 -*-
from typing import Sequence
from fastapi import Request
from sqlalchemy import Select
from backend.app.admin.crud.crud_data_rule import data_rule_dao
@@ -100,20 +99,21 @@ class RoleService:
if role:
raise errors.ForbiddenError(msg='角色已存在')
count = await role_dao.update(db, pk, obj)
for user in await role.awaitable_attrs.users:
await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
async def update_role_menu(*, request: Request, pk: int, menu_ids: UpdateRoleMenuParam) -> int:
async def update_role_menu(*, pk: int, menu_ids: UpdateRoleMenuParam) -> int:
"""
更新角色菜单
:param request: FastAPI 请求对象
:param pk: 角色 ID
:param menu_ids: 菜单 ID 列表
:return:
"""
async with async_db_session.begin() as db:
role = await role_dao.get(db, pk)
role = await role_dao.get_with_relation(db, pk)
if not role:
raise errors.NotFoundError(msg='角色不存在')
for menu_id in menu_ids.menus:
@@ -121,16 +121,15 @@ class RoleService:
if not menu:
raise errors.NotFoundError(msg='菜单不存在')
count = await role_dao.update_menus(db, pk, menu_ids)
if pk in [role.id for role in request.user.roles]:
await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}')
for user in await role.awaitable_attrs.users:
await redis_client.delete_prefix(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
async def update_role_rule(*, request: Request, pk: int, rule_ids: UpdateRoleRuleParam) -> int:
async def update_role_rule(*, pk: int, rule_ids: UpdateRoleRuleParam) -> int:
"""
更新角色数据权限
更新角色数据规则
:param request: FastAPI 请求对象
:param pk: 角色 ID
:param rule_ids: 权限规则 ID 列表
:return:
@@ -142,24 +141,27 @@ class RoleService:
for rule_id in rule_ids.rules:
rule = await data_rule_dao.get(db, rule_id)
if not rule:
raise errors.NotFoundError(msg='数据权限不存在')
raise errors.NotFoundError(msg='数据规则不存在')
count = await role_dao.update_rules(db, pk, rule_ids)
if pk in [role.id for role in request.user.roles]:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
async def delete(*, request: Request, pk: list[int]) -> int:
async def delete(*, pk: list[int]) -> int:
"""
删除角色
:param request: FastAPI 请求对象
:param pk: 角色 ID 列表
:return:
"""
async with async_db_session.begin() as db:
count = await role_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
for _pk in pk:
role = await role_dao.get(db, _pk)
if role:
for user in await role.awaitable_attrs.users:
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
+29 -39
View File
@@ -135,25 +135,25 @@ class UserService:
:return:
"""
async with async_db_session.begin() as db:
if not request.user.is_superuser and request.user.username != username:
if request.user.username != username:
raise errors.ForbiddenError(msg='你只能修改自己的信息')
input_user = await user_dao.get_with_relation(db, username=username)
if not input_user:
user = await user_dao.get_with_relation(db, username=username)
if not user:
raise errors.NotFoundError(msg='用户不存在')
if input_user.username != obj.username:
if user.username != obj.username:
_username = await user_dao.get_by_username(db, obj.username)
if _username:
raise errors.ForbiddenError(msg='用户名已注册')
if input_user.nickname != obj.nickname:
if user.nickname != obj.nickname:
nickname = await user_dao.get_by_nickname(db, obj.nickname)
if nickname:
raise errors.ForbiddenError(msg='昵称已注册')
if input_user.email != obj.email:
if user.email != obj.email:
email = await user_dao.check_email(db, obj.email)
if email:
raise errors.ForbiddenError(msg='邮箱已注册')
count = await user_dao.update_userinfo(db, input_user.id, obj)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
count = await user_dao.update_userinfo(db, user.id, obj)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
@@ -168,7 +168,7 @@ class UserService:
"""
async with async_db_session.begin() as db:
if not request.user.is_superuser and request.user.username != username:
raise errors.AuthorizationError
raise errors.ForbiddenError(msg='你只能修改自己的信息')
input_user = await user_dao.get_with_relation(db, username=username)
if not input_user:
raise errors.NotFoundError(msg='用户不存在')
@@ -190,13 +190,13 @@ class UserService:
:return:
"""
async with async_db_session.begin() as db:
if not request.user.is_superuser and request.user.username != username:
if request.user.username != username:
raise errors.AuthorizationError
input_user = await user_dao.get_by_username(db, username)
if not input_user:
user = await user_dao.get_by_username(db, username)
if not user:
raise errors.NotFoundError(msg='用户不存在')
count = await user_dao.update_avatar(db, input_user.id, avatar)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
count = await user_dao.update_avatar(db, user.id, avatar)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
@@ -230,7 +230,7 @@ class UserService:
raise errors.ForbiddenError(msg='非法操作')
super_status = await user_dao.get_super(db, pk)
count = await user_dao.set_super(db, pk, not super_status)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
@@ -251,7 +251,7 @@ class UserService:
raise errors.ForbiddenError(msg='非法操作')
staff_status = await user_dao.get_staff(db, pk)
count = await user_dao.set_staff(db, pk, not staff_status)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
@@ -272,7 +272,7 @@ class UserService:
raise errors.ForbiddenError(msg='非法操作')
status = await user_dao.get_status(db, pk)
count = await user_dao.set_status(db, pk, 0 if status == 1 else 1)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{pk}')
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
return count
@staticmethod
@@ -289,32 +289,22 @@ class UserService:
user = await user_dao.get(db, pk)
if not user:
raise errors.NotFoundError(msg='用户不存在')
user_id = request.user.id
multi_login = await user_dao.get_multi_login(db, pk) if pk != user_id else request.user.is_multi_login
count = await user_dao.set_multi_login(db, pk, not multi_login)
# 删除当前用户缓存
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
multi_login = await user_dao.get_multi_login(db, pk) if pk != user.id else request.user.is_multi_login
new_multi_login = not multi_login
count = await user_dao.set_multi_login(db, pk, new_multi_login)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{user.id}')
token = get_token(request)
token_payload = jwt_decode(token)
latest_multi_login = await user_dao.get_multi_login(db, pk)
# 超级用户修改自身时,除当前 token 外,其他 token 失效
if pk == user_id:
if not latest_multi_login:
key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{pk}'
if pk == user.id:
# 系统管理员修改自身时,除当前 token 外,其他 token 失效
if not new_multi_login:
key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{user.id}'
await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{token_payload.session_uuid}')
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
if refresh_token:
key_prefix = f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}'
await redis_client.delete_prefix(key_prefix, exclude=f'{key_prefix}:{refresh_token}')
# 超级用户修改他人时,其他 token 将全部失效
else:
if not latest_multi_login:
key_prefix = [f'{settings.TOKEN_REDIS_PREFIX}:{pk}']
refresh_token = request.cookies.get(settings.COOKIE_REFRESH_TOKEN_KEY)
if refresh_token:
key_prefix.append(f'{settings.TOKEN_REFRESH_REDIS_PREFIX}:{pk}')
for prefix in key_prefix:
await redis_client.delete_prefix(prefix)
# 系统管理员修改他人时,他人 token 全部失效
if not new_multi_login:
key_prefix = f'{settings.TOKEN_REDIS_PREFIX}:{user.id}'
await redis_client.delete_prefix(key_prefix)
return count
@staticmethod
+2 -2
View File
@@ -47,14 +47,14 @@ class MenuType(IntEnum):
class RoleDataRuleOperatorType(IntEnum):
"""数据权限规则运算符"""
"""数据规则运算符"""
AND = 0
OR = 1
class RoleDataRuleExpressionType(IntEnum):
"""数据权限规则表达式"""
"""数据规则表达式"""
eq = 0 # ==
ne = 1 # !=
+2 -2
View File
@@ -119,7 +119,7 @@ create table sys_data_rule
constraint name
unique (name)
)
comment '数据权限规则表';
comment '数据规则表';
create index ix_sys_data_rule_id
on sys_data_rule (id);
@@ -319,7 +319,7 @@ create table sys_role_data_rule
(
id int auto_increment comment '主键ID',
role_id int not null comment '角色ID',
data_rule_id int not null comment '数据权限规则ID',
data_rule_id int not null comment '数据规则ID',
primary key (id, role_id, data_rule_id),
constraint ix_sys_role_data_rule_id
unique (id),
+2 -2
View File
@@ -13,7 +13,7 @@ create table sys_data_rule
updated_time timestamp with time zone
);
comment on table sys_data_rule is '数据权限规则表';
comment on table sys_data_rule is '数据规则表';
comment on column sys_data_rule.id is '主键 ID';
@@ -609,7 +609,7 @@ comment on column sys_role_data_rule.id is '主键ID';
comment on column sys_role_data_rule.role_id is '角色ID';
comment on column sys_role_data_rule.data_rule_id is '数据权限规则ID';
comment on column sys_role_data_rule.data_rule_id is '数据规则ID';
alter table sys_role_data_rule
owner to postgres;