mirror of
https://github.com/fastapiadmin/FastapiAdmin.git
synced 2026-09-21 12:52:26 +00:00
feat: 添加IP归属地工具类并优化代码
refactor: 简化AuthPermission调用方式 style: 更新日志输出格式和内容 fix: 修复BaseSchema字段可选性 perf: 优化数据库连接日志显示 chore: 更新requirements.txt添加sqlglot依赖 docs: 更新配置注释说明
This commit is contained in:
@@ -21,7 +21,7 @@ MCPRouter = APIRouter(route_class=OperationLogRoute, prefix="/mcp", tags=["MCP
|
||||
@MCPRouter.post("/chat", summary="智能对话", description="与MCP智能助手进行对话")
|
||||
async def chat_controller(
|
||||
query: ChatQuerySchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:chat"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:chat"]))
|
||||
) -> StreamingResponse:
|
||||
"""智能对话接口"""
|
||||
user_name = auth.user.name if auth.user else "未知用户"
|
||||
@@ -43,7 +43,7 @@ async def chat_controller(
|
||||
@MCPRouter.get("/detail/{id}", summary="获取 MCP 服务器详情", description="获取 MCP 服务器详情")
|
||||
async def detail_controller(
|
||||
id: int = Path(..., description="MCP ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await McpService.detail_service(auth=auth, id=id)
|
||||
logger.info(f"获取 MCP 服务器详情成功 {id}")
|
||||
@@ -54,7 +54,7 @@ async def detail_controller(
|
||||
async def list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: McpQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await McpService.list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
@@ -65,7 +65,7 @@ async def list_controller(
|
||||
@MCPRouter.post("/create", summary="创建 MCP 服务器", description="创建 MCP 服务器")
|
||||
async def create_controller(
|
||||
data: McpCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await McpService.create_service(auth=auth, data=data)
|
||||
logger.info(f"创建 MCP 服务器成功: {result_dict}")
|
||||
@@ -76,7 +76,7 @@ async def create_controller(
|
||||
async def update_controller(
|
||||
data: McpUpdateSchema,
|
||||
id: int = Path(..., description="MCP ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await McpService.update_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改 MCP 服务器成功: {result_dict}")
|
||||
@@ -86,7 +86,7 @@ async def update_controller(
|
||||
@MCPRouter.delete("/delete", summary="删除 MCP 服务器", description="删除 MCP 服务器")
|
||||
async def delete_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["ai:mcp:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["ai:mcp:delete"]))
|
||||
) -> JSONResponse:
|
||||
await McpService.delete_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除 MCP 服务器成功: {ids}")
|
||||
|
||||
@@ -24,7 +24,7 @@ MyAppRouter = APIRouter(route_class=OperationLogRoute, prefix="/myapp", tags=["
|
||||
@MyAppRouter.get("/detail/{id}", summary="获取应用详情", description="获取应用详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="应用ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ApplicationService.detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取应用详情成功 {id}")
|
||||
@@ -34,7 +34,7 @@ async def get_obj_detail_controller(
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: ApplicationQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await ApplicationService.list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
@@ -44,7 +44,7 @@ async def get_obj_list_controller(
|
||||
@MyAppRouter.post("/create", summary="创建应用", description="创建应用")
|
||||
async def create_obj_controller(
|
||||
data: ApplicationCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ApplicationService.create_service(auth=auth, data=data)
|
||||
logger.info(f"创建应用成功: {result_dict}")
|
||||
@@ -54,7 +54,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: ApplicationUpdateSchema,
|
||||
id: int = Path(..., description="应用ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ApplicationService.update_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改应用成功: {result_dict}")
|
||||
@@ -63,7 +63,7 @@ async def update_obj_controller(
|
||||
@MyAppRouter.delete("/delete", summary="删除应用", description="删除应用")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:delete"]))
|
||||
) -> JSONResponse:
|
||||
await ApplicationService.delete_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除应用成功: {ids}")
|
||||
@@ -72,7 +72,7 @@ async def delete_obj_controller(
|
||||
@MyAppRouter.patch("/available/setting", summary="批量修改应用状态", description="批量修改应用状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["application:myapp:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["application:myapp:patch"]))
|
||||
) -> JSONResponse:
|
||||
await ApplicationService.set_available_service(auth=auth, data=data)
|
||||
logger.info(f"批量修改应用状态成功: {data.ids}")
|
||||
|
||||
@@ -13,7 +13,7 @@ from .service import FileService
|
||||
|
||||
FileRouter = APIRouter(route_class=OperationLogRoute, prefix="/file", tags=["文件管理"])
|
||||
|
||||
@FileRouter.post("/upload", summary="上传文件", description="上传文件",dependencies=[Depends(AuthPermission(permissions=["common:file:upload"]))])
|
||||
@FileRouter.post("/upload", summary="上传文件", description="上传文件",dependencies=[Depends(AuthPermission(["common:file:upload"]))])
|
||||
async def upload_controller(
|
||||
file: UploadFile,
|
||||
request: Request,
|
||||
@@ -22,7 +22,7 @@ async def upload_controller(
|
||||
logger.info(f"上传文件成功 {result_dict}")
|
||||
return SuccessResponse(data=result_dict, msg="上传文件成功")
|
||||
|
||||
@FileRouter.post("/download", summary="下载文件", description="下载文件", dependencies=[Depends(AuthPermission(permissions=["common:file:download"]))])
|
||||
@FileRouter.post("/download", summary="下载文件", description="下载文件", dependencies=[Depends(AuthPermission(["common:file:download"]))])
|
||||
async def download_controller(
|
||||
background_tasks: BackgroundTasks,
|
||||
file_path: str = Body(..., description="文件路径"),
|
||||
|
||||
@@ -26,7 +26,7 @@ DemoRouter = APIRouter(route_class=OperationLogRoute, prefix="/demo", tags=["示
|
||||
@DemoRouter.get("/detail/{id}", summary="获取示例详情", description="获取示例详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="示例ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DemoService.detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取示例详情成功 {id}")
|
||||
@@ -36,7 +36,7 @@ async def get_obj_detail_controller(
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: DemoQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await DemoService.list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
@@ -46,7 +46,7 @@ async def get_obj_list_controller(
|
||||
@DemoRouter.post("/create", summary="创建示例", description="创建示例")
|
||||
async def create_obj_controller(
|
||||
data: DemoCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DemoService.create_service(auth=auth, data=data)
|
||||
logger.info(f"创建示例成功: {result_dict.get('name')}")
|
||||
@@ -56,7 +56,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: DemoUpdateSchema,
|
||||
id: int = Path(..., description="示例ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DemoService.update_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改示例成功: {result_dict.get('name')}")
|
||||
@@ -65,7 +65,7 @@ async def update_obj_controller(
|
||||
@DemoRouter.delete("/delete", summary="删除示例", description="删除示例")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:delete"]))
|
||||
) -> JSONResponse:
|
||||
await DemoService.delete_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除示例成功: {ids}")
|
||||
@@ -74,7 +74,7 @@ async def delete_obj_controller(
|
||||
@DemoRouter.patch("/available/setting", summary="批量修改示例状态", description="批量修改示例状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:patch"]))
|
||||
) -> JSONResponse:
|
||||
await DemoService.set_available_service(auth=auth, data=data)
|
||||
logger.info(f"批量修改示例状态成功: {data.ids}")
|
||||
@@ -83,7 +83,7 @@ async def batch_set_available_obj_controller(
|
||||
@DemoRouter.post('/export', summary="导出示例", description="导出示例")
|
||||
async def export_obj_list_controller(
|
||||
search: DemoQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await DemoService.list_service(search=search, auth=auth)
|
||||
@@ -101,13 +101,13 @@ async def export_obj_list_controller(
|
||||
@DemoRouter.post('/import', summary="导入示例", description="导入示例")
|
||||
async def import_obj_list_controller(
|
||||
file: UploadFile,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["demo:example:import"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["demo:example:import"]))
|
||||
) -> JSONResponse:
|
||||
batch_import_result = await DemoService.batch_import_service(file=file, auth=auth, update_support=True)
|
||||
logger.info(f"导入示例成功: {batch_import_result}")
|
||||
return SuccessResponse(data=batch_import_result, msg="导入示例成功")
|
||||
|
||||
@DemoRouter.post('/download/template', summary="获取示例导入模板", description="获取示例导入模板", dependencies=[Depends(AuthPermission(permissions=["demo:example:download"]))])
|
||||
@DemoRouter.post('/download/template', summary="获取示例导入模板", description="获取示例导入模板", dependencies=[Depends(AuthPermission(["demo:example:download"]))])
|
||||
async def export_obj_template_controller() -> StreamingResponse:
|
||||
example_import_template_result = await DemoService.import_template_download_service()
|
||||
logger.info('获取示例导入模板成功')
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
from fastapi import APIRouter, Depends, Query, Body, Path
|
||||
from fastapi.responses import StreamingResponse, JSONResponse
|
||||
from fastapi.responses import JSONResponse
|
||||
|
||||
from app.common.response import SuccessResponse, ErrorResponse, StreamResponse
|
||||
from app.core.dependencies import AuthPermission
|
||||
@@ -11,9 +10,8 @@ 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.api.v1.module_system.user.schema import UserOutSchema
|
||||
from .param import GenTableQueryParam
|
||||
from .schema import GenTableDeleteSchema, GenTableUpdateSchema, GenTableOutSchema
|
||||
from .schema import GenTableDeleteSchema, GenTableSchema, GenTableOutSchema
|
||||
from .service import GenTableColumnService, GenTableService
|
||||
from app.utils.common_util import bytes2file_response
|
||||
from app.core.logger import logger
|
||||
@@ -22,38 +20,59 @@ from app.core.logger import logger
|
||||
GenRouter = APIRouter(route_class=OperationLogRoute, prefix='/gencode', tags=["代码生成模块"])
|
||||
|
||||
|
||||
@GenRouter.get("/list", summary="查询代码生成业务表列表", description="查询代码生成业务表列表")
|
||||
async def gen_table_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: GenTableQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await GenTableService.get_gen_table_list_service(auth=auth, search=search)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
logger.info('获取代码生成业务表列表成功')
|
||||
return SuccessResponse(data=result_dict, msg="获取代码生成业务表列表成功")
|
||||
|
||||
|
||||
@GenRouter.get("/db/list", summary="查询数据库表列表", description="查询数据库表列表")
|
||||
async def get_gen_db_table_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: GenTableQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:dblist:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await GenTableService.get_gen_db_table_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
logger.info('获取数据库表列表成功')
|
||||
return SuccessResponse(data=result_dict, msg="获取数据库表列表成功")
|
||||
|
||||
|
||||
@GenRouter.post("/import", summary="导入表结构", description="导入表结构")
|
||||
async def import_gen_table_controller(
|
||||
table_names: List[str] = Query(..., description="表名列表", embed=True),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:import"])),
|
||||
) -> JSONResponse:
|
||||
add_gen_table_list = await GenTableService.get_gen_db_table_list_by_name_service(auth, table_names)
|
||||
result = await GenTableService.import_gen_table_service(auth, add_gen_table_list)
|
||||
logger.info('导入表结构成功')
|
||||
return SuccessResponse(msg="导入表结构成功", data=result)
|
||||
|
||||
|
||||
@GenRouter.get("/detail/{table_id}", summary="获取业务表详细信息", description="获取业务表详细信息")
|
||||
async def get_gen_table_detail_controller(
|
||||
async def gen_table_detail_controller(
|
||||
table_id: int = Path(..., description="业务表ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:query"]))
|
||||
) -> 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_columns = await GenTableColumnService.get_gen_table_column_list_by_table_id_service(auth, table_id)
|
||||
gen_table_detail_result = dict(info=gen_table, rows=gen_columns, tables=gen_tables)
|
||||
gen_table_detail_result = dict(info=gen_table, rows=gen_table.columns, tables=gen_tables)
|
||||
logger.info(f'获取table_id为{table_id}的信息成功')
|
||||
return SuccessResponse(data=gen_table_detail_result, msg="获取业务表详细信息成功")
|
||||
|
||||
|
||||
@GenRouter.get("/list", summary="查询代码生成业务表列表", description="查询代码生成业务表列表")
|
||||
async def get_gen_table_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: GenTableQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await GenTableService.get_gen_table_list_service(auth=auth, query_object=search, is_page=False)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list["items"], page_no=page.page_no, page_size=page.page_size)
|
||||
logger.info('获取代码生成业务表列表成功')
|
||||
return SuccessResponse(data=result_dict, msg="获取代码生成业务表列表成功")
|
||||
|
||||
|
||||
@GenRouter.post("/create", summary="创建表结构", description="创建表结构")
|
||||
async def create_table_controller(
|
||||
sql: str = Query(..., description="SQL语句"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:create"])),
|
||||
current_user: UserOutSchema = Depends(lambda auth: auth.user)
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:create"])),
|
||||
) -> JSONResponse:
|
||||
result = await GenTableService.create_table_service(auth, sql, current_user)
|
||||
result = await GenTableService.create_table_service(auth, sql)
|
||||
logger.info('创建表结构成功')
|
||||
return SuccessResponse(msg="创建表结构成功", data=result)
|
||||
|
||||
@@ -61,54 +80,30 @@ async def create_table_controller(
|
||||
@GenRouter.put("/update/{table_id}", summary="编辑业务表信息", description="编辑业务表信息")
|
||||
async def update_gen_table_controller(
|
||||
table_id: int = Path(..., description="业务表ID"),
|
||||
data: GenTableUpdateSchema = Body(..., description="业务表信息"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:update"])),
|
||||
current_user: UserOutSchema = Depends(lambda auth: auth.user)
|
||||
data: GenTableSchema = Body(..., description="业务表信息"),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:update"])),
|
||||
) -> JSONResponse:
|
||||
# 创建一个新的字典来包含所有数据,包括审计字段
|
||||
update_data = data.model_dump()
|
||||
update_data['update_by'] = current_user.username
|
||||
update_data['updated_at'] = datetime.now()
|
||||
|
||||
# 创建一个新的GenTableUpdateSchema实例
|
||||
updated_data = GenTableUpdateSchema(**update_data)
|
||||
|
||||
await GenTableService.validate_edit(updated_data)
|
||||
edit_gen_result = await GenTableService.update_gen_table_service(auth, updated_data, table_id)
|
||||
await GenTableService.validate_edit(data)
|
||||
result_dict = await GenTableService.update_gen_table_service(auth, data, table_id)
|
||||
logger.info('编辑业务表信息成功')
|
||||
return SuccessResponse(data=edit_gen_result, msg="编辑业务表信息成功")
|
||||
return SuccessResponse(data=result_dict, msg="编辑业务表信息成功")
|
||||
|
||||
|
||||
@GenRouter.delete("/delete", summary="删除业务表信息", description="删除业务表信息")
|
||||
async def delete_gen_table_controller(
|
||||
table_ids: str = Body(..., description="ID列表,用逗号分隔"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:delete"]))
|
||||
data: GenTableDeleteSchema = Body(..., description="业务表ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:delete"]))
|
||||
) -> JSONResponse:
|
||||
delete_gen_table = GenTableDeleteSchema(table_ids=table_ids)
|
||||
result = await GenTableService.delete_gen_table_service(auth, delete_gen_table)
|
||||
result = await GenTableService.delete_gen_table_service(auth, data)
|
||||
logger.info('删除业务表信息成功')
|
||||
return result
|
||||
return SuccessResponse(msg="删除业务表信息成功", data=result)
|
||||
|
||||
|
||||
@GenRouter.post("/import", summary="导入表结构", description="导入表结构")
|
||||
async def import_gen_table_controller(
|
||||
tables: List[str] = Body(..., description="表名列表", embed=True),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:import"])),
|
||||
current_user: UserOutSchema = Depends(lambda auth: auth.user)
|
||||
) -> JSONResponse:
|
||||
table_names = tables if tables else []
|
||||
add_gen_table_list = await GenTableService.get_gen_db_table_list_by_name_service(auth, table_names)
|
||||
result = await GenTableService.import_gen_table_service(auth, add_gen_table_list, current_user)
|
||||
logger.info('导入表结构成功')
|
||||
return result
|
||||
|
||||
|
||||
@GenRouter.patch("/batch/out", summary="批量生成代码", description="批量生成代码")
|
||||
@GenRouter.patch("/batch/output", summary="批量生成代码", description="批量生成代码")
|
||||
async def batch_gen_code_controller(
|
||||
tables: str = Query(..., description="表名列表,用逗号分隔"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:operate"]))
|
||||
table_names: List[str] = Query(None, description="表名列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:operate"]))
|
||||
) -> StreamResponse:
|
||||
table_names = tables.split(',') if tables else []
|
||||
batch_gen_code_result = await GenTableService.batch_gen_code_service(auth, table_names)
|
||||
logger.info('批量生成代码成功')
|
||||
return StreamResponse(
|
||||
@@ -118,10 +113,10 @@ async def batch_gen_code_controller(
|
||||
)
|
||||
|
||||
|
||||
@GenRouter.post("/out/path/{table_name}", summary="生成代码到指定路径", description="生成代码到指定路径")
|
||||
@GenRouter.post("/output/{table_name}", summary="生成代码到指定路径", description="生成代码到指定路径")
|
||||
async def gen_code_local_controller(
|
||||
table_name: str = Path(..., description="表名"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:code"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:code"]))
|
||||
) -> JSONResponse:
|
||||
from app.config.setting import settings
|
||||
if not settings.allow_overwrite:
|
||||
@@ -135,29 +130,17 @@ async def gen_code_local_controller(
|
||||
@GenRouter.get("/preview/{table_id}", summary="预览代码", description="预览代码")
|
||||
async def preview_code_controller(
|
||||
table_id: int = Path(..., description="业务表ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:gencode:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:gencode:query"]))
|
||||
) -> JSONResponse:
|
||||
preview_code_result = await GenTableService.preview_code_service(auth, table_id)
|
||||
logger.info('预览代码成功')
|
||||
return SuccessResponse(data=preview_code_result, msg="预览代码成功")
|
||||
|
||||
|
||||
@GenRouter.get("/db/list", summary="查询数据库表列表", description="查询数据库表列表")
|
||||
async def get_gen_db_table_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: GenTableQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:dblist:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await GenTableService.get_gen_db_table_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list=result_dict_list, page_no=page.page_no, page_size=page.page_size)
|
||||
logger.info('获取数据库表列表成功')
|
||||
return SuccessResponse(data=result_dict, msg="获取数据库表列表成功")
|
||||
|
||||
|
||||
@GenRouter.post("/sync/db/{table_name}", summary="同步数据库", description="同步数据库")
|
||||
@GenRouter.post("/synch_db/{table_name}", summary="同步数据库", description="同步数据库")
|
||||
async def sync_db_controller(
|
||||
table_name: str = Path(..., description="表名"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["generator:db:sync"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["generator:db:sync"]))
|
||||
) -> JSONResponse:
|
||||
result = await GenTableService.sync_db_service(auth, table_name)
|
||||
logger.info('同步数据库成功')
|
||||
|
||||
@@ -3,23 +3,24 @@
|
||||
from sqlalchemy.engine.row import Row
|
||||
from sqlalchemy import and_, delete, select, text, update
|
||||
from sqlalchemy.orm import selectinload
|
||||
from sqlglot.expressions import Expression
|
||||
from typing import List, Optional, Sequence, Dict
|
||||
|
||||
from app.core.logger import logger
|
||||
|
||||
from .model import GenTableModel, GenTableColumnModel
|
||||
from app.config.setting import settings
|
||||
from app.common.request import PaginationService
|
||||
from app.core.base_crud import CRUDBase
|
||||
from app.api.v1.module_system.auth.schema import AuthSchema
|
||||
from .param import GenTableQueryParam, GenTableColumnQueryParam
|
||||
from .model import GenTableModel, GenTableColumnModel
|
||||
from .schema import (
|
||||
GenTableSchema,
|
||||
GenTableOutSchema,
|
||||
GenTableDeleteSchema,
|
||||
GenTableColumnSchema,
|
||||
GenTableColumnOutSchema,
|
||||
GenTableColumnDeleteSchema,
|
||||
GenDBTableSchema,
|
||||
)
|
||||
from .param import GenTableQueryParam, GenTableColumnQueryParam
|
||||
from app.core.base_crud import CRUDBase
|
||||
from app.api.v1.module_system.auth.schema import AuthSchema
|
||||
|
||||
|
||||
class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
@@ -70,12 +71,27 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
)
|
||||
|
||||
return gen_table
|
||||
|
||||
async def get_gen_table_all(self) -> Sequence[GenTableModel]:
|
||||
"""
|
||||
获取所有业务表信息
|
||||
|
||||
async def get_gen_table_list(self, search: Optional[GenTableQueryParam] = None):
|
||||
:return: 所有业务表信息列表
|
||||
"""
|
||||
gen_table_all = (
|
||||
await self.db.execute(
|
||||
select(GenTableModel)
|
||||
.options(selectinload(GenTableModel.columns))
|
||||
)
|
||||
).scalars().all()
|
||||
|
||||
return gen_table_all
|
||||
|
||||
async def get_gen_table_list(self, search: Optional[GenTableQueryParam] = None) -> Sequence[GenTableModel]:
|
||||
"""
|
||||
根据查询参数获取代码生成业务表列表信息
|
||||
|
||||
:param query_object: 查询参数对象
|
||||
:param search: 查询参数对象
|
||||
:return: 代码生成业务表列表信息对象
|
||||
"""
|
||||
# 构建查询条件
|
||||
@@ -90,7 +106,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
|
||||
# 获取所有数据
|
||||
result = await self.db.execute(query)
|
||||
gen_table_all = list(result.scalars().all())
|
||||
gen_table_all = result.scalars().all()
|
||||
|
||||
return gen_table_all
|
||||
|
||||
@@ -105,7 +121,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
await self.db.flush()
|
||||
return gen_table
|
||||
|
||||
async def edit_gen_table(self, table_id: int, edit_model: GenTableSchema):
|
||||
async def edit_gen_table(self, table_id: int, edit_model: GenTableSchema) -> GenTableSchema:
|
||||
"""
|
||||
修改
|
||||
"""
|
||||
@@ -119,12 +135,12 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
await self.db.commit()
|
||||
return edit_model
|
||||
|
||||
async def delete_gen_table(self, delete_model: GenTableDeleteSchema) -> None:
|
||||
async def delete_gen_table(self, data: GenTableDeleteSchema) -> None:
|
||||
"""
|
||||
删除
|
||||
"""
|
||||
await self.db.execute(
|
||||
delete(GenTableModel).where(GenTableModel.id.in_(delete_model.table_ids))
|
||||
delete(GenTableModel).where(GenTableModel.id.in_(data.table_ids))
|
||||
)
|
||||
await self.db.flush()
|
||||
|
||||
@@ -212,7 +228,7 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
dict_data.append(dict_row)
|
||||
return dict_data
|
||||
|
||||
async def get_db_table_list_by_names(self, table_names: List[str]) -> list[Dict]:
|
||||
async def get_db_table_list_by_names(self, table_names: List[str]) -> list[GenDBTableSchema]:
|
||||
"""
|
||||
根据业务表名称组获取数据库列表信息
|
||||
|
||||
@@ -280,14 +296,14 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
# 检查row是否为Row对象
|
||||
if isinstance(row, Row):
|
||||
# 使用._mapping获取字典
|
||||
dict_row = GenDBTableSchema(**dict(row._mapping)).model_dump()
|
||||
dict_row = GenDBTableSchema(**dict(row._mapping))
|
||||
dict_data.append(dict_row)
|
||||
else:
|
||||
dict_row = GenDBTableSchema(**dict(row)).model_dump()
|
||||
dict_row = GenDBTableSchema(**dict(row))
|
||||
dict_data.append(dict_row)
|
||||
return dict_data
|
||||
|
||||
async def create_table_by_sql(self, sql: str) -> bool:
|
||||
async def create_table_by_sql(self, sql_statements: List[Expression | None]) -> None:
|
||||
"""
|
||||
根据sql语句创建表结构
|
||||
|
||||
@@ -296,16 +312,16 @@ class GenTableCRUD(CRUDBase[GenTableModel, GenTableSchema, GenTableSchema]):
|
||||
:return:
|
||||
"""
|
||||
try:
|
||||
await self.db.execute(text(sql))
|
||||
# 提交事务
|
||||
await self.db.commit()
|
||||
await self.db.flush()
|
||||
return True
|
||||
for sql_statement in sql_statements:
|
||||
# 检查sql_statement是否为空
|
||||
if not sql_statement:
|
||||
continue
|
||||
sql = sql_statement.sql(dialect=settings.DATABASE_TYPE)
|
||||
await self.db.execute(text(sql))
|
||||
except Exception as e:
|
||||
# 如果发生异常,回滚事务
|
||||
await self.db.rollback()
|
||||
logger.error(f"创建表时发生错误: {e}")
|
||||
return False
|
||||
|
||||
|
||||
class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, GenTableColumnSchema]):
|
||||
@@ -315,35 +331,11 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
|
||||
"""初始化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 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: GenTableColumnSchema
|
||||
) -> Optional[GenTableColumnModel]:
|
||||
"""创建"""
|
||||
return await self.create(data=data)
|
||||
|
||||
async def update_crud(
|
||||
self, id: int, data: GenTableColumnSchema
|
||||
) -> 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_db_table_columns_by_name(self, table_name: str) -> List[GenTableColumnSchema]:
|
||||
async def get_gen_table_column_list_by_table_id(self, table_id: int) -> Optional[GenTableColumnModel]:
|
||||
"""根据业务表ID获取业务表字段列表信息"""
|
||||
return await self.get(table_id=table_id)
|
||||
|
||||
async def get_gen_db_table_columns_by_name(self, table_name: str | None) -> List[GenTableColumnOutSchema]:
|
||||
"""
|
||||
根据业务表名称获取业务表字段列表信息
|
||||
|
||||
@@ -412,7 +404,7 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
|
||||
).fetchall()
|
||||
|
||||
return [
|
||||
GenTableColumnSchema(
|
||||
GenTableColumnOutSchema(
|
||||
column_name=row[0],
|
||||
is_required=row[1],
|
||||
is_pk=row[2],
|
||||
@@ -423,3 +415,23 @@ class GenTableColumnCRUD(CRUDBase[GenTableColumnModel, GenTableColumnSchema, Gen
|
||||
)
|
||||
for row in gen_db_table_columns_raw
|
||||
]
|
||||
|
||||
async def list_gen_table_column_crud(self, search: Optional[Dict] = None, order_by: Optional[List[Dict[str, str]]] = None) -> Sequence[GenTableColumnModel]:
|
||||
"""根据业务表ID查询业务表字段列表"""
|
||||
return await self.list(search=search, order_by=order_by)
|
||||
|
||||
async def create_gen_table_column_crud(self, data: GenTableColumnSchema) -> Optional[GenTableColumnModel]:
|
||||
"""创建业务表字段"""
|
||||
return await self.create(data=data)
|
||||
|
||||
async def update_gen_table_column_crud(self, id: int, data: GenTableColumnSchema) -> Optional[GenTableColumnModel]:
|
||||
"""更新业务表字段"""
|
||||
return await self.update(id=id, data=data)
|
||||
|
||||
async def delete_gen_table_column_by_table_id_dao(self, data: GenTableDeleteSchema) -> None:
|
||||
"""根据业务表ID批量删除"""
|
||||
return await self.delete(ids=data.table_ids)
|
||||
|
||||
async def delete_gen_table_column_by_column_id_dao(self, data: GenTableColumnDeleteSchema) -> None:
|
||||
"""根据业务表字段ID批量删除"""
|
||||
return await self.delete(ids=data.column_ids)
|
||||
|
||||
@@ -35,16 +35,6 @@ class GenTableColumnQueryParam:
|
||||
def __init__(
|
||||
self,
|
||||
column_name: 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.column_name = ("like", column_name)
|
||||
|
||||
# 精确查询字段
|
||||
self.creator_id = creator
|
||||
|
||||
# 时间范围查询
|
||||
if start_time and end_time:
|
||||
self.created_at = ("between", (start_time, end_time))
|
||||
@@ -1,10 +1,9 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
from typing import Any, List, Literal, Optional
|
||||
from typing import List, Literal, Optional
|
||||
from pydantic import BaseModel, ConfigDict, Field, model_validator
|
||||
from pydantic.alias_generators import to_camel
|
||||
|
||||
from app.utils.string_util import StringUtil
|
||||
from app.common.constant import GenConstant
|
||||
from app.core.base_schema import BaseSchema
|
||||
|
||||
@@ -18,6 +17,7 @@ class GenTableOptionModel(BaseModel):
|
||||
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)
|
||||
@@ -34,12 +34,13 @@ class GenTableBaseSchema(BaseModel):
|
||||
"""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
table_id: Optional[int] = Field(default=None, 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: 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_category: Optional[str] = Field(default=None, description='使用的模板(crud单表操作 tree树表操作)')
|
||||
tpl_web_type: Optional[str] = Field(default=None, description='前端模板类型(element-ui模版 element-plus模版)')
|
||||
package_name: Optional[str] = Field(default=None, description='生成包路径')
|
||||
module_name: Optional[str] = Field(default=None, description='生成模块名')
|
||||
@@ -51,16 +52,17 @@ class GenTableBaseSchema(BaseModel):
|
||||
options: Optional[str] = Field(default=None, description='其它生成选项')
|
||||
description: Optional[str] = Field(default=None, description='功能描述')
|
||||
|
||||
params: Optional[Any] = Field(default=None, description='前端传递过来的表附加信息,转换成json字符串后放到options')
|
||||
params: Optional[GenTableOptionModel] = Field(default=None, description='前端传递过来的表附加信息,转换成json字符串后放到options')
|
||||
|
||||
|
||||
class GenTableSchema(GenTableBaseSchema):
|
||||
"""
|
||||
代码生成业务表更新模型
|
||||
"""
|
||||
pk_column: Optional['GenTableColumnSchema'] = Field(default=None, description='主键信息')
|
||||
|
||||
pk_column: Optional['GenTableColumnOutSchema'] = Field(default=None, description='主键信息')
|
||||
sub_table: Optional['GenTableSchema'] = Field(default=None, description='子表信息')
|
||||
columns: Optional[List['GenTableColumnSchema']] = Field(default=None, description='表列信息')
|
||||
columns: Optional[List['GenTableColumnOutSchema']] = 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='树名称字段ree_name')
|
||||
@@ -78,13 +80,17 @@ class GenTableSchema(GenTableBaseSchema):
|
||||
return self
|
||||
|
||||
|
||||
class GenTableOutSchema(GenTableSchema, BaseSchema):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
||||
class GenTableDeleteSchema(BaseModel):
|
||||
"""
|
||||
删除代码生成业务表模型
|
||||
"""
|
||||
model_config = ConfigDict(alias_generator=to_camel)
|
||||
|
||||
table_ids: str = Field(..., description='需要删除的代码生成业务表ID')
|
||||
table_ids: List[int] = Field(..., description='需要删除的代码生成业务表ID列表')
|
||||
|
||||
|
||||
class GenTableColumnSchema(BaseModel):
|
||||
@@ -114,6 +120,22 @@ class GenTableColumnSchema(BaseModel):
|
||||
description: Optional[str] = Field(default=None, description='功能描述')
|
||||
|
||||
|
||||
class GenTableColumnOutSchema(GenTableColumnSchema, BaseSchema):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
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='是否为基类字段白名单')
|
||||
|
||||
|
||||
class GenTableColumnDeleteSchema(BaseModel):
|
||||
"""
|
||||
删除代码生成业务表字段模型
|
||||
|
||||
@@ -4,23 +4,21 @@ import io
|
||||
import json
|
||||
import os
|
||||
import zipfile
|
||||
from datetime import datetime
|
||||
from typing import Any, List, Dict, Optional, Sequence
|
||||
from sqlalchemy.ext.asyncio import AsyncSession
|
||||
from typing import Any, List, Dict, Literal, Optional
|
||||
from sqlglot.expressions import Add, Alter, Create, Delete, Drop, Expression, Insert, Table, TruncateTable, Update
|
||||
from sqlglot import parse as sqlglot_parse
|
||||
|
||||
from app.config.setting import settings
|
||||
from app.core.base_model import CamelCaseUtil
|
||||
from app.core.exceptions import CustomException
|
||||
from app.utils.gen_util import GenUtils
|
||||
from app.utils.template_util import TemplateInitializer, TemplateUtils
|
||||
from app.common.constant import GenConstant
|
||||
from app.common.response import SuccessResponse
|
||||
from app.api.v1.module_system.user.schema import UserOutSchema
|
||||
from app.api.v1.module_system.auth.schema import AuthSchema
|
||||
from .schema import GenTableCreateSchema, GenTableUpdateSchema, GenTableOutSchema, GenTableDeleteSchema, GenTableColumnCreateSchema, GenTableColumnUpdateSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
|
||||
from app.utils.common_util import CamelCaseUtil
|
||||
from app.utils.gen_util import GenUtils
|
||||
from app.utils.jinja2_template_util import Jinja2TemplateInitializerUtil, Jinja2TemplateUtil
|
||||
from .schema import GenTableSchema, GenTableOutSchema, GenTableOutSchema, GenTableDeleteSchema, GenTableColumnSchema, GenTableColumnOutSchema, GenTableColumnDeleteSchema
|
||||
from .param import GenTableQueryParam
|
||||
from .crud import GenTableColumnCRUD, GenTableCRUD
|
||||
from .model import GenTableModel, GenTableColumnModel
|
||||
|
||||
|
||||
# 定义默认的GenConfig值
|
||||
@@ -40,197 +38,129 @@ class GenTableService:
|
||||
|
||||
@classmethod
|
||||
async def get_gen_table_list_service(
|
||||
cls, auth: AuthSchema, query_object: GenTableQueryParam, is_page: bool = False
|
||||
) -> Dict:
|
||||
cls, auth: AuthSchema, search: GenTableQueryParam
|
||||
) -> List[Dict]:
|
||||
"""获取代码生成业务表列表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table_list_result = await gen_table_dao.get_gen_table_list(query_object, is_page)
|
||||
return gen_table_list_result
|
||||
gen_table_list_result = await GenTableCRUD(auth=auth).get_gen_table_list(search)
|
||||
return [GenTableOutSchema.model_validate(obj).model_dump() for obj in gen_table_list_result]
|
||||
|
||||
@classmethod
|
||||
async def get_gen_db_table_list_service(cls, auth: AuthSchema, search: GenTableQueryParam, order_by: Optional[List[Dict[str, str]]] = None) -> list[Any]:
|
||||
"""获取数据库列表信息"""
|
||||
# 确保db是AsyncSession类型
|
||||
gen_db_table_list_result = await GenTableCRUD(auth=auth).get_gen_db_table_list(search, order_by)
|
||||
gen_db_table_list_result = await GenTableCRUD(auth=auth).get_db_table_list(search)
|
||||
return gen_db_table_list_result
|
||||
|
||||
@classmethod
|
||||
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_gen_db_table_list_by_names(table_names)
|
||||
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)]
|
||||
|
||||
@classmethod
|
||||
async def import_gen_table_service(
|
||||
cls, auth: AuthSchema, gen_table_list: List[GenTableOutSchema], current_user: UserOutSchema
|
||||
) -> SuccessResponse:
|
||||
cls, auth: AuthSchema, gen_table_list: List[GenTableOutSchema]
|
||||
) -> Literal[True] | None:
|
||||
"""导入表结构"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
try:
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table_column_dao = GenTableColumnCRUD(auth=auth)
|
||||
|
||||
for table in gen_table_list:
|
||||
table_name = table.table_name
|
||||
GenUtils.init_table(table, current_user.username)
|
||||
add_gen_table = await gen_table_dao.create(data=table.model_dump())
|
||||
GenUtils.init_table(table)
|
||||
add_gen_table = await GenTableCRUD(auth).add_gen_table(table)
|
||||
if add_gen_table:
|
||||
# 使用id而不是table_id
|
||||
table.id = add_gen_table.id
|
||||
gen_table_columns = await gen_table_column_dao.get_gen_db_table_columns_by_name(db, table_name or "")
|
||||
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 [
|
||||
GenTableColumnOutSchema(**gen_table_column)
|
||||
GenTableColumnSchema(**gen_table_column)
|
||||
for gen_table_column in CamelCaseUtil.transform_result(gen_table_columns)
|
||||
]:
|
||||
GenUtils.init_column_field(column, table)
|
||||
await gen_table_column_dao.create(data=column.model_dump())
|
||||
if isinstance(db, AsyncSession):
|
||||
await db.commit()
|
||||
return SuccessResponse(msg='导入成功')
|
||||
await GenTableColumnCRUD(auth).create_gen_table_column_crud(column)
|
||||
return True
|
||||
except Exception as e:
|
||||
if isinstance(db, AsyncSession):
|
||||
try:
|
||||
await db.rollback()
|
||||
except:
|
||||
pass # 忽略回滚错误
|
||||
raise CustomException(msg=f'导入失败, {str(e)}')
|
||||
|
||||
@classmethod
|
||||
async def create_table_service(cls, auth: AuthSchema, sql: str, current_user: UserOutSchema) -> SuccessResponse:
|
||||
async def create_table_service(cls, auth: AuthSchema, sql: str) -> Literal[True] | None:
|
||||
"""创建表结构"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
|
||||
try:
|
||||
sql_statements = sqlglot_parse(sql, dialect=settings.DATABASE_TYPE)
|
||||
# 校验sql语句是否为合法的建表语句
|
||||
if not cls.__is_valid_create_table(sql_statements):
|
||||
raise CustomException(msg='sql语句不是合法的建表语句')
|
||||
table_names = cls.__get_table_names(sql_statements)
|
||||
# 执行SQL语句创建表
|
||||
await gen_table_dao.create_table_by_sql_dao(db, [sql])
|
||||
if isinstance(db, AsyncSession):
|
||||
await db.commit()
|
||||
return SuccessResponse(msg='创建表结构成功')
|
||||
await GenTableCRUD(auth=auth).create_table_by_sql(sql_statements)
|
||||
gen_table_list = await cls.get_gen_db_table_list_by_name_service(auth, table_names)
|
||||
import_result = await cls.import_gen_table_service(auth, gen_table_list)
|
||||
return import_result
|
||||
except Exception as e:
|
||||
if isinstance(db, AsyncSession):
|
||||
try:
|
||||
await db.rollback()
|
||||
except:
|
||||
pass # 忽略回滚错误
|
||||
raise CustomException(msg=f'创建表结构失败: {str(e)}')
|
||||
|
||||
@classmethod
|
||||
def __is_valid_create_table(cls, sql_statements: List[Expression | None]) -> bool:
|
||||
"""
|
||||
校验sql语句是否为合法的建表语句
|
||||
|
||||
:param sql_statements: sql语句的ast列表
|
||||
:return: 校验结果
|
||||
"""
|
||||
validate_create = [isinstance(sql_statement, Create) for sql_statement in sql_statements]
|
||||
validate_forbidden_keywords = [
|
||||
isinstance(
|
||||
sql_statement,
|
||||
(Add, Alter, Delete, Drop, Insert, TruncateTable, Update),
|
||||
)
|
||||
for sql_statement in sql_statements
|
||||
]
|
||||
if not any(validate_create) or any(validate_forbidden_keywords):
|
||||
return False
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
def __get_table_names(cls, sql_statements: List[Expression | None]) -> List[str]:
|
||||
"""
|
||||
获取sql语句中所有的建表表名
|
||||
|
||||
:param sql_statements: sql语句的ast列表
|
||||
:return: 建表表名列表
|
||||
"""
|
||||
table_names = []
|
||||
for sql_statement in sql_statements:
|
||||
if isinstance(sql_statement, Create):
|
||||
table_names.append(sql_statement.find(Table).name)
|
||||
return table_names
|
||||
|
||||
@classmethod
|
||||
async def update_gen_table_service(cls, auth: AuthSchema, page_object: GenTableUpdateSchema, table_id: int) -> Dict[str, Any]:
|
||||
"""编辑业务表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table_column_dao = GenTableColumnCRUD(auth=auth)
|
||||
|
||||
edit_gen_table = page_object.model_dump(exclude_unset=True, by_alias=True)
|
||||
async def update_gen_table_service(cls, auth: AuthSchema, data: GenTableSchema, table_id: int) -> Dict[str, Any]:
|
||||
"""编辑业务表信息"""
|
||||
edit_gen_table = data.model_dump(exclude_unset=True, by_alias=True)
|
||||
gen_table_info = await cls.get_gen_table_by_id_service(auth, table_id)
|
||||
if gen_table_info.id:
|
||||
try:
|
||||
# 确保options字段存在且为有效JSON
|
||||
if 'options' not in edit_gen_table or edit_gen_table['options'] is None:
|
||||
edit_gen_table['options'] = '{}' # 默认空对象
|
||||
else:
|
||||
# 验证options是否为有效的JSON
|
||||
try:
|
||||
json.loads(edit_gen_table['options'])
|
||||
except json.JSONDecodeError:
|
||||
edit_gen_table['options'] = '{}'
|
||||
|
||||
await gen_table_dao.update(id=table_id, data=edit_gen_table)
|
||||
if hasattr(page_object, 'columns') and page_object.columns:
|
||||
for gen_table_column in page_object.columns:
|
||||
# 为列添加更新信息
|
||||
gen_table_column_dict = gen_table_column.model_dump()
|
||||
gen_table_column_dict['update_by'] = getattr(page_object, 'update_by', '')
|
||||
gen_table_column_dict['update_time'] = datetime.now()
|
||||
# 检查是否有id属性
|
||||
column_id = getattr(gen_table_column, 'id', None)
|
||||
if column_id is not None:
|
||||
await gen_table_column_dao.update(
|
||||
id=column_id,
|
||||
data=gen_table_column_dict
|
||||
)
|
||||
if isinstance(db, AsyncSession):
|
||||
await db.commit()
|
||||
return {"is_success": True, "message": "更新成功"}
|
||||
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)
|
||||
return result.model_dump()
|
||||
except Exception as e:
|
||||
if isinstance(db, AsyncSession):
|
||||
try:
|
||||
await db.rollback()
|
||||
except:
|
||||
pass # 忽略回滚错误
|
||||
raise CustomException(msg=f'更新失败: {str(e)}')
|
||||
else:
|
||||
raise CustomException(msg='业务表不存在')
|
||||
|
||||
@classmethod
|
||||
async def delete_gen_table_service(cls, auth: AuthSchema, page_object: GenTableDeleteSchema) -> SuccessResponse:
|
||||
async def delete_gen_table_service(cls, auth: AuthSchema, data: GenTableDeleteSchema) -> None:
|
||||
"""删除业务表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table_column_dao = GenTableColumnCRUD(auth=auth)
|
||||
|
||||
if page_object.table_ids:
|
||||
table_id_list = page_object.table_ids.split(',')
|
||||
try:
|
||||
for table_id in table_id_list:
|
||||
await gen_table_dao.delete(ids=[int(table_id)])
|
||||
# 删除相关的字段信息
|
||||
# 这里需要先查询出所有相关的column_id,然后删除
|
||||
columns = await gen_table_column_dao.get_gen_table_column_list_by_table_id(db, int(table_id))
|
||||
if columns:
|
||||
column_ids = [column.id for column in columns]
|
||||
await gen_table_column_dao.delete(ids=column_ids)
|
||||
if isinstance(db, AsyncSession):
|
||||
await db.commit()
|
||||
return SuccessResponse(msg='删除成功')
|
||||
except Exception as e:
|
||||
if isinstance(db, AsyncSession):
|
||||
try:
|
||||
await db.rollback()
|
||||
except:
|
||||
pass # 忽略回滚错误
|
||||
raise CustomException(msg=f'删除失败: {str(e)}')
|
||||
else:
|
||||
raise CustomException(msg='传入业务表id为空')
|
||||
try:
|
||||
await GenTableCRUD(auth=auth).delete_gen_table(data)
|
||||
await GenTableColumnCRUD(auth=auth).delete_gen_table_column_by_table_id_dao(data)
|
||||
except Exception as e:
|
||||
raise CustomException(msg=f'删除失败: {str(e)}')
|
||||
|
||||
@classmethod
|
||||
async def get_gen_table_by_id_service(cls, auth: AuthSchema, table_id: int) -> GenTableOutSchema:
|
||||
"""获取需要生成的业务表详细信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table = await gen_table_dao.get_gen_table_by_id(db, table_id)
|
||||
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)))
|
||||
return result
|
||||
@@ -240,42 +170,38 @@ class GenTableService:
|
||||
@classmethod
|
||||
async def get_gen_table_all_service(cls, auth: AuthSchema) -> List[GenTableOutSchema]:
|
||||
"""获取所有业务表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_tables = await gen_table_dao.get_gen_table_all(db)
|
||||
result = []
|
||||
for table in gen_tables:
|
||||
table_info = await cls.set_table_from_options(GenTableOutSchema(**CamelCaseUtil.transform_result(table)))
|
||||
result.append(table_info)
|
||||
gen_table_all = await GenTableCRUD(auth=auth).get_gen_table_all()
|
||||
result = [GenTableOutSchema(**gen_table) for gen_table in CamelCaseUtil.transform_result(gen_table_all)]
|
||||
return result
|
||||
|
||||
@classmethod
|
||||
async def preview_code_service(cls, auth: AuthSchema, table_id: int) -> Dict[Any, Any]:
|
||||
"""预览代码"""
|
||||
gen_table = await cls.get_gen_table_by_id_service(auth, table_id)
|
||||
await cls.set_sub_table(auth, gen_table)
|
||||
await cls._set_pk_column(gen_table)
|
||||
env = TemplateInitializer.init_jinja2()
|
||||
context = TemplateUtils.prepare_context(gen_table)
|
||||
template_list = TemplateUtils.get_template_list(
|
||||
gen_table.tpl_category or "",
|
||||
gen_table.tpl_web_type or ""
|
||||
"""
|
||||
预览代码service
|
||||
|
||||
:param auth: 认证对象
|
||||
:param table_id: 业务表id
|
||||
:return: 预览数据列表
|
||||
"""
|
||||
gen_table = GenTableOutSchema(
|
||||
**CamelCaseUtil.transform_result(await GenTableCRUD(auth).get_gen_table_by_id(table_id))
|
||||
)
|
||||
await cls.set_sub_table(auth, gen_table)
|
||||
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)
|
||||
preview_code_result = {}
|
||||
for template in template_list:
|
||||
render_content = env.get_template(template).render(**context)
|
||||
preview_code_result[template] = render_content
|
||||
return preview_code_result
|
||||
|
||||
|
||||
@classmethod
|
||||
async def generate_code_service(cls, auth: AuthSchema, table_name: str) -> SuccessResponse:
|
||||
"""生成代码至指定路径"""
|
||||
env = TemplateInitializer.init_jinja2()
|
||||
env = Jinja2TemplateInitializerUtil.init_jinja2()
|
||||
render_info = await cls.__get_gen_render_info(auth, table_name)
|
||||
for template in render_info[0]:
|
||||
try:
|
||||
@@ -292,11 +218,17 @@ class GenTableService:
|
||||
|
||||
@classmethod
|
||||
async def batch_gen_code_service(cls, auth: AuthSchema, table_names: List[str]) -> bytes:
|
||||
"""批量生成代码"""
|
||||
"""
|
||||
批量生成代码service
|
||||
|
||||
:param auth: 认证对象
|
||||
:param table_names: 业务表名称组
|
||||
:return: 下载代码结果
|
||||
"""
|
||||
zip_buffer = io.BytesIO()
|
||||
with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zip_file:
|
||||
for table_name in table_names:
|
||||
env = TemplateInitializer.init_jinja2()
|
||||
env = Jinja2TemplateInitializerUtil.init_jinja2()
|
||||
render_info = await cls.__get_gen_render_info(auth, table_name)
|
||||
for template_file, output_file in zip(render_info[0], render_info[1]):
|
||||
render_content = env.get_template(template_file).render(**render_info[2])
|
||||
@@ -307,93 +239,58 @@ class GenTableService:
|
||||
return zip_data
|
||||
|
||||
@classmethod
|
||||
async def sync_db_service(cls, auth: AuthSchema, table_name: str) -> SuccessResponse:
|
||||
async def sync_db_service(cls, auth: AuthSchema, table_name: str) -> None:
|
||||
"""同步数据库"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table_column_dao = GenTableColumnCRUD(auth=auth)
|
||||
|
||||
gen_table = await gen_table_dao.get_gen_table_by_name(db, table_name)
|
||||
if gen_table:
|
||||
table = GenTableOutSchema(**CamelCaseUtil.transform_result(gen_table))
|
||||
table_columns = table.columns or [] # 确保不为None
|
||||
table_column_map = {column.column_name: column for column in table_columns}
|
||||
query_db_table_columns = await gen_table_column_dao.get_gen_db_table_columns_by_name(db, table_name)
|
||||
db_table_columns = [
|
||||
GenTableColumnOutSchema(**column) for column in CamelCaseUtil.transform_result(query_db_table_columns)
|
||||
]
|
||||
if not db_table_columns:
|
||||
raise CustomException('同步数据失败,原表结构不存在')
|
||||
db_table_column_names = [column.column_name for column in db_table_columns]
|
||||
try:
|
||||
for column in db_table_columns:
|
||||
GenUtils.init_column_field(column, table)
|
||||
if column.column_name in table_column_map:
|
||||
prev_column = table_column_map[column.column_name]
|
||||
# 使用getattr安全访问id属性
|
||||
column_id = getattr(prev_column, 'id', None)
|
||||
if column_id is not None:
|
||||
# 为column设置id属性
|
||||
column.id = column_id
|
||||
if getattr(column, 'list', False): # 使用getattr安全访问属性
|
||||
column.dict_type = prev_column.dict_type
|
||||
column.query_type = prev_column.query_type
|
||||
if (
|
||||
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
|
||||
# 使用getattr安全访问id属性
|
||||
column_id = getattr(column, 'id', None)
|
||||
if column_id is not None:
|
||||
await gen_table_column_dao.update(id=column_id, data=column.model_dump(by_alias=True))
|
||||
else:
|
||||
await gen_table_column_dao.create(data=column.model_dump(by_alias=True))
|
||||
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:
|
||||
# 使用getattr安全访问id属性
|
||||
column_id = getattr(column, 'id', None)
|
||||
if column_id is not None:
|
||||
await gen_table_column_dao.delete(ids=[column_id])
|
||||
if isinstance(db, AsyncSession):
|
||||
await db.commit()
|
||||
return SuccessResponse(msg='同步成功')
|
||||
except Exception as e:
|
||||
if isinstance(db, AsyncSession):
|
||||
try:
|
||||
await db.rollback()
|
||||
except:
|
||||
pass # 忽略回滚错误
|
||||
raise CustomException(msg=f'同步失败: {str(e)}')
|
||||
else:
|
||||
raise CustomException('业务表不存在')
|
||||
gen_table = await GenTableCRUD(auth).get_gen_table_by_name(table_name)
|
||||
table = GenTableSchema(**CamelCaseUtil.transform_result(gen_table))
|
||||
table_columns = table.columns
|
||||
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)
|
||||
]
|
||||
if not db_table_columns:
|
||||
raise CustomException(msg='同步数据失败,原表结构不存在')
|
||||
db_table_column_names = [column.column_name for column in db_table_columns]
|
||||
try:
|
||||
for column in db_table_columns:
|
||||
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
|
||||
if column.list:
|
||||
column.dict_type = prev_column.dict_type
|
||||
column.query_type = prev_column.query_type
|
||||
if (
|
||||
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)
|
||||
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)
|
||||
except Exception as e:
|
||||
raise e
|
||||
|
||||
|
||||
@classmethod
|
||||
async def set_sub_table(cls, auth: AuthSchema, gen_table: GenTableOutSchema) -> None:
|
||||
"""设置主子表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
if gen_table.sub_table_name:
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
sub_table = await gen_table_dao.get_gen_table_by_name(db, gen_table.sub_table_name)
|
||||
sub_table = await gen_table_dao.get_gen_table_by_name(gen_table.sub_table_name)
|
||||
if sub_table:
|
||||
gen_table.sub_table = GenTableOutSchema(**CamelCaseUtil.transform_result(sub_table))
|
||||
|
||||
@classmethod
|
||||
async def _set_pk_column(cls, gen_table: GenTableOutSchema) -> None:
|
||||
async def set_pk_column(cls, gen_table: GenTableOutSchema) -> None:
|
||||
"""设置主键列信息"""
|
||||
if gen_table.columns:
|
||||
for column in gen_table.columns:
|
||||
@@ -425,7 +322,7 @@ class GenTableService:
|
||||
return gen_table
|
||||
|
||||
@classmethod
|
||||
async def validate_edit(cls, edit_gen_table: GenTableUpdateSchema) -> None:
|
||||
async def validate_edit(cls, edit_gen_table: GenTableSchema) -> None:
|
||||
"""编辑保存参数校验"""
|
||||
if edit_gen_table.tpl_category == GenConstant.TPL_TREE:
|
||||
# 从options字段获取参数,而不是params
|
||||
@@ -448,29 +345,26 @@ class GenTableService:
|
||||
|
||||
@classmethod
|
||||
async def __get_gen_render_info(cls, auth: AuthSchema, table_name: str) -> List[Any]:
|
||||
"""获取生成代码渲染模板相关信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_dao = GenTableCRUD(auth=auth)
|
||||
gen_table = await gen_table_dao.get_gen_table_by_name(db, table_name)
|
||||
if gen_table:
|
||||
gen_table_schema = GenTableOutSchema(**CamelCaseUtil.transform_result(gen_table))
|
||||
await cls.set_sub_table(auth, gen_table_schema)
|
||||
await cls._set_pk_column(gen_table_schema)
|
||||
context = TemplateUtils.prepare_context(gen_table_schema)
|
||||
template_list = TemplateUtils.get_template_list(
|
||||
gen_table_schema.tpl_category or "",
|
||||
gen_table_schema.tpl_web_type or ""
|
||||
)
|
||||
output_files = [TemplateUtils.get_file_name([template], gen_table_schema)[0] for template in template_list]
|
||||
"""
|
||||
获取生成代码渲染模板相关信息
|
||||
|
||||
return [template_list, output_files, context, gen_table_schema]
|
||||
else:
|
||||
raise CustomException(msg=f'业务表 {table_name} 不存在')
|
||||
:param auth: 认证对象
|
||||
:param table_name: 业务表名称
|
||||
:return: 生成代码渲染模板相关信息
|
||||
"""
|
||||
gen_table = await GenTableCRUD(auth=auth).get_gen_table_by_name(table_name)
|
||||
gen_table_schema = GenTableOutSchema(**CamelCaseUtil.transform_result(gen_table))
|
||||
await cls.set_sub_table(auth, gen_table_schema)
|
||||
await cls.set_pk_column(gen_table_schema)
|
||||
context = Jinja2TemplateUtil.prepare_context(gen_table_schema)
|
||||
template_list = Jinja2TemplateUtil.get_template_list(
|
||||
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]
|
||||
|
||||
return [template_list, output_files, context, gen_table_schema]
|
||||
|
||||
|
||||
@classmethod
|
||||
def __get_gen_path(cls, gen_table: GenTableOutSchema, template: str) -> Optional[str]:
|
||||
@@ -478,10 +372,10 @@ class GenTableService:
|
||||
try:
|
||||
gen_path = gen_table.gen_path or ""
|
||||
if gen_path == '/':
|
||||
file_name = TemplateUtils.get_file_name([template], gen_table)[0]
|
||||
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table)[0]
|
||||
return os.path.join(os.getcwd(), GEN_PATH, file_name)
|
||||
else:
|
||||
file_name = TemplateUtils.get_file_name([template], gen_table)[0]
|
||||
file_name = Jinja2TemplateUtil.get_file_name([template], gen_table)[0]
|
||||
return os.path.join(gen_path, file_name)
|
||||
except Exception:
|
||||
return None
|
||||
@@ -493,14 +387,7 @@ class GenTableColumnService:
|
||||
@classmethod
|
||||
async def get_gen_table_column_list_by_table_id_service(cls, auth: AuthSchema, table_id: int) -> List[GenTableColumnOutSchema]:
|
||||
"""获取业务表字段列表信息"""
|
||||
if not auth.db:
|
||||
raise CustomException(msg='数据库连接不存在')
|
||||
# 确保db是AsyncSession类型
|
||||
db = auth.db
|
||||
if not isinstance(db, AsyncSession):
|
||||
raise CustomException(msg='数据库连接类型不正确')
|
||||
gen_table_column_dao = GenTableColumnCRUD(auth=auth)
|
||||
gen_table_column_list_result = await gen_table_column_dao.get_gen_table_column_list_by_table_id(db, table_id)
|
||||
gen_table_column_list_result = await GenTableColumnCRUD(auth).list_gen_table_column_crud({"table_id": table_id})
|
||||
return [
|
||||
GenTableColumnOutSchema(**gen_table_column)
|
||||
for gen_table_column in CamelCaseUtil.transform_result(gen_table_column_list_result)
|
||||
|
||||
+7
-7
@@ -17,7 +17,7 @@ CacheRouter = APIRouter(route_class=OperationLogRoute, prefix="/cache", tags=["
|
||||
|
||||
@CacheRouter.get(
|
||||
'/info',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:query']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:query']))],
|
||||
summary="获取缓存监控信息",
|
||||
description="获取缓存监控信息"
|
||||
)
|
||||
@@ -32,7 +32,7 @@ async def get_monitor_cache_info_controller(
|
||||
|
||||
@CacheRouter.get(
|
||||
'/get/names',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:query']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:query']))],
|
||||
summary="获取缓存名称列表",
|
||||
description="获取缓存名称列表"
|
||||
)
|
||||
@@ -45,7 +45,7 @@ async def get_monitor_cache_name_controller() -> JSONResponse:
|
||||
|
||||
@CacheRouter.get(
|
||||
'/get/keys/{cache_name}',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:query']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:query']))],
|
||||
summary="获取缓存键名列表",
|
||||
description="获取缓存键名列表"
|
||||
)
|
||||
@@ -61,7 +61,7 @@ async def get_monitor_cache_key_controller(
|
||||
|
||||
@CacheRouter.get(
|
||||
'/get/value/{cache_name}/{cache_key}',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:query']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:query']))],
|
||||
summary="获取缓存值",
|
||||
description="获取缓存值"
|
||||
)
|
||||
@@ -78,7 +78,7 @@ async def get_monitor_cache_value_controller(
|
||||
|
||||
@CacheRouter.delete(
|
||||
'/delete/name/{cache_name}',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:delete']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:delete']))],
|
||||
summary="清除指定缓存名称的所有缓存",
|
||||
description="清除指定缓存名称的所有缓存"
|
||||
)
|
||||
@@ -96,7 +96,7 @@ async def clear_monitor_cache_name_controller(
|
||||
|
||||
@CacheRouter.delete(
|
||||
'/delete/key/{cache_key}',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:delete']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:delete']))],
|
||||
summary="清除指定缓存键",
|
||||
description="清除指定缓存键"
|
||||
)
|
||||
@@ -114,7 +114,7 @@ async def clear_monitor_cache_key_controller(
|
||||
|
||||
@CacheRouter.delete(
|
||||
'/delete/all',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:cache:delete']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:cache:delete']))],
|
||||
summary="清除所有缓存",
|
||||
description="清除所有缓存"
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ JobRouter = APIRouter(route_class=OperationLogRoute, prefix="/job", tags=["定
|
||||
@JobRouter.get("/detail/{id}", summary="获取定时任务详情", description="获取定时任务详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="定时任务ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await JobService.get_job_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取定时任务详情成功 {id}")
|
||||
@@ -35,7 +35,7 @@ async def get_obj_detail_controller(
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: JobQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await JobService.get_job_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list= result_dict_list, page_no= page.page_no, page_size = page.page_size)
|
||||
@@ -45,7 +45,7 @@ async def get_obj_list_controller(
|
||||
@JobRouter.post("/create", summary="创建定时任务", description="创建定时任务")
|
||||
async def create_obj_controller(
|
||||
data: JobCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await JobService.create_job_service(auth=auth, data=data)
|
||||
logger.info(f"创建定时任务成功: {result_dict}")
|
||||
@@ -55,7 +55,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: JobUpdateSchema,
|
||||
id: int = Path(..., description="定时任务ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await JobService.update_job_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改定时任务成功: {result_dict}")
|
||||
@@ -64,7 +64,7 @@ async def update_obj_controller(
|
||||
@JobRouter.delete("/delete", summary="删除定时任务", description="删除定时任务")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:delete"]))
|
||||
) -> JSONResponse:
|
||||
await JobService.delete_job_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除定时任务成功: {ids}")
|
||||
@@ -73,7 +73,7 @@ async def delete_obj_controller(
|
||||
@JobRouter.post('/export', summary="导出定时任务", description="导出定时任务")
|
||||
async def export_obj_list_controller(
|
||||
search: JobQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await JobService.get_job_list_service(search=search, auth=auth)
|
||||
@@ -90,7 +90,7 @@ async def export_obj_list_controller(
|
||||
|
||||
@JobRouter.delete("/clear", summary="清空定时任务日志", description="清空定时任务日志")
|
||||
async def clear_obj_log_controller(
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:delete"]))
|
||||
) -> JSONResponse:
|
||||
await JobService.clear_job_service(auth=auth)
|
||||
logger.info(f"清空定时任务成功")
|
||||
@@ -100,13 +100,13 @@ async def clear_obj_log_controller(
|
||||
async def option_obj_controller(
|
||||
id: int = Body(..., description="定时任务ID"),
|
||||
option: int = Body(..., description="操作类型 1: 暂停 2: 恢复 3: 重启"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:update"]))
|
||||
) -> JSONResponse:
|
||||
await JobService.option_job_service(auth=auth, id=id, option=option)
|
||||
logger.info(f"操作定时任务成功: {id}")
|
||||
return SuccessResponse(msg="操作定时任务成功")
|
||||
|
||||
@JobRouter.get("/log", summary="获取定时任务日志", description="获取定时任务日志", dependencies=[Depends(AuthPermission(permissions=["monitor:job:query"]))])
|
||||
@JobRouter.get("/log", summary="获取定时任务日志", description="获取定时任务日志", dependencies=[Depends(AuthPermission(["monitor:job:query"]))])
|
||||
async def get_job_log_controller():
|
||||
data = [
|
||||
{
|
||||
@@ -134,7 +134,7 @@ async def get_job_log_controller():
|
||||
@JobRouter.get("/log/detail/{id}", summary="获取定时任务日志详情", description="获取定时任务日志详情")
|
||||
async def get_job_log_detail_controller(
|
||||
id: int = Path(..., description="定时任务日志ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await JobLogService.get_job_log_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取定时任务日志详情成功 {id}")
|
||||
@@ -145,7 +145,7 @@ async def get_job_log_detail_controller(
|
||||
async def get_job_log_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: JobLogQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:query"]))
|
||||
) -> JSONResponse:
|
||||
order_by = [{"create_time": "desc"}]
|
||||
result_dict_list = await JobLogService.get_job_log_list_service(auth=auth, search=search, order_by=order_by)
|
||||
@@ -157,7 +157,7 @@ async def get_job_log_list_controller(
|
||||
@JobRouter.delete("/log/delete", summary="删除定时任务日志", description="删除定时任务日志")
|
||||
async def delete_job_log_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:delete"]))
|
||||
) -> JSONResponse:
|
||||
await JobLogService.delete_job_log_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除定时任务日志成功: {ids}")
|
||||
@@ -166,7 +166,7 @@ async def delete_job_log_controller(
|
||||
|
||||
@JobRouter.delete("/log/clear", summary="清空定时任务日志", description="清空定时任务日志")
|
||||
async def clear_job_log_controller(
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:delete"]))
|
||||
) -> JSONResponse:
|
||||
await JobLogService.clear_job_log_service(auth=auth)
|
||||
logger.info(f"清空定时任务日志成功")
|
||||
@@ -176,7 +176,7 @@ async def clear_job_log_controller(
|
||||
@JobRouter.post('/log/export', summary="导出定时任务日志", description="导出定时任务日志")
|
||||
async def export_job_log_list_controller(
|
||||
search: JobLogQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["monitor:job:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["monitor:job:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await JobLogService.get_job_log_list_service(search=search, auth=auth)
|
||||
|
||||
@@ -19,7 +19,7 @@ OnlineRouter = APIRouter(route_class=OperationLogRoute, prefix="/online", tags=[
|
||||
|
||||
@OnlineRouter.get(
|
||||
'/list',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:online:query']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:online:query']))],
|
||||
summary="获取在线用户列表",
|
||||
description="获取在线用户列表"
|
||||
)
|
||||
@@ -38,7 +38,7 @@ async def get_online_list_controller(
|
||||
|
||||
@OnlineRouter.delete(
|
||||
'/delete',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:online:delete']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:online:delete']))],
|
||||
summary="强制下线",
|
||||
description="强制下线"
|
||||
)
|
||||
@@ -56,7 +56,7 @@ async def delete_online_controller(
|
||||
|
||||
@OnlineRouter.delete(
|
||||
'/clear',
|
||||
dependencies=[Depends(AuthPermission(permissions=['monitor:online:delete']))],
|
||||
dependencies=[Depends(AuthPermission(['monitor:online:delete']))],
|
||||
summary="清除所有在线用户",
|
||||
description="清除所有在线用户"
|
||||
)
|
||||
|
||||
@@ -28,7 +28,7 @@ ResourceRouter = APIRouter(route_class=OperationLogRoute, prefix="/resource", ta
|
||||
"/list",
|
||||
summary="获取目录列表",
|
||||
description="获取指定目录下的文件和子目录列表",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:query"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:query"]))]
|
||||
)
|
||||
async def get_directory_list_controller(
|
||||
request: Request,
|
||||
@@ -56,7 +56,7 @@ async def get_directory_list_controller(
|
||||
"/upload",
|
||||
summary="上传文件",
|
||||
description="上传文件到指定目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:upload"]))])
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:upload"]))])
|
||||
async def upload_file_controller(
|
||||
file: UploadFile,
|
||||
request: Request,
|
||||
@@ -76,7 +76,7 @@ async def upload_file_controller(
|
||||
"/download",
|
||||
summary="下载文件",
|
||||
description="下载指定文件",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:download"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:download"]))]
|
||||
)
|
||||
async def download_file_controller(
|
||||
request: Request,
|
||||
@@ -104,7 +104,7 @@ async def download_file_controller(
|
||||
"/delete",
|
||||
summary="删除文件",
|
||||
description="删除指定文件或目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:delete"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:delete"]))]
|
||||
)
|
||||
async def delete_files_controller(
|
||||
paths: List[str] = Body(..., description="文件路径列表")
|
||||
@@ -119,7 +119,7 @@ async def delete_files_controller(
|
||||
"/move",
|
||||
summary="移动文件",
|
||||
description="移动文件或目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:move"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:move"]))]
|
||||
)
|
||||
async def move_file_controller(
|
||||
data: ResourceMoveSchema
|
||||
@@ -134,7 +134,7 @@ async def move_file_controller(
|
||||
"/copy",
|
||||
summary="复制文件",
|
||||
description="复制文件或目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:copy"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:copy"]))]
|
||||
)
|
||||
async def copy_file_controller(
|
||||
data: ResourceCopySchema
|
||||
@@ -149,7 +149,7 @@ async def copy_file_controller(
|
||||
"/rename",
|
||||
summary="重命名文件",
|
||||
description="重命名文件或目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:rename"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:rename"]))]
|
||||
)
|
||||
async def rename_file_controller(
|
||||
data: ResourceRenameSchema
|
||||
@@ -164,7 +164,7 @@ async def rename_file_controller(
|
||||
"/create-dir",
|
||||
summary="创建目录",
|
||||
description="在指定路径创建新目录",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:create_dir"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:create_dir"]))]
|
||||
)
|
||||
async def create_directory_controller(
|
||||
data: ResourceCreateDirSchema
|
||||
@@ -179,7 +179,7 @@ async def create_directory_controller(
|
||||
"/export",
|
||||
summary="导出资源列表",
|
||||
description="导出资源列表",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:resource:export"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:resource:export"]))]
|
||||
)
|
||||
async def export_resource_list_controller(
|
||||
request: Request,
|
||||
|
||||
@@ -17,7 +17,7 @@ ServerRouter = APIRouter(route_class=OperationLogRoute, prefix="/server", tags=[
|
||||
'/info',
|
||||
summary="查询服务器监控信息",
|
||||
description="查询服务器监控信息",
|
||||
dependencies=[Depends(AuthPermission(permissions=["monitor:server:query"]))]
|
||||
dependencies=[Depends(AuthPermission(["monitor:server:query"]))]
|
||||
)
|
||||
async def get_monitor_server_info_controller() -> JSONResponse:
|
||||
# 获取全量数据
|
||||
|
||||
@@ -23,7 +23,7 @@ DeptRouter = APIRouter(route_class=OperationLogRoute, prefix="/dept", tags=["部
|
||||
@DeptRouter.get("/tree", summary="查询部门树", description="查询部门树")
|
||||
async def get_dept_tree_controller(
|
||||
search: DeptQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:query"]))
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
result_dict_list = await DeptService.get_dept_tree_service(search=search, auth=auth, order_by=order_by)
|
||||
@@ -34,7 +34,7 @@ async def get_dept_tree_controller(
|
||||
@DeptRouter.get("/detail/{id}", summary="查询部门详情", description="查询部门详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="部门ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService.get_dept_detail_service(id=id, auth=auth)
|
||||
logger.info(f"查询部门详情成功 {id}")
|
||||
@@ -44,7 +44,7 @@ async def get_obj_detail_controller(
|
||||
@DeptRouter.post("/create", summary="创建部门", description="创建部门")
|
||||
async def create_obj_controller(
|
||||
data: DeptCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService.create_dept_service(data=data, auth=auth)
|
||||
logger.info(f"创建部门成功: {result_dict}")
|
||||
@@ -55,7 +55,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: DeptUpdateSchema,
|
||||
id: int = Path(..., description="部门ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DeptService.update_dept_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改部门成功: {result_dict}")
|
||||
@@ -65,7 +65,7 @@ async def update_obj_controller(
|
||||
@DeptRouter.delete("/delete", summary="删除部门", description="删除部门")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:delete"]))
|
||||
) -> JSONResponse:
|
||||
await DeptService.delete_dept_service(ids=ids, auth=auth)
|
||||
logger.info(f"删除部门成功: {ids}")
|
||||
@@ -75,7 +75,7 @@ async def delete_obj_controller(
|
||||
@DeptRouter.patch("/available/setting", summary="批量修改部门状态", description="批量修改部门状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dept:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dept:patch"]))
|
||||
) -> JSONResponse:
|
||||
await DeptService.batch_set_available_service(data=data, auth=auth)
|
||||
logger.info(f"批量修改部门状态成功: {data.ids}")
|
||||
|
||||
@@ -29,7 +29,7 @@ DictRouter = APIRouter(route_class=OperationLogRoute, prefix="/dict", tags=["字
|
||||
@DictRouter.get("/type/detail/{id}", summary="获取字典类型详情", description="获取字典类型详情")
|
||||
async def get_type_detail_controller(
|
||||
id: int = Path(..., description="字典类型ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService.get_obj_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取字典类型详情成功 {id}")
|
||||
@@ -39,7 +39,7 @@ async def get_type_detail_controller(
|
||||
async def get_type_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: DictTypeQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await DictTypeService.get_obj_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list= result_dict_list, page_no= page.page_no, page_size = page.page_size)
|
||||
@@ -48,7 +48,7 @@ async def get_type_list_controller(
|
||||
|
||||
@DictRouter.get("/type/optionselect", summary="获取全部字典类型", description="获取全部字典类型")
|
||||
async def get_type_loptionselect_controller(
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await DictTypeService.get_obj_list_service(auth=auth)
|
||||
logger.info(f"获取字典类型列表成功")
|
||||
@@ -58,7 +58,7 @@ async def get_type_loptionselect_controller(
|
||||
async def create_type_controller(
|
||||
data: DictTypeCreateSchema,
|
||||
redis: Redis = Depends(redis_getter),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService.create_obj_service(auth=auth, redis=redis, data=data)
|
||||
logger.info(f"创建字典类型成功: {result_dict}")
|
||||
@@ -69,7 +69,7 @@ async def update_type_controller(
|
||||
data: DictTypeUpdateSchema,
|
||||
redis: Redis = Depends(redis_getter),
|
||||
id: int = Path(..., description="字典类型ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictTypeService.update_obj_service(auth=auth, redis=redis, id=id, data=data)
|
||||
logger.info(f"修改字典类型成功: {result_dict}")
|
||||
@@ -79,7 +79,7 @@ async def update_type_controller(
|
||||
async def delete_type_controller(
|
||||
redis: Redis = Depends(redis_getter),
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:delete"]))
|
||||
) -> JSONResponse:
|
||||
await DictTypeService.delete_obj_service(auth=auth, redis=redis, ids=ids)
|
||||
logger.info(f"删除字典类型成功: {ids}")
|
||||
@@ -88,7 +88,7 @@ async def delete_type_controller(
|
||||
@DictRouter.patch("/type/available/setting", summary="批量修改字典类型状态", description="批量修改字典类型状态")
|
||||
async def batch_set_available_dict_type_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:patch"]))
|
||||
) -> JSONResponse:
|
||||
await DictTypeService.set_obj_available_service(auth=auth, data=data)
|
||||
logger.info(f"批量修改字典类型状态成功: {data.ids}")
|
||||
@@ -97,7 +97,7 @@ async def batch_set_available_dict_type_controller(
|
||||
@DictRouter.post('/type/export', summary="导出字典类型", description="导出字典类型")
|
||||
async def export_type_list_controller(
|
||||
search: DictTypeQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_type:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_type:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await DictTypeService.get_obj_list_service(search=search, auth=auth)
|
||||
@@ -115,7 +115,7 @@ async def export_type_list_controller(
|
||||
@DictRouter.get("/data/detail/{id}", summary="获取字典数据详情", description="获取字典数据详情")
|
||||
async def get_data_detail_controller(
|
||||
id: int = Path(..., description="字典数据ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService.get_obj_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取字典数据详情成功 {id}")
|
||||
@@ -125,7 +125,7 @@ async def get_data_detail_controller(
|
||||
async def get_data_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: DictDataQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await DictDataService.get_obj_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list= result_dict_list, page_no= page.page_no, page_size = page.page_size)
|
||||
@@ -136,7 +136,7 @@ async def get_data_list_controller(
|
||||
async def create_data_controller(
|
||||
data: DictDataCreateSchema,
|
||||
redis: Redis = Depends(redis_getter),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService.create_obj_service(auth=auth, redis=redis, data=data)
|
||||
logger.info(f"创建字典数据成功: {result_dict}")
|
||||
@@ -147,7 +147,7 @@ async def update_data_controller(
|
||||
data: DictDataUpdateSchema,
|
||||
redis: Redis = Depends(redis_getter),
|
||||
id: int = Path(..., description="字典数据ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await DictDataService.update_obj_service(auth=auth, redis=redis, id=id, data=data)
|
||||
logger.info(f"修改字典数据成功: {result_dict}")
|
||||
@@ -157,7 +157,7 @@ async def update_data_controller(
|
||||
async def delete_data_controller(
|
||||
redis: Redis = Depends(redis_getter),
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:delete"]))
|
||||
) -> JSONResponse:
|
||||
await DictDataService.delete_obj_service(auth=auth, redis=redis, ids=ids)
|
||||
logger.info(f"删除字典数据成功: {ids}")
|
||||
@@ -166,7 +166,7 @@ async def delete_data_controller(
|
||||
@DictRouter.patch("/data/available/setting", summary="批量修改字典数据状态", description="批量修改字典数据状态")
|
||||
async def batch_set_available_dict_data_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:patch"]))
|
||||
) -> JSONResponse:
|
||||
await DictDataService.set_obj_available_service(auth=auth, data=data)
|
||||
logger.info(f"批量修改字典数据状态成功: {data.ids}")
|
||||
@@ -176,7 +176,7 @@ async def batch_set_available_dict_data_controller(
|
||||
async def export_data_list_controller(
|
||||
search: DictDataQueryParam = Depends(),
|
||||
page: PaginationQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:dict_data:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:dict_data:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await DictDataService.get_obj_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
|
||||
@@ -183,14 +183,14 @@ class DictDataService:
|
||||
auth = AuthSchema(db=session)
|
||||
obj_list = await DictTypeCRUD(auth).get_obj_list_crud()
|
||||
if not obj_list:
|
||||
logger.warning("未找到任何字典类型数据")
|
||||
logger.warning("❗️ 未找到任何字典类型数据")
|
||||
return
|
||||
for obj in obj_list:
|
||||
dict_type = obj.dict_type
|
||||
dict_data_list = await DictDataCRUD(auth).get_obj_list_crud(search={'dict_type': dict_type})
|
||||
|
||||
if not dict_data_list:
|
||||
logger.warning(f"字典类型 {dict_type} 未找到对应的字典数据")
|
||||
logger.warning(f"❗️ 字典类型 {dict_type} 未找到对应的字典数据")
|
||||
continue
|
||||
|
||||
dict_data = [DictDataOutSchema.model_validate(row).model_dump() for row in dict_data_list if row]
|
||||
@@ -204,7 +204,7 @@ class DictDataService:
|
||||
value=value,
|
||||
)
|
||||
except Exception as e:
|
||||
logger.error(f"初始化字典数据失败: {e}")
|
||||
logger.error(f"❌️ 初始化字典数据失败: {e}")
|
||||
raise CustomException(msg=f"初始化字典数据失败 {e}")
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -22,7 +22,7 @@ LogRouter = APIRouter(route_class=OperationLogRoute, prefix="/log", tags=["日
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: OperationLogQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:log:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:log:query"]))
|
||||
) -> JSONResponse:
|
||||
""" 查询日志 """
|
||||
order_by = [{"created_at": "desc"}]
|
||||
@@ -37,7 +37,7 @@ async def get_obj_list_controller(
|
||||
@LogRouter.get("/detail/{id}", summary="日志详情", description="日志详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="操作日志ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:log:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:log:query"]))
|
||||
) -> JSONResponse:
|
||||
""" 详情日志 """
|
||||
result_dict = await OperationLogService.get_log_detail_service(id=id, auth=auth)
|
||||
@@ -48,7 +48,7 @@ async def get_obj_detail_controller(
|
||||
@LogRouter.delete("/delete", summary="删除日志", description="删除日志")
|
||||
async def delete_obj_log_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:log:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:log:delete"]))
|
||||
) -> JSONResponse:
|
||||
""" 删除日志 """
|
||||
await OperationLogService.delete_log_service(ids=ids, auth=auth)
|
||||
@@ -59,7 +59,7 @@ async def delete_obj_log_controller(
|
||||
@LogRouter.post("/export", summary="导出日志", description="导出日志")
|
||||
async def export_obj_list_controller(
|
||||
search: OperationLogQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:log:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:log:export"]))
|
||||
) -> StreamingResponse:
|
||||
""" 导出日志 """
|
||||
operation_log_list = await OperationLogService.get_log_list_service(search=search, auth=auth)
|
||||
|
||||
@@ -22,7 +22,7 @@ MenuRouter = APIRouter(route_class=OperationLogRoute, prefix="/menu", tags=["菜
|
||||
@MenuRouter.get("/tree", summary="查询菜单树", description="查询菜单树")
|
||||
async def get_menu_tree_controller(
|
||||
search: MenuQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:query"]))
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
result_dict_list = await MenuService.get_menu_tree_service(search=search, auth=auth, order_by=order_by)
|
||||
@@ -33,7 +33,7 @@ async def get_menu_tree_controller(
|
||||
@MenuRouter.get("/detail/{id}", summary="查询菜单详情", description="查询菜单详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="菜单ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await MenuService.get_menu_detail_service(id=id, auth=auth)
|
||||
logger.info(f"查询菜单情成功 {id}")
|
||||
@@ -43,7 +43,7 @@ async def get_obj_detail_controller(
|
||||
@MenuRouter.post("/create", summary="创建菜单", description="创建菜单")
|
||||
async def create_obj_controller(
|
||||
data: MenuCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await MenuService.create_menu_service(data=data, auth=auth)
|
||||
logger.info(f"创建菜单成功: {result_dict}")
|
||||
@@ -54,7 +54,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: MenuUpdateSchema,
|
||||
id: int = Path(..., description="菜单ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await MenuService.update_menu_service(id=id, data=data, auth=auth)
|
||||
logger.info(f"修改菜单成功: {result_dict}")
|
||||
@@ -64,7 +64,7 @@ async def update_obj_controller(
|
||||
@MenuRouter.delete("/delete", summary="删除菜单", description="删除菜单")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:delete"]))
|
||||
) -> JSONResponse:
|
||||
await MenuService.delete_menu_service(ids=ids, auth=auth)
|
||||
logger.info(f"删除菜单成功: {ids}")
|
||||
@@ -74,7 +74,7 @@ async def delete_obj_controller(
|
||||
@MenuRouter.patch("/available/setting", summary="批量修改菜单状态", description="批量修改菜单状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:menu:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:menu:patch"]))
|
||||
) -> JSONResponse:
|
||||
await MenuService.set_menu_available_service(data=data, auth=auth)
|
||||
logger.info(f"批量修改菜单状态成功: {data.ids}")
|
||||
|
||||
@@ -25,7 +25,7 @@ NoticeRouter = APIRouter(route_class=OperationLogRoute, prefix="/notice", tags=[
|
||||
@NoticeRouter.get("/detail/{id}", summary="获取公告详情", description="获取公告详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="公告ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService.get_notice_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取公告详情成功 {id}")
|
||||
@@ -35,7 +35,7 @@ async def get_obj_detail_controller(
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: NoticeQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await NoticeService.get_notice_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list= result_dict_list, page_no= page.page_no, page_size = page.page_size)
|
||||
@@ -45,7 +45,7 @@ async def get_obj_list_controller(
|
||||
@NoticeRouter.post("/create", summary="创建公告", description="创建公告")
|
||||
async def create_obj_controller(
|
||||
data: NoticeCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService.create_notice_service(auth=auth, data=data)
|
||||
logger.info(f"创建公告成功: {result_dict}")
|
||||
@@ -55,7 +55,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: NoticeUpdateSchema,
|
||||
id: int = Path(..., description="公告ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await NoticeService.update_notice_service(auth=auth, id=id, data=data)
|
||||
logger.info(f"修改公告成功: {result_dict}")
|
||||
@@ -64,7 +64,7 @@ async def update_obj_controller(
|
||||
@NoticeRouter.delete("/delete", summary="删除公告", description="删除公告")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:delete"]))
|
||||
) -> JSONResponse:
|
||||
await NoticeService.delete_notice_service(auth=auth, ids=ids)
|
||||
logger.info(f"删除公告成功: {ids}")
|
||||
@@ -73,7 +73,7 @@ async def delete_obj_controller(
|
||||
@NoticeRouter.patch("/available/setting", summary="批量修改公告状态", description="批量修改公告状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:patch"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:patch"]))
|
||||
) -> JSONResponse:
|
||||
await NoticeService.set_notice_available_service(auth=auth, data=data)
|
||||
logger.info(f"批量修改公告状态成功: {data.ids}")
|
||||
@@ -82,7 +82,7 @@ async def batch_set_available_obj_controller(
|
||||
@NoticeRouter.post('/export', summary="导出公告", description="导出公告")
|
||||
async def export_obj_list_controller(
|
||||
search: NoticeQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:notice:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:notice:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await NoticeService.get_notice_list_service(search=search, auth=auth)
|
||||
|
||||
@@ -23,7 +23,7 @@ ParamsRouter = APIRouter(route_class=OperationLogRoute, prefix="/param", tags=["
|
||||
@ParamsRouter.get("/detail/{id}", summary="获取参数详情", description="获取参数详情")
|
||||
async def get_type_detail_controller(
|
||||
id: int = Path(..., description="参数ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService.get_obj_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取参数详情成功 {id}")
|
||||
@@ -33,7 +33,7 @@ async def get_type_detail_controller(
|
||||
@ParamsRouter.get("/key/{config_key}", summary="根据配置键获取参数详情", description="根据配置键获取参数详情")
|
||||
async def get_obj_by_key_controller(
|
||||
config_key: str = Path(..., description="配置键"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:query"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService.get_obj_by_key_service(config_key=config_key, auth=auth)
|
||||
logger.info(f"根据配置键获取参数详情成功 {config_key}")
|
||||
@@ -43,7 +43,7 @@ async def get_obj_by_key_controller(
|
||||
@ParamsRouter.get("/value/{config_key}", summary="根据配置键获取参数值", description="根据配置键获取参数值")
|
||||
async def get_config_value_by_key_controller(
|
||||
config_key: str = Path(..., description="配置键"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:query"]))
|
||||
) -> JSONResponse:
|
||||
result_value = await ParamsService.get_config_value_by_key_service(config_key=config_key, auth=auth)
|
||||
logger.info(f"根据配置键获取参数值成功 {config_key}")
|
||||
@@ -52,7 +52,7 @@ async def get_config_value_by_key_controller(
|
||||
|
||||
@ParamsRouter.get("/list", summary="获取参数列表", description="获取参数列表")
|
||||
async def get_obj_list_controller(
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:query"])),
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: ParamsQueryParam = Depends(),
|
||||
) -> JSONResponse:
|
||||
@@ -66,7 +66,7 @@ async def get_obj_list_controller(
|
||||
async def create_obj_controller(
|
||||
data: ParamsCreateSchema,
|
||||
redis: Redis = Depends(redis_getter),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:create"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:create"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService.create_obj_service(auth=auth, redis=redis, data=data)
|
||||
logger.info(f"创建参数成功: {result_dict}")
|
||||
@@ -78,7 +78,7 @@ async def update_objs_controller(
|
||||
data: ParamsUpdateSchema,
|
||||
id: int = Path(..., description="参数ID"),
|
||||
redis: Redis = Depends(redis_getter),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:update"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:update"]))
|
||||
) -> JSONResponse:
|
||||
result_dict = await ParamsService.update_obj_service(auth=auth, redis=redis, id=id, data=data)
|
||||
logger.info(f"更新参数成功 {result_dict}")
|
||||
@@ -89,7 +89,7 @@ async def update_objs_controller(
|
||||
async def delete_obj_controller(
|
||||
redis: Redis = Depends(redis_getter),
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:delete"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:delete"]))
|
||||
) -> JSONResponse:
|
||||
await ParamsService.delete_obj_service(auth=auth, redis=redis, ids=ids)
|
||||
logger.info(f"删除参数成功: {ids}")
|
||||
@@ -99,7 +99,7 @@ async def delete_obj_controller(
|
||||
@ParamsRouter.post('/export', summary="导出参数", description="导出参数")
|
||||
async def export_obj_list_controller(
|
||||
search: ParamsQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:param:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:param:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
result_dict_list = await ParamsService.get_obj_list_service(search=search, auth=auth)
|
||||
@@ -115,7 +115,7 @@ async def export_obj_list_controller(
|
||||
)
|
||||
|
||||
|
||||
@ParamsRouter.post("/upload", summary="上传文件", dependencies=[Depends(AuthPermission(permissions=["system:param:upload"]))])
|
||||
@ParamsRouter.post("/upload", summary="上传文件", dependencies=[Depends(AuthPermission(["system:param:upload"]))])
|
||||
async def upload_file_controller(
|
||||
file: UploadFile,
|
||||
request: Request
|
||||
|
||||
@@ -194,10 +194,10 @@ class ParamsService:
|
||||
value=value,
|
||||
)
|
||||
if not result:
|
||||
logger.error(f"初始化系统配置失败: {config_obj_dict}")
|
||||
logger.error(f"❌️ 初始化系统配置失败: {config_obj_dict}")
|
||||
raise CustomException(msg="初始化系统配置失败")
|
||||
except Exception as e:
|
||||
logger.error(f"初始化系统配置失败: {e}")
|
||||
logger.error(f"❌️ 初始化系统配置失败: {e}")
|
||||
raise CustomException(msg="初始化系统配置失败")
|
||||
|
||||
@classmethod
|
||||
|
||||
@@ -27,7 +27,7 @@ PositionRouter = APIRouter(route_class=OperationLogRoute, prefix="/position", ta
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: PositionQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:query"])),
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
if page.order_by:
|
||||
@@ -41,7 +41,7 @@ async def get_obj_list_controller(
|
||||
@PositionRouter.get("/detail/{id}", summary="查询岗位详情", description="查询岗位详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="岗位ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:query"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService.get_position_detail_service(id=id, auth=auth)
|
||||
logger.info(f"查询岗位详情成功 {id}")
|
||||
@@ -51,7 +51,7 @@ async def get_obj_detail_controller(
|
||||
@PositionRouter.post("/create", summary="创建岗位", description="创建岗位")
|
||||
async def create_obj_controller(
|
||||
data: PositionCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:create"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:create"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService.create_position_service(data=data, auth=auth)
|
||||
logger.info(f"创建岗位成功: {result_dict}")
|
||||
@@ -62,7 +62,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: PositionUpdateSchema,
|
||||
id: int = Path(..., description="岗位ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:update"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:update"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await PositionService.update_position_service(id=id, data=data, auth=auth)
|
||||
logger.info(f"修改岗位成功: {result_dict}")
|
||||
@@ -72,7 +72,7 @@ async def update_obj_controller(
|
||||
@PositionRouter.delete("/delete", summary="删除岗位", description="删除岗位")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:delete"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:delete"])),
|
||||
) -> JSONResponse:
|
||||
await PositionService.delete_position_service(ids=ids, auth=auth)
|
||||
logger.info(f"删除岗位成功: {ids}")
|
||||
@@ -82,7 +82,7 @@ async def delete_obj_controller(
|
||||
@PositionRouter.patch("/available/setting", summary="批量修改岗位状态", description="批量修改岗位状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:patch"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:patch"])),
|
||||
) -> JSONResponse:
|
||||
await PositionService.set_position_available_service(data=data, auth=auth)
|
||||
logger.info(f"批量修改岗位状态成功: {data.ids}")
|
||||
@@ -92,7 +92,7 @@ async def batch_set_available_obj_controller(
|
||||
@PositionRouter.post('/export', summary="导出岗位", description="导出岗位")
|
||||
async def export_obj_list_controller(
|
||||
search: PositionQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:position:export"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:position:export"])),
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
position_query_result = await PositionService.get_position_list_service(search=search, auth=auth)
|
||||
|
||||
@@ -28,7 +28,7 @@ RoleRouter = APIRouter(route_class=OperationLogRoute, prefix="/role", tags=["角
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: RoleQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:query"])),
|
||||
) -> JSONResponse:
|
||||
order_by = [{"order": "asc"}]
|
||||
if page.order_by:
|
||||
@@ -42,7 +42,7 @@ async def get_obj_list_controller(
|
||||
@RoleRouter.get("/detail/{id}", summary="查询角色详情", description="查询角色详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="角色ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:query"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService.get_role_detail_service(id=id, auth=auth)
|
||||
logger.info(f"获取角色详情成功 {id}")
|
||||
@@ -52,7 +52,7 @@ async def get_obj_detail_controller(
|
||||
@RoleRouter.post("/create", summary="创建角色", description="创建角色")
|
||||
async def create_obj_controller(
|
||||
data: RoleCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:create"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:create"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService.create_role_service(data=data, auth=auth)
|
||||
logger.info(f"创建角色成功: {result_dict}")
|
||||
@@ -63,7 +63,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: RoleUpdateSchema,
|
||||
id: int = Path(..., description="角色ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:update"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:update"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await RoleService.update_role_service(id=id, data=data, auth=auth)
|
||||
logger.info(f"修改角色成功: {result_dict}")
|
||||
@@ -73,7 +73,7 @@ async def update_obj_controller(
|
||||
@RoleRouter.delete("/delete", summary="删除角色", description="删除角色")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:delete"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:delete"])),
|
||||
) -> JSONResponse:
|
||||
await RoleService.delete_role_service(ids=ids, auth=auth)
|
||||
logger.info(f"删除角色成功: {ids}")
|
||||
@@ -83,7 +83,7 @@ async def delete_obj_controller(
|
||||
@RoleRouter.patch("/available/setting", summary="批量修改角色状态", description="批量修改角色状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:patch"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:patch"])),
|
||||
) -> JSONResponse:
|
||||
await RoleService.set_role_available_service(data=data, auth=auth)
|
||||
logger.info(f"批量修改角色状态成功: {data.ids}")
|
||||
@@ -93,7 +93,7 @@ async def batch_set_available_obj_controller(
|
||||
@RoleRouter.patch("/permission/setting", summary="角色授权", description="角色授权")
|
||||
async def set_role_permission_controller(
|
||||
data: RolePermissionSettingSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:permission"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:permission"])),
|
||||
) -> JSONResponse:
|
||||
await RoleService.set_role_permission_service(data=data, auth=auth)
|
||||
logger.info(f"设置角色权限成功: {data}")
|
||||
@@ -103,7 +103,7 @@ async def set_role_permission_controller(
|
||||
@RoleRouter.post('/export', summary="导出角色", description="导出角色")
|
||||
async def export_obj_list_controller(
|
||||
search: RoleQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:role:export"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:role:export"])),
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
role_query_result = await RoleService.get_role_list_service(search=search, auth=auth)
|
||||
|
||||
@@ -103,7 +103,7 @@ async def forget_password_controller(
|
||||
async def get_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: UserQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:query"])),
|
||||
) -> JSONResponse:
|
||||
result_dict_list = await UserService.get_user_list_service(search=search, auth=auth, order_by=page.order_by)
|
||||
result_dict = await PaginationService.paginate(data_list= result_dict_list, page_no= page.page_no, page_size = page.page_size)
|
||||
@@ -114,7 +114,7 @@ async def get_obj_list_controller(
|
||||
@UserRouter.get("/detail/{id}", summary="查询用户详情", description="查询用户详情")
|
||||
async def get_obj_detail_controller(
|
||||
id: int = Path(..., description="用户ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:query"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:query"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService.get_detail_by_id_service(id=id, auth=auth)
|
||||
logger.info(f"获取用户详情成功 {id}")
|
||||
@@ -124,7 +124,7 @@ async def get_obj_detail_controller(
|
||||
@UserRouter.post("/create", summary="创建用户", description="创建用户")
|
||||
async def create_obj_controller(
|
||||
data: UserCreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:create"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:create"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService.create_user_service(data=data, auth=auth)
|
||||
logger.info(f"创建用户成功: {result_dict}")
|
||||
@@ -135,7 +135,7 @@ async def create_obj_controller(
|
||||
async def update_obj_controller(
|
||||
data: UserUpdateSchema,
|
||||
id: int = Path(..., description="用户ID"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:update"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:update"])),
|
||||
) -> JSONResponse:
|
||||
result_dict = await UserService.update_user_service(id=id, data=data, auth=auth)
|
||||
logger.info(f"修改用户成功: {result_dict}")
|
||||
@@ -145,7 +145,7 @@ async def update_obj_controller(
|
||||
@UserRouter.delete("/delete", summary="删除用户", description="删除用户")
|
||||
async def delete_obj_controller(
|
||||
ids: list[int] = Body(..., description="ID列表"),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:delete"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:delete"])),
|
||||
) -> JSONResponse:
|
||||
await UserService.delete_user_service(ids=ids, auth=auth)
|
||||
logger.info(f"删除用户成功: {ids}")
|
||||
@@ -155,14 +155,14 @@ async def delete_obj_controller(
|
||||
@UserRouter.patch("/available/setting", summary="批量修改用户状态", description="批量修改用户状态")
|
||||
async def batch_set_available_obj_controller(
|
||||
data: BatchSetAvailable,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:patch"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:patch"])),
|
||||
) -> JSONResponse:
|
||||
await UserService.set_user_available_service(data=data, auth=auth)
|
||||
logger.info(f"批量修改用户状态成功: {data.ids}")
|
||||
return SuccessResponse(msg="批量修改用户状态成功")
|
||||
|
||||
|
||||
@UserRouter.post('/import/template', summary="获取用户导入模板", description="获取用户导入模板", dependencies=[Depends(AuthPermission(permissions=["system:user:import"]))])
|
||||
@UserRouter.post('/import/template', summary="获取用户导入模板", description="获取用户导入模板", dependencies=[Depends(AuthPermission(["system:user:import"]))])
|
||||
async def export_obj_template_controller()-> StreamingResponse:
|
||||
user_import_template_result = await UserService.get_import_template_user_service()
|
||||
logger.info('获取用户导入模板成功')
|
||||
@@ -181,7 +181,7 @@ async def export_obj_template_controller()-> StreamingResponse:
|
||||
async def export_obj_list_controller(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: UserQueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:export"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:export"])),
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
user_list = await UserService.get_user_list_service(auth=auth, search=search, order_by=page.order_by)
|
||||
@@ -200,7 +200,7 @@ async def export_obj_list_controller(
|
||||
@UserRouter.post('/import/data', summary="导入用户", description="导入用户")
|
||||
async def import_obj_list_controller(
|
||||
file: UploadFile,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["system:user:import"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["system:user:import"]))
|
||||
) -> JSONResponse:
|
||||
batch_import_result = await UserService.batch_import_user_service(file=file, auth=auth, update_support=True)
|
||||
logger.info(f"导入用户成功: {batch_import_result}")
|
||||
|
||||
@@ -79,7 +79,7 @@ class UserCRUD(CRUDBase[UserModel, UserCreateSchema, UserUpdateSchema]):
|
||||
Returns:
|
||||
Optional[UserModel]: 更新后的用户信息
|
||||
"""
|
||||
return await self.update(id=id, data=UserUpdateSchema(last_login=datetime.now()))
|
||||
return await self.update(id=id, data={"last_login": datetime.now()})
|
||||
|
||||
async def set_available_crud(self, ids: List[int], status: bool) -> None:
|
||||
"""
|
||||
|
||||
+111
-256
@@ -3,235 +3,6 @@
|
||||
from enum import Enum
|
||||
from app.config.setting import settings
|
||||
|
||||
class GenConfig:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
# 作者
|
||||
author: str = 'Richard'
|
||||
# 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
||||
packageName: str = ''
|
||||
# 自动去除表前缀,默认是True
|
||||
autoRemovePre: bool = True
|
||||
# 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
|
||||
tablePrefix: str = 'system_'
|
||||
# 是否允许生成文件覆盖到本地(自定义路径),默认不允许
|
||||
allowOverwrite: bool = False
|
||||
|
||||
|
||||
class GenConstants:
|
||||
"""代码生成通用常量"""
|
||||
|
||||
# 单表(增删改查)
|
||||
TPL_CRUD = "crud"
|
||||
|
||||
# 树表(增删改查)
|
||||
TPL_TREE = "tree"
|
||||
|
||||
# 主子表(增删改查)
|
||||
TPL_SUB = "sub"
|
||||
|
||||
# 树编码字段
|
||||
TREE_CODE = "treeCode"
|
||||
|
||||
# 树父编码字段
|
||||
TREE_PARENT_CODE = "treeParentCode"
|
||||
|
||||
# 树名称字段
|
||||
TREE_NAME = "treeName"
|
||||
|
||||
# 上级菜单ID字段
|
||||
PARENT_MENU_ID = "parentMenuId"
|
||||
|
||||
# 上级菜单名称字段
|
||||
PARENT_MENU_NAME = "parentMenuName"
|
||||
|
||||
# 数据库字符串类型
|
||||
TYPE_STRING = ["char", "varchar", "nvarchar", "varchar2"]
|
||||
|
||||
# 数据库文本类型
|
||||
TYPE_TEXT = ["tinytext", "text", "mediumtext", "longtext"]
|
||||
|
||||
# 数据库时间类型
|
||||
TYPE_DATE_TIME = ["datetime", "time", "date", "timestamp" ]
|
||||
|
||||
# 数据库数字类型
|
||||
TYPE_NUMBER = ["tinyint", "smallint", "mediumint", "int", "number", "integer", "bigint", "float", "float", "double", "decimal"]
|
||||
|
||||
# 页面不需要编辑字段
|
||||
COLUMN_NAME_NOT_EDIT = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_time"]
|
||||
|
||||
# 页面不需要显示的列表字段
|
||||
COLUMN_NAME_NOT_LIST = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_by"]
|
||||
|
||||
# 页面不需要查询字段
|
||||
COLUMN_NAME_NOT_QUERY = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_by", "update_time", "remark"]
|
||||
|
||||
# Dao基类字段
|
||||
DAO_COLUMN_NOT_EDIT = ["create_by", "dept_id", "create_time", "del_flag", "update_time"]
|
||||
|
||||
# Entity基类字段
|
||||
BASE_ENTITY = ['id', 'create_time', 'update_time', "create_by", "dept_id", 'del_flag']
|
||||
|
||||
# Tree基类字段
|
||||
TREE_ENTITY = ["parentName", "parentId", "orderNum", "ancestors"]
|
||||
|
||||
# 文本框
|
||||
HTML_INPUT = "input"
|
||||
|
||||
# 文本域
|
||||
HTML_TEXTAREA = "textarea"
|
||||
|
||||
# 下拉框
|
||||
HTML_SELECT = "select"
|
||||
|
||||
# 单选框
|
||||
HTML_RADIO = "radio"
|
||||
|
||||
# 复选框
|
||||
HTML_CHECKBOX = "checkbox"
|
||||
|
||||
# 日期控件
|
||||
HTML_DATETIME = "datetime"
|
||||
|
||||
# 图片上传控件
|
||||
HTML_IMAGE_UPLOAD = "imageUpload"
|
||||
|
||||
# 文件上传控件
|
||||
HTML_FILE_UPLOAD = "fileUpload"
|
||||
|
||||
# 富文本控件
|
||||
HTML_EDITOR = "editor"
|
||||
|
||||
# 模糊查询
|
||||
QUERY_LIKE = "LIKE"
|
||||
|
||||
# 相等查询
|
||||
QUERY_EQ = "EQ"
|
||||
|
||||
# 需要
|
||||
REQUIRE = "1"
|
||||
|
||||
# MySQL -> SQLAlchemy 类型映射
|
||||
MYSQL_TO_SQLALCHEMY = {
|
||||
# Numeric Types
|
||||
"TINYINT": "SmallInteger",
|
||||
"SMALLINT": "SmallInteger",
|
||||
"MEDIUMINT": "Integer",
|
||||
"INT": "Integer",
|
||||
"INTEGER": "Integer",
|
||||
"BIGINT": "BigInteger",
|
||||
"FLOAT": "Float",
|
||||
"DOUBLE": "Float",
|
||||
"DECIMAL": "Numeric",
|
||||
"NUMERIC": "Numeric",
|
||||
|
||||
# String Types
|
||||
"CHAR": "String",
|
||||
"VARCHAR": "String",
|
||||
"TEXT": "Text",
|
||||
"TINYTEXT": "Text",
|
||||
"MEDIUMTEXT": "Text",
|
||||
"LONGTEXT": "Text",
|
||||
"BLOB": "LargeBinary",
|
||||
"TINYBLOB": "LargeBinary",
|
||||
"MEDIUMBLOB": "LargeBinary",
|
||||
"LONGBLOB": "LargeBinary",
|
||||
|
||||
# Date and Time Types
|
||||
"DATE": "Date",
|
||||
"DATETIME": "DateTime",
|
||||
"TIMESTAMP": "DateTime",
|
||||
"TIME": "Time",
|
||||
"YEAR": "Integer", # MySQL YEAR type is commonly represented as Integer in SQLAlchemy
|
||||
|
||||
# Binary Types
|
||||
"BINARY": "Binary",
|
||||
"VARBINARY": "Binary",
|
||||
|
||||
# Enum and Set Types
|
||||
"ENUM": "Enum",
|
||||
"SET": "Enum", # Set can be represented using Enum type in SQLAlchemy
|
||||
|
||||
# JSON Types
|
||||
"JSON": "JSON", # SQLAlchemy supports JSON type from 1.3.0 version
|
||||
|
||||
# Spatial Types (less common in typical usage)
|
||||
"GEOMETRY": "String", # Can be represented as String or Binary
|
||||
"POINT": "String", # Represented as String in SQLAlchemy
|
||||
"LINESTRING": "String", # Represented as String in SQLAlchemy
|
||||
"POLYGON": "String", # Represented as String in SQLAlchemy
|
||||
|
||||
# Other Types
|
||||
"BIT": "Boolean",
|
||||
"BOOL": "Boolean",
|
||||
"UUID": "String", # UUIDs in SQLAlchemy can be represented as String
|
||||
"BINARY": "Binary", # MySQL BINARY type corresponds to SQLAlchemy's Binary
|
||||
}
|
||||
|
||||
MYSQL_TO_PYTHON = {
|
||||
# 字符串类型
|
||||
"VARCHAR": "str",
|
||||
"CHAR": "str",
|
||||
"TEXT": "str",
|
||||
"TINYTEXT": "str",
|
||||
"MEDIUMTEXT": "str",
|
||||
"LONGTEXT": "str",
|
||||
# 数值类型
|
||||
"INT": "int",
|
||||
"TINYINT": "int",
|
||||
"SMALLINT": "int",
|
||||
"MEDIUMINT": "int",
|
||||
"BIGINT": "int",
|
||||
"FLOAT": "float",
|
||||
"DOUBLE": "float",
|
||||
"DECIMAL": "float",
|
||||
"NUMERIC": "float",
|
||||
"BIT": "bool", # 位字段,0 或 1
|
||||
# 日期和时间类型
|
||||
"DATETIME": "datetime",
|
||||
"TIMESTAMP": "datetime",
|
||||
"DATE": "datetime.date",
|
||||
"TIME": "datetime.time",
|
||||
"YEAR": "int", # 存储年份
|
||||
"TINYINT UNSIGNED": "int", # 无符号小整数类型
|
||||
# 布尔类型
|
||||
"BOOLEAN": "bool",
|
||||
"BOOL": "bool", # 布尔类型,通常与 BOOLEAN 相同
|
||||
# JSON 数据类型
|
||||
"JSON": "dict", # JSON 数据存储为字典
|
||||
# 二进制类型
|
||||
"BLOB": "bytes",
|
||||
"TINYBLOB": "bytes",
|
||||
"MEDIUMBLOB": "bytes",
|
||||
"LONGBLOB": "bytes",
|
||||
# 枚举和集合类型
|
||||
"ENUM": "str", # 枚举类型作为字符串
|
||||
"SET": "list", # 集合类型作为列表
|
||||
# 时间单位类型
|
||||
"DATE": "datetime.date", # 仅日期
|
||||
"TIME": "datetime.time", # 仅时间
|
||||
# 大文本类型
|
||||
"LONGTEXT": "str",
|
||||
"MEDIUMTEXT": "str",
|
||||
"TINYTEXT": "str",
|
||||
# UUID
|
||||
"UUID": "str", # UUID 一般作为字符串
|
||||
# 用于二进制数据
|
||||
"BINARY": "bytes", # 固定长度的二进制数据
|
||||
"VARBINARY": "bytes", # 可变长度的二进制数据
|
||||
# 其他数据类型
|
||||
"GEOMETRY": "bytes", # 空间数据类型,通常存储为字节流
|
||||
"POINT": "bytes", # 点数据类型
|
||||
"LINESTRING": "bytes", # 线数据类型
|
||||
"POLYGON": "bytes", # 多边形数据类型
|
||||
"MULTIPOINT": "bytes", # 多点数据类型
|
||||
"MULTILINESTRING": "bytes", # 多线数据类型
|
||||
"MULTIPOLYGON": "bytes", # 多多边形数据类型
|
||||
"GEOMETRYCOLLECTION": "bytes", # 几何集合类型
|
||||
}
|
||||
|
||||
|
||||
class RET(Enum):
|
||||
"""
|
||||
系统返回码枚举
|
||||
@@ -587,22 +358,43 @@ class GenConstant:
|
||||
DB_TO_PYTHON_TYPE_MAPPING: 数据库类型与python类型映射
|
||||
"""
|
||||
|
||||
TPL_CRUD = 'crud'
|
||||
TPL_TREE = 'tree'
|
||||
TPL_SUB = 'sub'
|
||||
TREE_CODE = 'treeCode'
|
||||
TREE_PARENT_CODE = 'treeParentCode'
|
||||
TREE_NAME = 'treeName'
|
||||
PARENT_MENU_ID = 'parentMenuId'
|
||||
PARENT_MENU_NAME = 'parentMenuName'
|
||||
# 单表(增删改查)
|
||||
TPL_CRUD = "crud"
|
||||
|
||||
# 树表(增删改查)
|
||||
TPL_TREE = "tree"
|
||||
|
||||
# 主子表(增删改查)
|
||||
TPL_SUB = "sub"
|
||||
|
||||
# 树编码字段
|
||||
TREE_CODE = "treeCode"
|
||||
|
||||
# 树父编码字段
|
||||
TREE_PARENT_CODE = "treeParentCode"
|
||||
|
||||
# 树名称字段
|
||||
TREE_NAME = "treeName"
|
||||
|
||||
# 上级菜单ID字段
|
||||
PARENT_MENU_ID = "parentMenuId"
|
||||
|
||||
# 上级菜单名称字段
|
||||
PARENT_MENU_NAME = "parentMenuName"
|
||||
|
||||
# 数据库字符串类型
|
||||
COLUMNTYPE_STR = (
|
||||
['character varying', 'varchar', 'character', 'char']
|
||||
if settings.DATABASE_TYPE == 'postgresql'
|
||||
else ['char', 'varchar', 'nvarchar', 'varchar2']
|
||||
)
|
||||
|
||||
# 数据库文本类型
|
||||
COLUMNTYPE_TEXT = (
|
||||
['text', 'citext'] if settings.DATABASE_TYPE == 'postgresql' else ['tinytext', 'text', 'mediumtext', 'longtext']
|
||||
)
|
||||
|
||||
# 数据库时间类型
|
||||
COLUMNTYPE_TIME = (
|
||||
[
|
||||
'date',
|
||||
@@ -617,6 +409,8 @@ class GenConstant:
|
||||
if settings.DATABASE_TYPE == 'postgresql'
|
||||
else ['datetime', 'time', 'date', 'timestamp']
|
||||
)
|
||||
|
||||
# 数据库字空间类型
|
||||
COLUMNTYPE_GEOMETRY = (
|
||||
['point', 'line', 'lseg', 'box', 'path', 'polygon', 'circle']
|
||||
if settings.DATABASE_TYPE == 'postgresql'
|
||||
@@ -631,6 +425,8 @@ class GenConstant:
|
||||
'geometrycollection',
|
||||
]
|
||||
)
|
||||
|
||||
# 数据库数字类型
|
||||
COLUMNTYPE_NUMBER = [
|
||||
'tinyint',
|
||||
'smallint',
|
||||
@@ -644,28 +440,74 @@ class GenConstant:
|
||||
'double',
|
||||
'decimal',
|
||||
]
|
||||
# 页面不需要显示的添加字段
|
||||
COLUMNNAME_NOT_ADD_SHOW = ['create_by', 'create_time']
|
||||
|
||||
# 页面不需要显示的编辑字段
|
||||
COLUMNNAME_NOT_EDIT_SHOW = ['updated_at']
|
||||
COLUMNNAME_NOT_EDIT = ['id', 'created_at', 'updated_at', 'del_flag']
|
||||
COLUMNNAME_NOT_LIST = ['id', 'created_at', 'updated_at', 'del_flag']
|
||||
COLUMNNAME_NOT_QUERY = ['id', 'created_at', 'updated_at', 'del_flag', 'remark']
|
||||
BASE_ENTITY = ['createdAt', 'updatedAt', 'remark']
|
||||
|
||||
# 页面不需要编辑字段
|
||||
COLUMNNAME_NOT_EDIT = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_time"]
|
||||
|
||||
# 页面不需要显示的列表字段
|
||||
COLUMNNAME_NOT_LIST = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_time"]
|
||||
|
||||
# 页面不需要查询字段
|
||||
COLUMNNAME_NOT_QUERY = ["id", "create_by", "dept_id", "create_time", "del_flag", "update_by", "update_time", "remark"]
|
||||
|
||||
# Crud基类字段
|
||||
CRUD_COLUMN_NOT_EDIT = ["create_by", "dept_id", "create_time", "del_flag", "update_time"]
|
||||
|
||||
# 实体基类字段
|
||||
BASE_ENTITY = ['id', 'create_time', 'update_time', "create_by", "dept_id", 'del_flag']
|
||||
|
||||
# Tree基类字段
|
||||
TREE_ENTITY = ['parentName', 'parentId', 'orderNum', 'ancestors', 'children']
|
||||
|
||||
# 文本框
|
||||
HTML_INPUT = 'input'
|
||||
|
||||
# 文本域
|
||||
HTML_TEXTAREA = 'textarea'
|
||||
|
||||
# 下拉框
|
||||
HTML_SELECT = 'select'
|
||||
|
||||
# 单选框
|
||||
HTML_RADIO = 'radio'
|
||||
|
||||
# 复选框
|
||||
HTML_CHECKBOX = 'checkbox'
|
||||
|
||||
# 日期控件
|
||||
HTML_DATETIME = 'datetime'
|
||||
|
||||
# 图片上传控件
|
||||
HTML_IMAGE_UPLOAD = 'imageUpload'
|
||||
|
||||
# 文件上传控件
|
||||
HTML_FILE_UPLOAD = 'fileUpload'
|
||||
|
||||
# 富文本控件
|
||||
HTML_EDITOR = 'editor'
|
||||
|
||||
# 高精度计算类型
|
||||
TYPE_DECIMAL = 'Decimal'
|
||||
|
||||
# 时间类型
|
||||
TYPE_DATE = ['date', 'time', 'datetime']
|
||||
|
||||
# 模糊查询
|
||||
QUERY_LIKE = 'LIKE'
|
||||
|
||||
# 相等查询
|
||||
QUERY_EQ = 'EQ'
|
||||
|
||||
# 需要
|
||||
REQUIRE = '1'
|
||||
DB_TO_SQLALCHEMY_TYPE_MAPPING = (
|
||||
|
||||
# 数据库类型与sqlalchemy类型映射
|
||||
DB_TO_SQLALCHEMY = (
|
||||
{
|
||||
'boolean': 'Boolean',
|
||||
'smallint': 'SmallInteger',
|
||||
@@ -734,6 +576,7 @@ class GenConstant:
|
||||
'DOUBLE': 'Float',
|
||||
'DECIMAL': 'DECIMAL',
|
||||
'BIT': 'Integer',
|
||||
"NUMERIC": "Numeric",
|
||||
# 日期和时间类型
|
||||
'DATE': 'Date',
|
||||
'TIME': 'Time',
|
||||
@@ -767,9 +610,14 @@ class GenConstant:
|
||||
'MULTILINESTRING': 'Geometry',
|
||||
'MULTIPOLYGON': 'Geometry',
|
||||
'GEOMETRYCOLLECTION': 'Geometry',
|
||||
# 其他类型
|
||||
"BOOL": "Boolean",
|
||||
"UUID": "String",
|
||||
}
|
||||
)
|
||||
DB_TO_PYTHON_TYPE_MAPPING = (
|
||||
|
||||
# 数据库类型与python类型映射
|
||||
DB_TO_PYTHON = (
|
||||
{
|
||||
'boolean': 'bool',
|
||||
'smallint': 'int',
|
||||
@@ -836,14 +684,21 @@ class GenConstant:
|
||||
'BIGINT': 'int',
|
||||
'FLOAT': 'float',
|
||||
'DOUBLE': 'float',
|
||||
"NUMERIC": "float",
|
||||
'DECIMAL': 'Decimal',
|
||||
'BIT': 'int',
|
||||
# 日期和时间类型
|
||||
'DATE': 'date',
|
||||
'TIME': 'time',
|
||||
'DATETIME': 'datetime',
|
||||
'TIMESTAMP': 'datetime',
|
||||
'DATE': 'datetime.date',
|
||||
'TIME': 'datetime.time',
|
||||
'DATETIME': 'datetime.datetime',
|
||||
'TIMESTAMP': 'datetime.datetime',
|
||||
'YEAR': 'int',
|
||||
"TINYINT UNSIGNED": "int", # 无符号小整数类型
|
||||
# 布尔类型
|
||||
"BOOLEAN": "bool",
|
||||
"BOOL": "bool", # 布尔类型,通常与 BOOLEAN 相同
|
||||
# UUID
|
||||
"UUID": "str", # UUID 一般作为字符串
|
||||
# 字符串类型
|
||||
'CHAR': 'str',
|
||||
'VARCHAR': 'str',
|
||||
@@ -859,18 +714,18 @@ class GenConstant:
|
||||
'LONGBLOB': 'bytes',
|
||||
# 枚举和集合类型
|
||||
'ENUM': 'str',
|
||||
'SET': 'str',
|
||||
'SET': 'list',
|
||||
# JSON 类型
|
||||
'JSON': 'dict',
|
||||
# 空间数据类型(通常需要特殊处理)
|
||||
'GEOMETRY': 'bytes',
|
||||
'POINT': 'bytes',
|
||||
'LINESTRING': 'bytes',
|
||||
'POLYGON': 'bytes',
|
||||
'MULTIPOINT': 'bytes',
|
||||
'MULTILINESTRING': 'bytes',
|
||||
'MULTIPOLYGON': 'bytes',
|
||||
'GEOMETRYCOLLECTION': 'bytes',
|
||||
"GEOMETRY": "bytes", # 空间数据类型,通常存储为字节流
|
||||
"POINT": "bytes", # 点数据类型
|
||||
"LINESTRING": "bytes", # 线数据类型
|
||||
"POLYGON": "bytes", # 多边形数据类型
|
||||
"MULTIPOINT": "bytes", # 多点数据类型
|
||||
"MULTILINESTRING": "bytes", # 多线数据类型
|
||||
"MULTIPOLYGON": "bytes", # 多多边形数据类型
|
||||
"GEOMETRYCOLLECTION": "bytes", # 几何集合类型
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@@ -243,11 +243,11 @@ class Settings(BaseSettings):
|
||||
# ================================================= #
|
||||
# ******************* 代码生成配置 ****************** #
|
||||
# ================================================= #
|
||||
author: str = 'insistence'
|
||||
package_name: str = 'module_admin.system'
|
||||
auto_remove_pre: bool = False
|
||||
table_prefix: str = 'gen_'
|
||||
allow_overwrite: bool = False
|
||||
author: str = 'insistence' # 作者
|
||||
package_name: str = 'module_generator.gencode' # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool
|
||||
auto_remove_pre: bool = False # 自动去除表前缀,默认是True
|
||||
table_prefix: str = 'gen_' # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)
|
||||
allow_overwrite: bool = False # 是否允许生成文件覆盖到本地(自定义路径),默认不允许
|
||||
|
||||
GEN_PATH: Path = BASE_DIR.joinpath('app/api/v1/module_generator/gen_backend_code')
|
||||
|
||||
|
||||
@@ -4,15 +4,11 @@
|
||||
提供跨数据库兼容的基础模型类和类型装饰器
|
||||
"""
|
||||
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Literal, Optional, Dict, Any, Union
|
||||
|
||||
from typing import Optional
|
||||
from sqlalchemy import Integer, DateTime, Text
|
||||
from sqlalchemy.ext.asyncio import AsyncAttrs
|
||||
from sqlalchemy.orm import relationship, DeclarativeBase, Mapped, declared_attr, mapped_column
|
||||
from sqlalchemy.engine.row import Row
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
|
||||
|
||||
class MappedBase(AsyncAttrs, DeclarativeBase):
|
||||
@@ -51,7 +47,7 @@ class ModelMixin(MappedBase):
|
||||
description: Mapped[Optional[str]] = mapped_column(Text, nullable=True, default=None, comment="备注/描述")
|
||||
created_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, comment='创建时间')
|
||||
updated_at: Mapped[Optional[datetime]] = mapped_column(DateTime, nullable=True, default=datetime.now, onupdate=datetime.now, comment='更新时间')
|
||||
|
||||
|
||||
|
||||
class CreatorMixin(ModelMixin):
|
||||
"""
|
||||
@@ -72,121 +68,3 @@ class CreatorMixin(ModelMixin):
|
||||
viewonly=True,
|
||||
uselist=False # 明确指定返回单个对象
|
||||
)
|
||||
|
||||
|
||||
class SqlalchemyUtil:
|
||||
"""
|
||||
sqlalchemy工具类
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def base_to_dict(
|
||||
cls, obj: Union[MappedBase, Dict], transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
|
||||
) -> dict[str, Any] | dict[Any, Any]:
|
||||
"""
|
||||
将sqlalchemy模型对象转换为字典
|
||||
|
||||
:param obj: sqlalchemy模型对象或普通字典
|
||||
:param transform_case: 转换得到的结果形式,可选的有'no_case'(不转换)、'snake_to_camel'(下划线转小驼峰)、'camel_to_snake'(小驼峰转下划线),默认为'no_case'
|
||||
:return: 字典结果
|
||||
"""
|
||||
if isinstance(obj, MappedBase):
|
||||
base_dict = obj.__dict__.copy()
|
||||
base_dict.pop('_sa_instance_state', None)
|
||||
for name, value in base_dict.items():
|
||||
if isinstance(value, InstrumentedList):
|
||||
base_dict[name] = cls.serialize_result(value, 'snake_to_camel')
|
||||
elif isinstance(obj, dict):
|
||||
base_dict = obj.copy()
|
||||
if transform_case == 'snake_to_camel':
|
||||
return {CamelCaseUtil.snake_to_camel(k): v for k, v in base_dict.items()}
|
||||
elif transform_case == 'camel_to_snake':
|
||||
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in base_dict.items()}
|
||||
|
||||
return base_dict
|
||||
|
||||
@classmethod
|
||||
def serialize_result(
|
||||
cls, result: Any, transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
|
||||
) -> Any:
|
||||
"""
|
||||
将sqlalchemy查询结果序列化
|
||||
|
||||
:param result: sqlalchemy查询结果
|
||||
:param transform_case: 转换得到的结果形式,可选的有'no_case'(不转换)、'snake_to_camel'(下划线转小驼峰)、'camel_to_snake'(小驼峰转下划线),默认为'no_case'
|
||||
:return: 序列化结果
|
||||
"""
|
||||
if isinstance(result, (MappedBase, dict)):
|
||||
return cls.base_to_dict(result, transform_case)
|
||||
elif isinstance(result, list):
|
||||
return [cls.serialize_result(row, transform_case) for row in result]
|
||||
elif isinstance(result, Row):
|
||||
if all([isinstance(row, MappedBase) for row in result]):
|
||||
return [cls.base_to_dict(row, transform_case) for row in result]
|
||||
elif any([isinstance(row, MappedBase) for row in result]):
|
||||
return [cls.serialize_result(row, transform_case) for row in result]
|
||||
else:
|
||||
result_dict = result._asdict()
|
||||
if transform_case == 'snake_to_camel':
|
||||
return {CamelCaseUtil.snake_to_camel(k): v for k, v in result_dict.items()}
|
||||
elif transform_case == 'camel_to_snake':
|
||||
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in result_dict.items()}
|
||||
return result_dict
|
||||
return result
|
||||
|
||||
|
||||
class CamelCaseUtil:
|
||||
"""
|
||||
下划线形式(snake_case)转小驼峰形式(camelCase)工具方法
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def snake_to_camel(cls, snake_str: str) -> str:
|
||||
"""
|
||||
下划线形式字符串(snake_case)转换为小驼峰形式字符串(camelCase)
|
||||
|
||||
:param snake_str: 下划线形式字符串
|
||||
:return: 小驼峰形式字符串
|
||||
"""
|
||||
# 分割字符串
|
||||
words = snake_str.split('_')
|
||||
# 小驼峰命名,第一个词首字母小写,其余词首字母大写
|
||||
return words[0] + ''.join(word.capitalize() for word in words[1:])
|
||||
|
||||
@classmethod
|
||||
def transform_result(cls, result: Any) -> Any:
|
||||
"""
|
||||
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
|
||||
|
||||
:param result: 输入数据
|
||||
:return: 小驼峰形式结果
|
||||
"""
|
||||
return SqlalchemyUtil.serialize_result(result=result, transform_case='snake_to_camel')
|
||||
|
||||
|
||||
class SnakeCaseUtil:
|
||||
"""
|
||||
小驼峰形式(camelCase)转下划线形式(snake_case)工具方法
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def camel_to_snake(cls, camel_str: str) -> str:
|
||||
"""
|
||||
小驼峰形式字符串(camelCase)转换为下划线形式字符串(snake_case)
|
||||
|
||||
:param camel_str: 小驼峰形式字符串
|
||||
:return: 下划线形式字符串
|
||||
"""
|
||||
# 在大写字母前添加一个下划线,然后将整个字符串转为小写
|
||||
words = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', camel_str)
|
||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', words).lower()
|
||||
|
||||
@classmethod
|
||||
def transform_result(cls, result: Any) -> Any:
|
||||
"""
|
||||
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
|
||||
|
||||
:param result: 输入数据
|
||||
:return: 小驼峰形式结果
|
||||
"""
|
||||
return SqlalchemyUtil.serialize_result(result=result, transform_case='camel_to_snake')
|
||||
@@ -26,10 +26,10 @@ class BaseSchema(BaseModel):
|
||||
"""通用输出模型,包含基础字段和审计字段"""
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
id: int = Field(description="主键ID")
|
||||
id: Optional[int] = Field(default=None, description="主键ID")
|
||||
description: Optional[str] = Field(default=None, description="描述")
|
||||
created_at: DateTimeStr = Field(description="创建时间")
|
||||
updated_at: DateTimeStr = Field(description="更新时间")
|
||||
created_at: Optional[DateTimeStr] = Field(default=None, description="创建时间")
|
||||
updated_at: Optional[DateTimeStr] = Field(default=None, description="更新时间")
|
||||
creator_id: Optional[int] = Field(default=None, description="创建人ID")
|
||||
creator: Optional[UserInfoSchema] = Field(default=None, description="创建人信息")
|
||||
|
||||
|
||||
@@ -77,7 +77,7 @@ async def redis_connect(app: FastAPI, status: bool) -> Redis | None:
|
||||
)
|
||||
app.state.redis = rd
|
||||
if await rd.ping():
|
||||
logger.info("Redis连接成功...")
|
||||
logger.info("✅️ Redis连接成功...")
|
||||
return rd
|
||||
raise CustomException(msg="Redis连接失败")
|
||||
except exceptions.AuthenticationError as e:
|
||||
@@ -113,4 +113,4 @@ async def mongodb_connect(app: FastAPI, status: bool) -> AsyncIOMotorClient | No
|
||||
raise ValueError(f"MongoDB连接失败: {e}")
|
||||
else:
|
||||
app.state.mongo_client.close()
|
||||
logger.info("MongoDB连接已关闭")
|
||||
logger.info("❌️ MongoDB连接已关闭")
|
||||
@@ -30,17 +30,17 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[Any, Any]:
|
||||
logger.info(settings.BANNER + '\n' + f'{settings.TITLE} 服务开始启动...')
|
||||
|
||||
await InitializeData().init_db()
|
||||
logger.info(f"初始化 {settings.DATABASE_TYPE} 数据库初始化完成...")
|
||||
logger.info(f"✅️ 初始化 {settings.DATABASE_TYPE} 数据库初始化完成...")
|
||||
await import_modules_async(modules=settings.EVENT_LIST, desc="全局事件", app=app, status=True)
|
||||
logger.info("初始化全局事件完成...")
|
||||
logger.info("✅️ 初始化全局事件完成...")
|
||||
await ParamsService().init_config_service(redis=app.state.redis)
|
||||
logger.info("初始化Redis系统配置完成...")
|
||||
logger.info("✅️ 初始化Redis系统配置完成...")
|
||||
await DictDataService().init_dict_service(redis=app.state.redis)
|
||||
logger.info('初始化Redis数据字典完成...')
|
||||
logger.info('✅️ 初始化Redis数据字典完成...')
|
||||
await SchedulerUtil.init_system_scheduler()
|
||||
logger.info('初始化定时任务完成...')
|
||||
logger.info('✅️ 初始化定时任务完成...')
|
||||
|
||||
logger.info(f'{settings.TITLE} 服务成功启动...')
|
||||
logger.info(f'✅️ {settings.TITLE} 服务成功启动...')
|
||||
|
||||
yield
|
||||
|
||||
|
||||
@@ -58,9 +58,9 @@ class InitializeData:
|
||||
# 使用引擎创建所有表
|
||||
async with async_engine.begin() as conn:
|
||||
await conn.run_sync(MappedBase.metadata.create_all)
|
||||
logger.info("数据库表结构初始化完成")
|
||||
logger.info("✅️ 数据库表结构初始化完成")
|
||||
except Exception as e:
|
||||
logger.error(f"数据库表结构初始化失败: {str(e)}")
|
||||
logger.error(f"❌️ 数据库表结构初始化失败: {str(e)}")
|
||||
raise
|
||||
|
||||
async def __init_data(self, db: AsyncSession) -> None:
|
||||
@@ -72,12 +72,12 @@ class InitializeData:
|
||||
count_result = await db.execute(select(func.count()).select_from(model))
|
||||
existing_count = count_result.scalar()
|
||||
if existing_count and existing_count > 0:
|
||||
logger.warning(f"跳过 {table_name} 表数据初始化(表已存在 {existing_count} 条记录)")
|
||||
logger.warning(f"⚠️ 跳过 {table_name} 表数据初始化(表已存在 {existing_count} 条记录)")
|
||||
continue
|
||||
|
||||
data = await self.__get_data(table_name)
|
||||
if not data:
|
||||
logger.warning(f"跳过 {table_name} 表,无初始化数据")
|
||||
logger.warning(f"⚠️ 跳过 {table_name} 表,无初始化数据")
|
||||
continue
|
||||
|
||||
try:
|
||||
@@ -91,10 +91,10 @@ class InitializeData:
|
||||
objs = [model(**item) for item in data]
|
||||
db.add_all(objs)
|
||||
await db.flush()
|
||||
logger.info(f"已向 {table_name} 表写入初始化数据")
|
||||
logger.info(f"✅️ 已向 {table_name} 表写入初始化数据")
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"初始化 {table_name} 表数据失败: {str(e)}")
|
||||
logger.error(f"❌️ 初始化 {table_name} 表数据失败: {str(e)}")
|
||||
raise
|
||||
|
||||
def __create_objects_with_children(self, data: List[Dict], model_class) -> List:
|
||||
@@ -129,10 +129,10 @@ class InitializeData:
|
||||
with open(json_path, 'r', encoding='utf-8') as f:
|
||||
return json.loads(f.read())
|
||||
except json.JSONDecodeError as e:
|
||||
logger.error(f"解析 {json_path} 失败: {str(e)}")
|
||||
logger.error(f"❌️ 解析 {json_path} 失败: {str(e)}")
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f"读取 {json_path} 失败: {str(e)}")
|
||||
logger.error(f"❌️ 读取 {json_path} 失败: {str(e)}")
|
||||
raise
|
||||
|
||||
async def init_db(self) -> None:
|
||||
|
||||
@@ -1,16 +1,20 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from pathlib import Path
|
||||
import importlib
|
||||
from types import ModuleType
|
||||
import re
|
||||
import uuid
|
||||
from typing import Any, Generator, List, Dict, Sequence, Optional
|
||||
from pathlib import Path
|
||||
from typing import Any, Generator, List, Dict, Literal, Sequence, Optional, Union
|
||||
from sqlalchemy.engine.row import Row
|
||||
from sqlalchemy.orm import DeclarativeBase
|
||||
from sqlalchemy.orm.collections import InstrumentedList
|
||||
|
||||
from app.config import setting
|
||||
from app.core.base_model import MappedBase
|
||||
from app.core.logger import logger
|
||||
from app.core.exceptions import CustomException
|
||||
|
||||
|
||||
def worship():
|
||||
print("""
|
||||
______ _ _
|
||||
@@ -23,6 +27,7 @@ def worship():
|
||||
|_|
|
||||
""")
|
||||
|
||||
|
||||
def import_module(module: str, desc: str) -> Any:
|
||||
"""
|
||||
动态导入模块
|
||||
@@ -35,10 +40,10 @@ def import_module(module: str, desc: str) -> Any:
|
||||
module = importlib.import_module(module_path)
|
||||
return getattr(module, module_class)
|
||||
except ModuleNotFoundError:
|
||||
logger.error(f"导入{desc}失败,未找到模块:{module}")
|
||||
logger.error(f"❗️ 导入{desc}失败,未找到模块:{module}")
|
||||
raise ModuleNotFoundError(f"导入{desc}失败,未找到模块:{module}")
|
||||
except AttributeError:
|
||||
logger.error(f"导入{desc}失败,未找到模块方法:{module}")
|
||||
logger.error(f"❗ ️导入{desc}失败,未找到模块方法:{module}")
|
||||
raise AttributeError(f"导入{desc}失败,未找到模块方法:{module}")
|
||||
|
||||
|
||||
@@ -58,10 +63,10 @@ async def import_modules_async(modules: list, desc: str, **kwargs):
|
||||
module_obj = importlib.import_module(module_path)
|
||||
await getattr(module_obj, module_name)(**kwargs)
|
||||
except ModuleNotFoundError:
|
||||
logger.error(f"导入{desc}失败,未找到模块:{module}")
|
||||
logger.error(f"❌️ 导入{desc}失败,未找到模块:{module}")
|
||||
raise ModuleNotFoundError(f"导入{desc}失败,未找到模块:{module}")
|
||||
except AttributeError:
|
||||
logger.error(f"导入{desc}失败,未找到模块方法:{module}")
|
||||
logger.error(f"❌️ 导入{desc}失败,未找到模块方法:{module}")
|
||||
raise AttributeError(f"导入{desc}失败,未找到模块方法:{module}")
|
||||
|
||||
|
||||
@@ -79,11 +84,7 @@ def get_parent_id_map(model_list: Sequence[DeclarativeBase]) -> Dict[int, int]:
|
||||
return {item.id: item.parent_id for item in model_list}
|
||||
|
||||
|
||||
def get_parent_recursion(
|
||||
id: int,
|
||||
id_map: Dict[int, int],
|
||||
ids: Optional[List[int]] = None
|
||||
) -> List[int]:
|
||||
def get_parent_recursion(id: int, id_map: Dict[int, int], ids: Optional[List[int]] = None) -> List[int]:
|
||||
"""
|
||||
递归获取所有父级ID
|
||||
:param id: 当前ID
|
||||
@@ -115,11 +116,7 @@ def get_child_id_map(model_list: Sequence[DeclarativeBase]) -> Dict[int, List[in
|
||||
return data_map
|
||||
|
||||
|
||||
def get_child_recursion(
|
||||
id: int,
|
||||
id_map: Dict[int, List[int]],
|
||||
ids: Optional[List[int]] = None
|
||||
) -> List[int]:
|
||||
def get_child_recursion(id: int, id_map: Dict[int, List[int]], ids: Optional[List[int]] = None) -> List[int]:
|
||||
"""
|
||||
递归获取所有子级ID
|
||||
:param id: 当前ID
|
||||
@@ -224,3 +221,121 @@ def get_filepath_from_url(url: str) -> Path:
|
||||
filepath = setting.settings.STATIC_ROOT.joinpath(task_path, task_id, file_name)
|
||||
|
||||
return filepath
|
||||
|
||||
|
||||
class SqlalchemyUtil:
|
||||
"""
|
||||
sqlalchemy工具类
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def base_to_dict(
|
||||
cls, obj: Union[MappedBase, Dict], transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
|
||||
) -> dict[str, Any] | dict[Any, Any]:
|
||||
"""
|
||||
将sqlalchemy模型对象转换为字典
|
||||
|
||||
:param obj: sqlalchemy模型对象或普通字典
|
||||
:param transform_case: 转换得到的结果形式,可选的有'no_case'(不转换)、'snake_to_camel'(下划线转小驼峰)、'camel_to_snake'(小驼峰转下划线),默认为'no_case'
|
||||
:return: 字典结果
|
||||
"""
|
||||
if isinstance(obj, MappedBase):
|
||||
base_dict = obj.__dict__.copy()
|
||||
base_dict.pop('_sa_instance_state', None)
|
||||
for name, value in base_dict.items():
|
||||
if isinstance(value, InstrumentedList):
|
||||
base_dict[name] = cls.serialize_result(value, 'snake_to_camel')
|
||||
elif isinstance(obj, dict):
|
||||
base_dict = obj.copy()
|
||||
if transform_case == 'snake_to_camel':
|
||||
return {CamelCaseUtil.snake_to_camel(k): v for k, v in base_dict.items()}
|
||||
elif transform_case == 'camel_to_snake':
|
||||
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in base_dict.items()}
|
||||
|
||||
return base_dict
|
||||
|
||||
@classmethod
|
||||
def serialize_result(
|
||||
cls, result: Any, transform_case: Literal['no_case', 'snake_to_camel', 'camel_to_snake'] = 'no_case'
|
||||
) -> Any:
|
||||
"""
|
||||
将sqlalchemy查询结果序列化
|
||||
|
||||
:param result: sqlalchemy查询结果
|
||||
:param transform_case: 转换得到的结果形式,可选的有'no_case'(不转换)、'snake_to_camel'(下划线转小驼峰)、'camel_to_snake'(小驼峰转下划线),默认为'no_case'
|
||||
:return: 序列化结果
|
||||
"""
|
||||
if isinstance(result, (MappedBase, dict)):
|
||||
return cls.base_to_dict(result, transform_case)
|
||||
elif isinstance(result, list):
|
||||
return [cls.serialize_result(row, transform_case) for row in result]
|
||||
elif isinstance(result, Row):
|
||||
if all([isinstance(row, MappedBase) for row in result]):
|
||||
return [cls.base_to_dict(row, transform_case) for row in result]
|
||||
elif any([isinstance(row, MappedBase) for row in result]):
|
||||
return [cls.serialize_result(row, transform_case) for row in result]
|
||||
else:
|
||||
result_dict = result._asdict()
|
||||
if transform_case == 'snake_to_camel':
|
||||
return {CamelCaseUtil.snake_to_camel(k): v for k, v in result_dict.items()}
|
||||
elif transform_case == 'camel_to_snake':
|
||||
return {SnakeCaseUtil.camel_to_snake(k): v for k, v in result_dict.items()}
|
||||
return result_dict
|
||||
return result
|
||||
|
||||
|
||||
class CamelCaseUtil:
|
||||
"""
|
||||
下划线形式(snake_case)转小驼峰形式(camelCase)工具方法
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def snake_to_camel(cls, snake_str: str) -> str:
|
||||
"""
|
||||
下划线形式字符串(snake_case)转换为小驼峰形式字符串(camelCase)
|
||||
|
||||
:param snake_str: 下划线形式字符串
|
||||
:return: 小驼峰形式字符串
|
||||
"""
|
||||
# 分割字符串
|
||||
words = snake_str.split('_')
|
||||
# 小驼峰命名,第一个词首字母小写,其余词首字母大写
|
||||
return words[0] + ''.join(word.capitalize() for word in words[1:])
|
||||
|
||||
@classmethod
|
||||
def transform_result(cls, result: Any) -> Any:
|
||||
"""
|
||||
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
|
||||
|
||||
:param result: 输入数据
|
||||
:return: 小驼峰形式结果
|
||||
"""
|
||||
return SqlalchemyUtil.serialize_result(result=result, transform_case='snake_to_camel')
|
||||
|
||||
|
||||
class SnakeCaseUtil:
|
||||
"""
|
||||
小驼峰形式(camelCase)转下划线形式(snake_case)工具方法
|
||||
"""
|
||||
|
||||
@classmethod
|
||||
def camel_to_snake(cls, camel_str: str) -> str:
|
||||
"""
|
||||
小驼峰形式字符串(camelCase)转换为下划线形式字符串(snake_case)
|
||||
|
||||
:param camel_str: 小驼峰形式字符串
|
||||
:return: 下划线形式字符串
|
||||
"""
|
||||
# 在大写字母前添加一个下划线,然后将整个字符串转为小写
|
||||
words = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', camel_str)
|
||||
return re.sub('([a-z0-9])([A-Z])', r'\1_\2', words).lower()
|
||||
|
||||
@classmethod
|
||||
def transform_result(cls, result: Any) -> Any:
|
||||
"""
|
||||
针对不同类型将下划线形式(snake_case)批量转换为小驼峰形式(camelCase)方法
|
||||
|
||||
:param result: 输入数据
|
||||
:return: 小驼峰形式结果
|
||||
"""
|
||||
return SqlalchemyUtil.serialize_result(result=result, transform_case='camel_to_snake')
|
||||
+37
-27
@@ -1,11 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import List
|
||||
|
||||
from app.common.constant import GenConstant
|
||||
from app.config.setting import settings
|
||||
from app.api.v1.module_generator.gencode.schema import GenTableColumnOutSchema as GenTableColumnSchema, GenTableOutSchema as GenTableSchema
|
||||
from .string_util import StringUtil
|
||||
from app.utils.string_util import StringUtil
|
||||
from app.api.v1.module_generator.gencode.schema import (
|
||||
GenTableOptionModel,
|
||||
GenDBTableSchema,
|
||||
GenTableBaseSchema,
|
||||
GenTableSchema,
|
||||
GenTableOutSchema,
|
||||
GenTableDeleteSchema,
|
||||
GenTableColumnSchema,
|
||||
GenTableColumnOutSchema,
|
||||
GenTableColumnDeleteSchema
|
||||
)
|
||||
|
||||
|
||||
class GenUtils:
|
||||
@@ -20,14 +31,13 @@ class GenUtils:
|
||||
param oper_name: 操作人
|
||||
:return:
|
||||
"""
|
||||
gen_table.class_name = cls.convert_class_name(gen_table.table_name)
|
||||
gen_table.package_name = settings.package_name
|
||||
gen_table.module_name = cls.get_module_name(settings.package_name)
|
||||
gen_table.business_name = cls.get_business_name(gen_table.table_name)
|
||||
gen_table.function_name = cls.replace_text(gen_table.table_comment)
|
||||
gen_table.class_name = cls.convert_class_name(gen_table.table_name or "")
|
||||
gen_table.package_name = cls.get_package_name(gen_table.table_name or "")
|
||||
gen_table.module_name = cls.get_module_name(settings.package_name or "")
|
||||
gen_table.business_name = cls.get_business_name(gen_table.table_name or "")
|
||||
gen_table.function_name = cls.replace_text(gen_table.table_comment or "")
|
||||
gen_table.function_author = settings.author
|
||||
gen_table.created_at = datetime.now()
|
||||
gen_table.updated_at = datetime.now()
|
||||
|
||||
|
||||
@classmethod
|
||||
def init_column_field(cls, column: GenTableColumnSchema, table: GenTableSchema) -> None:
|
||||
@@ -38,22 +48,20 @@ class GenUtils:
|
||||
param table: 业务表对象
|
||||
:return:
|
||||
"""
|
||||
data_type = cls.get_db_type(column.column_type)
|
||||
column_name = column.column_name
|
||||
column.table_id = table.id
|
||||
data_type = cls.get_db_type(column.column_type or "")
|
||||
column_name = column.column_name or ""
|
||||
column.table_id = table.table_id
|
||||
# 设置Python字段名
|
||||
column.python_field = cls.to_camel_case(column_name)
|
||||
column.python_field = column_name
|
||||
# 设置默认类型
|
||||
column.python_type = StringUtil.get_mapping_value_by_key_ignore_case(
|
||||
GenConstant.DB_TO_PYTHON_TYPE_MAPPING, data_type
|
||||
)
|
||||
column.python_type = GenConstant.DB_TO_PYTHON.get(data_type.upper(), "Any")
|
||||
column.query_type = GenConstant.QUERY_EQ
|
||||
|
||||
if cls.arrays_contains(GenConstant.COLUMNTYPE_STR, data_type) or cls.arrays_contains(
|
||||
GenConstant.COLUMNTYPE_TEXT, data_type
|
||||
):
|
||||
# 字符串长度超过500设置为文本域
|
||||
column_length = cls.get_column_length(column.column_type)
|
||||
column_length = cls.get_column_length(column.column_type or "")
|
||||
html_type = (
|
||||
GenConstant.HTML_TEXTAREA
|
||||
if column_length >= 500 or cls.arrays_contains(GenConstant.COLUMNTYPE_TEXT, data_type)
|
||||
@@ -69,13 +77,13 @@ class GenUtils:
|
||||
column.is_insert = GenConstant.REQUIRE
|
||||
|
||||
# 编辑字段
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_EDIT, column_name) and not column.pk:
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_EDIT, column_name) and not column.is_pk == '1':
|
||||
column.is_edit = GenConstant.REQUIRE
|
||||
# 列表字段
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_LIST, column_name) and not column.pk:
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_LIST, column_name) and not column.is_pk == '1':
|
||||
column.is_list = GenConstant.REQUIRE
|
||||
# 查询字段
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_QUERY, column_name) and not column.pk:
|
||||
if not cls.arrays_contains(GenConstant.COLUMNNAME_NOT_QUERY, column_name) and not column.is_pk == '1':
|
||||
column.is_query = GenConstant.REQUIRE
|
||||
|
||||
# 查询字段类型
|
||||
@@ -96,11 +104,8 @@ class GenUtils:
|
||||
# 内容字段设置富文本控件
|
||||
elif column_name.lower().endswith('content'):
|
||||
column.html_type = GenConstant.HTML_EDITOR
|
||||
|
||||
column.create_by = table.create_by
|
||||
column.create_time = datetime.now()
|
||||
column.update_by = table.update_by
|
||||
column.update_time = datetime.now()
|
||||
else:
|
||||
column.html_type = GenConstant.HTML_INPUT
|
||||
|
||||
@classmethod
|
||||
def arrays_contains(cls, arr: List[str], target_value: str) -> bool:
|
||||
@@ -123,6 +128,11 @@ class GenUtils:
|
||||
"""
|
||||
return package_name.split('.')[-1]
|
||||
|
||||
@classmethod
|
||||
def get_package_name(cls, table_name: str) -> str:
|
||||
"""获取包名"""
|
||||
return settings.package_name # 可配置的包名
|
||||
|
||||
@classmethod
|
||||
def get_business_name(cls, table_name: str) -> str:
|
||||
"""
|
||||
@@ -170,7 +180,7 @@ class GenUtils:
|
||||
param text: 需要被替换的字符串
|
||||
:return: 替换后的字符串
|
||||
"""
|
||||
return re.sub(r'(?:表|若依)', '', text)
|
||||
return re.sub(r'(?:表|测试)', '', text)
|
||||
|
||||
@classmethod
|
||||
def get_db_type(cls, column_type: str) -> str:
|
||||
+94
-88
@@ -1,20 +1,20 @@
|
||||
# -*- coding:utf-8 -*-
|
||||
|
||||
import json
|
||||
import os
|
||||
from datetime import datetime
|
||||
from jinja2 import Environment, FileSystemLoader
|
||||
from typing import Dict, List, Set
|
||||
from jinja2.environment import Environment
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape, Template
|
||||
from typing import Dict, List, Any, Set
|
||||
|
||||
from app.common.constant import GenConstant
|
||||
from app.config.setting import settings
|
||||
from app.api.v1.module_generator.gencode.schema import GenTableOutSchema as GenTableSchema, GenTableColumnOutSchema as GenTableColumnSchema
|
||||
from app.core.base_model import CamelCaseUtil, SnakeCaseUtil
|
||||
from app.core.exceptions import CustomException
|
||||
from .string_util import StringUtil
|
||||
from . import jinja2_util
|
||||
from app.utils.common_util import CamelCaseUtil, SnakeCaseUtil
|
||||
from app.api.v1.module_generator.gencode.schema import GenTableOutSchema, GenTableColumnOutSchema
|
||||
from app.utils.string_util import StringUtil
|
||||
|
||||
|
||||
class TemplateInitializer:
|
||||
class Jinja2TemplateInitializerUtil:
|
||||
"""
|
||||
模板引擎初始化类
|
||||
"""
|
||||
@@ -29,9 +29,9 @@ class TemplateInitializer:
|
||||
try:
|
||||
# 修复模板路径,使用正确的相对路径
|
||||
|
||||
template_dir = settings.TEMPLATE_DIR
|
||||
env = Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
loader=FileSystemLoader(settings.TEMPLATE_DIR),
|
||||
autoescape=select_autoescape(['html', 'xml']),
|
||||
keep_trailing_newline=True,
|
||||
trim_blocks=True,
|
||||
lstrip_blocks=True,
|
||||
@@ -40,10 +40,7 @@ class TemplateInitializer:
|
||||
{
|
||||
'camel_to_snake': SnakeCaseUtil.camel_to_snake,
|
||||
'snake_to_camel': CamelCaseUtil.snake_to_camel,
|
||||
'snake_to_pascal_case': jinja2_util.snake_to_pascal_case,
|
||||
'is_base_column': jinja2_util.is_base_column,
|
||||
'get_column_options': jinja2_util.get_column_options,
|
||||
'get_sqlalchemy_type': jinja2_util.get_sqlalchemy_type,
|
||||
'get_sqlalchemy_type': Jinja2TemplateUtil.get_sqlalchemy_type,
|
||||
}
|
||||
)
|
||||
return env
|
||||
@@ -51,18 +48,34 @@ class TemplateInitializer:
|
||||
raise RuntimeError(f'初始化Jinja2模板引擎失败: {e}')
|
||||
|
||||
|
||||
class TemplateUtils:
|
||||
class Jinja2TemplateUtil:
|
||||
"""
|
||||
模板工具类
|
||||
模板处理工具类
|
||||
"""
|
||||
|
||||
# 项目路径
|
||||
FRONTEND_PROJECT_PATH = 'frontend'
|
||||
BACKEND_PROJECT_PATH = 'backend'
|
||||
DEFAULT_PARENT_MENU_ID = '3'
|
||||
|
||||
# 默认上级菜单,系统工具
|
||||
DEFAULT_PARENT_MENU_ID = "3"
|
||||
|
||||
# 环境对象
|
||||
_env = None
|
||||
|
||||
@classmethod
|
||||
def prepare_context(cls, gen_table: GenTableSchema):
|
||||
def get_env(cls) -> Environment:
|
||||
"""获取模板环境对象"""
|
||||
if cls._env is None:
|
||||
cls._env = Jinja2TemplateInitializerUtil.init_jinja2()
|
||||
return cls._env
|
||||
|
||||
@classmethod
|
||||
def get_template(cls, template_path: str) -> Template:
|
||||
"""获取模板"""
|
||||
return cls.get_env().get_template(template_path)
|
||||
|
||||
@classmethod
|
||||
def prepare_context(cls, gen_table: GenTableOutSchema) -> dict[str, Any]:
|
||||
"""
|
||||
准备模板变量
|
||||
|
||||
@@ -77,7 +90,7 @@ class TemplateUtils:
|
||||
package_name = gen_table.package_name
|
||||
tpl_category = gen_table.tpl_category
|
||||
function_name = gen_table.function_name
|
||||
|
||||
|
||||
context = {
|
||||
'tplCategory': tpl_category,
|
||||
'tableName': gen_table.table_name,
|
||||
@@ -111,9 +124,9 @@ class TemplateUtils:
|
||||
cls.set_sub_context(context, gen_table)
|
||||
|
||||
return context
|
||||
|
||||
|
||||
@classmethod
|
||||
def set_menu_context(cls, context: Dict, gen_table: GenTableSchema):
|
||||
def set_menu_context(cls, context: Dict, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
设置菜单上下文
|
||||
|
||||
@@ -122,12 +135,11 @@ class TemplateUtils:
|
||||
:return: 新的模板上下文字典
|
||||
"""
|
||||
options = gen_table.options
|
||||
if options:
|
||||
params_obj = json.loads(options)
|
||||
context['parentMenuId'] = cls.get_parent_menu_id(params_obj)
|
||||
|
||||
params_obj = json.loads(options)
|
||||
context['parentMenuId'] = cls.get_parent_menu_id(params_obj)
|
||||
|
||||
@classmethod
|
||||
def set_tree_context(cls, context: Dict, gen_table: GenTableSchema):
|
||||
def set_tree_context(cls, context: Dict, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
设置树形结构上下文
|
||||
|
||||
@@ -136,15 +148,14 @@ class TemplateUtils:
|
||||
:return: 新的模板上下文字典
|
||||
"""
|
||||
options = gen_table.options
|
||||
if options:
|
||||
params_obj = json.loads(options)
|
||||
context['treeCode'] = cls.get_tree_code(params_obj)
|
||||
context['treeParentCode'] = cls.get_tree_parent_code(params_obj)
|
||||
context['treeName'] = cls.get_tree_name(params_obj)
|
||||
context['expandColumn'] = cls.get_expand_column(gen_table)
|
||||
|
||||
params_obj = json.loads(options)
|
||||
context['treeCode'] = cls.get_tree_code(params_obj)
|
||||
context['treeParentCode'] = cls.get_tree_parent_code(params_obj)
|
||||
context['treeName'] = cls.get_tree_name(params_obj)
|
||||
context['expandColumn'] = cls.get_expand_column(gen_table)
|
||||
|
||||
@classmethod
|
||||
def set_sub_context(cls, context: Dict, gen_table: GenTableSchema):
|
||||
def set_sub_context(cls, context: Dict, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
设置子表上下文
|
||||
|
||||
@@ -155,12 +166,8 @@ class TemplateUtils:
|
||||
sub_table = gen_table.sub_table
|
||||
sub_table_name = gen_table.sub_table_name
|
||||
sub_table_fk_name = gen_table.sub_table_fk_name
|
||||
# 修复类型检查问题,确保sub_table存在
|
||||
if sub_table:
|
||||
sub_class_name = sub_table.class_name or ""
|
||||
else:
|
||||
sub_class_name = ""
|
||||
sub_table_fk_class_name = StringUtil.convert_to_camel_case(sub_table_fk_name or "")
|
||||
sub_class_name = sub_table.class_name
|
||||
sub_table_fk_class_name = StringUtil.convert_to_camel_case(sub_table_fk_name)
|
||||
context['subTable'] = sub_table
|
||||
context['subTableName'] = sub_table_name
|
||||
context['subTableFkName'] = sub_table_fk_name
|
||||
@@ -182,13 +189,17 @@ class TemplateUtils:
|
||||
if tpl_web_type == 'element-plus':
|
||||
use_web_type = 'vue/v3'
|
||||
templates = [
|
||||
# Python相关模板
|
||||
'python/controller.py.j2',
|
||||
'python/crud.py.j2',
|
||||
'python/model.py.j2',
|
||||
'python/schema.py.j2',
|
||||
'python/service.py.j2',
|
||||
'python/crud.py.j2',
|
||||
'python/schema.py.j2',
|
||||
'python/param.py.j2',
|
||||
'python/model.py.j2',
|
||||
# Vue相关模板
|
||||
'ts/api.ts.j2',
|
||||
# SQL脚本模板
|
||||
'sql/sql.j2',
|
||||
'vue/api.js.j2',
|
||||
]
|
||||
if tpl_category == GenConstant.TPL_CRUD:
|
||||
templates.append(f'{use_web_type}/index.vue.j2')
|
||||
@@ -198,9 +209,9 @@ class TemplateUtils:
|
||||
templates.append(f'{use_web_type}/index.vue.j2')
|
||||
# templates.append('python/sub-domain.python.jinja2')
|
||||
return templates
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_file_name(cls, template: List[str], gen_table: GenTableSchema):
|
||||
def get_file_name(cls, template: List[str], gen_table: GenTableOutSchema):
|
||||
"""
|
||||
根据模板生成文件名
|
||||
|
||||
@@ -216,25 +227,25 @@ class TemplateUtils:
|
||||
python_path = f'{cls.BACKEND_PROJECT_PATH}/{package_name.replace(".", "/")}'
|
||||
|
||||
if 'controller.py.j2' in template:
|
||||
return f'{python_path}/{business_name}_controller.py'
|
||||
return f'{python_path}/controller/{business_name}_controller.py'
|
||||
elif 'crud.py.j2' in template:
|
||||
return f'{python_path}/{business_name}_crud.py'
|
||||
return f'{python_path}/crud/{business_name}_crud.py'
|
||||
elif 'model.py.j2' in template:
|
||||
return f'{python_path}/{business_name}_model.py'
|
||||
return f'{python_path}/entity/model/{business_name}_model.py'
|
||||
elif 'service.py.j2' in template:
|
||||
return f'{python_path}/{business_name}_service.py'
|
||||
return f'{python_path}/service/{business_name}_service.py'
|
||||
elif 'schema.py.j2' in template:
|
||||
return f'{python_path}/{business_name}_schema.py'
|
||||
return f'{python_path}/entity/schema/{business_name}_schema.py'
|
||||
elif 'sql.j2' in template:
|
||||
return f'{cls.BACKEND_PROJECT_PATH}/sql/{business_name}_menu.sql'
|
||||
elif 'api.js.j2' in template:
|
||||
return f'{vue_path}/api/{module_name}/{business_name}.js'
|
||||
elif 'api.ts.j2' in template:
|
||||
return f'{vue_path}/api/{module_name}/{business_name}.ts'
|
||||
elif 'index.vue.j2' in template or 'index-tree.vue.j2' in template:
|
||||
return f'{vue_path}/views/{module_name}/{business_name}/index.vue'
|
||||
return ''
|
||||
|
||||
@classmethod
|
||||
def get_package_prefix(cls, package_name: str):
|
||||
def get_package_prefix(cls, package_name: str) -> str:
|
||||
"""
|
||||
获取包前缀
|
||||
|
||||
@@ -244,7 +255,7 @@ class TemplateUtils:
|
||||
return package_name[: package_name.rfind('.')]
|
||||
|
||||
@classmethod
|
||||
def get_vo_import_list(cls, gen_table: GenTableSchema):
|
||||
def get_vo_import_list(cls, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
获取vo模板导入包列表
|
||||
|
||||
@@ -258,8 +269,7 @@ class TemplateUtils:
|
||||
import_list.add(f'from datetime import {column.python_type}')
|
||||
elif column.python_type == GenConstant.TYPE_DECIMAL:
|
||||
import_list.add('from decimal import Decimal')
|
||||
# 修复类型检查问题,确保sub_table存在且有columns属性
|
||||
if gen_table.sub and gen_table.sub_table:
|
||||
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:
|
||||
@@ -267,9 +277,9 @@ class TemplateUtils:
|
||||
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: GenTableSchema):
|
||||
def get_do_import_list(cls, gen_table: GenTableOutSchema) -> List[str]:
|
||||
"""
|
||||
获取do模板导入包列表
|
||||
|
||||
@@ -284,16 +294,15 @@ class TemplateUtils:
|
||||
if data_type in GenConstant.COLUMNTYPE_GEOMETRY:
|
||||
import_list.add('from geoalchemy2 import Geometry')
|
||||
import_list.add(
|
||||
f'from sqlalchemy import {StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.DB_TO_SQLALCHEMY_TYPE_MAPPING, data_type)}'
|
||||
f'from sqlalchemy import {StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.DB_TO_SQLALCHEMY, data_type)}'
|
||||
)
|
||||
# 修复类型检查问题,确保sub_table存在且有columns属性
|
||||
if gen_table.sub and gen_table.sub_table:
|
||||
if gen_table.sub:
|
||||
import_list.add('from sqlalchemy import ForeignKey')
|
||||
sub_columns = gen_table.sub_table.columns or []
|
||||
for sub_column in sub_columns:
|
||||
data_type = cls.get_db_type(sub_column.column_type)
|
||||
import_list.add(
|
||||
f'from sqlalchemy import {StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.DB_TO_SQLALCHEMY_TYPE_MAPPING, data_type)}'
|
||||
f'from sqlalchemy import {StringUtil.get_mapping_value_by_key_ignore_case(GenConstant.DB_TO_SQLALCHEMY, data_type)}'
|
||||
)
|
||||
return cls.merge_same_imports(list(import_list), 'from sqlalchemy import')
|
||||
|
||||
@@ -308,7 +317,7 @@ class TemplateUtils:
|
||||
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]:
|
||||
"""
|
||||
@@ -332,9 +341,9 @@ class TemplateUtils:
|
||||
merged_imports.append(merged_datetime_import)
|
||||
|
||||
return merged_imports
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_dicts(cls, gen_table: GenTableSchema):
|
||||
def get_dicts(cls, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
获取字典列表
|
||||
|
||||
@@ -345,12 +354,11 @@ class TemplateUtils:
|
||||
dicts = set()
|
||||
cls.add_dicts(dicts, columns)
|
||||
if gen_table.sub_table is not None:
|
||||
sub_columns = gen_table.sub_table.columns or []
|
||||
cls.add_dicts(dicts, sub_columns)
|
||||
cls.add_dicts(dicts, gen_table.sub_table.columns)
|
||||
return ', '.join(dicts)
|
||||
|
||||
@classmethod
|
||||
def add_dicts(cls, dicts: Set[str], columns: List):
|
||||
def add_dicts(cls, dicts: Set[str], columns: List[GenTableColumnOutSchema]):
|
||||
"""
|
||||
添加字典列表
|
||||
|
||||
@@ -369,7 +377,7 @@ class TemplateUtils:
|
||||
dicts.add(f"'{column.dict_type}'")
|
||||
|
||||
@classmethod
|
||||
def get_permission_prefix(cls, module_name: str, business_name: str):
|
||||
def get_permission_prefix(cls, module_name: str | None, business_name: str | None) -> str:
|
||||
"""
|
||||
获取权限前缀
|
||||
|
||||
@@ -378,7 +386,7 @@ class TemplateUtils:
|
||||
:return: 权限前缀
|
||||
"""
|
||||
return f'{module_name}:{business_name}'
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_parent_menu_id(cls, params_obj: Dict):
|
||||
"""
|
||||
@@ -390,7 +398,7 @@ class TemplateUtils:
|
||||
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):
|
||||
"""
|
||||
@@ -400,9 +408,9 @@ class TemplateUtils:
|
||||
:return: 树编码
|
||||
"""
|
||||
if GenConstant.TREE_CODE in params_obj:
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_CODE, 'treeCode'))
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_CODE))
|
||||
return ''
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_tree_parent_code(cls, params_obj: Dict):
|
||||
"""
|
||||
@@ -412,9 +420,9 @@ class TemplateUtils:
|
||||
:return: 树父编码
|
||||
"""
|
||||
if GenConstant.TREE_PARENT_CODE in params_obj:
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_PARENT_CODE, 'treeParentCode'))
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_PARENT_CODE))
|
||||
return ''
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_tree_name(cls, params_obj: Dict):
|
||||
"""
|
||||
@@ -424,11 +432,11 @@ class TemplateUtils:
|
||||
:return: 树名称
|
||||
"""
|
||||
if GenConstant.TREE_NAME in params_obj:
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_NAME, 'treeName'))
|
||||
return cls.to_camel_case(params_obj.get(GenConstant.TREE_NAME))
|
||||
return ''
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_expand_column(cls, gen_table: GenTableSchema):
|
||||
def get_expand_column(cls, gen_table: GenTableOutSchema):
|
||||
"""
|
||||
获取展开列
|
||||
|
||||
@@ -436,18 +444,16 @@ class TemplateUtils:
|
||||
:return: 展开列
|
||||
"""
|
||||
options = gen_table.options
|
||||
if not options:
|
||||
return 0
|
||||
params_obj = json.loads(options)
|
||||
tree_name = params_obj.get(GenConstant.TREE_NAME)
|
||||
num = 0
|
||||
for column in gen_table.columns or []:
|
||||
for column in gen_table.columns:
|
||||
if column.list:
|
||||
num += 1
|
||||
if column.column_name == tree_name:
|
||||
break
|
||||
return num
|
||||
|
||||
|
||||
@classmethod
|
||||
def to_camel_case(cls, text: str) -> str:
|
||||
"""
|
||||
@@ -458,7 +464,7 @@ class TemplateUtils:
|
||||
"""
|
||||
parts = text.split('_')
|
||||
return parts[0] + ''.join(word.capitalize() for word in parts[1:])
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_sqlalchemy_type(cls, column_type: str):
|
||||
"""
|
||||
@@ -472,18 +478,18 @@ class TemplateUtils:
|
||||
if column_type_list[0] in GenConstant.COLUMNTYPE_STR:
|
||||
sqlalchemy_type = (
|
||||
StringUtil.get_mapping_value_by_key_ignore_case(
|
||||
GenConstant.DB_TO_SQLALCHEMY_TYPE_MAPPING, column_type_list[0]
|
||||
GenConstant.DB_TO_SQLALCHEMY, column_type_list[0]
|
||||
)
|
||||
+ '('
|
||||
+ column_type_list[1]
|
||||
)
|
||||
else:
|
||||
sqlalchemy_type = StringUtil.get_mapping_value_by_key_ignore_case(
|
||||
GenConstant.DB_TO_SQLALCHEMY_TYPE_MAPPING, column_type_list[0]
|
||||
GenConstant.DB_TO_SQLALCHEMY, column_type_list[0]
|
||||
)
|
||||
else:
|
||||
sqlalchemy_type = StringUtil.get_mapping_value_by_key_ignore_case(
|
||||
GenConstant.DB_TO_SQLALCHEMY_TYPE_MAPPING, column_type
|
||||
GenConstant.DB_TO_SQLALCHEMY, column_type
|
||||
)
|
||||
|
||||
return sqlalchemy_type
|
||||
@@ -1,53 +0,0 @@
|
||||
import re
|
||||
|
||||
from app.common.constant import GenConstants
|
||||
|
||||
|
||||
def snake_to_pascal_case(value):
|
||||
"""将下划线命名 (snake_case) 转换大驼峰"""
|
||||
return ''.join(word.capitalize() for word in value.split('_'))
|
||||
|
||||
|
||||
def snake_to_camel(snake_str):
|
||||
"""将下划线命名 (snake_case) 转换小驼峰"""
|
||||
components = snake_str.split('_')
|
||||
return components[0] + ''.join(x.title() for x in components[1:])
|
||||
|
||||
def snake_2_colon(snake_str: str) -> str:
|
||||
"""将下划线命名 (snake_case) 转换冒号分隔"""
|
||||
return snake_str.replace('_', ':')
|
||||
|
||||
def is_base_column(column_name: str) -> bool:
|
||||
"""判断是否是基础字段"""
|
||||
return column_name in GenConstants.BASE_ENTITY
|
||||
|
||||
def get_sqlalchemy_type(mysql_field_type: str) -> str:
|
||||
"""mysql_field_type 转sqlalchemy类型"""
|
||||
if mysql_field_type:
|
||||
base_type = mysql_field_type.split("(", 1)[0]
|
||||
if base_type.upper() in GenConstants.MYSQL_TO_SQLALCHEMY.keys():
|
||||
sqlalchemy_type = GenConstants.MYSQL_TO_SQLALCHEMY[base_type.upper()]
|
||||
if sqlalchemy_type == 'String' :
|
||||
match = re.search(r'\((.*?)\)', mysql_field_type)
|
||||
if match:
|
||||
return f'{sqlalchemy_type}({match.group(1)})'
|
||||
else:
|
||||
return f'{sqlalchemy_type}'
|
||||
else:
|
||||
return f'{sqlalchemy_type}'
|
||||
return "String"
|
||||
|
||||
def get_column_options(col) -> str:
|
||||
options = []
|
||||
# 主键
|
||||
if col['isPk'] == "1":
|
||||
options.append("primary_key=True")
|
||||
# 是否允许为空
|
||||
if col['isRequired'] == "1":
|
||||
options.append("nullable=False")
|
||||
# 自增
|
||||
if col["isIncrement"] == "1":
|
||||
options.append("autoincrement=True")
|
||||
# 注释
|
||||
options.append(f"comment='{col['columnComment']}'")
|
||||
return ", ".join(options)
|
||||
@@ -35,4 +35,5 @@ PyMySQL==1.1.2 # mysql 异步操作数据库基于 pymysql:aiomys
|
||||
cryptography==45.0.2 # mysql8 密码加密
|
||||
openai==1.55.2 # ai 大模型
|
||||
oss2==2.18.4 # 阿里云对象存储
|
||||
rich==13.9.4
|
||||
rich==13.9.4
|
||||
sqlglot[rs]==27.8.0 # sql 解析
|
||||
@@ -22,7 +22,7 @@ from {{ packageName }}.param import {{ tableName|snake_to_pascal_case }}QueryPar
|
||||
async def get_{{ tableName }}_list(
|
||||
page: PaginationQueryParam = Depends(),
|
||||
search: {{ tableName|snake_to_pascal_case }}QueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:list"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:list"]))
|
||||
):
|
||||
{{ tableName }}_result_list = await {{ tableName|snake_to_pascal_case }}Service.get_{{ tableName }}_list_service(auth, search, page.order_by)
|
||||
{{ tableName }}_result = await PaginationService.paginate(
|
||||
@@ -36,7 +36,7 @@ async def get_{{ tableName }}_list(
|
||||
@{{ tableName|snake_to_camel }}Controller.get('/{id}', summary="获取{{ functionName }}详细信息", description="获取{{ functionName }}详细信息")
|
||||
async def get_{{ tableName }}_by_id(
|
||||
id: int,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:query"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:query"]))
|
||||
):
|
||||
{{ tableName }} = await {{ tableName|snake_to_pascal_case }}Service.get_{{ tableName }}_by_id_service(auth, id)
|
||||
return SuccessResponse(data={{ tableName }})
|
||||
@@ -45,7 +45,7 @@ async def get_{{ tableName }}_by_id(
|
||||
@{{ tableName|snake_to_camel }}Controller.post('', summary="新增{{ functionName }}", description="新增{{ functionName }}")
|
||||
async def add_{{ tableName }} (
|
||||
add_model: {{ tableName|snake_to_pascal_case }}CreateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:add"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:add"])),
|
||||
current_user: UserOutSchema = Depends(lambda auth: auth.user)
|
||||
):
|
||||
add_result = await {{ tableName|snake_to_pascal_case }}Service.add_{{ tableName }}_service(auth, add_model)
|
||||
@@ -56,7 +56,7 @@ async def add_{{ tableName }} (
|
||||
async def update_{{ tableName }}(
|
||||
id: int,
|
||||
edit_model: {{ tableName|snake_to_pascal_case }}UpdateSchema,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:edit"])),
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:edit"])),
|
||||
current_user: UserOutSchema = Depends(lambda auth: auth.user)
|
||||
):
|
||||
update_result = await {{ tableName|snake_to_pascal_case }}Service.update_{{ tableName }}_service(auth, id, edit_model)
|
||||
@@ -66,7 +66,7 @@ async def update_{{ tableName }}(
|
||||
@{{ tableName|snake_to_camel }}Controller.delete('/{ids}', summary="删除{{ functionName }}", description="删除{{ functionName }}")
|
||||
async def del_{{ tableName }}(
|
||||
ids: str,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:remove"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:remove"]))
|
||||
):
|
||||
id_list = [int(id) for id in ids.split(',')]
|
||||
del_result = await {{ tableName|snake_to_pascal_case }}Service.del_{{ tableName }}_service(auth, id_list)
|
||||
@@ -76,7 +76,7 @@ async def del_{{ tableName }}(
|
||||
@{{ tableName|snake_to_camel }}Controller.post('/export', summary="导出{{ functionName }}", description="导出{{ functionName }}")
|
||||
async def export_{{ tableName }}(
|
||||
search: {{ tableName|snake_to_pascal_case }}QueryParam = Depends(),
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:export"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:export"]))
|
||||
) -> StreamingResponse:
|
||||
# 获取全量数据
|
||||
{{ tableName }}_list = await {{ tableName|snake_to_pascal_case }}Service.get_{{ tableName }}_list_service(auth=auth, search=search)
|
||||
@@ -93,7 +93,7 @@ async def export_{{ tableName }}(
|
||||
@{{ tableName|snake_to_camel }}Controller.post('/import', summary="导入{{ functionName }}", description="导入{{ functionName }}")
|
||||
async def import_{{ tableName }}(
|
||||
file: UploadFile,
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:import"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:import"]))
|
||||
) -> JSONResponse:
|
||||
batch_import_result = await {{ tableName|snake_to_pascal_case }}Service.import_{{ tableName }}_service(file=file, auth=auth, update_support=True)
|
||||
return SuccessResponse(data=batch_import_result, msg="导入成功")
|
||||
@@ -101,7 +101,7 @@ async def import_{{ tableName }}(
|
||||
|
||||
@{{ tableName|snake_to_camel }}Controller.post('/download/template', summary="获取{{ functionName }}导入模板", description="获取{{ functionName }}导入模板")
|
||||
async def export_{{ tableName }}_template(
|
||||
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:import"]))
|
||||
auth: AuthSchema = Depends(AuthPermission(["{{ permissionPrefix }}:import"]))
|
||||
) -> StreamingResponse:
|
||||
{{ tableName }}_import_template_result = await {{ tableName|snake_to_pascal_case }}Service.get_import_template_{{ tableName }}_service()
|
||||
return StreamResponse(
|
||||
|
||||
Reference in New Issue
Block a user