diff --git a/backend/app/admin/crud/crud_user.py b/backend/app/admin/crud/crud_user.py index df2bac28..f7af5135 100644 --- a/backend/app/admin/crud/crud_user.py +++ b/backend/app/admin/crud/crud_user.py @@ -150,7 +150,6 @@ class CRUDUser(CRUDPlus[User]): dict_obj = obj.model_dump(exclude={'roles'}) dict_obj.update({'salt': salt}) - dict_obj = inject_tenant_dict(dict_obj) new_user = self.model(**dict_obj) db.add(new_user) @@ -179,7 +178,6 @@ class CRUDUser(CRUDPlus[User]): """ dict_obj = obj.model_dump() dict_obj.update({'is_staff': True, 'salt': None}) - dict_obj = inject_tenant_dict(dict_obj) new_user = self.model(**dict_obj) db.add(new_user) diff --git a/backend/app/admin/model/dept.py b/backend/app/admin/model/dept.py index 98b6ad7f..5855ab02 100644 --- a/backend/app/admin/model/dept.py +++ b/backend/app/admin/model/dept.py @@ -3,16 +3,24 @@ import sqlalchemy as sa from sqlalchemy.orm import Mapped, mapped_column from backend.common.model import Base, TenantMixin, id_key +from backend.core.conf import settings class Dept(Base, TenantMixin): """部门表""" __tablename__ = 'sys_dept' - __table_args__ = ( - sa.UniqueConstraint('name', 'deleted', name='uk_sys_dept_name_deleted'), - {'comment': '部门表'}, - ) + + if settings.TENANT_ENABLED: + __table_args__ = ( + sa.UniqueConstraint('name', 'tenant_id', 'deleted', name='uk_sys_dept_name_tenant_deleted'), + {'comment': '部门表'}, + ) + else: + __table_args__ = ( + sa.UniqueConstraint('name', 'deleted', name='uk_sys_dept_name_deleted'), + {'comment': '部门表'}, + ) id: Mapped[id_key] = mapped_column(init=False) name: Mapped[str] = mapped_column(sa.String(64), comment='部门名称') diff --git a/backend/app/admin/model/role.py b/backend/app/admin/model/role.py index fa56d7aa..20e57058 100644 --- a/backend/app/admin/model/role.py +++ b/backend/app/admin/model/role.py @@ -10,15 +10,17 @@ class Role(Base, TenantMixin): """角色表""" __tablename__ = 'sys_role' - __table_args__ = ( - sa.UniqueConstraint('name', 'deleted', name='uk_sys_role_name_deleted'), - {'comment': '角色表'}, - ) if settings.TENANT_ENABLED: - __table_args__ = (sa.UniqueConstraint('name', 'tenant_id'),) + __table_args__ = ( + sa.UniqueConstraint('name', 'tenant_id', 'deleted', name='uk_sys_role_name_tenant_deleted'), + {'comment': '角色表'}, + ) else: - __table_args__ = (sa.UniqueConstraint('name'),) + __table_args__ = ( + sa.UniqueConstraint('name', 'deleted', name='uk_sys_role_name_deleted'), + {'comment': '角色表'}, + ) id: Mapped[id_key] = mapped_column(init=False) name: Mapped[str] = mapped_column(sa.String(32), comment='角色名称') diff --git a/backend/app/admin/model/user.py b/backend/app/admin/model/user.py index de3cc1d7..14e5b133 100644 --- a/backend/app/admin/model/user.py +++ b/backend/app/admin/model/user.py @@ -14,21 +14,18 @@ class User(Base, TenantMixin): """用户表""" __tablename__ = 'sys_user' - __table_args__ = ( - sa.UniqueConstraint('username', 'deleted', name='uk_sys_user_username_deleted'), - sa.UniqueConstraint('email', 'deleted', name='uk_sys_user_email_deleted'), - {'comment': '用户表'}, - ) if settings.TENANT_ENABLED: __table_args__ = ( - sa.UniqueConstraint('username', 'tenant_id'), - sa.UniqueConstraint('email', 'tenant_id'), + sa.UniqueConstraint('username', 'tenant_id', 'deleted', name='uk_sys_user_username_tenant_deleted'), + sa.UniqueConstraint('email', 'tenant_id', 'deleted', name='uk_sys_user_email_tenant_deleted'), + {'comment': '用户表'}, ) else: __table_args__ = ( - sa.UniqueConstraint('username'), - sa.UniqueConstraint('email'), + sa.UniqueConstraint('username', 'deleted', name='uk_sys_user_username_deleted'), + sa.UniqueConstraint('email', 'deleted', name='uk_sys_user_email_deleted'), + {'comment': '用户表'}, ) id: Mapped[id_key] = mapped_column(init=False) diff --git a/backend/app/admin/schema/login_log.py b/backend/app/admin/schema/login_log.py index 9fbbf25d..7b829204 100644 --- a/backend/app/admin/schema/login_log.py +++ b/backend/app/admin/schema/login_log.py @@ -3,7 +3,6 @@ from datetime import datetime from pydantic import ConfigDict, Field from backend.common.schema import SchemaBase -from backend.core.conf import settings class LoginLogSchemaBase(SchemaBase): @@ -27,9 +26,6 @@ class LoginLogSchemaBase(SchemaBase): class CreateLoginLogParam(LoginLogSchemaBase): """创建登录日志参数""" - if settings.TENANT_ENABLED: - tenant_id: int = Field(description='租户 ID') - class UpdateLoginLogParam(LoginLogSchemaBase): """更新登录日志参数""" diff --git a/backend/app/admin/schema/opera_log.py b/backend/app/admin/schema/opera_log.py index f75e7f6a..7ac1de32 100644 --- a/backend/app/admin/schema/opera_log.py +++ b/backend/app/admin/schema/opera_log.py @@ -5,7 +5,6 @@ from pydantic import ConfigDict, Field from backend.common.enums import StatusType from backend.common.schema import SchemaBase -from backend.core.conf import settings class OperaLogSchemaBase(SchemaBase): @@ -35,9 +34,6 @@ class OperaLogSchemaBase(SchemaBase): class CreateOperaLogParam(OperaLogSchemaBase): """创建操作日志参数""" - if settings.TENANT_ENABLED: - tenant_id: int = Field(description='租户 ID') - class UpdateOperaLogParam(OperaLogSchemaBase): """更新操作日志参数""" diff --git a/backend/app/admin/schema/user.py b/backend/app/admin/schema/user.py index 2ba783df..601fcae8 100644 --- a/backend/app/admin/schema/user.py +++ b/backend/app/admin/schema/user.py @@ -22,7 +22,7 @@ class AuthLoginParam(AuthSchemaBase): """用户登录参数""" if settings.TENANT_ENABLED: - tenant_id: int = Field(settings.TENANT_DEFAULT_ID, description='租户 ID') + tenant_id: int = Field(description='租户 ID') uuid: str | None = Field(None, description='验证码 UUID') captcha: str | None = Field(None, description='验证码') diff --git a/backend/app/admin/service/auth_service.py b/backend/app/admin/service/auth_service.py index 71507160..779cc062 100644 --- a/backend/app/admin/service/auth_service.py +++ b/backend/app/admin/service/auth_service.py @@ -75,7 +75,7 @@ class AuthService: await user_dao.update_login_time(db, obj.username) access_token_data = await create_access_token( user.id, - user.tenant_id, + ctx.tenant_id, multi_login=user.is_multi_login, # extra info swagger=True, @@ -100,7 +100,6 @@ class AuthService: :return: """ user = None - tenant_id = settings.TENANT_DEFAULT_ID try: await load_login_config(db) @@ -115,18 +114,20 @@ class AuthService: await redis_client.delete(f'{settings.LOGIN_CAPTCHA_REDIS_PREFIX}:{obj.uuid}') if settings.TENANT_ENABLED: - tenant_id = obj.tenant_id - await check_tenant_status(db, tenant_id) - - # 登录前先写入当前租户,供后续登录请求流程使用 - ctx.tenant_id = tenant_id + if obj.tenant_id is None: + raise errors.RequestError(msg='租户 ID 不能为空') + ctx.tenant_id = obj.tenant_id + await check_tenant_status(db, ctx.tenant_id) + else: + # 登录前先写入当前租户,供后续登录请求流程使用 + ctx.tenant_id = settings.TENANT_DEFAULT_ID user, days_remaining = await self.user_verify(db, obj.username, obj.password) await user_dao.update_login_time(db, obj.username) await db.refresh(user) access_token_data = await create_access_token( user.id, - user.tenant_id, + ctx.tenant_id, multi_login=user.is_multi_login, # extra info username=user.username, @@ -140,7 +141,7 @@ class AuthService: refresh_token_data = await create_refresh_token( access_token_data.session_uuid, user.id, - user.tenant_id, + ctx.tenant_id, multi_login=user.is_multi_login, ) response.set_cookie( @@ -163,7 +164,6 @@ class AuthService: login_time=timezone.now(), status=LoginLogStatusType.fail.value, msg=e.msg, - tenant_id=tenant_id, ) raise errors.RequestError(code=e.code, msg=e.msg, background=task) except Exception as e: @@ -177,7 +177,6 @@ class AuthService: login_time=timezone.now(), status=LoginLogStatusType.success.value, msg=t('success.login.success'), - tenant_id=tenant_id, ) data = GetLoginToken( access_token=access_token_data.access_token, @@ -228,13 +227,14 @@ class AuthService: raise errors.RequestError(msg='Refresh Token 已过期,请重新登录') token_payload = jwt_decode(refresh_token) + ctx.tenant_id = token_payload.tenant_id user = await user_dao.get(db, token_payload.user_id) if not user: raise errors.NotFoundError(msg='用户不存在') if not user.status: - raise errors.AuthorizationError(msg='用户已被锁定, 请联系统管理员') + raise errors.AuthorizationError(msg='用户已被锁定, 请联系系统管理员') - await check_tenant_status(db, user.tenant_id) + await check_tenant_status(db, ctx.tenant_id) token_keys = await redis_client.get_prefix(f'{settings.TOKEN_REDIS_PREFIX}:{user.id}:*') if not user.is_multi_login and [ key for key in token_keys if not key.endswith(f':{token_payload.session_uuid}') @@ -244,7 +244,7 @@ class AuthService: refresh_token, token_payload.session_uuid, user.id, - user.tenant_id, + ctx.tenant_id, multi_login=user.is_multi_login, # extra info username=user.username, diff --git a/backend/app/admin/service/login_log_service.py b/backend/app/admin/service/login_log_service.py index 99f9839f..71514635 100644 --- a/backend/app/admin/service/login_log_service.py +++ b/backend/app/admin/service/login_log_service.py @@ -8,7 +8,6 @@ from backend.app.admin.schema.login_log import CreateLoginLogParam, DeleteLoginL from backend.common.context import ctx from backend.common.log import log from backend.common.pagination import paging_data -from backend.core.conf import settings from backend.database.db import async_db_session @@ -37,7 +36,6 @@ class LoginLogService: login_time: datetime, status: int, msg: str, - tenant_id: int = settings.TENANT_DEFAULT_ID, ) -> None: """ 创建登录日志 @@ -47,7 +45,6 @@ class LoginLogService: :param login_time: 登录时间 :param status: 状态 :param msg: 消息 - :param tenant_id: 租户 ID :return: """ try: @@ -66,8 +63,6 @@ class LoginLogService: 'msg': msg, 'login_time': login_time, } - if settings.TENANT_ENABLED: - data['tenant_id'] = tenant_id obj = CreateLoginLogParam(**data) async with async_db_session.begin() as db: await login_log_dao.create(db, obj) diff --git a/backend/common/model.py b/backend/common/model.py index f765d2e5..d9860a51 100644 --- a/backend/common/model.py +++ b/backend/common/model.py @@ -87,7 +87,14 @@ class TenantMixin(MappedAsDataclass): """租户 Mixin 数据类""" if settings.TENANT_ENABLED: - tenant_id: Mapped[int] = mapped_column(BigInteger, index=True, sort_order=997, comment='租户ID') + tenant_id: Mapped[int] = mapped_column( + BigInteger, + init=False, + nullable=False, + index=True, + sort_order=997, + comment='租户ID', + ) class DateTimeMixin(MappedAsDataclass): diff --git a/backend/common/security/jwt.py b/backend/common/security/jwt.py index acd55f4f..4be8fa69 100644 --- a/backend/common/security/jwt.py +++ b/backend/common/security/jwt.py @@ -268,7 +268,7 @@ async def get_current_user(db: AsyncSession, pk: int) -> User: raise errors.AuthorizationError(msg='用户已被锁定,请联系系统管理员') if settings.TENANT_ENABLED: - await check_tenant_status(db, user.tenant_id) + await check_tenant_status(db, ctx.tenant_id) if user.dept_id and not user.dept: raise errors.AuthorizationError(msg='用户所属部门不存在或已被删除,请联系系统管理员') diff --git a/backend/middleware/opera_log_middleware.py b/backend/middleware/opera_log_middleware.py index 2353ce0b..150ec4aa 100644 --- a/backend/middleware/opera_log_middleware.py +++ b/backend/middleware/opera_log_middleware.py @@ -2,12 +2,14 @@ import json import time from asyncio import Queue +from collections import defaultdict from typing import Any from fastapi import Response from starlette.datastructures import UploadFile from starlette.middleware.base import BaseHTTPMiddleware from starlette.requests import Request +from starlette_context import request_cycle_context from backend.app.admin.schema.opera_log import CreateOperaLogParam from backend.app.admin.service.opera_log_service import opera_log_service @@ -26,7 +28,7 @@ class OperaLogMiddleware(BaseHTTPMiddleware): """操作日志中间件""" opera_log_queue_name = 'opera_log_queue' - opera_log_queue: Queue[CreateOperaLogParam] = Queue(maxsize=settings.OPERA_LOG_QUEUE_MAXSIZE) + opera_log_queue: Queue[tuple[dict[str, Any], CreateOperaLogParam]] = Queue(maxsize=settings.OPERA_LOG_QUEUE_MAXSIZE) async def dispatch(self, request: Request, call_next: Any) -> Response: # noqa: C901 """ @@ -98,10 +100,6 @@ class OperaLogMiddleware(BaseHTTPMiddleware): log.info(f'{ctx.ip: <15} | {method: <8} | {code!s: <6} | {path} | {elapsed:.3f}ms') if should_log_opera and request.method != 'OPTIONS': - tenant_id = settings.TENANT_DEFAULT_ID - if settings.TENANT_ENABLED: - tenant_id = ctx.tenant_id - opera_log_data = { 'trace_id': get_request_trace_id(), 'username': username, @@ -124,10 +122,13 @@ class OperaLogMiddleware(BaseHTTPMiddleware): 'opera_time': ctx.start_time, } if settings.TENANT_ENABLED: + tenant_id = ctx.get('tenant_id') + if tenant_id is None: + raise RuntimeError('opera log context is missing tenant_id') opera_log_data['tenant_id'] = tenant_id opera_log_in = CreateOperaLogParam(**opera_log_data) - await self.opera_log_queue.put(opera_log_in) + await self.opera_log_queue.put((ctx.copy(), opera_log_in)) if settings.GRAFANA_METRICS_ENABLE: observe_queue_size(self.opera_log_queue, queue_name=self.opera_log_queue_name) @@ -255,12 +256,21 @@ class OperaLogMiddleware(BaseHTTPMiddleware): async def consumer(cls) -> None: """操作日志消费者""" - async def bulk_create_opera_log(logs: list[CreateOperaLogParam]) -> None: + async def bulk_create_opera_log(logs: list[tuple[dict[str, Any], CreateOperaLogParam]]) -> None: """批量创建操作日志""" if settings.DATABASE_ECHO: log.info('自动执行【操作日志批量创建】任务...') + logs_by_tenant = defaultdict(list) + for context_data, log_in in logs: + tenant_id = context_data.get('tenant_id') + if tenant_id is None: + raise RuntimeError('opera log context is missing tenant_id') + logs_by_tenant[tenant_id].append((context_data, log_in)) async with async_db_session.begin() as db: - await opera_log_service.bulk_create(db=db, objs=logs) + for tenant_logs in logs_by_tenant.values(): + request_context = dict(tenant_logs[0][0]) + with request_cycle_context(request_context): + await opera_log_service.bulk_create(db=db, objs=[log_in for _, log_in in tenant_logs]) await batch_consume( cls.opera_log_queue, diff --git a/backend/plugin/oauth2/api/v1/user_social.py b/backend/plugin/oauth2/api/v1/user_social.py index 51a8509d..f4216e70 100644 --- a/backend/plugin/oauth2/api/v1/user_social.py +++ b/backend/plugin/oauth2/api/v1/user_social.py @@ -1,5 +1,6 @@ from fastapi import APIRouter, Request +from backend.common.context import ctx from backend.common.response.response_schema import ResponseModel, ResponseSchemaModel, response_base from backend.common.security.jwt import DependsJwtAuth from backend.database.db import CurrentSession, CurrentSessionTransaction @@ -19,7 +20,7 @@ async def get_user_bindings(db: CurrentSession, request: Request) -> ResponseSch async def get_binding_auth_url(request: Request, source: UserSocialType) -> ResponseSchemaModel[str]: binding_url = await user_social_service.get_binding_auth_url( user_id=request.user.id, - tenant_id=request.user.tenant_id, + tenant_id=ctx.tenant_id, source=source, ) return response_base.success(data=binding_url) diff --git a/backend/plugin/oauth2/crud/crud_user_social.py b/backend/plugin/oauth2/crud/crud_user_social.py index 8a13f0d7..68174696 100644 --- a/backend/plugin/oauth2/crud/crud_user_social.py +++ b/backend/plugin/oauth2/crud/crud_user_social.py @@ -5,6 +5,7 @@ from sqlalchemy.ext.asyncio import AsyncSession from sqlalchemy_crud_plus import CRUDPlus, JoinConfig from backend.app.admin.model import User +from backend.core.conf import settings from backend.plugin.oauth2.model import UserSocial from backend.plugin.oauth2.schema.user_social import CreateUserSocialParam from backend.utils.timezone import timezone @@ -40,9 +41,10 @@ class CRUDUserSocial(CRUDPlus[UserSocial]): :param source: 社交账号类型 :return: """ + conditions = [User.tenant_id == tenant_id] if settings.TENANT_ENABLED else [] return await self.select_model_by_column( db, - User.tenant_id == tenant_id, + *conditions, sid=sid, source=source, deleted=0, diff --git a/backend/plugin/oauth2/service/oauth2_service.py b/backend/plugin/oauth2/service/oauth2_service.py index 3483b954..dd0c3f48 100644 --- a/backend/plugin/oauth2/service/oauth2_service.py +++ b/backend/plugin/oauth2/service/oauth2_service.py @@ -62,6 +62,8 @@ class OAuth2Service: tenant = await tenant_service.get_by_domain(db=db, domain=tenant_domain) if tenant: tenant_id = tenant.id + if tenant_id == settings.TENANT_DEFAULT_ID: + raise errors.ForbiddenError(msg='OAuth2 登录缺少有效租户上下文') state = str(uuid.uuid4()) await redis_client.setex( @@ -78,7 +80,6 @@ class OAuth2Service: db: AsyncSession, response: Response, background_tasks: BackgroundTasks, - tenant_id: int, sid: str, source: UserSocialType, username: str | None = None, @@ -92,7 +93,6 @@ class OAuth2Service: :param db: 数据库会话 :param response: FastAPI 响应对象 :param background_tasks: FastAPI 后台任务 - :param tenant_id: 租户 ID :param sid: 社交账号唯一编码 :param source: 社交平台 :param username: 用户名 @@ -101,7 +101,7 @@ class OAuth2Service: :param avatar: 头像地址 :return: """ - user_social = await user_social_dao.get_by_sid(db, tenant_id, sid, source.value) + user_social = await user_social_dao.get_by_sid(db, ctx.tenant_id, sid, source.value) if user_social: sys_user = await user_dao.get(db, user_social.user_id) # 更新用户头像 @@ -143,7 +143,7 @@ class OAuth2Service: # 创建 token access_token_data = await jwt.create_access_token( sys_user.id, - sys_user.tenant_id, + ctx.tenant_id, multi_login=sys_user.is_multi_login, # extra info username=sys_user.username, @@ -157,7 +157,7 @@ class OAuth2Service: refresh_token_data = await jwt.create_refresh_token( access_token_data.session_uuid, sys_user.id, - sys_user.tenant_id, + ctx.tenant_id, multi_login=sys_user.is_multi_login, ) await user_dao.update_login_time(db, sys_user.username) @@ -169,7 +169,6 @@ class OAuth2Service: login_time=timezone.now(), status=LoginLogStatusType.success.value, msg=t('success.login.oauth2_success'), - tenant_id=tenant_id, ) await redis_client.delete(f'{settings.LOGIN_CAPTCHA_REDIS_PREFIX}:{ctx.ip}') response.set_cookie( @@ -208,7 +207,6 @@ class OAuth2Service: :param state: OAuth2 state 参数 :return: """ - sid = user.get('uuid') username = user.get('username') nickname = user.get('nickname') @@ -237,7 +235,10 @@ class OAuth2Service: state_info = json.loads(state_data) await redis_client.delete(f'{settings.OAUTH2_STATE_REDIS_PREFIX}:{state}') - tenant_id = int(state_info.get('tenant_id', settings.TENANT_DEFAULT_ID)) + tenant_id = state_info.get('tenant_id') + if tenant_id is None: + raise errors.ForbiddenError(msg='OAuth2 状态信息缺少租户 ID') + tenant_id = int(tenant_id) current_tenant_id = ctx.tenant_id ctx.tenant_id = tenant_id @@ -254,7 +255,6 @@ class OAuth2Service: user_id=user_id, sid=str(sid), source=social, - tenant_id=tenant_id, ) return None @@ -266,7 +266,6 @@ class OAuth2Service: db=db, response=response, background_tasks=background_tasks, - tenant_id=tenant_id, sid=str(sid), source=social, username=username, diff --git a/backend/plugin/oauth2/service/user_social_service.py b/backend/plugin/oauth2/service/user_social_service.py index 332a9e2b..4f3cf955 100644 --- a/backend/plugin/oauth2/service/user_social_service.py +++ b/backend/plugin/oauth2/service/user_social_service.py @@ -3,6 +3,7 @@ import uuid from sqlalchemy.ext.asyncio import AsyncSession +from backend.common.context import ctx from backend.common.exception import errors from backend.core.conf import settings from backend.database.redis import redis_client @@ -20,7 +21,7 @@ class UserSocialService: :param db: 数据库会话 :param user_id: 用户 ID - :return: 绑定列表,每个元素包含 sid、source 等信息 + :return: """ bindings = await user_social_dao.get_by_user_id(db, user_id) return [binding.source for binding in bindings] @@ -30,7 +31,6 @@ class UserSocialService: *, db: AsyncSession, user_id: int, - tenant_id: int, sid: str, source: UserSocialType, ) -> None: @@ -39,7 +39,6 @@ class UserSocialService: :param db: 数据库会话 :param user_id: 用户 ID - :param tenant_id: 租户 ID :param sid: 社交账号唯一编码 :param source: 绑定源 :return: @@ -47,7 +46,7 @@ class UserSocialService: if await user_social_dao.check_binding(db, user_id, source.value): raise errors.RequestError(msg=f'用户已绑定 {source.value} 账号') - if await user_social_dao.get_by_sid(db, tenant_id, sid, source.value): + if await user_social_dao.get_by_sid(db, ctx.tenant_id, sid, source.value): raise errors.RequestError(msg=f'该 {source.value} 账号已被其他用户绑定') new_user_social = CreateUserSocialParam(sid=sid, source=source.value, user_id=user_id) diff --git a/backend/sql/mysql/init_snowflake_test_data_tenant.sql b/backend/sql/mysql/init_snowflake_test_data_tenant.sql index ee00a8c5..6df41cb0 100644 --- a/backend/sql/mysql/init_snowflake_test_data_tenant.sql +++ b/backend/sql/mysql/init_snowflake_test_data_tenant.sql @@ -1,5 +1,5 @@ -insert into sys_dept (id, name, sort, leader, phone, email, status, del_flag, parent_id, created_time, updated_time, tenant_id) -values (2048601258595581952, '测试', 0, null, null, null, 1, false, null, now(), null, 0); +insert into sys_dept (id, name, sort, leader, phone, email, status, deleted, parent_id, created_time, updated_time, tenant_id) +values (2048601258595581952, '测试', 0, null, null, null, 1, 0, null, now(), null, 0); insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time) values diff --git a/backend/sql/mysql/init_test_data_tenant.sql b/backend/sql/mysql/init_test_data_tenant.sql index a791509f..44294983 100644 --- a/backend/sql/mysql/init_test_data_tenant.sql +++ b/backend/sql/mysql/init_test_data_tenant.sql @@ -1,5 +1,5 @@ -insert into sys_dept (id, name, sort, leader, phone, email, status, del_flag, parent_id, created_time, updated_time, tenant_id) -values (1, '测试', 0, null, null, null, 1, false, null, now(), null, 0); +insert into sys_dept (id, name, sort, leader, phone, email, status, deleted, parent_id, created_time, updated_time, tenant_id) +values (1, '测试', 0, null, null, null, 1, 0, null, now(), null, 0); insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time) values diff --git a/backend/sql/postgresql/init_snowflake_test_data_tenant.sql b/backend/sql/postgresql/init_snowflake_test_data_tenant.sql index 3029d422..86d2a124 100644 --- a/backend/sql/postgresql/init_snowflake_test_data_tenant.sql +++ b/backend/sql/postgresql/init_snowflake_test_data_tenant.sql @@ -1,5 +1,5 @@ -insert into sys_dept (id, name, sort, leader, phone, email, status, del_flag, parent_id, created_time, updated_time, tenant_id) -values (2048601264366944256, '测试', 0, null, null, null, 1, false, null, now(), null, 0); +insert into sys_dept (id, name, sort, leader, phone, email, status, deleted, parent_id, created_time, updated_time, tenant_id) +values (2048601264366944256, '测试', 0, null, null, null, 1, 0, null, now(), null, 0); insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time) values diff --git a/backend/sql/postgresql/init_test_data_tenant.sql b/backend/sql/postgresql/init_test_data_tenant.sql index 22c8ecc9..143e952a 100644 --- a/backend/sql/postgresql/init_test_data_tenant.sql +++ b/backend/sql/postgresql/init_test_data_tenant.sql @@ -1,5 +1,5 @@ -insert into sys_dept (id, name, sort, leader, phone, email, status, del_flag, parent_id, created_time, updated_time, tenant_id) -values (1, '测试', 0, null, null, null, 1, false, null, now(), null, 0); +insert into sys_dept (id, name, sort, leader, phone, email, status, deleted, parent_id, created_time, updated_time, tenant_id) +values (1, '测试', 0, null, null, null, 1, 0, null, now(), null, 0); insert into sys_menu (id, title, name, path, sort, icon, type, component, perms, status, display, cache, link, remark, parent_id, created_time, updated_time) values