refactor(gencode): 重构代码生成模块,优化模板和查询逻辑

重构代码生成模块的模板文件,统一命名规范为下划线风格
优化GenTableQueryParam查询参数类,移除不必要的字段
修复SQLite数据库支持问题,改进表结构查询逻辑
添加数据验证处理,防止空值导致的异常
改进批量生成代码时的错误处理和参数校验
This commit is contained in:
zhangtao
2025-10-04 23:38:42 +08:00
parent f4b55334e2
commit 1dc8e4f3e2
17 changed files with 1102 additions and 856 deletions
@@ -10,6 +10,7 @@ from app.core.router_class import OperationLogRoute
from app.core.base_params import PaginationQueryParam
from app.common.request import PaginationService
from app.api.v1.module_system.auth.schema import AuthSchema
from app.common.constant import RET
from .param import GenTableQueryParam
from .schema import GenTableDeleteSchema, GenTableSchema, GenTableOutSchema
from .service import GenTableColumnService, GenTableService
@@ -62,14 +63,14 @@ async def gen_table_detail_controller(
) -> JSONResponse:
gen_table = await GenTableService.get_gen_table_by_id_service(auth, table_id)
gen_tables = await GenTableService.get_gen_table_all_service(auth)
gen_table_detail_result = dict(info=gen_table, rows=gen_table.columns, tables=gen_tables)
gen_table_detail_result = dict(info=gen_table.model_dump(), rows=gen_table.model_dump()['columns'], tables=[gen_table.model_dump() for gen_table in gen_tables])
logger.info(f'获取table_id为{table_id}的信息成功')
return SuccessResponse(data=gen_table_detail_result, msg="获取业务表详细信息成功")
@GenRouter.post("/create", summary="创建表结构", description="创建表结构")
async def create_table_controller(
sql: str = Query(..., description="SQL语句"),
sql: str = Query(..., description="SQL语句CREATE TABLE user_demo (\n id INTEGER NOT NULL PRIMARY KEY,\n username VARCHAR(64) NOT NULL UNIQUE,\n);"),
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:create"])),
) -> JSONResponse:
result = await GenTableService.create_table_service(auth, sql)
@@ -101,9 +102,19 @@ async def delete_gen_table_controller(
@GenRouter.patch("/batch/output", summary="批量生成代码", description="批量生成代码")
async def batch_gen_code_controller(
table_names: List[str] = Query(None, description="表名列表"),
table_names: List[str] = Query(..., description="表名列表"),
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:operate"]))
) -> StreamResponse:
# 检查table_names是否为空
if not table_names:
logger.error('表名列表不能为空')
# 返回一个空的StreamResponse,包含错误信息
error_content = bytes(f'{RET.ERROR.msg}: 表名列表不能为空', 'utf-8')
return StreamResponse(
data=bytes2file_response(error_content),
media_type='text/plain',
headers={'Content-Disposition': 'attachment; filename=error.txt'}
)
batch_gen_code_result = await GenTableService.batch_gen_code_service(auth, table_names)
logger.info('批量生成代码成功')
return StreamResponse(
@@ -95,14 +95,16 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
: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()
)
query = select(GenTableModel).options(selectinload(GenTableModel.columns))
if search:
# 手动构建查询条件
if search.table_name and search.table_name[1]: # ('like', value)
query = query.where(GenTableModel.table_name.like(f"%{search.table_name[1]}%"))
if search.table_comment and search.table_comment[1]: # ('like', value)
query = query.where(GenTableModel.table_comment.like(f"%{search.table_comment[1]}%"))
query = query.order_by(GenTableModel.created_at.desc()).distinct()
# 获取所有数据
result = await self.db.execute(query)
@@ -167,7 +169,6 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
text("table_catalog = (select current_database())"),
text("is_insertable_into = 'YES'"),
text("table_schema = 'public'"),
)
)
)
@@ -189,31 +190,44 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
else:
query_sql = (
select(
text(f"{settings.DATABASE_NAME} as database_name"),
text("'' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("name as table_name"),
text("type as table_type"),
text("tbl_name as table_comment"),
text("name as table_comment"), # SQLite中使用name作为表名和注释
)
.select_from(text("sqlite_master"))
.where(
and_(
text("type = 'table'"),
)
)
)
)
# 动态条件构造
if search and search.table_name:
query_sql = query_sql.where(
text("lower(table_name) like lower(:table_name)")
)
if search and search.table_comment:
query_sql = query_sql.where(
text("lower(table_comment) like lower(:table_comment)")
)
params = {}
if search and search.table_name and search.table_name[1]:
if settings.DATABASE_TYPE == "sqlite":
query_sql = query_sql.where(
text("lower(name) like lower(:table_name)")
)
else:
query_sql = query_sql.where(
text("lower(table_name) like lower(:table_name)")
)
params['table_name'] = f"%{search.table_name[1]}%"
if search and search.table_comment and search.table_comment[1]:
if settings.DATABASE_TYPE == "sqlite":
query_sql = query_sql.where(
text("lower(name) like lower(:table_comment)")
)
else:
query_sql = query_sql.where(
text("lower(table_comment) like lower(:table_comment)")
)
params['table_comment'] = f"%{search.table_comment[1]}%"
# 执行查询
all_data =(await self.db.execute(query_sql)).fetchall()
# 执行查询并绑定参数
all_data = (await self.db.execute(query_sql, params)).fetchall()
# 将Row对象转换为字典列表,解决JSON序列化问题
dict_data = []
@@ -250,7 +264,6 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
text("table_catalog = (select current_database())"),
text("is_insertable_into = 'YES'"),
text("table_schema = 'public'"),
)
)
)
@@ -272,10 +285,10 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
else:
query_sql = (
select(
text(f"{settings.DATABASE_NAME} as database_name"),
text("'' as database_name"), # SQLite没有数据库名概念,设为空字符串
text("name as table_name"),
text("type as table_type"),
text("tbl_name as table_comment"),
text("name as table_comment"), # SQLite中使用name作为表名和注释
)
.select_from(text("sqlite_master"))
.where(
@@ -285,10 +298,25 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
)
)
query_sql = query_sql.where(
text(f"table_name in :{table_names}")
)
gen_db_table_list = (await self.db.execute(query_sql)).fetchall()
# 修复SQL查询中的参数绑定问题
if table_names:
if settings.DATABASE_TYPE == "sqlite":
# 对于SQLite,我们直接在SQL中使用表名,因为参数绑定有问题
table_names_str = "','".join(table_names)
query_sql = query_sql.where(
text(f"name IN ('{table_names_str}')")
)
gen_db_table_list = (await self.db.execute(query_sql)).fetchall()
else:
# MySQL和PostgreSQL使用:table_names占位符
query_sql = query_sql.where(
text("table_name IN :table_names")
)
# 使用params方法正确绑定参数
query_sql = query_sql.params(table_names=tuple(table_names))
gen_db_table_list = (await self.db.execute(query_sql)).fetchall()
else:
gen_db_table_list = (await self.db.execute(query_sql)).fetchall()
# 将Row对象转换为字典列表,解决JSON序列化问题
dict_data = []
@@ -358,10 +386,9 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
(CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS is_increment,
column_type
FROM
information_schema.tables
information_schema.columns
WHERE
table_catalog = (select current_database())
AND is_insertable_into = 'YES'
AND table_schema = 'public'
AND table_name = :table_name
"""
@@ -373,29 +400,27 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
(CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END) AS is_pk,
ordinal_position AS sort,
column_comment,
(CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS is_increment,
(CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' end) AS is_increment,
column_type
FROM
information_schema.tables
information_schema.columns
WHERE
table_schema = (SELECT DATABASE())
AND table_name = :table_name
"""
else:
query_sql = f"""
# 修复SQLite查询语句,使用PRAGMA获取表结构信息
query_sql = """
SELECT
column_name,
(CASE WHEN (is_nullable = 'no' AND column_key != 'PRI') THEN '1' ELSE '0' END) AS is_required,
(CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END) AS is_pk,
ordinal_position AS sort,
column_comment,
(CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END) AS is_increment,
column_type
name as column_name,
(CASE WHEN (type != '' AND pk != 1) THEN '1' ELSE '0' END) AS is_required,
(CASE WHEN pk = 1 THEN '1' ELSE '0' END) AS is_pk,
cid AS sort,
'' as column_comment,
(CASE WHEN type LIKE '%AUTOINCREMENT%' THEN '1' ELSE '0' END) AS is_increment,
type as column_type
FROM
sqlite_master
WHERE
type = 'table'
AND name = :table_name
pragma_table_info(:table_name)
"""
query = text(query_sql).bindparams(table_name=table_name)
@@ -403,18 +428,24 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
await self.db.execute(query)
).fetchall()
return [
GenTableColumnOutSchema(
column_name=row[0],
is_required=row[1],
is_pk=row[2],
sort=row[3],
column_comment=row[4],
is_increment=row[5],
column_type=row[6],
)
for row in gen_db_table_columns_raw
]
result = []
for row in gen_db_table_columns_raw:
# 构造字段信息字典
column_dict = {
"column_name": row[0],
"is_required": row[1],
"is_pk": row[2],
"sort": row[3],
"column_comment": row[4],
"is_increment": row[5],
"column_type": row[6]
}
# 创建GenTableColumnOutSchema对象
column_schema = GenTableColumnOutSchema(**column_dict)
result.append(column_schema)
return result
async def list_gen_table_column_crud(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None) -> Sequence[GenTableColumnModel]:
"""根据业务表ID查询业务表字段列表"""
@@ -430,7 +461,14 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
async def delete_gen_table_column_by_table_id_dao(self, data: GenTableDeleteSchema) -> None:
"""根据业务表ID批量删除"""
return await self.delete(ids=data.table_ids)
# 先查询出这些表ID对应的所有字段ID
query = select(GenTableColumnModel.id).where(GenTableColumnModel.table_id.in_(data.table_ids))
result = await self.db.execute(query)
column_ids = [row[0] for row in result.fetchall()]
# 如果有字段ID,则删除这些字段
if column_ids:
await self.delete(ids=column_ids)
async def delete_gen_table_column_by_column_id_dao(self, data: GenTableColumnDeleteSchema) -> None:
"""根据业务表字段ID批量删除"""
@@ -13,21 +13,11 @@ class GenTableQueryParam:
self,
table_name: Optional[str] = Query(None, description="表名称"),
table_comment: Optional[str] = Query(None, description="表注释"),
creator: Optional[int] = Query(None, description="创建人"),
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2025-01-01 00:00:00"),
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2025-12-31 23:59:59"),
) -> None:
# 模糊查询字段
self.table_name = ("like", table_name)
self.table_comment = ("like", table_comment)
# 精确查询字段
self.creator_id = creator
# 时间范围查询
if start_time and end_time:
self.created_at = ("between", (start_time, end_time))
class GenTableColumnQueryParam:
"""代码生成业务表字段查询参数"""
@@ -82,6 +82,30 @@ class GenTableSchema(GenTableBaseSchema):
class GenTableOutSchema(GenTableSchema, BaseSchema):
model_config = ConfigDict(from_attributes=True)
# 添加数据验证和转换的root_validator
@model_validator(mode='before')
def handle_null_values(cls, values):
# 处理None值,转换为空字符串或适当的默认值
# 检查values是否为对象而非字典
if hasattr(values, '__dict__'):
# 如果是对象,获取其字典表示
values_dict = values.__dict__
for key in ['table_name', 'table_comment', 'class_name', 'columns']:
if key in values_dict and values_dict[key] is None:
if key != 'columns':
setattr(values, key, '')
else:
setattr(values, key, [])
return values
elif isinstance(values, dict):
# 如果是字典,执行原来的逻辑
for key, value in values.items():
if value is None:
if key in ['table_name', 'table_comment', 'class_name', 'columns']:
values[key] = '' if key != 'columns' else []
return values
return values
class GenTableDeleteSchema(BaseModel):
@@ -55,13 +55,51 @@ class GenTableService:
async def get_gen_db_table_list_by_name_service(cls, auth: AuthSchema, table_names: List[str]) -> List[GenTableOutSchema]:
"""根据表名称组获取数据库列表信息"""
gen_db_table_list_result = await GenTableCRUD(auth=auth).get_db_table_list_by_names(table_names)
return [GenTableOutSchema(**gen_table) for gen_table in CamelCaseUtil.transform_result(gen_db_table_list_result)]
# 修复:将GenDBTableSchema对象转换为字典后再传递给GenTableOutSchema
result = []
for gen_table in CamelCaseUtil.transform_result(gen_db_table_list_result):
# 确保gen_table是字典类型
if hasattr(gen_table, 'model_dump'):
gen_table_dict = gen_table.model_dump()
elif isinstance(gen_table, dict):
gen_table_dict = gen_table
else:
gen_table_dict = gen_table.__dict__
result.append(GenTableOutSchema(**gen_table_dict))
# 检查是否有未找到的表
found_table_names = [table.table_name for table in result]
missing_tables = [name for name in table_names if name not in found_table_names]
if missing_tables:
raise CustomException(msg=f"以下数据表不存在: {', '.join(missing_tables)}")
return result
@classmethod
async def import_gen_table_service(
cls, auth: AuthSchema, gen_table_list: List[GenTableOutSchema]
) -> Literal[True] | None:
"""导入表结构"""
# 检查是否有表需要导入
if not gen_table_list:
raise CustomException(msg="没有可导入的表结构")
# 检查表是否已存在
existing_tables = []
for table in gen_table_list:
table_name = table.table_name
# 确保table_name不为None
if table_name is None:
raise CustomException(msg="表名不能为空")
# 检查表是否已存在
existing_table = await GenTableCRUD(auth).get_gen_table_by_name(table_name)
if existing_table:
existing_tables.append(table_name)
# 如果有已存在的表,抛出异常
if existing_tables:
raise CustomException(msg=f"以下表已存在,不能重复导入: {', '.join(existing_tables)}")
try:
for table in gen_table_list:
table_name = table.table_name
@@ -69,14 +107,27 @@ class GenTableService:
add_gen_table = await GenTableCRUD(auth).add_gen_table(table)
if add_gen_table:
table.table_id = add_gen_table.id
# 获取数据库表的字段信息
gen_table_columns = await GenTableColumnCRUD(auth).get_gen_db_table_columns_by_name(table_name)
for column in [
GenTableColumnSchema(**gen_table_column)
for gen_table_column in CamelCaseUtil.transform_result(gen_table_columns)
]:
GenUtils.init_column_field(column, table)
await GenTableColumnCRUD(auth).create_gen_table_column_crud(column)
return True
# 为每个字段初始化并保存到数据库
for column in gen_table_columns:
# 将GenTableColumnOutSchema转换为GenTableColumnSchema
column_schema = GenTableColumnSchema(
table_id=table.table_id,
column_name=column.column_name,
column_comment=column.column_comment,
column_type=column.column_type,
is_pk=column.is_pk,
is_increment=column.is_increment,
is_required=column.is_required,
sort=column.sort
)
# 初始化字段属性
GenUtils.init_column_field(column_schema, table)
# 保存到数据库
await GenTableColumnCRUD(auth).create_gen_table_column_crud(column_schema)
return True
except Exception as e:
raise CustomException(msg=f'导入失败, {str(e)}')
@@ -128,7 +179,9 @@ class GenTableService:
table_names = []
for sql_statement in sql_statements:
if isinstance(sql_statement, Create):
table_names.append(sql_statement.find(Table).name)
table = sql_statement.find(Table)
if table and table.name:
table_names.append(table.name)
return table_names
@classmethod
@@ -138,10 +191,19 @@ class GenTableService:
gen_table_info = await cls.get_gen_table_by_id_service(auth, table_id)
if gen_table_info.id:
try:
edit_gen_table['options'] = json.dumps(edit_gen_table.get('params'))
result = await GenTableCRUD(auth).edit_gen_table(table_id, edit_gen_table)
for gen_table_column in data.columns:
await GenTableColumnCRUD(auth).update_gen_table_column_crud(table_id, gen_table_column)
# 处理params为None的情况
params = edit_gen_table.get('params')
if params:
edit_gen_table['options'] = json.dumps(params)
# 将字典转换为GenTableSchema对象
gen_table_schema = GenTableSchema(**edit_gen_table)
result = await GenTableCRUD(auth).edit_gen_table(table_id, gen_table_schema)
# 处理data.columns为None的情况
if data.columns:
for gen_table_column in data.columns:
# 确保column有id字段
if hasattr(gen_table_column, 'id') and gen_table_column.id:
await GenTableColumnCRUD(auth).update_gen_table_column_crud(gen_table_column.id, gen_table_column)
return result.model_dump()
except Exception as e:
raise CustomException(msg=f'更新失败: {str(e)}')
@@ -152,8 +214,10 @@ class GenTableService:
async def delete_gen_table_service(cls, auth: AuthSchema, data: GenTableDeleteSchema) -> None:
"""删除业务表信息"""
try:
await GenTableCRUD(auth=auth).delete_gen_table(data)
# 先删除相关的字段信息
await GenTableColumnCRUD(auth=auth).delete_gen_table_column_by_table_id_dao(data)
# 再删除表信息
await GenTableCRUD(auth=auth).delete_gen_table(data)
except Exception as e:
raise CustomException(msg=f'删除失败: {str(e)}')
@@ -162,7 +226,33 @@ class GenTableService:
"""获取需要生成的业务表详细信息"""
gen_table = await GenTableCRUD(auth=auth).get_gen_table_by_id(table_id)
if gen_table:
result = await cls.set_table_from_options(GenTableOutSchema(**CamelCaseUtil.transform_result(gen_table)))
# 使用更直接的转换方式
result_dict = gen_table.__dict__.copy()
result_dict.pop('_sa_instance_state', None)
# 确保columns正确加载
if hasattr(gen_table, 'columns') and gen_table.columns:
columns_list = []
for column in gen_table.columns:
column_dict = column.__dict__.copy()
column_dict.pop('_sa_instance_state', None)
# 处理None值,转换为空字符串或适当的默认值
for key, value in column_dict.items():
if value is None:
column_dict[key] = ''
columns_list.append(column_dict)
result_dict['columns'] = columns_list
else:
result_dict['columns'] = []
# 处理其他None值,特殊处理creator_id和creator字段
for key, value in result_dict.items():
if value is None:
# 对于creator_id和creator字段,保持为None而不是转换为空字符串
if key not in ['creator_id', 'creator']:
result_dict[key] = ''
# 手动创建GenTableOutSchema对象
result = GenTableOutSchema(**result_dict)
# 设置额外选项
result = await cls.set_table_from_options(result)
return result
else:
raise CustomException(msg='业务表不存在')
@@ -190,7 +280,10 @@ class GenTableService:
await cls.set_pk_column(gen_table)
env = Jinja2TemplateInitializerUtil.init_jinja2()
context = Jinja2TemplateUtil.prepare_context(gen_table)
template_list = Jinja2TemplateUtil.get_template_list(gen_table.tpl_category, gen_table.tpl_web_type)
# 处理tpl_category和tpl_web_type为None的情况
tpl_category = gen_table.tpl_category or ''
tpl_web_type = gen_table.tpl_web_type or ''
template_list = Jinja2TemplateUtil.get_template_list(tpl_category, tpl_web_type)
preview_code_result = {}
for template in template_list:
render_content = env.get_template(template).render(**context)
@@ -243,12 +336,12 @@ class GenTableService:
"""同步数据库"""
gen_table = await GenTableCRUD(auth).get_gen_table_by_name(table_name)
table = GenTableSchema(**CamelCaseUtil.transform_result(gen_table))
table_columns = table.columns
# 处理table.columns为None的情况
table_columns = table.columns or []
table_column_map = {column.column_name: column for column in table_columns}
query_db_table_columns = await GenTableColumnCRUD(auth).get_gen_db_table_columns_by_name(table_name)
db_table_columns = [
GenTableColumnOutSchema(**column) for column in CamelCaseUtil.transform_result(query_db_table_columns)
]
# 直接使用查询结果,因为get_gen_db_table_columns_by_name已经返回GenTableColumnOutSchema对象列表
db_table_columns = query_db_table_columns
if not db_table_columns:
raise CustomException(msg='同步数据失败,原表结构不存在')
db_table_column_names = [column.column_name for column in db_table_columns]
@@ -257,25 +350,33 @@ class GenTableService:
GenUtils.init_column_field(column, table)
if column.column_name in table_column_map:
prev_column = table_column_map[column.column_name]
column.id = prev_column.id
# 处理column.id为None的情况
if hasattr(prev_column, 'id') and prev_column.id:
column.id = prev_column.id
if column.list:
column.dict_type = prev_column.dict_type
column.query_type = prev_column.query_type
if (
prev_column.is_required != ''
hasattr(prev_column, 'is_required') and prev_column.is_required != ''
and not column.pk
and (column.insert or column.edit)
and (column.usable_column or column.super_column)
):
column.is_required = prev_column.is_required
column.html_type = prev_column.html_type
await GenTableColumnCRUD(auth).update_gen_table_column_crud(column.id,column)
# 处理column.id为None的情况
if hasattr(column, 'id') and column.id:
await GenTableColumnCRUD(auth).update_gen_table_column_crud(column.id, column)
else:
await GenTableColumnCRUD(auth).create_gen_table_column_crud(column)
del_columns = [column for column in table_columns if column.column_name not in db_table_column_names]
if del_columns:
for column in del_columns:
await GenTableColumnCRUD(auth).delete_gen_table_column_by_column_id_dao(column.id)
# 处理column.id为None的情况
if hasattr(column, 'id') and column.id:
await GenTableColumnCRUD(auth).delete_gen_table_column_by_column_id_dao(
GenTableColumnDeleteSchema(column_ids=[column.id])
)
except Exception as e:
raise e
@@ -311,7 +412,15 @@ class GenTableService:
@classmethod
async def set_table_from_options(cls, gen_table: GenTableOutSchema) -> GenTableOutSchema:
"""设置代码生成其他选项值"""
params_obj = json.loads(gen_table.options) if gen_table.options else None
# 处理gen_table.options为None的情况
if gen_table.options:
try:
params_obj = json.loads(gen_table.options)
except json.JSONDecodeError:
params_obj = {}
else:
params_obj = {}
if params_obj:
gen_table.tree_code = params_obj.get(GenConstant.TREE_CODE)
gen_table.tree_parent_code = params_obj.get(GenConstant.TREE_PARENT_CODE)
@@ -329,7 +438,11 @@ class GenTableService:
if not edit_gen_table.options:
raise CustomException(msg='树表参数不能为空')
params_obj = json.loads(edit_gen_table.options)
# 处理json解析异常
try:
params_obj = json.loads(edit_gen_table.options)
except json.JSONDecodeError:
raise CustomException(msg='树表参数格式不正确')
if GenConstant.TREE_CODE not in params_obj:
raise CustomException(msg='树编码字段不能为空')
@@ -353,7 +466,16 @@ class GenTableService:
:return: 生成代码渲染模板相关信息
"""
gen_table = await GenTableCRUD(auth=auth).get_gen_table_by_name(table_name)
gen_table_schema = GenTableOutSchema(**CamelCaseUtil.transform_result(gen_table))
# 检查表是否存在
if gen_table is None:
raise CustomException(msg=f"业务表 {table_name} 不存在")
# 确保CamelCaseUtil.transform_result返回的是字典
transformed_result = CamelCaseUtil.transform_result(gen_table)
if transformed_result is None:
raise CustomException(msg=f"业务表 {table_name} 数据转换失败")
gen_table_schema = GenTableOutSchema(**transformed_result)
await cls.set_sub_table(auth, gen_table_schema)
await cls.set_pk_column(gen_table_schema)
context = Jinja2TemplateUtil.prepare_context(gen_table_schema)
@@ -361,7 +483,12 @@ class GenTableService:
gen_table_schema.tpl_category or "",
gen_table_schema.tpl_web_type or ""
)
output_files = [Jinja2TemplateUtil.get_file_name([template], gen_table_schema)[0] for template in template_list]
# 修复:确保get_file_name返回的文件名不为空
output_files = []
for template in template_list:
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table_schema)
if file_name: # 只有当文件名不为空时才添加到列表中
output_files.append(file_name)
return [template_list, output_files, context, gen_table_schema]
@@ -371,11 +498,13 @@ class GenTableService:
"""根据GenTableModel对象和模板名称生成路径"""
try:
gen_path = gen_table.gen_path or ""
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table)
# 修复:检查文件名是否为空
if not file_name:
return None
if gen_path == '/':
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table)[0]
return os.path.join(os.getcwd(), GEN_PATH, file_name)
else:
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table)[0]
return os.path.join(gen_path, file_name)
except Exception:
return None