From fe41a207fa96b887a3a3824bc25c41a3ee0ef60c Mon Sep 17 00:00:00 2001 From: insistence <3055204202@qq.com> Date: Sun, 16 Feb 2025 23:29:15 +0800 Subject: [PATCH] =?UTF-8?q?perf:=20=E4=BC=98=E5=8C=96=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../module_generator/dao/gen_dao.py | 70 ++- .../module_generator/service/gen_service.py | 112 ++--- .../templates/python/controller.py.jinja2 | 24 +- .../templates/python/dao.py.jinja2 | 14 +- .../templates/python/do.py.jinja2 | 17 +- .../templates/python/service.py.jinja2 | 11 +- .../templates/python/vo.py.jinja2 | 9 +- .../templates/vue/v3/index-tree.vue.jinja2 | 454 ++++++++++++++++++ .../templates/vue/v3/index.vue.jinja2 | 11 +- ruoyi-fastapi-backend/utils/gen_util.py | 92 +++- ruoyi-fastapi-backend/utils/template_util.py | 216 +++++++-- 11 files changed, 854 insertions(+), 176 deletions(-) diff --git a/ruoyi-fastapi-backend/module_generator/dao/gen_dao.py b/ruoyi-fastapi-backend/module_generator/dao/gen_dao.py index 8844ab2..c125741 100644 --- a/ruoyi-fastapi-backend/module_generator/dao/gen_dao.py +++ b/ruoyi-fastapi-backend/module_generator/dao/gen_dao.py @@ -16,17 +16,17 @@ from utils.page_util import PageUtil class GenTableDao: """ - 代码生成表模块数据库操作层 + 代码生成业务表模块数据库操作层 """ @classmethod async def get_gen_table_by_id(cls, db: AsyncSession, table_id: int): """ - 根据表格id获取需要生成的表格信息 + 根据业务表id获取需要生成的业务表信息 :param db: orm对象 - :param table_id: 岗位id - :return: 需要生成的表格信息对象 + :param table_id: 业务表id + :return: 需要生成的业务表信息对象 """ gen_table_info = ( ( @@ -43,11 +43,11 @@ class GenTableDao: @classmethod async def get_gen_table_by_name(cls, db: AsyncSession, table_name: str): """ - 根据表格名称获取需要生成的表格信息 + 根据业务表名称获取需要生成的业务表信息 :param db: orm对象 - :param table_name: 表格名称 - :return: 需要生成的表格信息对象 + :param table_name: 业务表名称 + :return: 需要生成的业务表信息对象 """ gen_table_info = ( ( @@ -64,10 +64,10 @@ class GenTableDao: @classmethod async def get_gen_table_all(cls, db: AsyncSession): """ - 根据表格id获取需要生成的表格详细信息 + 获取所有业务表信息 :param db: orm对象 - :return: 需要生成的表格信息对象 + :return: 所有业务表信息 """ gen_table_all = (await db.execute(select(GenTable).options(selectinload(GenTable.columns)))).scalars().all() @@ -87,12 +87,12 @@ class GenTableDao: @classmethod async def get_gen_table_list(cls, db: AsyncSession, query_object: GenTablePageQueryModel, is_page: bool = False): """ - 根据查询参数获取代码生成列表信息 + 根据查询参数获取代码生成业务表列表信息 :param db: orm对象 :param query_object: 查询参数对象 :param is_page: 是否开启分页 - :return: 代码生成列表信息对象 + :return: 代码生成业务表列表信息对象 """ query = ( select(GenTable) @@ -164,11 +164,10 @@ class GenTableDao: @classmethod async def get_gen_db_table_list_by_names(cls, db: AsyncSession, table_names: List[str]): """ - 根据查询参数获取数据库列表信息 + 根据业务表名称组获取数据库列表信息 :param db: orm对象 - :param query_object: 查询参数对象 - :param is_page: 是否开启分页 + :param table_names: 业务表名称组 :return: 数据库列表信息对象 """ query_sql = """ @@ -193,10 +192,10 @@ class GenTableDao: @classmethod async def add_gen_table_dao(cls, db: AsyncSession, gen_table: GenTableModel): """ - 新增岗位数据库操作 + 新增业务表数据库操作 :param db: orm对象 - :param post: 岗位对象 + :param gen_table: 业务表对象 :return: """ db_gen_table = GenTable(**GenTableBaseModel(**gen_table.model_dump(by_alias=True)).model_dump()) @@ -208,10 +207,10 @@ class GenTableDao: @classmethod async def edit_gen_table_dao(cls, db: AsyncSession, gen_table: dict): """ - 编辑岗位数据库操作 + 编辑业务表数据库操作 :param db: orm对象 - :param post: 需要更新的岗位字典 + :param gen_table: 需要更新的业务表字典 :return: """ await db.execute(update(GenTable), [GenTableBaseModel(**gen_table).model_dump()]) @@ -219,10 +218,10 @@ class GenTableDao: @classmethod async def delete_gen_table_dao(cls, db: AsyncSession, gen_table: GenTableModel): """ - 删除岗位数据库操作 + 删除业务表数据库操作 :param db: orm对象 - :param post: 岗位对象 + :param gen_table: 业务表对象 :return: """ await db.execute(delete(GenTable).where(GenTable.table_id.in_([gen_table.table_id]))) @@ -230,17 +229,17 @@ class GenTableDao: class GenTableColumnDao: """ - 代码生成列模块数据库操作层 + 代码生成业务表字段模块数据库操作层 """ @classmethod async def get_gen_table_column_list_by_table_id(cls, db: AsyncSession, table_id: int): """ - 根据表格id获取需要生成的列列表信息 + 根据业务表id获取需要生成的业务表字段列表信息 :param db: orm对象 - :param table_id: 表格id - :return: 需要生成的列列表信息对象 + :param table_id: 业务表id + :return: 需要生成的业务表字段列表信息对象 """ gen_table_column_list = ( (await db.execute(select(GenTableColumn).where(GenTableColumn.table_id == table_id))).scalars().all() @@ -251,12 +250,11 @@ class GenTableColumnDao: @classmethod async def get_gen_db_table_columns_by_name(cls, db: AsyncSession, table_name: str): """ - 根据查询参数获取数据库列表信息 + 根据业务表名称获取业务表字段列表信息 :param db: orm对象 - :param query_object: 查询参数对象 - :param is_page: 是否开启分页 - :return: 数据库列表信息对象 + :param table_name: 业务表名称 + :return: 业务表字段列表信息对象 """ query_sql = """ select @@ -292,10 +290,10 @@ class GenTableColumnDao: @classmethod async def add_gen_table_column_dao(cls, db: AsyncSession, gen_table_column: GenTableColumnModel): """ - 新增岗位数据库操作 + 新增业务表字段数据库操作 :param db: orm对象 - :param post: 岗位对象 + :param gen_table_column: 岗位对象 :return: """ db_gen_table_column = GenTableColumn( @@ -309,10 +307,10 @@ class GenTableColumnDao: @classmethod async def edit_gen_table_column_dao(cls, db: AsyncSession, gen_table_column: dict): """ - 编辑岗位数据库操作 + 编辑业务表字段数据库操作 :param db: orm对象 - :param post: 需要更新的岗位字典 + :param gen_table_column: 需要更新的业务表字段字典 :return: """ await db.execute(update(GenTableColumn), [GenTableColumnBaseModel(**gen_table_column).model_dump()]) @@ -320,10 +318,10 @@ class GenTableColumnDao: @classmethod async def delete_gen_table_column_by_table_id_dao(cls, db: AsyncSession, gen_table_column: GenTableColumnModel): """ - 删除岗位数据库操作 + 通过业务表id删除业务表字段数据库操作 :param db: orm对象 - :param post: 岗位对象 + :param gen_table_column: 业务表字段对象 :return: """ await db.execute(delete(GenTableColumn).where(GenTableColumn.table_id.in_([gen_table_column.table_id]))) @@ -331,10 +329,10 @@ class GenTableColumnDao: @classmethod async def delete_gen_table_column_by_column_id_dao(cls, db: AsyncSession, gen_table_column: GenTableColumnModel): """ - 删除岗位数据库操作 + 通过业务字段id删除业务表字段数据库操作 :param db: orm对象 - :param post: 岗位对象 + :param post: 业务表字段对象 :return: """ await db.execute(delete(GenTableColumn).where(GenTableColumn.column_id.in_([gen_table_column.column_id]))) diff --git a/ruoyi-fastapi-backend/module_generator/service/gen_service.py b/ruoyi-fastapi-backend/module_generator/service/gen_service.py index 0879d31..9132e91 100644 --- a/ruoyi-fastapi-backend/module_generator/service/gen_service.py +++ b/ruoyi-fastapi-backend/module_generator/service/gen_service.py @@ -19,14 +19,13 @@ from module_generator.entity.vo.gen_vo import ( ) from module_generator.dao.gen_dao import GenTableColumnDao, GenTableDao from utils.common_util import CamelCaseUtil -from utils.excel_util import ExcelUtil from utils.gen_util import GenUtils from utils.template_util import TemplateInitializer, TemplateUtils class GenTableService: """ - 岗位管理模块服务层 + 代码生成业务表服务层 """ @classmethod @@ -34,12 +33,12 @@ class GenTableService: cls, query_db: AsyncSession, query_object: GenTablePageQueryModel, is_page: bool = False ): """ - 获取代码生成列表信息service + 获取代码生成业务表列表信息service :param query_db: orm对象 :param query_object: 查询参数对象 :param is_page: 是否开启分页 - :return: 代码生成列表信息对象 + :return: 代码生成业务列表信息对象 """ gen_table_list_result = await GenTableDao.get_gen_table_list(query_db, query_object, is_page) @@ -64,11 +63,10 @@ class GenTableService: @classmethod async def get_gen_db_table_list_by_name_services(cls, query_db: AsyncSession, table_names: List[str]): """ - 获取数据库列表信息service + 根据表名称组获取数据库列表信息service :param query_db: orm对象 - :param query_object: 查询参数对象 - :param is_page: 是否开启分页 + :param table_names: 表名称组 :return: 数据库列表信息对象 """ gen_db_table_list_result = await GenTableDao.get_gen_db_table_list_by_names(query_db, table_names) @@ -79,6 +77,14 @@ class GenTableService: async def import_gen_table_services( cls, query_db: AsyncSession, gen_table_list: List[GenTableModel], current_user: CurrentUserModel ): + """ + 导入表结构service + + :param query_db: orm对象 + :param gen_table_list: 导入表列表 + :param current_user: 当前用户信息对象 + :return: 导入结果 + """ try: for table in gen_table_list: table_name = table.table_name @@ -102,11 +108,11 @@ class GenTableService: @classmethod async def edit_gen_table_services(cls, query_db: AsyncSession, page_object: EditGenTableModel): """ - 编辑岗位信息service + 编辑业务表信息service :param query_db: orm对象 - :param page_object: 编辑岗位对象 - :return: 编辑岗位校验结果 + :param page_object: 编辑业务表对象 + :return: 编辑业务表校验结果 """ edit_gen_table = page_object.model_dump(exclude_unset=True, by_alias=True) gen_table_info = await cls.get_gen_table_by_id_services(query_db, page_object.table_id) @@ -129,11 +135,11 @@ class GenTableService: @classmethod async def delete_gen_table_services(cls, query_db: AsyncSession, page_object: DeleteGenTableModel): """ - 删除岗位信息service + 删除业务表信息service :param query_db: orm对象 - :param page_object: 删除岗位对象 - :return: 删除岗位校验结果 + :param page_object: 删除业务表对象 + :return: 删除业务表校验结果 """ if page_object.table_ids: table_id_list = page_object.table_ids.split(',') @@ -154,25 +160,24 @@ class GenTableService: @classmethod async def get_gen_table_by_id_services(cls, query_db: AsyncSession, table_id: int): """ - 获取需要生成的表格详细信息service + 获取需要生成的业务表详细信息service :param query_db: orm对象 - :param table_id: 需要生成的表格id - :return: 需要生成的表格id对应的信息 + :param table_id: 需要生成的业务表id + :return: 需要生成的业务表id对应的信息 """ gen_table = await GenTableDao.get_gen_table_by_id(query_db, table_id) - result = await cls.set_table_from_options(GenTableModel(**CamelCaseUtil.transform_result(gen_table))) + await cls.set_table_from_options(GenTableModel(**CamelCaseUtil.transform_result(gen_table))) - return result + return gen_table @classmethod async def get_gen_table_all_services(cls, query_db: AsyncSession): """ - 获取需要生成的表格详细信息service + 获取所有业务表信息service :param query_db: orm对象 - :param table_id: 需要生成的表格id - :return: 需要生成的表格id对应的信息 + :return: 所有业务表信息 """ gen_table_all = await GenTableDao.get_gen_table_all(query_db) result = [GenTableModel(**gen_table) for gen_table in CamelCaseUtil.transform_result(gen_table_all)] @@ -225,7 +230,7 @@ class GenTableService: 预览代码service :param query_db: orm对象 - :param table_id: 表格id + :param table_id: 业务表id :return: 预览数据列表 """ gen_table = GenTableModel( @@ -248,7 +253,7 @@ class GenTableService: 生成代码至指定路径service :param query_db: orm对象 - :param table_name: 表格名称 + :param table_name: 业务表名称 :return: 生成代码结果 """ env = TemplateInitializer.init_jinja2() @@ -273,7 +278,7 @@ class GenTableService: 批量生成代码service :param query_db: orm对象 - :param table_names: 表格名称 + :param table_names: 业务表名称组 :return: 下载代码结果 """ zip_buffer = io.BytesIO() @@ -295,7 +300,7 @@ class GenTableService: 获取生成代码渲染模板相关信息 :param query_db: orm对象 - :param table_name: 表格名称 + :param table_name: 业务表名称 :return: 生成代码渲染模板相关信息 """ gen_table = GenTableModel( @@ -327,11 +332,11 @@ class GenTableService: @classmethod async def sync_db_services(cls, query_db: AsyncSession, table_name: str): """ - 获取需要生成的表格详细信息service + 同步数据库service :param query_db: orm对象 - :param table_name: 表格名称 - :return: 需要生成的表格名称对应的信息 + :param table_name: 业务表名称 + :return: 同步数据库结果 """ gen_table = await GenTableDao.get_gen_table_by_name(query_db, table_name) table = GenTableModel(**CamelCaseUtil.transform_result(gen_table)) @@ -381,6 +386,7 @@ class GenTableService: :param query_db: orm对象 :param gen_table: 业务表信息 + :return: """ if gen_table.sub_table_name: sub_table = await GenTableDao.get_gen_table_by_name(query_db, gen_table.sub_table_name) @@ -392,6 +398,7 @@ class GenTableService: 设置主键列信息 :param gen_table: 业务表信息 + :return: """ for column in gen_table.columns: if column.pk: @@ -407,43 +414,13 @@ class GenTableService: if gen_table.sub_table.columns is None: gen_table.sub_table.pk_column = gen_table.sub_table.columns[0] - @staticmethod - async def export_post_list_services(post_list: List): - """ - 导出岗位信息service - - :param post_list: 岗位信息列表 - :return: 岗位信息对应excel的二进制数据 - """ - # 创建一个映射字典,将英文键映射到中文键 - mapping_dict = { - 'postId': '岗位编号', - 'postCode': '岗位编码', - 'postName': '岗位名称', - 'postSort': '显示顺序', - 'status': '状态', - 'createBy': '创建者', - 'createTime': '创建时间', - 'updateBy': '更新者', - 'updateTime': '更新时间', - 'remark': '备注', - } - - for item in post_list: - if item.get('status') == '0': - item['status'] = '正常' - else: - item['status'] = '停用' - binary_data = ExcelUtil.export_list2excel(post_list, mapping_dict) - - return binary_data - @classmethod async def set_table_from_options(cls, gen_table: GenTableModel): """ 设置代码生成其他选项值 :param gen_table: 设置后的生成对象 + :return: """ params_obj = json.loads(gen_table.options) if gen_table.options else None if params_obj: @@ -453,10 +430,13 @@ class GenTableService: gen_table.parent_menu_id = params_obj.get(GenConstant.PARENT_MENU_ID) gen_table.parent_menu_name = params_obj.get(GenConstant.PARENT_MENU_NAME) - return gen_table - @classmethod async def validate_edit(cls, edit_gen_table: EditGenTableModel): + """ + 编辑保存参数校验 + + :param edit_gen_table: 编辑业务表对象 + """ if edit_gen_table.tpl_category == GenConstant.TPL_TREE: params_obj = edit_gen_table.params @@ -474,14 +454,18 @@ class GenTableService: class GenTableColumnService: + """ + 代码生成业务表字段服务层 + """ + @classmethod async def get_gen_table_column_list_by_table_id_services(cls, query_db: AsyncSession, table_id: int): """ - 获取代码生成列列表信息service + 获取业务表字段列表信息service :param query_db: orm对象 - :param table_id: 表格id - :return: 代码生成列列表信息对象 + :param table_id: 业务表格id + :return: 业务表字段列表信息对象 """ gen_table_column_list_result = await GenTableColumnDao.get_gen_table_column_list_by_table_id(query_db, table_id) diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/controller.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/controller.py.jinja2 index 5f6c3d1..6236836 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/python/controller.py.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/python/controller.py.jinja2 @@ -1,6 +1,10 @@ {% set pkField = pkColumn.python_field %} {% set pk_field = pkColumn.python_field | camel_to_snake %} +{% for column in columns %} +{% if column.python_field == "createTime" %} from datetime import datetime +{% endif %} +{% endfor %} from fastapi import APIRouter, Depends, Form, Request from pydantic_validation_decorator import ValidateFields from sqlalchemy.ext.asyncio import AsyncSession @@ -29,18 +33,18 @@ async def get_{{ moduleName }}_{{ businessName }}_list( {{ businessName }}_page_query: {{ BusinessName }}PageQueryModel = Depends({{ BusinessName }}PageQueryModel.as_query), query_db: AsyncSession = Depends(get_db), ): -{% if table.crud or table.sub %} + {% if table.crud or table.sub %} # 获取分页数据 {{ businessName }}_page_query_result = await {{ BusinessName }}Service.get_{{ businessName }}_list_services(query_db, {{ businessName }}_page_query, is_page=True) logger.info('获取成功') return ResponseUtil.success(model_content={{ businessName }}_page_query_result) -{% elif table.tree %} + {% elif table.tree %} {{ businessName }}_query_result = await {{ BusinessName }}Service.get_{{ businessName }}_list_services(query_db, {{ businessName }}_query) logger.info('获取成功') return ResponseUtil.success(data={{ businessName }}_query_result) -{% endif %} + {% endif %} @{{ businessName }}Controller.post('', dependencies=[Depends(CheckUserInterfaceAuth('{{ permissionPrefix }}:add'))]) @@ -52,17 +56,17 @@ async def add_{{ moduleName }}_{{ businessName }}( query_db: AsyncSession = Depends(get_db), current_user: CurrentUserModel = Depends(LoginService.get_current_user), ): -{% for column in columns %} -{% if column.python_field == "createBy" %} + {% for column in columns %} + {% if column.python_field == "createBy" %} add_{{ businessName }}.create_by = current_user.user.user_name -{% elif column.python_field == "createTime" %} + {% elif column.python_field == "createTime" %} add_{{ businessName }}.create_time = datetime.now() -{% elif column.python_field == "updateBy" %} + {% elif column.python_field == "updateBy" %} add_{{ businessName }}.update_by = current_user.user.user_name -{% elif column.python_field == "updateTime" %} + {% elif column.python_field == "updateTime" %} add_{{ businessName }}.update_time = datetime.now() -{% endif %} -{% endfor %} + {% endif %} + {% endfor %} add_{{ businessName }}_result = await {{ BusinessName }}Service.add_{{ businessName }}_services(query_db, add_{{ businessName }}) logger.info(add_{{ businessName }}_result.message) diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2 index b1b99f5..cd2cfdb 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2 @@ -1,8 +1,13 @@ {% set pkField = pkColumn.python_field %} {% set pk_field = pkColumn.python_field | camel_to_snake %} +{% set pkParentheseIndex = pkColumn.column_comment.find("(") %} +{% set pk_field_comment = pkColumn.column_comment[:pkParentheseIndex] if pkParentheseIndex != -1 else pkColumn.column_comment %} from datetime import datetime, time from sqlalchemy import delete, select, update from sqlalchemy.ext.asyncio import AsyncSession +{% if table.sub %} +from sqlalchemy.orm import selectinload +{% endif %} from {{ packageName }}.entity.do.{{ businessName }}_do import {{ ClassName }} from {{ packageName }}.entity.vo.{{ businessName }}_vo import {{ BusinessName }}Model, {{ BusinessName }}PageQueryModel from utils.page_util import PageUtil @@ -16,10 +21,10 @@ class {{ BusinessName }}Dao: @classmethod async def get_{{ businessName }}_detail_by_id(cls, db: AsyncSession, {{ pk_field }}: int): """ - 根据{{ functionName }}id获取{{ functionName }}详细信息 + 根据{{ pk_field_comment }}获取{{ functionName }}详细信息 :param db: orm对象 - :param {{ pk_field }}: 通知公告id + :param {{ pk_field }}: {{ pk_field_comment }} :return: {{ functionName }}信息对象 """ {{ businessName }}_info = (await db.execute(select({{ ClassName }}).where({{ ClassName }}.{{ pk_field }} == {{ pk_field }}))).scalars().first() @@ -64,7 +69,12 @@ class {{ BusinessName }}Dao: :return: {{ functionName }}列表信息对象 """ query = ( + {% if table.sub %%} select({{ ClassName }}) + .options(selectinload{{ ClassName }}.{{ subTable.business_name }}) + {% else %} + select({{ ClassName }}) + {% endif %} .where( {% for column in columns %} {% set field = column.python_field | camel_to_snake %} diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/do.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/do.py.jinja2 index 404d76d..398159b 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/python/do.py.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/python/do.py.jinja2 @@ -1,5 +1,6 @@ -from datetime import datetime -from sqlalchemy import Column, DateTime, Integer, String +{% for do_import in doImportList %} +{{ do_import }} +{% endfor %} {% if table.sub %} from sqlalchemy.orm import relationship {% endif %} @@ -18,23 +19,23 @@ class {{ ClassName }}(Base): {% endfor %} {% if table.sub %} - {{ table.sub_table.business_name }} = relationship('{{ table.sub_table.class_name }}', back_populates='{{ businessName }}') + {{ subTable.business_name }} = relationship('{{ subTable.class_name }}', back_populates='{{ businessName }}') {% endif %} {% if table.sub %} -class {{ table.sub_table.class_name }}(Base): +class {{ subTable.class_name }}(Base): """ - {{ table.sub_table.function_name }}表 + {{ subTable.function_name }}表 """ - __tablename__ = '{{ table.sub_table.table_name }}' + __tablename__ = '{{ subTableName }}' - {% for column in table.sub_table.columns %} + {% for column in subTable.columns %} {{ column.column_name }} = Column({{ column.column_type | get_sqlalchemy_type }}, {% if column.pk %}primary_key=True, {% endif %}{% if column.increment %}autoincrement=True, {% endif %}{% if column.required %}nullable=True{% else %}nullable=False{% endif %}, comment='{{ column.column_comment }}') {% endfor %} {% if table.sub %} - {{ businessName }} = relationship('{{ ClassName }}', back_populates='{{ table.sub_table.business_name }}') + {{ businessName }} = relationship('{{ ClassName }}', back_populates='{{ subTable.business_name }}') {% endif %} {% endif %} diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2 index 1a2ad71..4020cd7 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2 @@ -1,6 +1,7 @@ {% set pkField = pkColumn.python_field %} {% set pk_field = pkColumn.python_field | camel_to_snake %} -{% set pk_field_comment = pkColumn.comment %} +{% set pkParentheseIndex = pkColumn.column_comment.find("(") %} +{% set pk_field_comment = pkColumn.column_comment[:pkParentheseIndex] if pkParentheseIndex != -1 else pkColumn.column_comment %} from sqlalchemy.ext.asyncio import AsyncSession from typing import List from config.constant import CommonConstant @@ -87,8 +88,8 @@ class {{ BusinessName }}Service: :return: 编辑{{ functionName }}校验结果 """ edit_{{ businessName }} = page_object.model_dump(exclude_unset=True) - {{ businessName }}_info = await cls.{{ businessName }}_detail_services(query_db, page_object.post_id) - if {{ businessName }}_info.post_id: + {{ businessName }}_info = await cls.{{ businessName }}_detail_services(query_db, page_object.{{ pk_field }}) + if {{ businessName }}_info.{{ pk_field }}: if not await cls.check_post_name_unique_services(query_db, page_object): raise ServiceException(message=f'修改岗位{page_object.post_name}失败,岗位名称已存在') elif not await cls.check_post_code_unique_services(query_db, page_object): @@ -133,8 +134,8 @@ class {{ BusinessName }}Service: 获取{{ functionName }}详细信息service :param query_db: orm对象 - :param post_id: 岗位id - :return: 岗位id对应的信息 + :param {{ pk_field }}: {{ pk_field_comment }} + :return: {{ pk_field_comment }}对应的信息 """ {{ businessName }} = await {{ BusinessName }}Dao.get_{{ businessName }}_detail_by_id(query_db, {{ pk_field }}={{ pk_field }}) if {{ businessName }}: diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2 index cd07326..c29a0cf 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2 @@ -1,11 +1,14 @@ {% set pkField = pkColumn.python_field %} {% set pk_field = pkColumn.python_field | camel_to_snake %} -{% set pk_field_comment = pkColumn.comment %} -from datetime import datetime +{% set pkParentheseIndex = pkColumn.column_comment.find("(") %} +{% set pk_field_comment = pkColumn.column_comment[:pkParentheseIndex] if pkParentheseIndex != -1 else pkColumn.column_comment %} +{% for vo_import in voImportList %} +{{ vo_import }} +{% endfor %} from pydantic import BaseModel, ConfigDict, Field from pydantic.alias_generators import to_camel from pydantic_validation_decorator import NotBlank -from typing import Literal, Optional +from typing import Optional from module_admin.annotation.pydantic_annotation import as_query diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2 index e69de29..b33a65b 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2 @@ -0,0 +1,454 @@ + + + \ No newline at end of file diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2 index 31b3cf8..a6d80f6 100644 --- a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2 +++ b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2 @@ -7,7 +7,6 @@ {% set AttrName = column.python_field[0] | upper + column.python_field[1:] %} {% set parentheseIndex = column.column_comment.find("(") %} {% set comment = column.column_comment[:parentheseIndex] if parentheseIndex != -1 else column.column_comment %} - {% if column.html_type == "input" %} None: - """初始化表信息""" + """ + 初始化表信息 + + param gen_table: 业务表对象 + param oper_name: 操作人 + :return: + """ gen_table.class_name = cls.convert_class_name(gen_table.table_name) gen_table.package_name = GenConfig.package_name gen_table.module_name = cls.get_module_name(GenConfig.package_name) @@ -26,7 +32,13 @@ class GenUtils: @classmethod def init_column_field(cls, column: GenTableColumnModel, table: GenTableModel) -> None: - """初始化列属性字段""" + """ + 初始化列属性字段 + + param column: 业务表字段对象 + param table: 业务表对象 + :return: + """ data_type = cls.get_db_type(column.column_type) column_name = column.column_name column.table_id = table.table_id @@ -34,7 +46,9 @@ class GenUtils: # 设置Python字段名 column.python_field = cls.to_camel_case(column_name) # 设置默认类型 - column.python_type = StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.MYSQL_TO_PYTHON_TYPE_MAPPING, data_type) + column.python_type = StringUtil.get_mapping_value_by_key_ignore_case( + GenConstant.MYSQL_TO_PYTHON_TYPE_MAPPING, data_type + ) column.query_type = GenConstant.QUERY_EQ if cls.arrays_contains(GenConstant.COLUMNTYPE_STR, data_type) or cls.arrays_contains( @@ -87,22 +101,43 @@ class GenUtils: @classmethod def arrays_contains(cls, arr: List[str], target_value: str) -> bool: - """校验数组是否包含指定值""" + """ + 校验数组是否包含指定值 + + param arr: 数组 + param target_value: 需要校验的值 + :return: 校验结果 + """ return target_value in arr @classmethod def get_module_name(cls, package_name: str) -> str: - """获取模块名""" + """ + 获取模块名 + + param package_name: 包名 + :return: 模块名 + """ return package_name.split('.')[-1] @classmethod def get_business_name(cls, table_name: str) -> str: - """获取业务名""" + """ + 获取业务名 + + param table_name: 业务表名 + :return: 业务名 + """ return table_name.split('_')[-1] @classmethod def convert_class_name(cls, table_name: str) -> str: - """表名转换成Python类名""" + """ + 表名转换成Python类名 + + param table_name: 业务表名 + :return: Python类名 + """ auto_remove_pre = GenConfig.auto_remove_pre table_prefix = GenConfig.table_prefix if auto_remove_pre and table_prefix: @@ -112,7 +147,13 @@ class GenUtils: @classmethod def replace_first(cls, replacement: str, search_list: List[str]) -> str: - """批量替换前缀""" + """ + 批量替换前缀 + + param replacement: 需要被替换的字符串 + param search_list: 可替换的字符串列表 + :return: 替换后的字符串 + """ for search_string in search_list: if replacement.startswith(search_string): return replacement.replace(search_string, '', 1) @@ -120,19 +161,34 @@ class GenUtils: @classmethod def replace_text(cls, text: str) -> str: - """关键字替换""" + """ + 关键字替换 + + param text: 需要被替换的字符串 + :return: 替换后的字符串 + """ return re.sub(r'(?:表|若依)', '', text) @classmethod def get_db_type(cls, column_type: str) -> str: - """获取数据库类型字段""" + """ + 获取数据库类型字段 + + param column_type: 字段类型 + :return: 数据库类型 + """ if '(' in column_type: return column_type.split('(')[0] return column_type @classmethod def get_column_length(cls, column_type: str) -> int: - """获取字段长度""" + """ + 获取字段长度 + + param column_type: 字段类型 + :return: 字段长度 + """ if '(' in column_type: length = len(column_type.split('(')[1].split(')')[0]) return length @@ -140,13 +196,23 @@ class GenUtils: @classmethod def split_column_type(cls, column_type: str) -> List[str]: - """拆分列类型""" + """ + 拆分列类型 + + param column_type: 字段类型 + :return: 拆分结果 + """ if '(' in column_type and ')' in column_type: return column_type.split('(')[1].split(')')[0].split(',') return [] @classmethod def to_camel_case(cls, text: str) -> str: - """将字符串转换为驼峰命名""" + """ + 将字符串转换为驼峰命名 + + param text: 需要转换的字符串 + :return: 驼峰命名 + """ parts = text.split('_') return parts[0] + ''.join(word.capitalize() for word in parts[1:]) diff --git a/ruoyi-fastapi-backend/utils/template_util.py b/ruoyi-fastapi-backend/utils/template_util.py index 47c4ac3..19c8573 100644 --- a/ruoyi-fastapi-backend/utils/template_util.py +++ b/ruoyi-fastapi-backend/utils/template_util.py @@ -55,6 +55,7 @@ class TemplateUtils: def prepare_context(cls, gen_table: GenTableModel): """ 准备模板变量 + :param gen_table: 生成表的配置信息 :return: 模板上下文字典 """ @@ -79,7 +80,8 @@ class TemplateUtils: 'author': gen_table.function_author, 'datetime': datetime.now().strftime('%Y-%m-%d %H:%M:%S'), 'pkColumn': gen_table.pk_column, - 'importList': cls.get_import_list(gen_table), + 'doImportList': cls.get_do_import_list(gen_table), + 'voImportList': cls.get_vo_import_list(gen_table), 'permissionPrefix': cls.get_permission_prefix(module_name, business_name), 'columns': gen_table.columns, 'table': gen_table, @@ -97,14 +99,26 @@ class TemplateUtils: @classmethod def set_menu_context(cls, context: Dict, gen_table: GenTableModel): - """设置菜单上下文""" + """ + 设置菜单上下文 + + :param context: 模板上下文字典 + :param gen_table: 生成表的配置信息 + :return: 新的模板上下文字典 + """ options = gen_table.options params_obj = json.loads(options) context['parentMenuId'] = cls.get_parent_menu_id(params_obj) @classmethod def set_tree_context(cls, context: Dict, gen_table: GenTableModel): - """设置树形结构上下文""" + """ + 设置树形结构上下文 + + :param context: 模板上下文字典 + :param gen_table: 生成表的配置信息 + :return: 新的模板上下文字典 + """ options = gen_table.options params_obj = json.loads(options) context['treeCode'] = cls.get_tree_code(params_obj) @@ -114,7 +128,13 @@ class TemplateUtils: @classmethod def set_sub_context(cls, context: Dict, gen_table: GenTableModel): - """设置子表上下文""" + """ + 设置子表上下文 + + :param context: 模板上下文字典 + :param gen_table: 生成表的配置信息 + :return: 新的模板上下文字典 + """ sub_table = gen_table.sub_table sub_table_name = gen_table.sub_table_name sub_table_fk_name = gen_table.sub_table_fk_name @@ -127,11 +147,16 @@ class TemplateUtils: context['subTableFkclassName'] = sub_table_fk_class_name.lower() context['subClassName'] = sub_class_name context['subclassName'] = sub_class_name.lower() - context['subImportList'] = cls.get_import_list(sub_table) @classmethod - def get_template_list(cls, tpl_category, tpl_web_type): - """获取模板列表""" + def get_template_list(cls, tpl_category: str, tpl_web_type: str): + """ + 获取模板列表 + + :param tpl_category: 生成模板类型 + :param tpl_web_type: 前端类型 + :return: 模板列表 + """ use_web_type = 'vue' if tpl_web_type == 'element-plus': use_web_type = 'vue/v3' @@ -154,14 +179,20 @@ class TemplateUtils: return templates @classmethod - def get_file_name(cls, template, gen_table: GenTableModel): - """根据模板生成文件名""" + def get_file_name(cls, template: List[str], gen_table: GenTableModel): + """ + 根据模板生成文件名 + + :param template: 模板列表 + :param gen_table: 生成表的配置信息 + :return: 模板生成文件名 + """ package_name = gen_table.package_name module_name = gen_table.module_name business_name = gen_table.business_name vue_path = cls.FRONTEND_PROJECT_PATH - python_path = f"{cls.BACKEND_PROJECT_PATH}/{package_name.replace('.', '/')}" + python_path = f'{cls.BACKEND_PROJECT_PATH}/{package_name.replace(".", "/")}' if 'controller.py.jinja2' in template: return f'{python_path}/controller/{business_name}_controller.py' @@ -183,27 +214,106 @@ class TemplateUtils: @classmethod def get_package_prefix(cls, package_name: str): - """获取包前缀""" + """ + 获取包前缀 + + :param package_name: 包名 + :return: 包前缀 + """ return package_name[: package_name.rfind('.')] @classmethod - def get_import_list(cls, gen_table: GenTableModel): - """获取导入包列表""" + def get_vo_import_list(cls, gen_table: GenTableModel): + """ + 获取vo模板导入包列表 + + :param gen_table: 生成表的配置信息 + :return: 导入包列表 + """ columns = gen_table.columns or [] - sub_gen_table = gen_table.sub_table import_list = set() - if sub_gen_table is not None: - import_list.add('python.util.List') for column in columns: - if not column.super_column and column.python_type in GenConstant.TYPE_DATE: + if column.python_type in GenConstant.TYPE_DATE: import_list.add(f'from datetime import {column.python_type}') - elif not column.super_column and column.python_type == GenConstant.TYPE_DECIMAL: + elif column.python_type == GenConstant.TYPE_DECIMAL: import_list.add('from decimal import Decimal') - return list(import_list) + if gen_table.sub: + sub_columns = gen_table.sub_table.columns or [] + for sub_column in sub_columns: + if sub_column.python_type in GenConstant.TYPE_DATE: + import_list.add(f'from datetime import {column.python_type}') + elif sub_column.python_type == GenConstant.TYPE_DECIMAL: + import_list.add('from decimal import Decimal') + return cls.merge_same_imports(list(import_list), 'from datetime import') + + @classmethod + def get_do_import_list(cls, gen_table: GenTableModel): + """ + 获取do模板导入包列表 + + :param gen_table: 生成表的配置信息 + :return: 导入包列表 + """ + columns = gen_table.columns or [] + import_list = set() + for column in columns: + data_type = cls.get_db_type(column.column_type) + import_list.add( + f'from sqlalchemy import {StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.MYSQL_TO_SQLALCHEMY_TYPE_MAPPING, data_type)}' + ) + if gen_table.sub: + sub_columns = gen_table.sub_table.columns or [] + for sub_column in sub_columns: + if sub_column.python_type in GenConstant.TYPE_DATE: + import_list.add(f'from datetime import {column.python_type}') + elif sub_column.python_type == GenConstant.TYPE_DECIMAL: + import_list.add('from decimal import Decimal') + return cls.merge_same_imports(list(import_list), 'from sqlalchemy import') + + @classmethod + def get_db_type(cls, column_type: str) -> str: + """ + 获取数据库类型字段 + + param column_type: 字段类型 + :return: 数据库类型 + """ + if '(' in column_type: + return column_type.split('(')[0] + return column_type + + @classmethod + def merge_same_imports(cls, imports: List[str], import_start: str) -> List[str]: + """ + 合并相同的导入语句 + + :param imports: 导入语句列表 + :param import_start: 导入语句的起始字符串 + :return: 合并后的导入语句列表 + """ + merged_imports = [] + _imports = [] + for import_stmt in imports: + if import_stmt.startswith(import_start): + imported_items = import_stmt.split('import')[1].strip() + _imports.extend(imported_items.split(', ')) + else: + merged_imports.append(import_stmt) + + if _imports: + merged_datetime_import = f'{import_start} {", ".join(_imports)}' + merged_imports.append(merged_datetime_import) + + return merged_imports @classmethod def get_dicts(cls, gen_table: GenTableModel): - """获取字典列表""" + """ + 获取字典列表 + + :param gen_table: 生成表的配置信息 + :return: 字典列表 + """ columns = gen_table.columns or [] dicts = set() cls.add_dicts(dicts, columns) @@ -213,7 +323,13 @@ class TemplateUtils: @classmethod def add_dicts(cls, dicts: Set[str], columns: List[GenTableColumnModel]): - """添加字典列表""" + """ + 添加字典列表 + + :param dicts: 字典列表 + :param columns: 字段列表 + :return: 新的字典列表 + """ for column in columns: if ( column.super_column @@ -226,40 +342,71 @@ class TemplateUtils: @classmethod def get_permission_prefix(cls, module_name: str, business_name: str): - """获取权限前缀""" + """ + 获取权限前缀 + + :param module_name: 模块名 + :param business_name: 业务名 + :return: 权限前缀 + """ return f'{module_name}:{business_name}' @classmethod - def get_parent_menu_id(cls, params_obj): - """获取上级菜单ID""" + def get_parent_menu_id(cls, params_obj: Dict): + """ + 获取上级菜单ID + + :param params_obj: 菜单参数字典 + :return: 上级菜单ID + """ if params_obj and params_obj.get(GenConstant.PARENT_MENU_ID): return params_obj.get(GenConstant.PARENT_MENU_ID) return cls.DEFAULT_PARENT_MENU_ID @classmethod def get_tree_code(cls, params_obj: Dict): - """获取树编码""" + """ + 获取树编码 + + :param params_obj: 菜单参数字典 + :return: 树编码 + """ if GenConstant.TREE_CODE in params_obj: return cls.to_camel_case(params_obj.get(GenConstant.TREE_CODE)) return '' @classmethod def get_tree_parent_code(cls, params_obj: Dict): - """获取树父编码""" + """ + 获取树父编码 + + :param params_obj: 菜单参数字典 + :return: 树父编码 + """ if GenConstant.TREE_PARENT_CODE in params_obj: return cls.to_camel_case(params_obj.get(GenConstant.TREE_PARENT_CODE)) return '' @classmethod def get_tree_name(cls, params_obj: Dict): - """获取树名称""" + """ + 获取树名称 + + :param params_obj: 菜单参数字典 + :return: 树名称 + """ if GenConstant.TREE_NAME in params_obj: return cls.to_camel_case(params_obj.get(GenConstant.TREE_NAME)) return '' @classmethod def get_expand_column(cls, gen_table: GenTableModel): - """获取展开列""" + """ + 获取展开列 + + :param gen_table: 生成表的配置信息 + :return: 展开列 + """ options = gen_table.options params_obj = json.loads(options) tree_name = params_obj.get(GenConstant.TREE_NAME) @@ -273,12 +420,23 @@ class TemplateUtils: @classmethod def to_camel_case(cls, text: str) -> str: - """将字符串转换为驼峰命名""" + """ + 将字符串转换为驼峰命名 + + :param text: 待转换的字符串 + :return: 转换后的驼峰命名字符串 + """ parts = text.split('_') return parts[0] + ''.join(word.capitalize() for word in parts[1:]) @classmethod def get_sqlalchemy_type(cls, column_type: str): + """ + 获取SQLAlchemy类型 + + :param column_type: 列类型 + :return: SQLAlchemy类型 + """ if '(' in column_type: column_type_list = column_type.split('(') sqlalchemy_type = (