Simplify data rule and remove type (#468)

* Simplify data rule and remove type

* fix lint

* fix user info cache
This commit is contained in:
Wu Clan
2024-11-27 14:09:57 +08:00
committed by GitHub
parent 1838b63b11
commit 7c4e288fd6
20 changed files with 406 additions and 624 deletions
-2
View File
@@ -6,7 +6,6 @@ from backend.app.admin.api.v1.sys.api import router as api_router
from backend.app.admin.api.v1.sys.casbin import router as casbin_router from backend.app.admin.api.v1.sys.casbin import router as casbin_router
from backend.app.admin.api.v1.sys.config import router as config_router from backend.app.admin.api.v1.sys.config import router as config_router
from backend.app.admin.api.v1.sys.data_rule import router as data_rule_router from backend.app.admin.api.v1.sys.data_rule import router as data_rule_router
from backend.app.admin.api.v1.sys.data_rule_type import router as data_rule_type_router
from backend.app.admin.api.v1.sys.dept import router as dept_router from backend.app.admin.api.v1.sys.dept import router as dept_router
from backend.app.admin.api.v1.sys.dict_data import router as dict_data_router from backend.app.admin.api.v1.sys.dict_data import router as dict_data_router
from backend.app.admin.api.v1.sys.dict_type import router as dict_type_router from backend.app.admin.api.v1.sys.dict_type import router as dict_type_router
@@ -26,4 +25,3 @@ router.include_router(menu_router, prefix='/menus', tags=['系统目录'])
router.include_router(role_router, prefix='/roles', tags=['系统角色']) router.include_router(role_router, prefix='/roles', tags=['系统角色'])
router.include_router(user_router, prefix='/users', 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(data_rule_type_router, prefix='/data-rule-types', tags=['系统数据权限类型'])
+11 -4
View File
@@ -2,7 +2,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends, Path, Query from fastapi import APIRouter, Depends, Path, Query, Request
from backend.app.admin.schema.data_rule import CreateDataRuleParam, GetDataRuleListDetails, UpdateDataRuleParam from backend.app.admin.schema.data_rule import CreateDataRuleParam, GetDataRuleListDetails, UpdateDataRuleParam
from backend.app.admin.service.data_rule_service import data_rule_service from backend.app.admin.service.data_rule_service import data_rule_service
@@ -12,7 +12,7 @@ from backend.common.security.jwt import DependsJwtAuth
from backend.common.security.permission import RequestPermission from backend.common.security.permission import RequestPermission
from backend.common.security.rbac import DependsRBAC from backend.common.security.rbac import DependsRBAC
from backend.database.db_mysql import CurrentSession from backend.database.db_mysql import CurrentSession
from backend.utils.serializers import select_as_dict from backend.utils.serializers import select_as_dict, select_list_serialize
router = APIRouter() router = APIRouter()
@@ -29,6 +29,13 @@ async def get_data_rule_model_columns(model: Annotated[str, Path()]) -> Response
return response_base.success(data=models) return response_base.success(data=models)
@router.get('/all', summary='获取所有数据规则', dependencies=[DependsJwtAuth])
async def get_all_data_rule() -> ResponseModel:
data_rules = await data_rule_service.get_all()
data = select_list_serialize(data_rules)
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(...)]) -> ResponseModel: async def get_data_rule(pk: Annotated[int, Path(...)]) -> ResponseModel:
data_rule = await data_rule_service.get(pk=pk) data_rule = await data_rule_service.get(pk=pk)
@@ -86,8 +93,8 @@ async def update_data_rule(pk: Annotated[int, Path(...)], obj: UpdateDataRulePar
DependsRBAC, DependsRBAC,
], ],
) )
async def delete_data_rule(pk: Annotated[list[int], Query(...)]) -> ResponseModel: async def delete_data_rule(request: Request, pk: Annotated[list[int], Query(...)]) -> ResponseModel:
count = await data_rule_service.delete(pk=pk) count = await data_rule_service.delete(request=request, pk=pk)
if count > 0: if count > 0:
return response_base.success() return response_base.success()
return response_base.fail() return response_base.fail()
@@ -1,85 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Annotated
from fastapi import APIRouter, Depends, Path, Query
from backend.app.admin.schema.data_rule_type import (
CreateDataRuleTypeParam,
GetDataRuleTypeListDetails,
UpdateDataRuleTypeParam,
)
from backend.app.admin.service.data_rule_type_service import data_rule_type_service
from backend.common.pagination import DependsPagination, paging_data
from backend.common.response.response_schema import ResponseModel, response_base
from backend.common.security.jwt import DependsJwtAuth
from backend.common.security.permission import RequestPermission
from backend.common.security.rbac import DependsRBAC
from backend.database.db_mysql import CurrentSession
from backend.utils.serializers import select_as_dict
router = APIRouter()
@router.get('/{pk}', summary='获取数据权限规则类型详情', dependencies=[DependsJwtAuth])
async def get_data_rule_type(pk: Annotated[int, Path(...)]) -> ResponseModel:
data_rule_type = await data_rule_type_service.get(pk=pk)
data = GetDataRuleTypeListDetails(**select_as_dict(data_rule_type))
return response_base.success(data=data)
@router.get(
'',
summary='(模糊条件)分页获取所有数据权限规则类型',
dependencies=[
DependsJwtAuth,
DependsPagination,
],
)
async def get_pagination_data_rule_type(db: CurrentSession) -> ResponseModel:
data_rule_type_select = await data_rule_type_service.get_select()
page_data = await paging_data(db, data_rule_type_select, GetDataRuleTypeListDetails)
return response_base.success(data=page_data)
@router.post(
'',
summary='创建数据权限规则类型',
dependencies=[
Depends(RequestPermission('data:rule:type:add')),
DependsRBAC,
],
)
async def create_data_rule_type(obj: CreateDataRuleTypeParam) -> ResponseModel:
await data_rule_type_service.create(obj=obj)
return response_base.success()
@router.put(
'/{pk}',
summary='更新数据权限规则类型',
dependencies=[
Depends(RequestPermission('data:rule:type:edit')),
DependsRBAC,
],
)
async def update_data_rule_type(pk: Annotated[int, Path(...)], obj: UpdateDataRuleTypeParam) -> ResponseModel:
count = await data_rule_type_service.update(pk=pk, obj=obj)
if count > 0:
return response_base.success()
return response_base.fail()
@router.delete(
'',
summary='(批量)删除数据权限规则类型',
dependencies=[
Depends(RequestPermission('data:rule:type:del')),
DependsRBAC,
],
)
async def delete_data_rule_type(pk: Annotated[list[int], Query(...)]) -> ResponseModel:
count = await data_rule_type_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 -*- # -*- coding: utf-8 -*-
from typing import Annotated from typing import Annotated
from fastapi import APIRouter, Depends, Path, Query from fastapi import APIRouter, Depends, Path, Query, Request
from backend.app.admin.schema.dept import CreateDeptParam, GetDeptListDetails, UpdateDeptParam from backend.app.admin.schema.dept import CreateDeptParam, GetDeptListDetails, UpdateDeptParam
from backend.app.admin.service.dept_service import dept_service from backend.app.admin.service.dept_service import dept_service
@@ -69,8 +69,8 @@ async def update_dept(pk: Annotated[int, Path(...)], obj: UpdateDeptParam) -> Re
DependsRBAC, DependsRBAC,
], ],
) )
async def delete_dept(pk: Annotated[int, Path(...)]) -> ResponseModel: async def delete_dept(request: Request, pk: Annotated[int, Path(...)]) -> ResponseModel:
count = await dept_service.delete(pk=pk) count = await dept_service.delete(request=request, pk=pk)
if count > 0: if count > 0:
return response_base.success() return response_base.success()
return response_base.fail() return response_base.fail()
+2 -2
View File
@@ -72,8 +72,8 @@ async def update_menu(pk: Annotated[int, Path(...)], obj: UpdateMenuParam) -> Re
DependsRBAC, DependsRBAC,
], ],
) )
async def delete_menu(pk: Annotated[int, Path(...)]) -> ResponseModel: async def delete_menu(request: Request, pk: Annotated[int, Path(...)]) -> ResponseModel:
count = await menu_service.delete(pk=pk) count = await menu_service.delete(request=request, pk=pk)
if count > 0: if count > 0:
return response_base.success() return response_base.success()
return response_base.fail() return response_base.fail()
+9 -2
View File
@@ -11,6 +11,7 @@ from backend.app.admin.schema.role import (
UpdateRoleParam, UpdateRoleParam,
UpdateRoleRuleParam, UpdateRoleRuleParam,
) )
from backend.app.admin.service.data_rule_service import data_rule_service
from backend.app.admin.service.menu_service import menu_service from backend.app.admin.service.menu_service import menu_service
from backend.app.admin.service.role_service import role_service from backend.app.admin.service.role_service import role_service
from backend.common.pagination import DependsPagination, paging_data from backend.common.pagination import DependsPagination, paging_data
@@ -44,6 +45,12 @@ async def get_role_all_menus(pk: Annotated[int, Path(...)]) -> ResponseModel:
return response_base.success(data=menu) return response_base.success(data=menu)
@router.get('/{pk}/rules', summary='获取角色所有数据规则', dependencies=[DependsJwtAuth])
async def get_role_all_rules(pk: Annotated[int, Path(...)]) -> ResponseModel:
rule = await data_rule_service.get_role_rules(pk=pk)
return response_base.success(data=rule)
@router.get('/{pk}', summary='获取角色详情', dependencies=[DependsJwtAuth]) @router.get('/{pk}', summary='获取角色详情', dependencies=[DependsJwtAuth])
async def get_role(pk: Annotated[int, Path(...)]) -> ResponseModel: async def get_role(pk: Annotated[int, Path(...)]) -> ResponseModel:
role = await role_service.get(pk=pk) role = await role_service.get(pk=pk)
@@ -140,8 +147,8 @@ async def update_role_rules(
DependsRBAC, DependsRBAC,
], ],
) )
async def delete_role(pk: Annotated[list[int], Query(...)]) -> ResponseModel: async def delete_role(request: Request, pk: Annotated[list[int], Query(...)]) -> ResponseModel:
count = await role_service.delete(pk=pk) count = await role_service.delete(request=request, pk=pk)
if count > 0: if count > 0:
return response_base.success() return response_base.success()
return response_base.fail() return response_base.fail()
@@ -1,83 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy import Select
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy_crud_plus import CRUDPlus
from backend.app.admin.model import DataRuleType
from backend.app.admin.schema.data_rule_type import CreateDataRuleTypeParam, UpdateDataRuleTypeParam
class CRUDDataRuleType(CRUDPlus[DataRuleType]):
async def get(self, db: AsyncSession, pk: int) -> DataRuleType | None:
"""
获取数据权限规则类型
:param db:
:param pk:
:return:
"""
return await self.select_model(db, pk)
async def get_list(self) -> Select:
"""
获取数据权限规则类型列表
:return:
"""
return await self.select_order('created_time', 'desc')
async def get_by_name(self, db: AsyncSession, name: str) -> DataRuleType | None:
"""
通过 name 获取数据权限规则类型
:param db:
:param name:
:return:
"""
return await self.select_model_by_column(db, name=name)
async def get_all(self, db: AsyncSession) -> Sequence[DataRuleType]:
"""
获取所有数据权限规则类型
:param db:
:return:
"""
return await self.select_models(db)
async def create(self, db: AsyncSession, obj_in: CreateDataRuleTypeParam) -> None:
"""
创建数据权限规则类型
:param db:
:param obj_in:
:return:
"""
await self.create_model(db, obj_in)
async def update(self, db: AsyncSession, pk: int, obj_in: UpdateDataRuleTypeParam) -> int:
"""
更新数据权限规则类型
:param db:
:param pk:
:param obj_in:
:return:
"""
return await self.update_model(db, pk, obj_in)
async def delete(self, db: AsyncSession, pk: list[int]) -> int:
"""
删除数据权限规则类型
:param db:
:param pk:
:return:
"""
return await self.delete_model_by_column(db, allow_multiple=True, id__in=pk)
data_rule_type_dao: CRUDDataRuleType = CRUDDataRuleType(DataRuleType)
+5 -1
View File
@@ -72,7 +72,11 @@ class CRUDRole(CRUDPlus[Role]):
:param status: :param status:
:return: :return:
""" """
stmt = select(self.model).options(selectinload(self.model.menus)).order_by(desc(self.model.created_time)) stmt = (
select(self.model)
.options(selectinload(self.model.menus), selectinload(self.model.rules))
.order_by(desc(self.model.created_time))
)
where_list = [] where_list = []
if name: if name:
where_list.append(self.model.name.like(f'%{name}%')) where_list.append(self.model.name.like(f'%{name}%'))
+4 -1
View File
@@ -186,7 +186,10 @@ class CRUDUser(CRUDPlus[User]):
select(self.model) select(self.model)
.options( .options(
selectinload(self.model.dept), selectinload(self.model.dept),
selectinload(self.model.roles).selectinload(Role.menus), selectinload(self.model.roles).options(
selectinload(Role.menus),
selectinload(Role.rules),
),
) )
.order_by(desc(self.model.join_time)) .order_by(desc(self.model.join_time))
) )
-1
View File
@@ -4,7 +4,6 @@ from backend.app.admin.model.api import Api
from backend.app.admin.model.casbin_rule import CasbinRule from backend.app.admin.model.casbin_rule import CasbinRule
from backend.app.admin.model.config import Config from backend.app.admin.model.config import Config
from backend.app.admin.model.data_rule import DataRule from backend.app.admin.model.data_rule import DataRule
from backend.app.admin.model.data_rule_type import DataRuleType
from backend.app.admin.model.dept import Dept from backend.app.admin.model.dept import Dept
from backend.app.admin.model.dict_data import DictData from backend.app.admin.model.dict_data import DictData
from backend.app.admin.model.dict_type import DictType from backend.app.admin.model.dict_type import DictType
+1 -7
View File
@@ -1,6 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from sqlalchemy import ForeignKey, String from sqlalchemy import String
from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.orm import Mapped, mapped_column, relationship
from backend.app.admin.model.m2m import sys_role_data_rule from backend.app.admin.model.m2m import sys_role_data_rule
@@ -22,11 +22,5 @@ class DataRule(Base):
) )
value: Mapped[str] = mapped_column(String(255), comment='规则值') value: Mapped[str] = mapped_column(String(255), comment='规则值')
# 数据权限规则类型一对多
type_id: Mapped[int] = mapped_column(
ForeignKey('sys_data_rule_type.id', ondelete='CASCADE'), comment='数据权限规则类型关联ID'
)
type: Mapped['DataRuleType'] = relationship(init=False, back_populates='rules') # noqa: F821
# 角色规则多对多 # 角色规则多对多
roles: Mapped[list['Role']] = relationship(init=False, secondary=sys_role_data_rule, back_populates='rules') # noqa: F821 roles: Mapped[list['Role']] = relationship(init=False, secondary=sys_role_data_rule, back_populates='rules') # noqa: F821
-21
View File
@@ -1,21 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from sqlalchemy import String
from sqlalchemy.dialects.mysql import LONGTEXT
from sqlalchemy.orm import Mapped, mapped_column, relationship
from backend.common.model import Base, id_key
class DataRuleType(Base):
"""数据权限规则类型表"""
__tablename__ = 'sys_data_rule_type'
id: Mapped[id_key] = mapped_column(init=False)
name: Mapped[str] = mapped_column(String(255), unique=True, comment='规则类型名')
status: Mapped[int] = mapped_column(default=1, comment='状态(0停用 1正常)')
remark: Mapped[str | None] = mapped_column(LONGTEXT, default=None, comment='备注')
# 数据权限规则类型一对多
rules: Mapped[list['DataRule']] = relationship(init=False, back_populates='type') # noqa: F821
-1
View File
@@ -9,7 +9,6 @@ from backend.common.schema import SchemaBase
class DataRuleSchemaBase(SchemaBase): class DataRuleSchemaBase(SchemaBase):
type_id: int
name: str name: str
model: str model: str
column: str column: str
@@ -1,30 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from datetime import datetime
from pydantic import ConfigDict, Field
from backend.common.enums import StatusType
from backend.common.schema import SchemaBase
class DataRuleTypeSchemaBase(SchemaBase):
name: str
status: StatusType = Field(default=StatusType.enable)
remark: str
class CreateDataRuleTypeParam(DataRuleTypeSchemaBase):
pass
class UpdateDataRuleTypeParam(DataRuleTypeSchemaBase):
pass
class GetDataRuleTypeListDetails(DataRuleTypeSchemaBase):
model_config = ConfigDict(from_attributes=True)
id: int
created_time: datetime
updated_time: datetime | None = None
+14 -8
View File
@@ -2,15 +2,17 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from typing import Sequence from typing import Sequence
from fastapi import Request
from sqlalchemy import Select from sqlalchemy import Select
from backend.app.admin.crud.crud_data_rule import data_rule_dao from backend.app.admin.crud.crud_data_rule import data_rule_dao
from backend.app.admin.crud.crud_data_rule_type import data_rule_type_dao from backend.app.admin.crud.crud_role import role_dao
from backend.app.admin.model import DataRule from backend.app.admin.model import DataRule
from backend.app.admin.schema.data_rule import CreateDataRuleParam, UpdateDataRuleParam from backend.app.admin.schema.data_rule import CreateDataRuleParam, UpdateDataRuleParam
from backend.common.exception import errors from backend.common.exception import errors
from backend.core.conf import settings from backend.core.conf import settings
from backend.database.db_mysql import async_db_session from backend.database.db_mysql import async_db_session
from backend.database.db_redis import redis_client
from backend.utils.import_parse import dynamic_import from backend.utils.import_parse import dynamic_import
@@ -23,6 +25,15 @@ class DataRuleService:
raise errors.NotFoundError(msg='数据规则不存在') raise errors.NotFoundError(msg='数据规则不存在')
return data_rule return data_rule
@staticmethod
async def get_role_rules(*, pk: int) -> list[int]:
async with async_db_session() as db:
role = await role_dao.get_with_relation(db, pk)
if not role:
raise errors.NotFoundError(msg='角色不存在')
rule_ids = [rule.id for rule in role.rules]
return rule_ids
@staticmethod @staticmethod
async def get_models() -> list: async def get_models() -> list:
return list(settings.DATA_PERMISSION_MODELS.keys()) return list(settings.DATA_PERMISSION_MODELS.keys())
@@ -53,9 +64,6 @@ class DataRuleService:
data_rule = await data_rule_dao.get_by_name(db, obj.name) data_rule = await data_rule_dao.get_by_name(db, obj.name)
if data_rule: if data_rule:
raise errors.ForbiddenError(msg='数据权限规则已存在') raise errors.ForbiddenError(msg='数据权限规则已存在')
data_rule_type = await data_rule_type_dao.get(db, obj.type_id)
if not data_rule_type:
raise errors.NotFoundError(msg='数据权限规则类型不存在')
await data_rule_dao.create(db, obj) await data_rule_dao.create(db, obj)
@staticmethod @staticmethod
@@ -64,16 +72,14 @@ class DataRuleService:
data_rule = await data_rule_dao.get(db, pk) data_rule = await data_rule_dao.get(db, pk)
if not data_rule: if not data_rule:
raise errors.NotFoundError(msg='数据权限规则不存在') raise errors.NotFoundError(msg='数据权限规则不存在')
data_rule_type = await data_rule_type_dao.get(db, obj.type_id)
if not data_rule_type:
raise errors.NotFoundError(msg='数据权限规则类型不存在')
count = await data_rule_dao.update(db, pk, obj) count = await data_rule_dao.update(db, pk, obj)
return count return count
@staticmethod @staticmethod
async def delete(*, pk: list[int]) -> int: async def delete(*, request: Request, pk: list[int]) -> int:
async with async_db_session.begin() as db: async with async_db_session.begin() as db:
count = await data_rule_dao.delete(db, pk) count = await data_rule_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
return count return count
@@ -1,60 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from typing import Sequence
from sqlalchemy import Select
from backend.app.admin.crud.crud_data_rule_type import data_rule_type_dao
from backend.app.admin.model import DataRuleType
from backend.app.admin.schema.data_rule_type import CreateDataRuleTypeParam, UpdateDataRuleTypeParam
from backend.common.exception import errors
from backend.database.db_mysql import async_db_session
class DataRuleTypeService:
@staticmethod
async def get(*, pk: int) -> DataRuleType:
async with async_db_session() as db:
data_rule_type = await data_rule_type_dao.get(db, pk)
if not data_rule_type:
raise errors.NotFoundError(msg='数据规则类型不存在')
return data_rule_type
@staticmethod
async def get_select() -> Select:
return await data_rule_type_dao.get_list()
@staticmethod
async def get_all() -> Sequence[DataRuleType]:
async with async_db_session() as db:
data_rule_types = await data_rule_type_dao.get_all(db)
return data_rule_types
@staticmethod
async def create(*, obj: CreateDataRuleTypeParam) -> None:
async with async_db_session.begin() as db:
data_rule_type = await data_rule_type_dao.get_by_name(db, obj.name)
if data_rule_type:
raise errors.ForbiddenError(msg='数据权限规则类型已存在')
await data_rule_type_dao.create(db, obj)
@staticmethod
async def update(*, pk: int, obj: UpdateDataRuleTypeParam) -> int:
async with async_db_session.begin() as db:
data_rule_type = await data_rule_type_dao.get(db, pk)
if not data_rule_type:
raise errors.NotFoundError(msg='数据权限规则类型不存在')
if data_rule_type.name != obj.name:
if await data_rule_type_dao.get_by_name(db, obj.name):
raise errors.ForbiddenError(msg='数据权限规则类型已存在')
count = await data_rule_type_dao.update(db, pk, obj)
return count
@staticmethod
async def delete(*, pk: list[int]) -> int:
async with async_db_session.begin() as db:
count = await data_rule_type_dao.delete(db, pk)
return count
data_rule_type_service: DataRuleTypeService = DataRuleTypeService()
+6 -1
View File
@@ -2,11 +2,15 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from typing import Any from typing import Any
from fastapi import Request
from backend.app.admin.crud.crud_dept import dept_dao from backend.app.admin.crud.crud_dept import dept_dao
from backend.app.admin.model import Dept from backend.app.admin.model import Dept
from backend.app.admin.schema.dept import CreateDeptParam, UpdateDeptParam from backend.app.admin.schema.dept import CreateDeptParam, UpdateDeptParam
from backend.common.exception import errors from backend.common.exception import errors
from backend.core.conf import settings
from backend.database.db_mysql import async_db_session from backend.database.db_mysql import async_db_session
from backend.database.db_redis import redis_client
from backend.utils.build_tree import get_tree_data from backend.utils.build_tree import get_tree_data
@@ -59,7 +63,7 @@ class DeptService:
return count return count
@staticmethod @staticmethod
async def delete(*, pk: int) -> int: async def delete(*, request: Request, pk: int) -> int:
async with async_db_session.begin() as db: async with async_db_session.begin() as db:
dept_user = await dept_dao.get_with_relation(db, pk) dept_user = await dept_dao.get_with_relation(db, pk)
if dept_user: if dept_user:
@@ -68,6 +72,7 @@ class DeptService:
if children: if children:
raise errors.ForbiddenError(msg='部门下存在子部门,无法删除') raise errors.ForbiddenError(msg='部门下存在子部门,无法删除')
count = await dept_dao.delete(db, pk) count = await dept_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
return count return count
+4 -1
View File
@@ -9,7 +9,9 @@ from backend.app.admin.crud.crud_role import role_dao
from backend.app.admin.model import Menu from backend.app.admin.model import Menu
from backend.app.admin.schema.menu import CreateMenuParam, UpdateMenuParam from backend.app.admin.schema.menu import CreateMenuParam, UpdateMenuParam
from backend.common.exception import errors from backend.common.exception import errors
from backend.core.conf import settings
from backend.database.db_mysql import async_db_session from backend.database.db_mysql import async_db_session
from backend.database.db_redis import redis_client
from backend.utils.build_tree import get_tree_data from backend.utils.build_tree import get_tree_data
@@ -84,12 +86,13 @@ class MenuService:
return count return count
@staticmethod @staticmethod
async def delete(*, pk: int) -> int: async def delete(*, request: Request, pk: int) -> int:
async with async_db_session.begin() as db: async with async_db_session.begin() as db:
children = await menu_dao.get_children(db, pk) children = await menu_dao.get_children(db, pk)
if children: if children:
raise errors.ForbiddenError(msg='菜单下存在子菜单,无法删除') raise errors.ForbiddenError(msg='菜单下存在子菜单,无法删除')
count = await menu_dao.delete(db, pk) count = await menu_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
return count return count
+2 -1
View File
@@ -98,9 +98,10 @@ class RoleService:
return count return count
@staticmethod @staticmethod
async def delete(*, pk: list[int]) -> int: async def delete(*, request: Request, pk: list[int]) -> int:
async with async_db_session.begin() as db: async with async_db_session.begin() as db:
count = await role_dao.delete(db, pk) count = await role_dao.delete(db, pk)
await redis_client.delete(f'{settings.JWT_USER_REDIS_PREFIX}:{request.user.id}')
return count return count
+345 -310
View File
@@ -5,400 +5,435 @@ SET FOREIGN_KEY_CHECKS = 0;
-- Table structure for sys_api -- Table structure for sys_api
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_api`; DROP TABLE IF EXISTS `sys_api`;
CREATE TABLE `sys_api` ( CREATE TABLE `sys_api`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(50) NOT NULL COMMENT 'api名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`method` varchar(16) NOT NULL COMMENT '请求方法', `name` varchar(50) NOT NULL COMMENT 'api名称',
`path` varchar(500) NOT NULL COMMENT 'api路径', `method` varchar(16) NOT NULL COMMENT '请求方法',
`remark` longtext COMMENT '备注', `path` varchar(500) NOT NULL COMMENT 'api路径',
`created_time` datetime NOT NULL COMMENT '创建时间', `remark` longtext COMMENT '备注',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `name` (`name`), PRIMARY KEY (`id`),
KEY `ix_sys_api_id` (`id`) UNIQUE KEY `name` (`name`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_api_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_casbin_rule -- Table structure for sys_casbin_rule
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_casbin_rule`; DROP TABLE IF EXISTS `sys_casbin_rule`;
CREATE TABLE `sys_casbin_rule` ( CREATE TABLE `sys_casbin_rule`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`ptype` varchar(255) NOT NULL COMMENT '策略类型: p / g', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`v0` varchar(255) NOT NULL COMMENT '角色ID / 用户uuid', `ptype` varchar(255) NOT NULL COMMENT '策略类型: p / g',
`v1` longtext NOT NULL COMMENT 'api路径 / 角色名称', `v0` varchar(255) NOT NULL COMMENT '角色ID / 用户uuid',
`v2` varchar(255) DEFAULT NULL COMMENT '请求方法', `v1` longtext NOT NULL COMMENT 'api路径 / 角色名称',
`v3` varchar(255) DEFAULT NULL, `v2` varchar(255) DEFAULT NULL COMMENT '请求方法',
`v4` varchar(255) DEFAULT NULL, `v3` varchar(255) DEFAULT NULL,
`v5` varchar(255) DEFAULT NULL, `v4` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`), `v5` varchar(255) DEFAULT NULL,
KEY `ix_sys_casbin_rule_id` (`id`) PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_casbin_rule_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_config -- Table structure for sys_config
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_config`; DROP TABLE IF EXISTS `sys_config`;
CREATE TABLE `sys_config` ( CREATE TABLE `sys_config`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(20) NOT NULL COMMENT '名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`type` varchar(20) DEFAULT NULL COMMENT '类型', `name` varchar(20) NOT NULL COMMENT '名称',
`key` varchar(50) NOT NULL COMMENT '键名', `type` varchar(20) DEFAULT NULL COMMENT '类型',
`value` longtext NOT NULL COMMENT '', `key` varchar(50) NOT NULL COMMENT '',
`is_frontend` tinyint(1) NOT NULL COMMENT '是否前端', `value` longtext NOT NULL COMMENT '键值',
`remark` longtext COMMENT '备注', `is_frontend` tinyint(1) NOT NULL COMMENT '是否前端',
`created_time` datetime NOT NULL COMMENT '创建时间', `remark` longtext COMMENT '备注',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `key` (`key`), PRIMARY KEY (`id`),
KEY `ix_sys_config_id` (`id`) UNIQUE KEY `key` (`key`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_config_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_data_rule -- Table structure for sys_data_rule
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_data_rule`; DROP TABLE IF EXISTS `sys_data_rule`;
CREATE TABLE `sys_data_rule` ( CREATE TABLE `sys_data_rule`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(255) NOT NULL COMMENT '规则名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`model` varchar(50) NOT NULL COMMENT 'SQLA 模型类', `name` varchar(255) NOT NULL COMMENT '规则名称',
`column` varchar(20) NOT NULL COMMENT '数据库字段', `model` varchar(50) NOT NULL COMMENT 'SQLA 模型类',
`operator` int NOT NULL COMMENT '运算符(0and、1or', `column` varchar(20) NOT NULL COMMENT '数据库字段',
`expression` int NOT NULL COMMENT '表达式(0>、1>=、2<、3<=、4==、5!=、6in、7not_in', `operator` int NOT NULL COMMENT '运算符(0and、1or',
`value` varchar(255) NOT NULL COMMENT '规则值', `expression` int NOT NULL COMMENT '表达式(0>、1>=、2<、3<=、4==、5!=、6in、7not_in',
`type_id` int NOT NULL COMMENT '数据权限规则类型关联ID', `value` varchar(255) NOT NULL COMMENT '规则值',
`created_time` datetime NOT NULL COMMENT '创建时间', `created_time` datetime NOT NULL COMMENT '创建时间',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`), UNIQUE KEY `name` (`name`),
KEY `type_id` (`type_id`), KEY `ix_sys_data_rule_id` (`id`)
KEY `ix_sys_data_rule_id` (`id`), ) ENGINE = InnoDB
CONSTRAINT `sys_data_rule_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `sys_data_rule_type` (`id`) ON DELETE CASCADE DEFAULT CHARSET = utf8mb4
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; COLLATE = utf8mb4_0900_ai_ci;
-- ----------------------------
-- Table structure for sys_data_rule_type
-- ----------------------------
DROP TABLE IF EXISTS `sys_data_rule_type`;
CREATE TABLE `sys_data_rule_type` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`name` varchar(255) NOT NULL COMMENT '规则类型名',
`status` int NOT NULL COMMENT '状态(0停用 1正常)',
`remark` longtext COMMENT '备注',
`created_time` datetime NOT NULL COMMENT '创建时间',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`),
KEY `ix_sys_data_rule_type_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_dept -- Table structure for sys_dept
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_dept`; DROP TABLE IF EXISTS `sys_dept`;
CREATE TABLE `sys_dept` ( CREATE TABLE `sys_dept`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(50) NOT NULL COMMENT '部门名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`level` int NOT NULL COMMENT '部门层级', `name` varchar(50) NOT NULL COMMENT '部门名称',
`sort` int NOT NULL COMMENT '排序', `level` int NOT NULL COMMENT '部门层级',
`leader` varchar(20) DEFAULT NULL COMMENT '负责人', `sort` int NOT NULL COMMENT '排序',
`phone` varchar(11) DEFAULT NULL COMMENT '手机', `leader` varchar(20) DEFAULT NULL COMMENT '负责人',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱', `phone` varchar(11) DEFAULT NULL COMMENT '手机',
`status` int NOT NULL COMMENT '部门状态(0停用 1正常)', `email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`del_flag` tinyint(1) NOT NULL COMMENT '删除标志(0删除 1存在)', `status` int NOT NULL COMMENT '部门状态(0停用 1正常)',
`parent_id` int DEFAULT NULL COMMENT '父部门ID', `del_flag` tinyint(1) NOT NULL COMMENT '删除标志(0删除 1存在)',
`created_time` datetime NOT NULL COMMENT '创建时间', `parent_id` int DEFAULT NULL COMMENT '父部门ID',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
KEY `ix_sys_dept_parent_id` (`parent_id`), PRIMARY KEY (`id`),
KEY `ix_sys_dept_id` (`id`), KEY `ix_sys_dept_parent_id` (`parent_id`),
CONSTRAINT `sys_dept_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `sys_dept` (`id`) ON DELETE SET NULL KEY `ix_sys_dept_id` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_dept_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `sys_dept` (`id`) ON DELETE SET NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_dict_data -- Table structure for sys_dict_data
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_dict_data`; DROP TABLE IF EXISTS `sys_dict_data`;
CREATE TABLE `sys_dict_data` ( CREATE TABLE `sys_dict_data`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`label` varchar(32) NOT NULL COMMENT '字典标签', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`value` varchar(32) NOT NULL COMMENT '字典', `label` varchar(32) NOT NULL COMMENT '字典标签',
`sort` int NOT NULL COMMENT '排序', `value` varchar(32) NOT NULL COMMENT '字典值',
`status` int NOT NULL COMMENT '状态(0停用 1正常)', `sort` int NOT NULL COMMENT '排序',
`remark` longtext COMMENT '备注', `status` int NOT NULL COMMENT '状态(0停用 1正常)',
`type_id` int NOT NULL COMMENT '字典类型关联ID', `remark` longtext COMMENT '备注',
`created_time` datetime NOT NULL COMMENT '创建时间', `type_id` int NOT NULL COMMENT '字典类型关联ID',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `label` (`label`), PRIMARY KEY (`id`),
UNIQUE KEY `value` (`value`), UNIQUE KEY `label` (`label`),
KEY `type_id` (`type_id`), UNIQUE KEY `value` (`value`),
KEY `ix_sys_dict_data_id` (`id`), KEY `type_id` (`type_id`),
CONSTRAINT `sys_dict_data_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `sys_dict_type` (`id`) ON DELETE CASCADE KEY `ix_sys_dict_data_id` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_dict_data_ibfk_1` FOREIGN KEY (`type_id`) REFERENCES `sys_dict_type` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_dict_type -- Table structure for sys_dict_type
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_dict_type`; DROP TABLE IF EXISTS `sys_dict_type`;
CREATE TABLE `sys_dict_type` ( CREATE TABLE `sys_dict_type`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(32) NOT NULL COMMENT '字典类型名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`code` varchar(32) NOT NULL COMMENT '字典类型编码', `name` varchar(32) NOT NULL COMMENT '字典类型名称',
`status` int NOT NULL COMMENT '状态(0停用 1正常)', `code` varchar(32) NOT NULL COMMENT '字典类型编码',
`remark` longtext COMMENT '备注', `status` int NOT NULL COMMENT '状态(0停用 1正常)',
`created_time` datetime NOT NULL COMMENT '创建时间', `remark` longtext COMMENT '备注',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `name` (`name`), PRIMARY KEY (`id`),
UNIQUE KEY `code` (`code`), UNIQUE KEY `name` (`name`),
KEY `ix_sys_dict_type_id` (`id`) UNIQUE KEY `code` (`code`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_dict_type_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_gen_business -- Table structure for sys_gen_business
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_gen_business`; DROP TABLE IF EXISTS `sys_gen_business`;
CREATE TABLE `sys_gen_business` ( CREATE TABLE `sys_gen_business`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`app_name` varchar(50) NOT NULL COMMENT '应用名称(英文)', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`table_name_en` varchar(255) NOT NULL COMMENT '名称(英文)', `app_name` varchar(50) NOT NULL COMMENT '应用名称(英文)',
`table_name_zh` varchar(255) NOT NULL COMMENT '表名称(文)', `table_name_en` varchar(255) NOT NULL COMMENT '表名称(文)',
`table_simple_name_zh` varchar(255) NOT NULL COMMENT '表名称(中文简称', `table_name_zh` varchar(255) NOT NULL COMMENT '表名称(中文)',
`table_comment` varchar(255) DEFAULT NULL COMMENT '描述', `table_simple_name_zh` varchar(255) NOT NULL COMMENT '名称(中文简称)',
`schema_name` varchar(255) DEFAULT NULL COMMENT 'Schema 名称 (默认为英文表名称)', `table_comment` varchar(255) DEFAULT NULL COMMENT '表描述',
`default_datetime_column` tinyint(1) NOT NULL COMMENT '是否存在默认时间列', `schema_name` varchar(255) DEFAULT NULL COMMENT 'Schema 名称 (默认为英文表名称)',
`api_version` varchar(20) NOT NULL COMMENT '代码生成 api 版本,默认为 v1', `default_datetime_column` tinyint(1) NOT NULL COMMENT '是否存在默认时间列',
`gen_path` varchar(255) DEFAULT NULL COMMENT '代码生成路径(默认为 app 根路径)', `api_version` varchar(20) NOT NULL COMMENT '代码生成 api 版本,默认为 v1',
`remark` longtext COMMENT '备注', `gen_path` varchar(255) DEFAULT NULL COMMENT '代码生成路径(默认为 app 根路径)',
`created_time` datetime NOT NULL COMMENT '创建时间', `remark` longtext COMMENT '备注',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `table_name_en` (`table_name_en`), PRIMARY KEY (`id`),
KEY `ix_sys_gen_business_id` (`id`) UNIQUE KEY `table_name_en` (`table_name_en`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_gen_business_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_gen_model -- Table structure for sys_gen_model
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_gen_model`; DROP TABLE IF EXISTS `sys_gen_model`;
CREATE TABLE `sys_gen_model` ( CREATE TABLE `sys_gen_model`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(50) NOT NULL COMMENT '列名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`comment` varchar(255) DEFAULT NULL COMMENT '描述', `name` varchar(50) NOT NULL COMMENT '名称',
`type` varchar(20) NOT NULL COMMENT 'SQLA 模型列类型', `comment` varchar(255) DEFAULT NULL COMMENT '列描述',
`pd_type` varchar(20) NOT NULL COMMENT '列类型对应的 pydantic 类型', `type` varchar(20) NOT NULL COMMENT 'SQLA 模型列类型',
`default` longtext COMMENT '列默认值', `pd_type` varchar(20) NOT NULL COMMENT '列类型对应的 pydantic 类型',
`sort` int DEFAULT NULL COMMENT '排序', `default` longtext COMMENT '默认值',
`length` int NOT NULL COMMENT '长度', `sort` int DEFAULT NULL COMMENT '排序',
`is_pk` tinyint(1) NOT NULL COMMENT '是否主键', `length` int NOT NULL COMMENT '列长度',
`is_nullable` tinyint(1) NOT NULL COMMENT '是否可为空', `is_pk` tinyint(1) NOT NULL COMMENT '是否主键',
`gen_business_id` int NOT NULL COMMENT '代码生成业务ID', `is_nullable` tinyint(1) NOT NULL COMMENT '是否可为空',
PRIMARY KEY (`id`), `gen_business_id` int NOT NULL COMMENT '代码生成业务ID',
KEY `gen_business_id` (`gen_business_id`), PRIMARY KEY (`id`),
KEY `ix_sys_gen_model_id` (`id`), KEY `gen_business_id` (`gen_business_id`),
CONSTRAINT `sys_gen_model_ibfk_1` FOREIGN KEY (`gen_business_id`) REFERENCES `sys_gen_business` (`id`) ON DELETE CASCADE KEY `ix_sys_gen_model_id` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_gen_model_ibfk_1` FOREIGN KEY (`gen_business_id`) REFERENCES `sys_gen_business` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_login_log -- Table structure for sys_login_log
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_login_log`; DROP TABLE IF EXISTS `sys_login_log`;
CREATE TABLE `sys_login_log` ( CREATE TABLE `sys_login_log`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`user_uuid` varchar(50) NOT NULL COMMENT '用户UUID', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar(20) NOT NULL COMMENT '用户', `user_uuid` varchar(50) NOT NULL COMMENT '用户UUID',
`status` int NOT NULL COMMENT '登录状态(0失败 1成功)', `username` varchar(20) NOT NULL COMMENT '用户名',
`ip` varchar(50) NOT NULL COMMENT '登录IP地址', `status` int NOT NULL COMMENT '登录状态(0失败 1成功)',
`country` varchar(50) DEFAULT NULL COMMENT '国家', `ip` varchar(50) NOT NULL COMMENT '登录IP地址',
`region` varchar(50) DEFAULT NULL COMMENT '地区', `country` varchar(50) DEFAULT NULL COMMENT '国家',
`city` varchar(50) DEFAULT NULL COMMENT '城市', `region` varchar(50) DEFAULT NULL COMMENT '地区',
`user_agent` varchar(255) NOT NULL COMMENT '请求头', `city` varchar(50) DEFAULT NULL COMMENT '城市',
`os` varchar(50) DEFAULT NULL COMMENT '操作系统', `user_agent` varchar(255) NOT NULL COMMENT '请求头',
`browser` varchar(50) DEFAULT NULL COMMENT '浏览器', `os` varchar(50) DEFAULT NULL COMMENT '操作系统',
`device` varchar(50) DEFAULT NULL COMMENT '设备', `browser` varchar(50) DEFAULT NULL COMMENT '浏览器',
`msg` longtext NOT NULL COMMENT '提示消息', `device` varchar(50) DEFAULT NULL COMMENT '设备',
`login_time` datetime NOT NULL COMMENT '登录时间', `msg` longtext NOT NULL COMMENT '提示消息',
`created_time` datetime NOT NULL COMMENT '创建时间', `login_time` datetime NOT NULL COMMENT '登录时间',
PRIMARY KEY (`id`), `created_time` datetime NOT NULL COMMENT '创建时间',
KEY `ix_sys_login_log_id` (`id`) PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_login_log_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_menu -- Table structure for sys_menu
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_menu`; DROP TABLE IF EXISTS `sys_menu`;
CREATE TABLE `sys_menu` ( CREATE TABLE `sys_menu`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`title` varchar(50) NOT NULL COMMENT '菜单标题', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`name` varchar(50) NOT NULL COMMENT '菜单名称', `title` varchar(50) NOT NULL COMMENT '菜单标题',
`level` int NOT NULL COMMENT '菜单层级', `name` varchar(50) NOT NULL COMMENT '菜单名称',
`sort` int NOT NULL COMMENT '排序', `level` int NOT NULL COMMENT '菜单层级',
`icon` varchar(100) DEFAULT NULL COMMENT '菜单图标', `sort` int NOT NULL COMMENT '排序',
`path` varchar(200) DEFAULT NULL COMMENT '路由地址', `icon` varchar(100) DEFAULT NULL COMMENT '菜单图标',
`menu_type` int NOT NULL COMMENT '菜单类型(0目录 1菜单 2按钮)', `path` varchar(200) DEFAULT NULL COMMENT '路由地址',
`component` varchar(255) DEFAULT NULL COMMENT '组件路径', `menu_type` int NOT NULL COMMENT '菜单类型(0目录 1菜单 2按钮)',
`perms` varchar(100) DEFAULT NULL COMMENT '权限标识', `component` varchar(255) DEFAULT NULL COMMENT '组件路径',
`status` int NOT NULL COMMENT '菜单状态(0停用 1正常)', `perms` varchar(100) DEFAULT NULL COMMENT '权限标识',
`show` int NOT NULL COMMENT '是否显示(0否 1是', `status` int NOT NULL COMMENT '菜单状态(0停用 1正常',
`cache` int NOT NULL COMMENT '是否缓存0否 1是)', `show` int NOT NULL COMMENT '是否显示0否 1是)',
`remark` longtext COMMENT '备注', `cache` int NOT NULL COMMENT '是否缓存(0否 1是)',
`parent_id` int DEFAULT NULL COMMENT '父菜单ID', `remark` longtext COMMENT '备注',
`created_time` datetime NOT NULL COMMENT '创建时间', `parent_id` int DEFAULT NULL COMMENT '父菜单ID',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
KEY `ix_sys_menu_parent_id` (`parent_id`), PRIMARY KEY (`id`),
KEY `ix_sys_menu_id` (`id`), KEY `ix_sys_menu_id` (`id`),
CONSTRAINT `sys_menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `sys_menu` (`id`) ON DELETE SET NULL KEY `ix_sys_menu_parent_id` (`parent_id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_menu_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `sys_menu` (`id`) ON DELETE SET NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_opera_log -- Table structure for sys_opera_log
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_opera_log`; DROP TABLE IF EXISTS `sys_opera_log`;
CREATE TABLE `sys_opera_log` ( CREATE TABLE `sys_opera_log`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`trace_id` varchar(32) NOT NULL COMMENT '请求跟踪 ID', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar(20) DEFAULT NULL COMMENT '用户名', `trace_id` varchar(32) NOT NULL COMMENT '请求跟踪 ID',
`method` varchar(20) NOT NULL COMMENT '请求类型', `username` varchar(20) DEFAULT NULL COMMENT '用户名',
`title` varchar(255) NOT NULL COMMENT '操作模块', `method` varchar(20) NOT NULL COMMENT '请求类型',
`path` varchar(500) NOT NULL COMMENT '请求路径', `title` varchar(255) NOT NULL COMMENT '操作模块',
`ip` varchar(50) NOT NULL COMMENT 'IP地址', `path` varchar(500) NOT NULL COMMENT '请求路径',
`country` varchar(50) DEFAULT NULL COMMENT '国家', `ip` varchar(50) NOT NULL COMMENT 'IP地址',
`region` varchar(50) DEFAULT NULL COMMENT '地区', `country` varchar(50) DEFAULT NULL COMMENT '国家',
`city` varchar(50) DEFAULT NULL COMMENT '城市', `region` varchar(50) DEFAULT NULL COMMENT '地区',
`user_agent` varchar(255) NOT NULL COMMENT '请求头', `city` varchar(50) DEFAULT NULL COMMENT '城市',
`os` varchar(50) DEFAULT NULL COMMENT '操作系统', `user_agent` varchar(255) NOT NULL COMMENT '请求头',
`browser` varchar(50) DEFAULT NULL COMMENT '浏览器', `os` varchar(50) DEFAULT NULL COMMENT '操作系统',
`device` varchar(50) DEFAULT NULL COMMENT '设备', `browser` varchar(50) DEFAULT NULL COMMENT '浏览器',
`args` json DEFAULT NULL COMMENT '请求参数', `device` varchar(50) DEFAULT NULL COMMENT '设备',
`status` int NOT NULL COMMENT '操作状态(0异常 1正常)', `args` json DEFAULT NULL COMMENT '请求参数',
`code` varchar(20) NOT NULL COMMENT '操作状态', `status` int NOT NULL COMMENT '操作状态0异常 1正常)',
`msg` longtext COMMENT '提示消息', `code` varchar(20) NOT NULL COMMENT '操作状态码',
`cost_time` float NOT NULL COMMENT '请求耗时(ms', `msg` longtext COMMENT '提示消息',
`opera_time` datetime NOT NULL COMMENT '操作时间', `cost_time` float NOT NULL COMMENT '请求耗时(ms',
`created_time` datetime NOT NULL COMMENT '创建时间', `opera_time` datetime NOT NULL COMMENT '操作时间',
PRIMARY KEY (`id`), `created_time` datetime NOT NULL COMMENT '创建时间',
KEY `ix_sys_opera_log_id` (`id`) PRIMARY KEY (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_opera_log_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_role -- Table structure for sys_role
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_role`; DROP TABLE IF EXISTS `sys_role`;
CREATE TABLE `sys_role` ( CREATE TABLE `sys_role`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`name` varchar(20) NOT NULL COMMENT '角色名称', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`data_scope` int DEFAULT NULL COMMENT '数据权限范围(0: 全部数据,1: 自定义数据,2: 所在部门及以下数据,3: 所在部门数据,4: 仅本人数据)', `name` varchar(20) NOT NULL COMMENT '角色名称',
`status` int NOT NULL COMMENT '角色状态(0停用 1正常', `data_scope` int DEFAULT NULL COMMENT '数据权限范围(0: 全部数据,1: 自定义数据,2: 所在部门及以下数据,3: 所在部门数据,4: 仅本人数据',
`remark` longtext COMMENT '备注', `status` int NOT NULL COMMENT '角色状态(0停用 1正常)',
`created_time` datetime NOT NULL COMMENT '创建时间', `remark` longtext COMMENT '备注',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `name` (`name`), PRIMARY KEY (`id`),
KEY `ix_sys_role_id` (`id`) UNIQUE KEY `name` (`name`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; KEY `ix_sys_role_id` (`id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_role_data_rule -- Table structure for sys_role_data_rule
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_role_data_rule`; DROP TABLE IF EXISTS `sys_role_data_rule`;
CREATE TABLE `sys_role_data_rule` ( CREATE TABLE `sys_role_data_rule`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', (
`role_id` int NOT NULL COMMENT '角色ID', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`data_rule_id` int NOT NULL COMMENT '数据权限规则ID', `role_id` int NOT NULL COMMENT '角色ID',
PRIMARY KEY (`id`,`role_id`,`data_rule_id`), `data_rule_id` int NOT NULL COMMENT '数据权限规则ID',
UNIQUE KEY `ix_sys_role_data_rule_id` (`id`), PRIMARY KEY (`id`, `role_id`, `data_rule_id`),
KEY `role_id` (`role_id`), UNIQUE KEY `ix_sys_role_data_rule_id` (`id`),
KEY `data_rule_id` (`data_rule_id`), KEY `role_id` (`role_id`),
CONSTRAINT `sys_role_data_rule_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE, KEY `data_rule_id` (`data_rule_id`),
CONSTRAINT `sys_role_data_rule_ibfk_2` FOREIGN KEY (`data_rule_id`) REFERENCES `sys_data_rule` (`id`) ON DELETE CASCADE CONSTRAINT `sys_role_data_rule_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_role_data_rule_ibfk_2` FOREIGN KEY (`data_rule_id`) REFERENCES `sys_data_rule` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_role_menu -- Table structure for sys_role_menu
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_role_menu`; DROP TABLE IF EXISTS `sys_role_menu`;
CREATE TABLE `sys_role_menu` ( CREATE TABLE `sys_role_menu`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', (
`role_id` int NOT NULL COMMENT '角色ID', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`menu_id` int NOT NULL COMMENT '菜单ID', `role_id` int NOT NULL COMMENT '角色ID',
PRIMARY KEY (`id`,`role_id`,`menu_id`), `menu_id` int NOT NULL COMMENT '菜单ID',
UNIQUE KEY `ix_sys_role_menu_id` (`id`), PRIMARY KEY (`id`, `role_id`, `menu_id`),
KEY `role_id` (`role_id`), UNIQUE KEY `ix_sys_role_menu_id` (`id`),
KEY `menu_id` (`menu_id`), KEY `role_id` (`role_id`),
CONSTRAINT `sys_role_menu_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE, KEY `menu_id` (`menu_id`),
CONSTRAINT `sys_role_menu_ibfk_2` FOREIGN KEY (`menu_id`) REFERENCES `sys_menu` (`id`) ON DELETE CASCADE CONSTRAINT `sys_role_menu_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_role_menu_ibfk_2` FOREIGN KEY (`menu_id`) REFERENCES `sys_menu` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_user -- Table structure for sys_user
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_user`; DROP TABLE IF EXISTS `sys_user`;
CREATE TABLE `sys_user` ( CREATE TABLE `sys_user`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`uuid` varchar(50) NOT NULL, `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`username` varchar(20) NOT NULL COMMENT '用户名', `uuid` varchar(50) NOT NULL,
`nickname` varchar(20) NOT NULL COMMENT '昵称', `username` varchar(20) NOT NULL COMMENT '用户名',
`password` varchar(255) DEFAULT NULL COMMENT '密码', `nickname` varchar(20) NOT NULL COMMENT '昵称',
`salt` varbinary(255) DEFAULT NULL COMMENT '加密盐', `password` varchar(255) DEFAULT NULL COMMENT '密码',
`email` varchar(50) NOT NULL COMMENT '邮箱', `salt` varbinary(255) DEFAULT NULL COMMENT '加密盐',
`is_superuser` tinyint(1) NOT NULL COMMENT '超级权限(0否 1是)', `email` varchar(50) NOT NULL COMMENT '邮箱',
`is_staff` tinyint(1) NOT NULL COMMENT '后台管理登陆(0否 1是)', `is_superuser` tinyint(1) NOT NULL COMMENT '超级权限(0否 1是)',
`status` int NOT NULL COMMENT '用户账号状态(0停用 1正常)', `is_staff` tinyint(1) NOT NULL COMMENT '后台管理登陆(0否 1是)',
`is_multi_login` tinyint(1) NOT NULL COMMENT '是否重复登陆(0否 1是)', `status` int NOT NULL COMMENT '用户账号状态(0停用 1正常)',
`avatar` varchar(255) DEFAULT NULL COMMENT '头像', `is_multi_login` tinyint(1) NOT NULL COMMENT '是否重复登陆(0否 1是)',
`phone` varchar(11) DEFAULT NULL COMMENT '手机号', `avatar` varchar(255) DEFAULT NULL COMMENT '头像',
`join_time` datetime NOT NULL COMMENT '注册时间', `phone` varchar(11) DEFAULT NULL COMMENT '手机号',
`last_login_time` datetime DEFAULT NULL COMMENT '上次登录', `join_time` datetime NOT NULL COMMENT '注册时间',
`dept_id` int DEFAULT NULL COMMENT '部门关联ID', `last_login_time` datetime DEFAULT NULL COMMENT '上次登录',
`created_time` datetime NOT NULL COMMENT '创建时间', `dept_id` int DEFAULT NULL COMMENT '部门关联ID',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
UNIQUE KEY `uuid` (`uuid`), PRIMARY KEY (`id`),
UNIQUE KEY `nickname` (`nickname`), UNIQUE KEY `uuid` (`uuid`),
UNIQUE KEY `ix_sys_user_username` (`username`), UNIQUE KEY `nickname` (`nickname`),
UNIQUE KEY `ix_sys_user_email` (`email`), UNIQUE KEY `ix_sys_user_username` (`username`),
KEY `dept_id` (`dept_id`), UNIQUE KEY `ix_sys_user_email` (`email`),
KEY `ix_sys_user_id` (`id`), KEY `dept_id` (`dept_id`),
CONSTRAINT `sys_user_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `sys_dept` (`id`) ON DELETE SET NULL KEY `ix_sys_user_id` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_user_ibfk_1` FOREIGN KEY (`dept_id`) REFERENCES `sys_dept` (`id`) ON DELETE SET NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_user_role -- Table structure for sys_user_role
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_user_role`; DROP TABLE IF EXISTS `sys_user_role`;
CREATE TABLE `sys_user_role` ( CREATE TABLE `sys_user_role`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID', (
`user_id` int NOT NULL COMMENT '用户ID', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`role_id` int NOT NULL COMMENT '角色ID', `user_id` int NOT NULL COMMENT '用户ID',
PRIMARY KEY (`id`,`user_id`,`role_id`), `role_id` int NOT NULL COMMENT '角色ID',
UNIQUE KEY `ix_sys_user_role_id` (`id`), PRIMARY KEY (`id`, `user_id`, `role_id`),
KEY `user_id` (`user_id`), UNIQUE KEY `ix_sys_user_role_id` (`id`),
KEY `role_id` (`role_id`), KEY `user_id` (`user_id`),
CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE CASCADE, KEY `role_id` (`role_id`),
CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE CONSTRAINT `sys_user_role_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_user_role_ibfk_2` FOREIGN KEY (`role_id`) REFERENCES `sys_role` (`id`) ON DELETE CASCADE
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
-- ---------------------------- -- ----------------------------
-- Table structure for sys_user_social -- Table structure for sys_user_social
-- ---------------------------- -- ----------------------------
DROP TABLE IF EXISTS `sys_user_social`; DROP TABLE IF EXISTS `sys_user_social`;
CREATE TABLE `sys_user_social` ( CREATE TABLE `sys_user_social`
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键id', (
`source` varchar(20) NOT NULL COMMENT '第三方用户来源', `id` int NOT NULL AUTO_INCREMENT COMMENT '主键id',
`open_id` varchar(20) DEFAULT NULL COMMENT '第三方用户的 open id', `source` varchar(20) NOT NULL COMMENT '第三方用户来源',
`uid` varchar(20) DEFAULT NULL COMMENT '第三方用户的 ID', `open_id` varchar(20) DEFAULT NULL COMMENT '第三方用户的 open id',
`union_id` varchar(20) DEFAULT NULL COMMENT '第三方用户的 union id', `uid` varchar(20) DEFAULT NULL COMMENT '第三方用户的 ID',
`scope` varchar(120) DEFAULT NULL COMMENT '第三方用户授予的权限', `union_id` varchar(20) DEFAULT NULL COMMENT '第三方用户的 union id',
`code` varchar(50) DEFAULT NULL COMMENT '用户的授权 code', `scope` varchar(120) DEFAULT NULL COMMENT '第三方用户授予的权限',
`user_id` int DEFAULT NULL COMMENT '用户关联ID', `code` varchar(50) DEFAULT NULL COMMENT '用户的授权 code',
`created_time` datetime NOT NULL COMMENT '创建时间', `user_id` int DEFAULT NULL COMMENT '用户关联ID',
`updated_time` datetime DEFAULT NULL COMMENT '更新时间', `created_time` datetime NOT NULL COMMENT '创建时间',
PRIMARY KEY (`id`), `updated_time` datetime DEFAULT NULL COMMENT '更新时间',
KEY `user_id` (`user_id`), PRIMARY KEY (`id`),
KEY `ix_sys_user_social_id` (`id`), KEY `user_id` (`user_id`),
CONSTRAINT `sys_user_social_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE SET NULL KEY `ix_sys_user_social_id` (`id`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; CONSTRAINT `sys_user_social_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `sys_user` (`id`) ON DELETE SET NULL
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci;
SET FOREIGN_KEY_CHECKS = 1; SET FOREIGN_KEY_CHECKS = 1;