diff --git a/backend/app/plugin/module_generator/gencode/templates/python/controller.py.j2 b/backend/app/plugin/module_generator/gencode/templates/python/controller.py.j2 index 1d890567..37d9f56f 100644 --- a/backend/app/plugin/module_generator/gencode/templates/python/controller.py.j2 +++ b/backend/app/plugin/module_generator/gencode/templates/python/controller.py.j2 @@ -16,23 +16,50 @@ from .schema import {{ class_name }}CreateSchema, {{ class_name }}UpdateSchema, {{ class_name }}Router = APIRouter(prefix='/{{ business_name }}', tags=["{{ function_name }}模块"]) -@{{ class_name }}Router.get("/detail/{id}", summary="获取{{ function_name }}详情", description="获取{{ function_name }}详情") +@{{ class_name }}Router.get( + "/detail/{id}", + summary="获取{{ function_name }}详情", + description="获取{{ function_name }}详情" +) async def get_{{ business_name }}_detail_controller( id: int = Path(..., description="ID"), auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:query"])) ) -> JSONResponse: - """获取{{ function_name }}详情接口""" + """ + 获取{{ function_name }}详情接口 + + 参数: + - id: int - 数据ID + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含{{ function_name }}详情的JSON响应 + """ result_dict = await {{ class_name }}Service.detail_{{ business_name }}_service(auth=auth, id=id) log.info(f"获取{{ function_name }}详情成功 {id}") return SuccessResponse(data=result_dict, msg="获取{{ function_name }}详情成功") -@{{ class_name }}Router.get("/list", summary="查询{{ function_name }}列表", description="查询{{ function_name }}列表") +@{{ class_name }}Router.get( + "/list", + summary="查询{{ function_name }}列表", + description="查询{{ function_name }}列表" +) async def get_{{ business_name }}_list_controller( page: PaginationQueryParam = Depends(), search: {{ class_name }}QueryParam = Depends(), auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:query"])) ) -> JSONResponse: - """查询{{ function_name }}列表接口(数据库分页)""" + """ + 查询{{ function_name }}列表接口(数据库分页) + + 参数: + - page: PaginationQueryParam - 分页参数 + - search: {{ class_name }}QueryParam - 查询参数 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含{{ function_name }}列表的JSON响应 + """ result_dict = await {{ class_name }}Service.page_{{ business_name }}_service( auth=auth, page_no=page.page_no if page.page_no is not None else 1, @@ -43,77 +70,164 @@ async def get_{{ business_name }}_list_controller( log.info("查询{{ function_name }}列表成功") return SuccessResponse(data=result_dict, msg="查询{{ function_name }}列表成功") -@{{ class_name }}Router.post("/create", summary="创建{{ function_name }}", description="创建{{ function_name }}") +@{{ class_name }}Router.post( + "/create", + summary="创建{{ function_name }}", + description="创建{{ function_name }}" +) async def create_{{ business_name }}_controller( data: {{ class_name }}CreateSchema, auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:create"])) ) -> JSONResponse: - """创建{{ function_name }}接口""" + """ + 创建{{ function_name }}接口 + + 参数: + - data: {{ class_name }}CreateSchema - 创建数据 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含创建{{ function_name }}结果的JSON响应 + """ result_dict = await {{ class_name }}Service.create_{{ business_name }}_service(auth=auth, data=data) log.info("创建{{ function_name }}成功") return SuccessResponse(data=result_dict, msg="创建{{ function_name }}成功") -@{{ class_name }}Router.put("/update/{id}", summary="修改{{ function_name }}", description="修改{{ function_name }}") +@{{ class_name }}Router.put( + "/update/{id}", + summary="修改{{ function_name }}", + description="修改{{ function_name }}" +) async def update_{{ business_name }}_controller( data: {{ class_name }}UpdateSchema, id: int = Path(..., description="ID"), auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:update"])) ) -> JSONResponse: - """修改{{ function_name }}接口""" + """ + 修改{{ function_name }}接口 + + 参数: + - id: int - 数据ID + - data: {{ class_name }}UpdateSchema - 更新数据 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含修改{{ function_name }}结果的JSON响应 + """ result_dict = await {{ class_name }}Service.update_{{ business_name }}_service(auth=auth, id=id, data=data) log.info("修改{{ function_name }}成功") return SuccessResponse(data=result_dict, msg="修改{{ function_name }}成功") -@{{ class_name }}Router.delete("/delete", summary="删除{{ function_name }}", description="删除{{ function_name }}") +@{{ class_name }}Router.delete( + "/delete", + summary="删除{{ function_name }}", + description="删除{{ function_name }}" +) async def delete_{{ business_name }}_controller( ids: list[int] = Body(..., description="ID列表"), auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:delete"])) ) -> JSONResponse: - """删除{{ function_name }}接口""" + """ + 删除{{ function_name }}接口 + + 参数: + - ids: list[int] - 数据ID列表 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含删除{{ function_name }}结果的JSON响应 + """ await {{ class_name }}Service.delete_{{ business_name }}_service(auth=auth, ids=ids) log.info(f"删除{{ function_name }}成功: {ids}") return SuccessResponse(msg="删除{{ function_name }}成功") -@{{ class_name }}Router.patch("/available/setting", summary="批量修改{{ function_name }}状态", description="批量修改{{ function_name }}状态") +@{{ class_name }}Router.patch( + "/available/setting", + summary="批量修改{{ function_name }}状态", + description="批量修改{{ function_name }}状态" +) async def batch_set_available_{{ business_name }}_controller( data: BatchSetAvailable, auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:patch"])) ) -> JSONResponse: - """批量修改{{ function_name }}状态接口""" + """ + 批量修改{{ function_name }}状态接口 + + 参数: + - data: BatchSetAvailable - 批量修改状态数据 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含批量修改{{ function_name }}状态结果的JSON响应 + """ await {{ class_name }}Service.set_available_{{ business_name }}_service(auth=auth, data=data) log.info(f"批量修改{{ function_name }}状态成功: {data.ids}") return SuccessResponse(msg="批量修改{{ function_name }}状态成功") -@{{ class_name }}Router.post('/export', summary="导出{{ function_name }}", description="导出{{ function_name }}") +@{{ class_name }}Router.post( + '/export', + summary="导出{{ function_name }}", + description="导出{{ function_name }}" +) async def export_{{ business_name }}_list_controller( search: {{ class_name }}QueryParam = Depends(), auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:export"])) ) -> StreamingResponse: - """导出{{ function_name }}接口""" + """ + 导出{{ function_name }}接口 + + 参数: + - search: {{ class_name }}QueryParam - 查询参数 + - auth: AuthSchema - 认证信息 + + 返回: + - StreamingResponse - 包含导出{{ function_name }}数据的流式响应 + """ result_dict_list = await {{ class_name }}Service.list_{{ business_name }}_service(search=search, auth=auth) export_result = await {{ class_name }}Service.batch_export_{{ business_name }}_service(obj_list=result_dict_list) log.info('导出{{ function_name }}成功') return StreamResponse( data=bytes2file_response(export_result), media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - headers={ - 'Content-Disposition': 'attachment; filename={{ table_name }}.xlsx' - } + headers={'Content-Disposition': 'attachment; filename={{ table_name }}.xlsx'} ) -@{{ class_name }}Router.post('/import', summary="导入{{ function_name }}", description="导入{{ function_name }}") +@{{ class_name }}Router.post( + '/import', + summary="导入{{ function_name }}", + description="导入{{ function_name }}" +) async def import_{{ business_name }}_list_controller( file: UploadFile, auth: AuthSchema = Depends(AuthPermission(["{{ permission_prefix }}:import"])) ) -> JSONResponse: - """导入{{ function_name }}接口""" + """ + 导入{{ function_name }}接口 + + 参数: + - file: UploadFile - 上传的Excel文件 + - auth: AuthSchema - 认证信息 + + 返回: + - JSONResponse - 包含导入{{ function_name }}结果的JSON响应 + """ batch_import_result = await {{ class_name }}Service.batch_import_{{ business_name }}_service(file=file, auth=auth, update_support=True) log.info("导入{{ function_name }}成功") return SuccessResponse(data=batch_import_result, msg="导入{{ function_name }}成功") -@{{ class_name }}Router.post('/download/template', summary="获取{{ function_name }}导入模板", description="获取{{ function_name }}导入模板", dependencies=[Depends(AuthPermission(["{{ permission_prefix }}:download"]))]) +@{{ class_name }}Router.post( + '/download/template', + summary="获取{{ function_name }}导入模板", + description="获取{{ function_name }}导入模板", + dependencies=[Depends(AuthPermission(["{{ permission_prefix }}:download"]))] +) async def export_{{ business_name }}_template_controller() -> StreamingResponse: - """获取{{ function_name }}导入模板接口""" + """ + 获取{{ function_name }}导入模板接口 + + 返回: + - StreamingResponse - 包含{{ function_name }}导入模板的流式响应 + """ import_template_result = await {{ class_name }}Service.import_template_download_{{ business_name }}_service() log.info('获取{{ function_name }}导入模板成功') return StreamResponse( diff --git a/backend/app/plugin/module_generator/gencode/templates/python/schema.py.j2 b/backend/app/plugin/module_generator/gencode/templates/python/schema.py.j2 index c48696b0..5d8427f9 100644 --- a/backend/app/plugin/module_generator/gencode/templates/python/schema.py.j2 +++ b/backend/app/plugin/module_generator/gencode/templates/python/schema.py.j2 @@ -11,6 +11,7 @@ from fastapi import Query {% if table.created_time %} from app.core.validator import DateTimeStr {% endif %} +from app.common.enums import QueueEnum from app.core.base_schema import BaseSchema, UserBySchema class {{ class_name }}CreateSchema(BaseModel): @@ -69,18 +70,28 @@ class {{ class_name }}QueryParam: {% for column in columns %} {% if column.query_type == 'LIKE' %} # 模糊查询字段 - self.{{ column.column_name }} = ("like", {{ column.column_name }}) + self.{{ column.column_name }} = (QueueEnum.like.value, {{ column.column_name }}) {% elif column.query_type == 'EQ' and column.column_name not in ['created_time', 'updated_time'] %} # 精确查询字段 - self.{{ column.column_name }} = {{ column.column_name }} + if {{ column.column_name }}: + self.{{ column.column_name }} = (QueueEnum.eq.value, {{ column.column_name }}) {% endif %} {% endfor %} {% if table.created_time %} # 时间范围查询 if created_time and len(created_time) == 2: - self.created_time = ("between", (created_time[0], created_time[1])) + self.created_time = (QueueEnum.between.value, (created_time[0], created_time[1])) {% endif %} {% if table.updated_time %} if updated_time and len(updated_time) == 2: - self.updated_time = ("between", (updated_time[0], updated_time[1])) + self.updated_time = (QueueEnum.between.value, (updated_time[0], updated_time[1])) + {% endif %} + {% if table.created_id %} + # 关联查询字段 + if created_id: + self.created_id = (QueueEnum.eq.value, created_id) + {% endif %} + {% if table.updated_id %} + if updated_id: + self.updated_id = (QueueEnum.eq.value, updated_id) {% endif %} diff --git a/backend/app/plugin/module_generator/gencode/templates/python/service.py.j2 b/backend/app/plugin/module_generator/gencode/templates/python/service.py.j2 index 829777ab..799424d9 100644 --- a/backend/app/plugin/module_generator/gencode/templates/python/service.py.j2 +++ b/backend/app/plugin/module_generator/gencode/templates/python/service.py.j2 @@ -1,16 +1,22 @@ # -*- coding: utf-8 -*- import io -from fastapi import UploadFile import pandas as pd +from fastapi import UploadFile +from app.api.v1.module_system.auth.schema import AuthSchema from app.core.base_schema import BatchSetAvailable from app.core.exceptions import CustomException -from app.utils.excel_util import ExcelUtil from app.core.logger import log -from app.api.v1.module_system.auth.schema import AuthSchema -from .schema import {{ class_name }}CreateSchema, {{ class_name }}UpdateSchema, {{ class_name }}OutSchema, {{ class_name }}QueryParam +from app.utils.excel_util import ExcelUtil + from .crud import {{ class_name }}CRUD +from .schema import ( + {{ class_name }}CreateSchema, + {{ class_name }}UpdateSchema, + {{ class_name }}OutSchema, + {{ class_name }}QueryParam +) class {{ class_name }}Service: @@ -20,7 +26,16 @@ class {{ class_name }}Service: @classmethod async def detail_{{ business_name }}_service(cls, auth: AuthSchema, id: int) -> dict: - """详情""" + """ + 详情 + + 参数: + - auth: AuthSchema - 认证信息 + - id: int - 数据ID + + 返回: + - dict - 数据详情 + """ obj = await {{ class_name }}CRUD(auth).get_by_id_{{ business_name }}_crud(id=id) if not obj: raise CustomException(msg="该数据不存在") @@ -28,14 +43,36 @@ class {{ class_name }}Service: @classmethod async def list_{{ business_name }}_service(cls, auth: AuthSchema, search: {{ class_name }}QueryParam | None = None, order_by: list[dict] | None = None) -> list[dict]: - """列表查询""" + """ + 列表查询 + + 参数: + - auth: AuthSchema - 认证信息 + - search: {{ class_name }}QueryParam | None - 查询参数 + - order_by: list[dict] | None - 排序参数 + + 返回: + - list[dict] - 数据列表 + """ search_dict = search.__dict__ if search else None obj_list = await {{ class_name }}CRUD(auth).list_{{ business_name }}_crud(search=search_dict, order_by=order_by) return [{{ class_name }}OutSchema.model_validate(obj).model_dump() for obj in obj_list] @classmethod async def page_{{ business_name }}_service(cls, auth: AuthSchema, page_no: int, page_size: int, search: {{ class_name }}QueryParam | None = None, order_by: list[dict] | None = None) -> dict: - """分页查询(数据库分页)""" + """ + 分页查询(数据库分页) + + 参数: + - auth: AuthSchema - 认证信息 + - page_no: int - 页码 + - page_size: int - 每页数量 + - search: {{ class_name }}QueryParam | None - 查询参数 + - order_by: list[dict] | None - 排序参数 + + 返回: + - dict - 分页查询结果 + """ search_dict = search.__dict__ if search else {} order_by_list = order_by or [{'id': 'asc'}] offset = (page_no - 1) * page_size @@ -49,8 +86,16 @@ class {{ class_name }}Service: @classmethod async def create_{{ business_name }}_service(cls, auth: AuthSchema, data: {{ class_name }}CreateSchema) -> dict: - """创建""" - # 检查唯一性约束 + """ + 创建 + + 参数: + - auth: AuthSchema - 认证信息 + - data: {{ class_name }}CreateSchema - 创建数据 + + 返回: + - dict - 创建结果 + """ {% for column in columns %} {% if column.is_unique == '1' %} obj = await {{ class_name }}CRUD(auth).get({{ column.column_name }}=data.{{ column.column_name }}) @@ -63,7 +108,17 @@ class {{ class_name }}Service: @classmethod async def update_{{ business_name }}_service(cls, auth: AuthSchema, id: int, data: {{ class_name }}UpdateSchema) -> dict: - """更新""" + """ + 更新 + + 参数: + - auth: AuthSchema - 认证信息 + - id: int - 数据ID + - data: {{ class_name }}UpdateSchema - 更新数据 + + 返回: + - dict - 更新结果 + """ # 检查数据是否存在 obj = await {{ class_name }}CRUD(auth).get_by_id_{{ business_name }}_crud(id=id) if not obj: @@ -83,7 +138,16 @@ class {{ class_name }}Service: @classmethod async def delete_{{ business_name }}_service(cls, auth: AuthSchema, ids: list[int]) -> None: - """删除""" + """ + 删除 + + 参数: + - auth: AuthSchema - 认证信息 + - ids: list[int] - 数据ID列表 + + 返回: + - None + """ if len(ids) < 1: raise CustomException(msg='删除失败,删除对象不能为空') for id in ids: @@ -94,36 +158,61 @@ class {{ class_name }}Service: @classmethod async def set_available_{{ business_name }}_service(cls, auth: AuthSchema, data: BatchSetAvailable) -> None: - """批量设置状态""" + """ + 批量设置状态 + + 参数: + - auth: AuthSchema - 认证信息 + - data: BatchSetAvailable - 批量设置状态数据 + + 返回: + - None + """ await {{ class_name }}CRUD(auth).set_available_{{ business_name }}_crud(ids=data.ids, status=data.status) @classmethod async def batch_export_{{ business_name }}_service(cls, obj_list: list[dict]) -> bytes: - """批量导出""" + """ + 批量导出 + + 参数: + - obj_list: list[dict] - 数据列表 + + 返回: + - bytes - 导出的Excel文件内容 + """ mapping_dict = { {% for column in columns %} '{{ column.column_name }}': '{{ column.column_comment }}', {% endfor %} - 'updated_id': '更新者ID', } - + # 复制数据并转换状态 data = obj_list.copy() for item in data: - # 状态转换 - if 'status' in item: - item['status'] = '启用' if item.get('status') == '0' else '停用' - # 创建者转换 - creator_info = item.get('creator') + # 处理状态 + item["status"] = "启用" if item.get("status") == "0" else "停用" + # 处理创建者 + creator_info = item.get("created_id") if isinstance(creator_info, dict): - item['creator'] = creator_info.get('name', '未知') - elif creator_info is None: - item['creator'] = '未知' + item["created_id"] = creator_info.get("name", "未知") + else: + item["created_id"] = "未知" return ExcelUtil.export_list2excel(list_data=data, mapping_dict=mapping_dict) @classmethod async def batch_import_{{ business_name }}_service(cls, auth: AuthSchema, file: UploadFile, update_support: bool = False) -> str: - """批量导入""" + """ + 批量导入 + + 参数: + - auth: AuthSchema - 认证信息 + - file: UploadFile - 上传的Excel文件 + - update_support: bool - 是否支持更新存在数据 + + 返回: + - str - 导入结果信息 + """ header_dict = { {% for column in columns %} '{{ column.column_comment }}': '{{ column.column_name }}', @@ -131,17 +220,20 @@ class {{ class_name }}Service: } try: + # 读取Excel文件 contents = await file.read() df = pd.read_excel(io.BytesIO(contents)) await file.close() - + if df.empty: raise CustomException(msg="导入文件为空") - + + # 检查表头是否完整 missing_headers = [header for header in header_dict.keys() if header not in df.columns] if missing_headers: raise CustomException(msg=f"导入文件缺少必要的列: {', '.join(missing_headers)}") - + + # 重命名列名 df.rename(columns=header_dict, inplace=True) # 验证必填字段 @@ -162,7 +254,7 @@ class {{ class_name }}Service: success_count = 0 count = 0 - for index, row in df.iterrows(): + for _index, row in df.iterrows(): count += 1 try: data = { @@ -204,7 +296,12 @@ class {{ class_name }}Service: @classmethod async def import_template_download_{{ business_name }}_service(cls) -> bytes: - """下载导入模板""" + """ + 下载导入模板 + + 返回: + - bytes - Excel文件的二进制数据 + """ header_list = [ {% for column in columns %} '{{ column.column_comment }}', @@ -213,7 +310,6 @@ class {{ class_name }}Service: selector_header_list = [] option_list = [] - # 添加下拉选项 {% for column in columns %} {% if column.html_type == 'select' and column.dict_type %} selector_header_list.append('{{ column.column_comment }}') diff --git a/backend/app/plugin/module_generator/gencode/templates/vue/index.vue.j2 b/backend/app/plugin/module_generator/gencode/templates/vue/index.vue.j2 index 658d7491..f8f897be 100644 --- a/backend/app/plugin/module_generator/gencode/templates/vue/index.vue.j2 +++ b/backend/app/plugin/module_generator/gencode/templates/vue/index.vue.j2 @@ -1,121 +1,6 @@