mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-20 20:39:55 +00:00
fix(gencode): 修复模型关系字段命名错误及优化用户服务逻辑
refactor(schema): 重构代码生成相关schema,增加可选字段和类型提示 refactor(crud): 优化CRUD操作,简化查询逻辑并增加类型安全 fix(user): 修复用户信息获取时的空指针异常及优化菜单权限查询
This commit is contained in:
@@ -8,10 +8,13 @@ from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from sqlalchemy.orm import selectinload
|
||||
from typing import List, Optional, Sequence, Any, Dict
|
||||
|
||||
from app.api.v1.module_system.params.schema import ParamsCreateSchema
|
||||
from app.core.logger import logger
|
||||
|
||||
from .model import GenTableModel, GenTableColumnModel
|
||||
from app.config.setting import settings
|
||||
from app.common.request import PaginationService
|
||||
from .schema import GenTableCreateSchema, GenTableUpdateSchema, GenTableOutSchema, GenTableDeleteSchema, GenTableColumnCreateSchema, GenTableColumnUpdateSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
|
||||
from .schema import GenTableCreateSchema, GenTableUpdateSchema, GenTableOutSchema, GenTableDeleteSchema, GenTableColumnCreateSchema, GenTableColumnUpdateSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema, GenDBTableSchema
|
||||
from .param import GenTableQueryParam
|
||||
from app.core.base_crud import CRUDBase
|
||||
from app.api.v1.module_system.auth.schema import AuthSchema
|
||||
@@ -28,41 +31,43 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableCreateSchema, GenTableUpdateS
|
||||
"""
|
||||
根据业务表id获取需要生成的业务表信息
|
||||
|
||||
:param db: orm对象
|
||||
:param table_id: 业务表id
|
||||
:return: 需要生成的业务表信息对象
|
||||
"""
|
||||
gen_table_info = (
|
||||
gen_table = (
|
||||
(
|
||||
await self.db.execute(
|
||||
select(GenTableModel).options(selectinload(GenTableModel.columns)).where(GenTableModel.id == table_id)
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns))
|
||||
.where(GenTableModel.id == table_id)
|
||||
)
|
||||
)
|
||||
.scalars()
|
||||
.first()
|
||||
)
|
||||
|
||||
return gen_table_info
|
||||
return gen_table
|
||||
|
||||
async def get_gen_table_by_name(self, table_name: str) -> Optional[GenTableModel]:
|
||||
"""
|
||||
根据业务表名称获取需要生成的业务表信息
|
||||
|
||||
:param db: orm对象
|
||||
:param table_name: 业务表名称
|
||||
:return: 需要生成的业务表信息对象
|
||||
"""
|
||||
gen_table_info = (
|
||||
gen_table = (
|
||||
(
|
||||
await self.db.execute(
|
||||
select(GenTableModel).options(selectinload(GenTableModel.columns)).where(GenTableModel.table_name == table_name)
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns))
|
||||
.where(GenTableModel.table_name == table_name)
|
||||
)
|
||||
)
|
||||
.scalars()
|
||||
.first()
|
||||
)
|
||||
|
||||
return gen_table_info
|
||||
return gen_table
|
||||
|
||||
async def get_gen_table_all(self) -> Sequence[GenTableModel]:
|
||||
"""
|
||||
@@ -71,11 +76,40 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableCreateSchema, GenTableUpdateS
|
||||
:param db: orm对象
|
||||
:return: 所有业务表信息
|
||||
"""
|
||||
gen_table_all = (await self.db.execute(select(GenTableModel).options(selectinload(GenTableModel.columns)))).scalars().all()
|
||||
gen_table_all = (
|
||||
await self.db.execute(
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns)))
|
||||
).scalars().all()
|
||||
|
||||
return gen_table_all
|
||||
|
||||
async def create_table_by_sql(self, sql_statements: List) -> None:
|
||||
async def get_gen_table_list(self, search: Optional[GenTableQueryParam] = None):
|
||||
"""
|
||||
根据查询参数获取代码生成业务表列表信息
|
||||
|
||||
:param query_object: 查询参数对象
|
||||
:return: 代码生成业务表列表信息对象
|
||||
"""
|
||||
# 构建查询条件
|
||||
conditions = await self.__build_conditions(**search.__dict__) if search else []
|
||||
query = (
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns))
|
||||
.where(
|
||||
*conditions
|
||||
)
|
||||
.order_by(GenTableModel.created_at.desc())
|
||||
.distinct()
|
||||
)
|
||||
|
||||
# 获取所有数据
|
||||
result = await self.db.execute(query)
|
||||
gen_table_all = list(result.scalars().all())
|
||||
|
||||
return gen_table_all
|
||||
|
||||
async def create_table_by_sql(self, sql: str) -> bool:
|
||||
"""
|
||||
根据sql语句创建表结构
|
||||
|
||||
@@ -83,68 +117,47 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableCreateSchema, GenTableUpdateS
|
||||
:param sql_statements: sql语句的ast列表
|
||||
:return:
|
||||
"""
|
||||
for sql_statement in sql_statements:
|
||||
sql = sql_statement.sql(dialect=settings.DATABASE_TYPE)
|
||||
await self.db.execute(text(sql))
|
||||
try:
|
||||
await self.db.execute(text(sql))
|
||||
# 提交事务
|
||||
await self.db.commit()
|
||||
await self.db.flush()
|
||||
return True
|
||||
except Exception as e:
|
||||
# 如果发生异常,回滚事务
|
||||
await self.db.rollback()
|
||||
logger.error(f"创建表时发生错误: {e}")
|
||||
return False
|
||||
|
||||
async def get_gen_table_list(self, query_object: GenTableQueryParam, is_page: bool = False):
|
||||
async def add_gen_table(self, add_model: GenTableCreateSchema) -> GenTableModel:
|
||||
"""
|
||||
根据查询参数获取代码生成业务表列表信息
|
||||
|
||||
:param db: orm对象
|
||||
:param query_object: 查询参数对象
|
||||
:param is_page: 是否开启分页
|
||||
:return: 代码生成业务表列表信息对象
|
||||
增加
|
||||
"""
|
||||
# 构建查询条件
|
||||
conditions = []
|
||||
gen_table = GenTableModel(**add_model.model_dump(exclude_unset=True, exclude={'sub', 'tree', 'crud'}))
|
||||
self.db.add(gen_table)
|
||||
await self.db.flush()
|
||||
return gen_table
|
||||
|
||||
# 访问table_name属性
|
||||
if getattr(query_object, 'table_name', None) and query_object.table_name[1]:
|
||||
conditions.append(func.lower(GenTableModel.table_name).like(f'%{str(query_object.table_name[1]).lower()}%'))
|
||||
async def delete_gen_table(self, delete_model: GenTableDeleteSchema) -> None:
|
||||
"""
|
||||
删除
|
||||
"""
|
||||
await self.db.execute(delete(GenTableModel).where(GenTableModel.id.in_(delete_model.table_ids)))
|
||||
await self.db.flush()
|
||||
|
||||
# 访问table_comment属性
|
||||
if getattr(query_object, 'table_comment', None):
|
||||
conditions.append(func.lower(GenTableModel.table_comment).like(f'%{str(query_object.table_comment).lower()}%'))
|
||||
async def edit_gen_table(self, table_id: int, edit_model: GenTableUpdateSchema, auto_commit: bool = True):
|
||||
"""
|
||||
修改
|
||||
"""
|
||||
edit_dict_data = edit_model.model_dump(exclude_unset=True)
|
||||
await self.db.execute(update(GenTableModel).where(GenTableModel.id == table_id).values(**edit_dict_data))
|
||||
await self.db.flush()
|
||||
if auto_commit:
|
||||
await self.db.commit()
|
||||
return edit_model
|
||||
|
||||
# 访问created_at属性而不是start_time和end_time
|
||||
if hasattr(query_object, 'created_at') and query_object.created_at:
|
||||
if isinstance(query_object.created_at, tuple) and query_object.created_at[0] == "between":
|
||||
conditions.append(GenTableModel.created_at.between(*query_object.created_at[1]))
|
||||
|
||||
query = (
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns))
|
||||
.where(*conditions)
|
||||
.order_by(GenTableModel.created_at.desc())
|
||||
.distinct()
|
||||
)
|
||||
|
||||
# 获取所有数据
|
||||
result = await self.db.execute(query)
|
||||
all_data = list(result.scalars().all())
|
||||
|
||||
# 使用PaginationService.paginate进行分页
|
||||
# 注意:这里假设query_object有page_no和page_size属性,如果没有需要从其他地方获取
|
||||
page_no = getattr(query_object, 'page_no', None)
|
||||
page_size = getattr(query_object, 'page_size', None)
|
||||
if is_page and page_no is not None and page_size is not None:
|
||||
paginated_result = await PaginationService.paginate(
|
||||
data_list=all_data,
|
||||
page_no=page_no,
|
||||
page_size=page_size
|
||||
)
|
||||
return paginated_result
|
||||
else:
|
||||
return {
|
||||
"items": all_data,
|
||||
"total": len(all_data),
|
||||
"page_no": None,
|
||||
"page_size": None,
|
||||
"has_next": False
|
||||
}
|
||||
|
||||
async def get_gen_db_table_list(self, search: GenTableQueryParam, order_by: Optional[List[Dict[str, str]]] = None) -> list[Any]:
|
||||
async def get_gen_db_table_list(self, table_name: Optional[str] = None) -> list[Any]:
|
||||
"""
|
||||
根据查询参数获取数据库列表信息
|
||||
|
||||
@@ -153,55 +166,6 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableCreateSchema, GenTableUpdateS
|
||||
:param order_by: 排序字段
|
||||
:return: 数据库列表信息对象
|
||||
"""
|
||||
# pg数据库
|
||||
# {
|
||||
# "table_catalog": "fastapiadmin",
|
||||
# "table_schema": "pg_catalog",
|
||||
# "table_name": "pg_foreign_table",
|
||||
# "table_type": "BASE TABLE",
|
||||
# "self_referencing_column_name": null,
|
||||
# "reference_generation": null,
|
||||
# "user_defined_type_catalog": null,
|
||||
# "user_defined_type_schema": null,
|
||||
# "user_defined_type_name": null,
|
||||
# "is_insertable_into": "YES",
|
||||
# "is_typed": "NO",
|
||||
# "commit_action": null
|
||||
# }
|
||||
|
||||
# mysql
|
||||
# {
|
||||
# "TABLE_CATALOG": "def",
|
||||
# "TABLE_SCHEMA": "fastapiadmin",
|
||||
# "TABLE_NAME": "ai_mcp",
|
||||
# "TABLE_TYPE": "BASE TABLE",
|
||||
# "ENGINE": "InnoDB",
|
||||
# "VERSION": 10,
|
||||
# "ROW_FORMAT": "Dynamic",
|
||||
# "TABLE_ROWS": 0,
|
||||
# "AVG_ROW_LENGTH": 0,
|
||||
# "DATA_LENGTH": 16384,
|
||||
# "MAX_DATA_LENGTH": 0,
|
||||
# "INDEX_LENGTH": 16384,
|
||||
# "DATA_FREE": 0,
|
||||
# "AUTO_INCREMENT": null,
|
||||
# "CREATE_TIME": "2025-10-02T03:43:02",
|
||||
# "UPDATE_TIME": null,
|
||||
# "CHECK_TIME": null,
|
||||
# "TABLE_COLLATION": "utf8mb4_0900_ai_ci",
|
||||
# "CHECKSUM": null,
|
||||
# "CREATE_OPTIONS": "",
|
||||
# "TABLE_COMMENT": "MCP 服务器表"
|
||||
# },
|
||||
|
||||
# sqlite
|
||||
# {
|
||||
# "type": "table",
|
||||
# "name": "system_users",
|
||||
# "tbl_name": "system_users",
|
||||
# "rootpage": 47,
|
||||
# "sql": "CREATE TABLE system_users (\n\tusername VARCHAR(32) NOT NULL, \n\tpassword VARCHAR(255) NOT NULL, \n\tname VARCHAR(32) NOT NULL, \n\tstatus BOOLEAN NOT NULL, \n\tmobile VARCHAR(20), \n\temail VARCHAR(64), \n\tgender VARCHAR(1), \n\tavatar VARCHAR(500), \n\tis_superuser BOOLEAN NOT NULL, \n\tlast_login DATETIME, \n\tdept_id INTEGER, \n\tcreator_id INTEGER, \n\tid INTEGER NOT NULL, \n\tdescription TEXT, \n\tcreated_at DATETIME, \n\tupdated_at DATETIME, \n\tPRIMARY KEY (id), \n\tUNIQUE (username), \n\tUNIQUE (mobile), \n\tUNIQUE (email), \n\tFOREIGN KEY(dept_id) REFERENCES system_dept (id) ON DELETE SET NULL ON UPDATE CASCADE\n)"
|
||||
# },
|
||||
|
||||
# 使用更健壮的方式检测数据库方言
|
||||
if settings.DATABASE_TYPE == 'postgresql':
|
||||
@@ -256,10 +220,13 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableCreateSchema, GenTableUpdateS
|
||||
# 检查row是否为Row对象
|
||||
if isinstance(row, Row):
|
||||
# 使用._mapping获取字典
|
||||
dict_row = dict(row._mapping)
|
||||
dict_row = GenDBTableSchema(**dict(row._mapping)).model_dump()
|
||||
if table_name:
|
||||
dict_row['table_name'] = table_name
|
||||
dict_data.append(dict_row)
|
||||
else:
|
||||
dict_data.append(row)
|
||||
dict_row = GenDBTableSchema(**dict(row)).model_dump()
|
||||
dict_data.append(dict_row)
|
||||
return dict_data
|
||||
|
||||
async def get_gen_db_table_list_by_names(self, table_names: List[str]):
|
||||
@@ -326,22 +293,43 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnCreateSchem
|
||||
"""初始化CRUD"""
|
||||
super().__init__(model=GenTableColumnModel, auth=auth)
|
||||
|
||||
async def get_by_id_crud(self, column_id: int) -> Optional[GenTableColumnModel]:
|
||||
"""详情"""
|
||||
return await self.get(id=column_id)
|
||||
|
||||
async def get_list_crud(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None) -> Sequence[GenTableColumnModel]:
|
||||
"""列表查询"""
|
||||
return await self.list(search=search, order_by=order_by)
|
||||
|
||||
async def create_crud(self, data: GenTableColumnCreateSchema) -> Optional[GenTableColumnModel]:
|
||||
"""创建"""
|
||||
return await self.create(data=data)
|
||||
|
||||
async def update_crud(self, id: int, data: GenTableColumnUpdateSchema) -> Optional[GenTableColumnModel]:
|
||||
"""更新"""
|
||||
return await self.update(id=id, data=data)
|
||||
|
||||
async def delete_crud(self, data: GenTableColumnDeleteSchema) -> None:
|
||||
"""批量删除"""
|
||||
return await self.delete(ids=data.column_ids)
|
||||
|
||||
async def get_gen_table_column_list_by_table_id_crud(self, table_id: int) -> Sequence[GenTableColumnModel]:
|
||||
"""根据业务表id获取需要生成的业务表字段列表信息"""
|
||||
return await self.list(search={"table_id": table_id})
|
||||
|
||||
async def get_gen_table_column_list_by_table_id(self, db: AsyncSession, table_id: int) -> Sequence[GenTableColumnModel]:
|
||||
async def get_gen_table_column_list_by_table_id(self, table_id: int) -> Sequence[GenTableColumnModel]:
|
||||
"""
|
||||
根据业务表id获取需要生成的业务表字段列表信息
|
||||
|
||||
:param db: orm对象
|
||||
:param table_id: 业务表id
|
||||
:return: 需要生成的业务表字段列表信息对象
|
||||
"""
|
||||
gen_table_column_list = (
|
||||
(
|
||||
await db.execute(
|
||||
select(GenTableColumnModel).where(GenTableColumnModel.table_id == table_id).order_by(GenTableColumnModel.sort)
|
||||
await self.db.execute(
|
||||
select(GenTableColumnModel)
|
||||
.where(GenTableColumnModel.table_id == table_id)
|
||||
.order_by(GenTableColumnModel.sort)
|
||||
)
|
||||
)
|
||||
.scalars()
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
from typing import Optional, List
|
||||
from sqlalchemy import String, Integer, ForeignKey
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship, declared_attr
|
||||
from sqlalchemy.orm import Mapped, mapped_column, relationship
|
||||
|
||||
from app.core.base_model import CreatorMixin
|
||||
|
||||
@@ -34,7 +34,7 @@ class GenTableModel(CreatorMixin):
|
||||
columns: Mapped[List['GenTableColumnModel']] = relationship(
|
||||
'GenTableColumnModel',
|
||||
order_by='GenTableColumnModel.sort',
|
||||
back_populates='table',
|
||||
back_populates='tables',
|
||||
cascade='all, delete-orphan'
|
||||
)
|
||||
|
||||
@@ -73,7 +73,7 @@ class GenTableColumnModel(CreatorMixin):
|
||||
)
|
||||
|
||||
# 关系定义
|
||||
table: Mapped['GenTableModel'] = relationship(
|
||||
tables: Mapped['GenTableModel'] = relationship(
|
||||
'GenTableModel',
|
||||
back_populates='columns'
|
||||
)
|
||||
@@ -9,27 +9,47 @@ from app.common.constant import GenConstant
|
||||
from app.core.base_schema import BaseSchema
|
||||
|
||||
|
||||
class GenTableOptionModel(BaseModel):
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
parent_menu_id: Optional[int] = Field(default=None, description='所属父级分类')
|
||||
tree_code: Optional[str] = Field(default=None, description='tree_code')
|
||||
tree_name: Optional[str] = Field(default=None, description='tree_name')
|
||||
tree_parent_code: Optional[str] = Field(default=None, description='tree_parent_code')
|
||||
|
||||
class GenDBTableSchema(BaseModel):
|
||||
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
database_name: Optional[str] = Field(default=None, description='数据库名称')
|
||||
table_name: Optional[str] = Field(default=None, description='表名称')
|
||||
table_type: Optional[str] = Field(default=None, description='表类型')
|
||||
table_comment: Optional[str] = Field(default=None, description='表描述')
|
||||
|
||||
|
||||
class GenTableCreateSchema(BaseModel):
|
||||
"""
|
||||
代码生成业务表创建模型
|
||||
"""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
table_name: str = Field(..., description='表名称')
|
||||
table_comment: str = Field(..., description='表描述')
|
||||
table_name: Optional[str] = Field(default=None, description='表名称')
|
||||
table_comment: Optional[str] = Field(default=None, description='表描述')
|
||||
sub_table_name: Optional[str] = Field(default=None, description='关联子表的表名')
|
||||
sub_table_fk_name: str = Field(..., description='子表关联的外键名')
|
||||
class_name: str = Field(..., description='实体类名称')
|
||||
tpl_category: Optional[str] = Field(default=None, description='使用的模板(crud单表操作 tree树表操作)')
|
||||
sub_table_fk_name: Optional[str] = Field(default=None, description='子表关联的外键名')
|
||||
class_name: Optional[str] = Field(default=None, description='实体类名称')
|
||||
tpl_category: Optional[Literal['crud', 'tree']] = Field(default=None, description='使用的模板(crud单表操作 tree树表操作)')
|
||||
tpl_web_type: Optional[str] = Field(default=None, description='前端模板类型(element-ui模版 element-plus模版)')
|
||||
package_name: str = Field(..., description='生成包路径')
|
||||
module_name: str = Field(..., description='生成模块名')
|
||||
business_name: str = Field(..., description='生成业务名')
|
||||
function_name: str = Field(..., description='生成功能名')
|
||||
package_name: Optional[str] = Field(default=None, description='生成包路径')
|
||||
module_name: Optional[str] = Field(default=None, description='生成模块名')
|
||||
business_name: Optional[str] = Field(default=None, description='生成业务名')
|
||||
function_name: Optional[str] = Field(default=None, description='生成功能名')
|
||||
function_author: Optional[str] = Field(default=None, description='生成功能作者')
|
||||
gen_type: Optional[Literal['0', '1']] = Field(default=None, description='生成代码方式(0zip压缩包 1自定义路径)')
|
||||
gen_path: Optional[str] = Field(default=None, description='生成路径(不填默认项目路径)')
|
||||
options: Optional[str] = Field(default=None, description='其它生成选项')
|
||||
description: Optional[str] = Field(default=None, description='功能描述')
|
||||
|
||||
|
||||
class GenTableUpdateSchema(GenTableCreateSchema):
|
||||
@@ -38,10 +58,10 @@ class GenTableUpdateSchema(GenTableCreateSchema):
|
||||
"""
|
||||
pk_column: Optional['GenTableColumnUpdateSchema'] = Field(default=None, description='主键信息')
|
||||
sub_table: Optional['GenTableUpdateSchema'] = Field(default=None, description='子表信息')
|
||||
columns: List['GenTableColumnUpdateSchema'] = Field(..., description='表列信息')
|
||||
tree_code: Optional[str] = Field(default=None, description='树编码字段')
|
||||
columns: Optional[List['GenTableColumnUpdateSchema']] = Field(default=None, description='表列信息')
|
||||
tree_code: Optional[str] = Field(default=None, description='树编码字段tree_code')
|
||||
tree_parent_code: Optional[str] = Field(default=None, description='树父编码字段')
|
||||
tree_name: Optional[str] = Field(default=None, description='树名称字段')
|
||||
tree_name: Optional[str] = Field(default=None, description='树名称字段ree_name')
|
||||
parent_menu_id: Optional[int] = Field(default=None, description='上级菜单ID字段')
|
||||
parent_menu_name: Optional[str] = Field(default=None, description='上级菜单名称字段')
|
||||
sub: Optional[bool] = Field(default=None, description='是否为子表')
|
||||
@@ -79,12 +99,11 @@ class GenTableColumnCreateSchema(BaseModel):
|
||||
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
|
||||
|
||||
table_id: Optional[int] = Field(default=None, description='归属表编号')
|
||||
|
||||
column_name: str = Field(..., description='列名称')
|
||||
column_name: Optional[str] = Field(default=None, description='列名称')
|
||||
column_comment: Optional[str] = Field(default=None, description='列描述')
|
||||
column_type: str = Field(..., description='列类型')
|
||||
column_type: Optional[str] = Field(default=None, description='列类型')
|
||||
python_type: Optional[str] = Field(default=None, description='PYTHON类型')
|
||||
python_field: str = Field(..., description='PYTHON字段名')
|
||||
python_field: Optional[str] = Field(default=None, description='PYTHON字段名')
|
||||
is_pk: Optional[str] = Field(default=None, description='是否主键(1是)')
|
||||
is_increment: Optional[str] = Field(default=None, description='是否自增(1是)')
|
||||
is_required: Optional[str] = Field(default=None, description='是否必填(1是)')
|
||||
@@ -94,48 +113,17 @@ class GenTableColumnCreateSchema(BaseModel):
|
||||
is_list: Optional[str] = Field(default=None, description='是否列表字段(1是)')
|
||||
is_query: Optional[str] = Field(default=None, description='是否查询字段(1是)')
|
||||
query_type: Optional[str] = Field(default=None, description='查询方式(等于、不等于、大于、小于、范围)')
|
||||
html_type: str = Field(..., description='显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)')
|
||||
dict_type: str = Field(..., description='字典类型')
|
||||
html_type: Optional[str] = Field(default=None, description='显示类型(文本框、文本域、下拉框、复选框、单选框、日期控件)')
|
||||
dict_type: Optional[str] = Field(default=None, description='字典类型')
|
||||
sort: Optional[int] = Field(default=None, description='排序')
|
||||
description: Optional[str] = Field(default=None, description='功能描述')
|
||||
|
||||
|
||||
class GenTableColumnUpdateSchema(GenTableColumnCreateSchema):
|
||||
"""
|
||||
代码生成业务表字段更新模型
|
||||
"""
|
||||
|
||||
cap_python_field: Optional[str] = Field(default=None, description='字段大写形式')
|
||||
pk: Optional[bool] = Field(default=None, description='是否主键')
|
||||
increment: Optional[bool] = Field(default=None, description='是否自增')
|
||||
required: Optional[bool] = Field(default=None, description='是否必填')
|
||||
unique: Optional[bool] = Field(default=None, description='是否唯一')
|
||||
insert: Optional[bool] = Field(default=None, description='是否为插入字段')
|
||||
edit: Optional[bool] = Field(default=None, description='是否编辑字段')
|
||||
list: Optional[bool] = Field(default=None, description='是否列表字段')
|
||||
query: Optional[bool] = Field(default=None, description='是否查询字段')
|
||||
super_column: Optional[bool] = Field(default=None, description='是否为基类字段')
|
||||
usable_column: Optional[bool] = Field(default=None, description='是否为基类字段白名单')
|
||||
|
||||
@model_validator(mode='after')
|
||||
def check_some_is(self) -> 'GenTableColumnUpdateSchema':
|
||||
self.cap_python_field = self.python_field[0].upper() + self.python_field[1:] if self.python_field else None
|
||||
self.pk = True if self.is_pk and self.is_pk == '1' else False
|
||||
self.increment = True if self.is_increment and self.is_increment == '1' else False
|
||||
self.required = True if self.is_required and self.is_required == '1' else False
|
||||
self.unique = True if self.is_unique and self.is_unique == '1' else False
|
||||
self.insert = True if self.is_insert and self.is_insert == '1' else False
|
||||
self.edit = True if self.is_edit and self.is_edit == '1' else False
|
||||
self.list = True if self.is_list and self.is_list == '1' else False
|
||||
self.query = True if self.is_query and self.is_query == '1' else False
|
||||
self.super_column = (
|
||||
True
|
||||
if StringUtil.equals_any_ignore_case(self.python_field, GenConstant.TREE_ENTITY + GenConstant.BASE_ENTITY)
|
||||
else False
|
||||
)
|
||||
self.usable_column = (
|
||||
True if StringUtil.equals_any_ignore_case(self.python_field, ['parentId', 'orderNum', 'remark']) else False
|
||||
)
|
||||
return self
|
||||
...
|
||||
|
||||
|
||||
class GenTableColumnOutSchema(GenTableColumnUpdateSchema, BaseSchema):
|
||||
@@ -151,4 +139,4 @@ class GenTableColumnDeleteSchema(BaseModel):
|
||||
"""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
column_ids: str = Field(..., description='需要删除的代码生成业务表字段ID')
|
||||
column_ids: List[int] = Field(..., description='需要删除的代码生成业务表字段ID')
|
||||
@@ -156,7 +156,7 @@ class UserService:
|
||||
raise CustomException(msg="超级管理员不能删除")
|
||||
if user.status:
|
||||
raise CustomException(msg="用户已启用,不能删除")
|
||||
if auth.user.id == id:
|
||||
if auth.user and auth.user.id == id:
|
||||
raise CustomException(msg="不能删除当前登陆用户")
|
||||
# 删除用户角色关联数据
|
||||
await UserCRUD(auth).set_user_roles_crud(user_ids=ids, role_ids=[])
|
||||
@@ -171,35 +171,35 @@ class UserService:
|
||||
async def get_current_user_info_service(cls, auth: AuthSchema) -> Dict:
|
||||
"""获取当前用户信息"""
|
||||
# 获取用户基本信息
|
||||
user = await UserCRUD(auth).get_by_id_crud(id=auth.user.id)
|
||||
if not user:
|
||||
if not auth.user:
|
||||
raise CustomException(msg="用户不存在")
|
||||
user = await UserCRUD(auth).get_by_id_crud(id=auth.user.id)
|
||||
# 获取部门名称
|
||||
if user.dept_id:
|
||||
dept = await DeptCRUD(auth).get_by_id_crud(id=auth.user.dept_id)
|
||||
user.dept_name = dept.name if dept else None
|
||||
if user and user.dept_id:
|
||||
dept = await DeptCRUD(auth).get_by_id_crud(id=user.dept_id)
|
||||
UserOutSchema.dept_name = dept.name if dept else None
|
||||
user_dict = UserOutSchema.model_validate(user).model_dump()
|
||||
|
||||
# 获取菜单权限
|
||||
if auth.user.is_superuser:
|
||||
if auth.user and auth.user.is_superuser:
|
||||
# 使用树形结构查询,预加载children关系
|
||||
menu_all = await MenuCRUD(auth).get_tree_list_crud(search={'type': ('in', [1, 2, 4]), 'status': True})
|
||||
menus = [MenuOutSchema.model_validate(menu).model_dump() for menu in menu_all]
|
||||
|
||||
else:
|
||||
# 收集用户所有角色的菜单ID
|
||||
menu_ids = []
|
||||
for role in auth.user.roles:
|
||||
for menu in role.menus:
|
||||
if menu.status and menu.type in [1, 2, 4]:
|
||||
menu_ids.append(menu.id)
|
||||
# 收集用户所有角色的菜单ID,使用列表推导式优化代码
|
||||
menu_ids = {
|
||||
menu.id
|
||||
for role in auth.user.roles or []
|
||||
for menu in role.menus
|
||||
if menu.status and menu.type in [1, 2, 4]
|
||||
}
|
||||
|
||||
# 使用树形结构查询,预加载children关系
|
||||
if menu_ids:
|
||||
menu_all = await MenuCRUD(auth).get_tree_list_crud(search={'id': ('in', menu_ids)})
|
||||
menus = [MenuOutSchema.model_validate(menu).model_dump() for menu in menu_all]
|
||||
else:
|
||||
menus = []
|
||||
menus = [
|
||||
MenuOutSchema.model_validate(menu).model_dump()
|
||||
for menu in await MenuCRUD(auth).get_tree_list_crud(search={'id': ('in', list(menu_ids))})
|
||||
] if menu_ids else []
|
||||
user_dict["menus"] = traversal_to_tree(menus)
|
||||
return user_dict
|
||||
|
||||
|
||||
Reference in New Issue
Block a user