refactor(module): 重构模块结构和代码生成模板

- 删除废弃的ticket和version模块相关代码
- 将resource模块从system迁移到monitor
- 移除前端资源管理相关配置
- 重构代码生成模板路径和配置
- 修复CRUD基类初始化参数问题
- 优化模板工具类路径处理
- 更新基础模型字段和配置
This commit is contained in:
zhangtao
2025-09-24 01:39:44 +08:00
parent 4a7533325a
commit d30d2faf6e
59 changed files with 663 additions and 2823 deletions
@@ -1,94 +0,0 @@
# -*- coding:utf-8 -*-
from fastapi import APIRouter, Depends, Form
from sqlalchemy.ext.asyncio import AsyncSession
from starlette.requests import Request
from typing import List
from app.common.enums import BusinessType
from app.core.dependencies import get_db
from app.common.response import SuccessResponse
from app.core.dependencies import AuthPermission
from app.api.v1.module_system.auth.schema import AuthSchema
from app.api.v1.module_system.user.schema import UserOutSchema
from app.utils.common_util import bytes2file_response
from {{ packageName }}.entity.vo.{{ tableName }}_vo import {{ tableName|snake_to_pascal_case }}PageModel, {{ tableName|snake_to_pascal_case }}Model
from {{ packageName }}.service.{{ tableName }}_service import {{ tableName|snake_to_pascal_case }}Service
{{ tableName|snake_to_camel }}Controller = APIRouter(prefix='/{{ moduleName }}/{{ businessName }}', tags=["{{ functionName }}模块"])
@{{ tableName|snake_to_camel }}Controller.get('/list', summary="查询{{ functionName }}列表", description="查询{{ functionName }}列表")
async def get_{{ tableName }}_list(
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:list"])),
page_query: {{ tableName|snake_to_pascal_case }}PageModel = Depends({{ tableName|snake_to_pascal_case }}PageModel.as_query)
):
{{ tableName }}_result = await {{ tableName|snake_to_pascal_case }}Service.get_{{ tableName }}_list_services(auth, page_query)
return SuccessResponse(data={{ tableName }}_result)
@{{ 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"]))
):
{{ tableName }} = await {{ tableName|snake_to_pascal_case }}Service.get_{{ tableName }}_by_id_services(auth, id)
return SuccessResponse(data={{ tableName }})
@{{ tableName|snake_to_camel }}Controller.post('', summary="新增{{ functionName }}", description="新增{{ functionName }}")
async def add_{{ tableName }} (
add_model: {{ tableName|snake_to_pascal_case }}Model,
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:add"])),
current_user: UserOutSchema = Depends(lambda auth: auth.user)
):
add_model.create_by = current_user.username
add_result = await {{ tableName|snake_to_pascal_case }}Service.add_{{ tableName }}_services(auth, add_model)
return SuccessResponse(msg="新增成功")
@{{ tableName|snake_to_camel }}Controller.put('', summary="修改{{ functionName }}", description="修改{{ functionName }}")
async def update_{{ tableName }}(
edit_model: {{ tableName|snake_to_pascal_case }}Model,
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:edit"])),
current_user: UserOutSchema = Depends(lambda auth: auth.user)
):
edit_model.update_by = current_user.username
update_result = await {{ tableName|snake_to_pascal_case }}Service.update_{{ tableName }}_services(auth, edit_model)
return SuccessResponse(msg="修改成功")
@{{ tableName|snake_to_camel }}Controller.delete('/{ids}', summary="删除{{ functionName }}", description="删除{{ functionName }}")
async def del_{{ tableName }}(
ids: str,
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:remove"]))
):
id_list = ids.split(',')
del_result = await {{ tableName|snake_to_pascal_case }}Service.del_{{ tableName }}_services(auth, id_list)
return SuccessResponse(msg="删除成功")
@{{ tableName|snake_to_camel }}Controller.post('/export', summary="导出{{ functionName }}", description="导出{{ functionName }}")
async def export_{{ tableName }}(
{{ tableName }}_form: {{ tableName|snake_to_pascal_case }}PageModel = Form(),
auth: AuthSchema = Depends(AuthPermission(permissions=["{{ permissionPrefix }}:export"]))
):
# 获取全量数据
export_result = await {{ tableName|snake_to_pascal_case }}Service.export_{{ tableName }}_list_services(
auth, {{ tableName }}_form
)
return bytes2file_response(export_result)
@{{ tableName|snake_to_camel }}Controller.post('/import', dependencies=[Depends(CheckUserInterfaceAuth('{{ permissionPrefix }}:import'))])
async def import_{{ tableName }}(request: Request,
import_model: ImportModel,
query_db: AsyncSession = Depends(get_db),
current_user: CurrentUserModel = Depends(LoginService.get_current_user)
):
"""
导入数据
"""
await ImportService.import_data(query_db, import_model, current_user)
return ResponseUtil.success()
@@ -1,185 +0,0 @@
# -*- coding:utf-8 -*-
from typing import List, Optional
from sqlalchemy import delete, func, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from sqlalchemy.orm import selectinload
from {{ packageName }}.entity.do.{{ tableName }}_do import {{ tableName|snake_to_pascal_case }}Model
from {{ packageName }}.entity.vo.{{ tableName }}_vo import {{ tableName|snake_to_pascal_case }}PageModel, {{ tableName|snake_to_pascal_case }}Model
from app.core.base_crud import CRUDBase
from app.api.v1.module_system.auth.schema import AuthSchema
# -*- coding:utf-8 -*-
from typing import List
from datetime import datetime, time
from module_admin.entity.do.role_do import SysRoleDept
from sqlalchemy import and_, delete, desc, func, or_, select, update
from sqlalchemy.ext.asyncio import AsyncSession
from module_gen.constants.gen_constants import GenConstants
{% if subTable %}
from sqlalchemy.orm import selectinload
{% endif %}
from {{ packageName }}.entity.do.{{ tableName }}_do import {{ tableName|snake_to_pascal_case }}
from {{ packageName }}.entity.vo.{{ tableName }}_vo import {{ tableName|snake_to_pascal_case }}PageModel, {{ tableName|snake_to_pascal_case }}Model
from utils.page_util import PageUtil, PageResponseModel
from utils.common_util import CamelCaseUtil
class {{ tableName|snake_to_pascal_case }}CRUD:
@classmethod
async def get_by_id(cls, db: AsyncSession, {{ tableName }}_id: int) -> {{ tableName|snake_to_pascal_case }}:
"""根据主键获取单条记录"""
{{ tableName }} = (((await db.execute(
select({{ tableName|snake_to_pascal_case }})
.where({{ tableName|snake_to_pascal_case }}.id == {{ tableName }}_id)))
.scalars())
.first())
return {{ tableName }}
"""
查询
"""
@classmethod
async def get_{{ tableName }}_list(cls, db: AsyncSession,
query_object: {{ tableName|snake_to_pascal_case }}PageModel,
data_scope_sql: str = None,
is_page: bool = False) -> [list | PageResponseModel]:
query = (
select({{ tableName|snake_to_pascal_case }})
{% if subTable %}
.options(selectinload({{ tableName|snake_to_pascal_case }}.{{ subTable.table_name }}_list))
{% endif %}
.where(
{% for column in columns %}
{% if column.isQuery == "1" %}
{% if column.queryType == "LIKE" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }}.like(f"%{query_object.{{ column.columnName }}}%") if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "EQ" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} == query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "GT" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} > query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "GTE" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} >= query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "NE" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} != query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "LT" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} < query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "LTE" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }} <= query_object.{{ column.columnName }} if query_object.{{ column.columnName }} else True,
{% elif column.queryType == "BETWEEN" %}
{{ tableName|snake_to_pascal_case }}.{{ column.columnName }}.between(query_object.begin_{{ column.columnName }}, query_object.end_{{ column.columnName }}) if query_object.{{ column.columnName }} else True,
{% endif %}
{% endif %}
{% endfor %}
{{ tableName|snake_to_pascal_case }}.del_flag == '0',
eval(data_scope_sql) if data_scope_sql else True,
)
.order_by(desc({{ tableName|snake_to_pascal_case }}.create_time))
.distinct()
)
{{ tableName }}_list = await PageUtil.paginate(db, query, query_object.page_num, query_object.page_size, is_page)
return {{ tableName }}_list
@classmethod
async def add_{{ tableName }}(cls, db: AsyncSession, add_model: {{ tableName|snake_to_pascal_case }}Model, auto_commit: bool = True) -> {{ tableName|snake_to_pascal_case }}Model:
"""
增加
"""
{{ tableName }} = {{ tableName|snake_to_pascal_case }}(**add_model.model_dump(exclude_unset=True, {% if subTable %}exclude={'{{ subTable.table_name }}_list',}{% endif %}))
db.add({{ tableName }})
await db.flush()
{{ tableName }}_model = {{ tableName|snake_to_pascal_case }}Model(**CamelCaseUtil.transform_result({{ tableName }}))
if auto_commit:
await db.commit()
return {{ tableName }}_model
@classmethod
async def edit_{{ tableName }}(cls, db: AsyncSession, edit_model: {{ tableName|snake_to_pascal_case }}Model, auto_commit: bool = True) -> {{ tableName|snake_to_pascal_case }}:
"""
修改
"""
edit_dict_data = edit_model.model_dump(exclude_unset=True, exclude={ {% if subTable %}'{{ subTable.table_name }}_list', {% endif %}*GenConstants.DAO_COLUMN_NOT_EDIT })
await db.execute(update({{ tableName|snake_to_pascal_case }}), [edit_dict_data])
await db.flush()
if auto_commit:
await db.commit()
return await cls.get_by_id(db, edit_model.{{ pkColumn.pythonField }})
@classmethod
async def del_{{ tableName }}(cls, db: AsyncSession, {{ tableName }}_ids: List[str], soft_del: bool = True, auto_commit: bool = True):
"""
删除
"""
if soft_del:
await db.execute(update({{ tableName|snake_to_pascal_case }}).where({{ tableName|snake_to_pascal_case }}.id.in_({{ tableName }}_ids)).values(del_flag='2'))
else:
await db.execute(delete({{ tableName|snake_to_pascal_case }}).where({{ tableName|snake_to_pascal_case }}.id.in_({{ tableName }}_ids)))
await db.flush()
if auto_commit:
await db.commit()
class {{ tableName|snake_to_pascal_case }}Dao(CRUDBase[{{ tableName|snake_to_pascal_case }}Model, {{ tableName|snake_to_pascal_case }}Model, {{ tableName|snake_to_pascal_case }}Model]):
"""
{{ functionName }}模块数据库操作层
"""
def __init__(self, auth: AuthSchema) -> None:
"""初始化CRUD"""
super().__init__(model={{ tableName|snake_to_pascal_case }}Model(), auth=auth)
async def get_{{ tableName }}_by_id(self, db: AsyncSession, {{ tableName }}_id: int) -> Optional[{{ tableName|snake_to_pascal_case }}Model]:
"""
根据{{ tableName }}id获取{{ functionName }}信息
:param db: orm对象
:param {{ tableName }}_id: {{ tableName }}id
:return: {{ functionName }}信息对象
"""
{{ tableName }}_info = (
(
await db.execute(
select({{ tableName|snake_to_pascal_case }}Model)
.where({{ tableName|snake_to_pascal_case }}Model.id == {{ tableName }}_id)
)
)
.scalars()
.first()
)
return {{ tableName }}_info
async def get_{{ tableName }}_list(self, db: AsyncSession, query_object: {{ tableName|snake_to_pascal_case }}PageModel, is_page: bool = False):
"""
根据查询参数获取{{ functionName }}列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: {{ functionName }}列表信息对象
"""
query = select({{ tableName|snake_to_pascal_case }}Model)
# 执行查询
result = await db.execute(query)
all_data = list(result.scalars().all())
# 使用PaginationService.paginate进行分页
if is_page:
paginated_result = await PaginationService.paginate(
data_list=all_data,
page_no=query_object.page_no,
page_size=query_object.page_size
)
return paginated_result
else:
return {
"items": all_data,
"total": len(all_data),
"page_no": None,
"page_size": None,
"has_next": False
}
@@ -1,67 +0,0 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional
from sqlalchemy import String, Integer, Text, DateTime
from sqlalchemy.orm import Mapped, mapped_column
from app.core.base_model import Base
# -*- coding:utf-8 -*-
from sqlalchemy import Column, ForeignKey, {{ importList }}
from config.database import BaseMixin, Base
{% if subTable %}
from sqlalchemy.orm import relationship
{% endif %}
class {{ tableName|snake_to_pascal_case }}Model(Base, BaseMixin):
"""
{{ functionName }}表
"""
__tablename__ = "{{ tableName }}"
{% for column in columns %}
{% if not column.columnName | is_base_column %}
{{ column.columnName }} = Column({{ column.columnType|get_sqlalchemy_type }}, {{ column | get_column_options }})
{% endif %}
{% endfor %}
{% if subTable %}
{{ subTable.table_name }}_list = relationship('{{ subClassName }}', back_populates='{{ tableName }}')
{% endif %}
{% if subTable %}
class {{ subClassName }}(Base, BaseMixin):
"""
{{ functionName }}表
"""
__tablename__ = '{{ subTableName }}'
{% for column in subTable.columns %}
{% if not column.column_name | is_base_column %}
{{ column.column_name }} = Column({{ column.column_type | get_sqlalchemy_type }}, {% if column.column_name == subTableFkName %}ForeignKey('{{ tableName }}.id'), {% endif %}{% if column.pk %}primary_key=True, {% endif %}{% if column.increment %}autoincrement=True, {% endif %}{% if column.required %}nullable=True{% else %}nullable=False{% endif %}, comment='{{ column.column_comment }}')
{% endif %}
{% endfor %}
{% if subTable %}
{{ tableName }} = relationship('{{ ClassName }}', back_populates='{{ subTable.table_name }}_list')
{% endif %}
{% endif %}
class {{ tableName|snake_to_pascal_case }}Model(Base):
"""
{{ functionName }}
"""
__tablename__ = '{{ tableName }}'
__table_args__ = {'comment': '{{ functionName }}'}
{% for column in columns %}
{{ column.columnName }}: Mapped[Optional[{{ column.pythonType }}]] = mapped_column({{ column.columnType|get_sqlalchemy_type }}, nullable=True, comment='{{ column.columnComment }}')
{% endfor %}
def __repr__(self):
return f"<{{ tableName|snake_to_pascal_case }}Model(id={self.id})>"
@@ -1,35 +0,0 @@
# -*- coding: utf-8 -*-
from datetime import datetime
from typing import Optional
from fastapi import Query
from app.core.validator import DateTimeStr
class {{ tableName|snake_to_pascal_case }}QueryParam:
"""示例查询参数"""
def __init__(
self,
name: Optional[str] = Query(None, description="名称"),
status: Optional[bool] = Query(None, description="是否启用"),
creator: Optional[int] = Query(None, description="创建人"),
start_time: Optional[DateTimeStr] = Query(None, description="开始时间", example="2023-01-01 00:00:00"),
end_time: Optional[DateTimeStr] = Query(None, description="结束时间", example="2023-12-31 23:59:59"),
) -> None:
super().__init__()
# 模糊查询字段
self.name = ("like", name)
# 精确查询字段
self.creator_id = creator
self.status = status
# 时间范围查询
if start_time and end_time:
start_datetime = datetime.strptime(str(start_time), '%Y-%m-%d %H:%M:%S')
end_datetime = datetime.strptime(str(end_time), '%Y-%m-%d %H:%M:%S')
self.created_at = ("between", (start_datetime, end_datetime))
@@ -1,111 +0,0 @@
# -*- coding:utf-8 -*-
from datetime import datetime
from typing import List, Optional
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from app.core.base_params import PageBaseParam
from app.core.base_schema import PageBaseSchema
# -*- coding:utf-8 -*-
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
from typing import List, Literal, Optional, Union
from module_admin.annotation.pydantic_annotation import as_query
class {{ tableName|snake_to_pascal_case }}{% if subTable %}Base{% endif %}Model(BaseModel):
"""
表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
{% for column in columns %}
{{ column.columnName }}: Optional[{{ column.pythonType }}] = Field(default=None, description='{{ column.columnComment }}')
{% if column.queryType == 'BETWEEN' %}
begin_{{ column.columnName }}: Optional[{{ column.pythonType }}] = Field(default=None, description='{{ column.columnComment }}最小值')
{% endif %}
{% if column.queryType == 'BETWEEN' %}
end_{{ column.columnName }}: Optional[{{ column.pythonType }}] = Field(default=None, description='{{ column.columnComment }}最大值')
{% endif %}
{% endfor %}
{% if subTable %}
class {{ tableName|snake_to_pascal_case }}Model({{ tableName|snake_to_pascal_case }}BaseModel):
{{ subTableName }}_list: Optional[List['{{ subTable.table_name | snake_to_pascal_case }}Model']] = Field(default=None, description='子表列信息')
{% endif %}
@as_query
class {{ tableName|snake_to_pascal_case }}PageModel({{ tableName|snake_to_pascal_case }}{% if subTable %}Base{% endif %}Model):
"""
分页查询模型
"""
page_num: int = Field(default=1, description='当前页码')
page_size: int = Field(default=10, description='每页记录数')
{% if subTable %}
class {{ subTable.table_name | snake_to_pascal_case }}Schema(BaseModel):
"""
{{ subTable.function_name }}表对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
{% for sub_column in subTable.columns %}
{{ sub_column.column_name }}: Optional[{{ sub_column.python_type }}] = Field(default=None, description='{{ sub_column.column_comment}}')
{% endfor %}
{% for sub_column in subTable.columns %}
{% if sub_column.required %}
{% set parentheseIndex = sub_column.column_comment.find("(") %}
{% set comment = sub_column.column_comment[:parentheseIndex] if parentheseIndex != -1 else sub_column.column_comment %}
@NotBlank(field_name='{{ sub_column.column_name }}', message='{{ comment }}不能为空')
def get_{{ sub_column.column_name }}(self):
return self.{{ sub_column.column_name }}
{% if not loop.last %}{{ "\n" }}{% endif %}
{% endif %}
{% endfor %}
{% endif %}
class {{ tableName|snake_to_pascal_case }}BaseModel(BaseModel):
"""
{{ functionName }}对应pydantic模型
"""
model_config = ConfigDict(alias_generator=to_camel, from_attributes=True)
{% for column in columns %}
{{ column.columnName }}: Optional[{{ column.pythonType }}] = Field(default=None, description='{{ column.columnComment }}')
{% endfor %}
class {{ tableName|snake_to_pascal_case }}Model({{ tableName|snake_to_pascal_case }}BaseModel):
"""
{{ functionName }}表模型
"""
id: Optional[int] = Field(default=None, description='编号')
create_by: Optional[str] = Field(default=None, description='创建者')
create_time: Optional[datetime] = Field(default=None, description='创建时间')
update_by: Optional[str] = Field(default=None, description='更新者')
update_time: Optional[datetime] = Field(default=None, description='更新时间')
remark: Optional[str] = Field(default=None, description='备注')
class {{ tableName|snake_to_pascal_case }}PageModel(PageBaseParam, {{ tableName|snake_to_pascal_case }}BaseModel):
"""
{{ functionName }}分页查询模型
"""
pass
class {{ tableName|snake_to_pascal_case }}PageObject(PageBaseSchema, {{ tableName|snake_to_pascal_case }}Model):
"""
{{ functionName }}分页查询结果模型
"""
pass
@@ -1,244 +0,0 @@
# -*- coding:utf-8 -*-
from datetime import datetime
from sqlalchemy.ext.asyncio import AsyncSession
from typing import Any, List, Dict, Optional
from app.core.exceptions import CustomException
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 {{ packageName }}.entity.vo.{{ tableName }}_vo import {{ tableName|snake_to_pascal_case }}PageModel, {{ tableName|snake_to_pascal_case }}Model
from {{ packageName }}.dao.{{ tableName }}_dao import {{ tableName|snake_to_pascal_case }}Dao
class {{ tableName|snake_to_pascal_case }}Service:
"""
{{ functionName }}服务层
"""
@classmethod
async def get_{{ tableName }}_list_services(
cls, auth: AuthSchema, query_object: {{ tableName|snake_to_pascal_case }}PageModel
):
"""
获取{{ functionName }}列表信息service
:param auth: 认证信息
:param query_object: 查询参数对象
:return: {{ functionName }}列表信息对象
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
{{ tableName }}_list_result = await {{ tableName }}_dao.get_{{ tableName }}_list(auth.db, query_object, is_page=True)
return {{ tableName }}_list_result
@classmethod
async def get_{{ tableName }}_by_id_services(cls, auth: AuthSchema, {{ tableName }}_id: int) -> {{ tableName|snake_to_pascal_case }}Model:
"""
根据{{ tableName }}id获取{{ functionName }}信息service
:param auth: 认证信息
:param {{ tableName }}_id: {{ tableName }}id
:return: {{ functionName }}信息对象
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
{{ tableName }} = await {{ tableName }}_dao.get_{{ tableName }}_by_id(auth.db, {{ tableName }}_id)
if {{ tableName }}:
return {{ tableName }}
else:
raise CustomException(msg='{{ functionName }}不存在')
@classmethod
async def add_{{ tableName }}_services(
cls, auth: AuthSchema, page_object: {{ tableName|snake_to_pascal_case }}Model
) -> SuccessResponse:
"""
新增{{ functionName }}service
:param auth: 认证信息
:param page_object: 新增{{ functionName }}对象
:return: 新增{{ functionName }}结果
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
try:
page_object.create_time = datetime.now()
await {{ tableName }}_dao.create(data=page_object.model_dump())
if isinstance(auth.db, AsyncSession):
await auth.db.commit()
return SuccessResponse(msg='新增成功')
except Exception as e:
if isinstance(auth.db, AsyncSession):
try:
await auth.db.rollback()
except:
pass # 忽略回滚错误
raise CustomException(msg=f'新增失败: {str(e)}')
@classmethod
async def update_{{ tableName }}_services(cls, auth: AuthSchema, page_object: {{ tableName|snake_to_pascal_case }}Model) -> SuccessResponse:
"""
编辑{{ functionName }}service
:param auth: 认证信息
:param page_object: 编辑{{ functionName }}对象
:return: 编辑{{ functionName }}结果
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
# 检查必要字段是否存在
if page_object.id is None:
raise CustomException(msg='{{ functionName }}ID不能为空')
edit_{{ tableName }} = page_object.model_dump(exclude_unset=True)
{{ tableName }}_info = await cls.get_{{ tableName }}_by_id_services(auth, page_object.id)
if {{ tableName }}_info:
try:
edit_{{ tableName }}['update_time'] = datetime.now()
await {{ tableName }}_dao.update(id=page_object.id, data=edit_{{ tableName }})
if isinstance(auth.db, AsyncSession):
await auth.db.commit()
return SuccessResponse(msg='更新成功')
except Exception as e:
if isinstance(auth.db, AsyncSession):
try:
await auth.db.rollback()
except:
pass # 忽略回滚错误
raise CustomException(msg=f'更新失败: {str(e)}')
else:
raise CustomException(msg='{{ functionName }}不存在')
@classmethod
async def del_{{ tableName }}_services(cls, auth: AuthSchema, ids: List[str]) -> SuccessResponse:
"""
删除{{ functionName }}service
:param auth: 认证信息
:param ids: {{ functionName }}id列表
:return: 删除{{ functionName }}结果
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
try:
id_list = [int(id) for id in ids]
await {{ tableName }}_dao.delete(ids=id_list)
if isinstance(auth.db, AsyncSession):
await auth.db.commit()
return SuccessResponse(msg='删除成功')
except Exception as e:
if isinstance(auth.db, AsyncSession):
try:
await auth.db.rollback()
except:
pass # 忽略回滚错误
raise CustomException(msg=f'删除失败: {str(e)}')
@classmethod
async def export_{{ tableName }}_list_services(cls, auth: AuthSchema, query_object: {{ tableName|snake_to_pascal_case }}PageModel) -> bytes:
"""
导出{{ functionName }}service
:param auth: 认证信息
:param query_object: 查询参数对象
:return: 导出{{ functionName }}结果
"""
# 确保db是AsyncSession类型
if not isinstance(auth.db, AsyncSession):
raise CustomException(msg='数据库会话类型不正确')
{{ tableName }}_dao = {{ tableName|snake_to_pascal_case }}Dao(auth=auth)
{{ tableName }}_list_result = await {{ tableName }}_dao.get_{{ tableName }}_list(auth.db, query_object, is_page=False)
# 这里应该实现导出逻辑,例如生成Excel文件
# 为简化起见,我们返回一个简单的文本文件
export_data = "ID,名称\n"
for item in {{ tableName }}_list_result.get("items", []):
export_data += f"{item.id},{getattr(item, 'name', '')}\n"
return export_data.encode('utf-8')
# -*- coding:utf-8 -*-
from typing import List
from sqlalchemy.ext.asyncio import AsyncSession
from utils.common_util import CamelCaseUtil, export_list2excel
from module_admin.entity.vo.sys_table_vo import SysTablePageModel
from module_admin.service.sys_table_service import SysTableService
from utils.page_util import PageResponseModel
from {{ packageName }}.dao.{{ tableName }}_dao import {{ tableName|snake_to_pascal_case }}Dao
from {{ packageName }}.entity.do.{{ tableName }}_do import {{ tableName|snake_to_pascal_case }}
from {{ packageName }}.entity.vo.{{ tableName }}_vo import {{ tableName|snake_to_pascal_case }}PageModel, {{ tableName|snake_to_pascal_case }}Model
class {{ tableName|snake_to_pascal_case }}Service:
"""
{{ tableName|snake_to_pascal_case }}管理模块服务层
"""
@classmethod
async def get_{{ tableName }}_list(cls, query_db: AsyncSession, query_object: {{ tableName|snake_to_pascal_case }}PageModel, data_scope_sql: str) -> [list | PageResponseModel]:
{{ tableName }}_list = await {{ tableName|snake_to_pascal_case }}Dao.get_{{ tableName }}_list(query_db, query_object, data_scope_sql, is_page=True)
return {{ tableName }}_list
@classmethod
async def get_{{ tableName }}_by_id(cls, query_db: AsyncSession, {{ tableName }}_id: int) -> {{ tableName|snake_to_pascal_case }}Model:
{{ tableName }} = await {{ tableName|snake_to_pascal_case }}Dao.get_by_id(query_db, {{ tableName }}_id)
{{ tableName }}_model = {{ tableName|snake_to_pascal_case }}Model(**CamelCaseUtil.transform_result({{ tableName }}))
return {{ tableName }}_model
@classmethod
async def add_{{ tableName }}(cls, query_db: AsyncSession, query_object: {{ tableName|snake_to_pascal_case }}Model) -> {{ tableName|snake_to_pascal_case }}Model:
{{ tableName }}_model = await {{ tableName|snake_to_pascal_case }}Dao.add_{{ tableName }}(query_db, query_object)
return {{ tableName }}_model
@classmethod
async def update_{{ tableName }}(cls, query_db: AsyncSession, query_object: {{ tableName|snake_to_pascal_case }}Model) -> {{ tableName|snake_to_pascal_case }}Model:
{{ tableName }} = await {{ tableName|snake_to_pascal_case }}Dao.edit_{{ tableName }}(query_db, query_object)
{{ tableName }}_model = {{ tableName|snake_to_pascal_case }}Model(**CamelCaseUtil.transform_result({{ tableName }}))
return {{ tableName }}_model
@classmethod
async def del_{{ tableName }}(cls, query_db: AsyncSession, {{ tableName }}_ids: List[str]):
await {{ tableName|snake_to_pascal_case }}Dao.del_{{ tableName }}(query_db, {{ tableName }}_ids)
@classmethod
async def export_{{ tableName }}_list(cls, query_db: AsyncSession, query_object: {{ tableName|snake_to_pascal_case }}PageModel, data_scope_sql) -> bytes:
{{ tableName }}_list = await {{ tableName|snake_to_pascal_case }}Dao.get_{{ tableName }}_list(query_db, query_object, data_scope_sql, is_page=False)
filed_list = await SysTableService.get_sys_table_list(query_db, SysTablePageModel(tableName='{{ tableName }}'), is_page=False)
filtered_filed = sorted(filter(lambda x: x["show"] == '1', filed_list), key=lambda x: x["sequence"])
new_data = []
for item in {{ tableName }}_list:
mapping_dict = {}
for fild in filtered_filed:
if fild["prop"] in item:
mapping_dict[fild["label"]] = item[fild["prop"]]
new_data.append(mapping_dict)
binary_data = export_list2excel(new_data)
return binary_data
@@ -1,36 +0,0 @@
-- 菜单 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}', '{{parentMenuId}}', '1', '{{businessName}}', '{{moduleName}}/{{businessName}}/index', 1, 0, 'C', '0', '0', '{{permissionPrefix}}:list', '#', 'admin', sysdate(), '', null, '{{functionName}}菜单');
-- 按钮父菜单ID
SELECT @parentId := LAST_INSERT_ID();
-- 按钮 SQL
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}查询', @parentId, '1', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:query', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}新增', @parentId, '2', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:add', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}修改', @parentId, '3', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:edit', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}删除', @parentId, '4', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:remove', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}导出', @parentId, '5', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:export', '#', 'admin', sysdate(), '', null, '');
insert into sys_menu (menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark)
values('{{functionName}}导入', @parentId, '6', '#', '', 1, 0, 'F', '0', '0', '{{permissionPrefix}}:import', '#', 'admin', sysdate(), '', null, '');
{% for column in columns %}
{% set pythonField = column.pythonField | snake_to_camel %}
{% set parentheseIndex = column.columnComment.find("(") %}
{% set comment = column.columnComment[:parentheseIndex] if parentheseIndex != -1 else column.columnComment %}
{% if column.isList %}
INSERT INTO `sys_table` (`table_name`, `field_name`, `prop`, `label`, `sequence`) VALUES ('{{ tableName }}', '{{ column.pythonField }}', '{{ pythonField }}', '{{ comment }}', {{ loop.index0 }});
{% endif %}
{% endfor %}
INSERT INTO `sys_table` (`table_name`, `field_name`, `prop`, `label`, `sequence`, `fixed`) VALUES ('{{ tableName }}', 'operate', 'operate', '操作', {{ columns|length }}, '2');
@@ -1,53 +0,0 @@
import request from '@/utils/request'
// 查询{{functionName}}列表
export function list{{BusinessName}}(query) {
return request({
url: '/{{moduleName}}/{{businessName}}/list',
method: 'get',
params: query
})
}
// 查询{{functionName}}详细
export function get{{BusinessName}}(id) {
return request({
url: '/{{moduleName}}/{{businessName}}/' + id,
method: 'get'
})
}
// 新增{{functionName}}
export function add{{BusinessName}}(data) {
return request({
url: '/{{moduleName}}/{{businessName}}/create',
method: 'post',
data: data
})
}
// 修改{{functionName}}
export function update{{BusinessName}}(data) {
return request({
url: '/{{moduleName}}/{{businessName}}/update',
method: 'put',
data: data
})
}
// 删除{{functionName}}
export function del{{BusinessName}}(ids) {
return request({
url: '/{{moduleName}}/{{businessName}}/' + ids,
method: 'delete'
})
}
// 导入{{functionName}}
export function import{{BusinessName}}(data) {
return request({
url: '/{{moduleName}}/{{businessName}}/import',
method: 'post',
data: data
})
}
@@ -1,628 +0,0 @@
<template>
<div class="app-container">
<el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch" label-width="68px">
{% for column in columns %}
{% if column.isQuery == "1" %}
{% set dictType = column.dictType %}
{% set parentheseIndex = column.columnComment.find("(") %}
{% set comment = column.columnComment[:parentheseIndex] if parentheseIndex != -1 else column.columnComment %}
{% if column.htmlType == "input" %}
<el-form-item label="{{ comment }}" prop="{{ column.pythonField | snake_to_camel }}">
<el-input
v-model="queryParams.{{ column.pythonField | snake_to_camel }}"
placeholder="请输入{{ comment }}"
clearable
@keyup.enter="handleQuery"
/>
</el-form-item>
{% elif (column.htmlType == "select" or column.htmlType == "radio") and dictType != "" %}
<el-form-item label="{{ comment }}" prop="{{ column.pythonField | snake_to_camel }}">
<el-select
v-model="queryParams.{{ column.pythonField | snake_to_camel }}"
placeholder="请选择{{ comment }}"
style="width: 180px"
clearable>
<el-option
v-for="dict in {{ dictType }}"
:key="dict.value"
:label="dict.label"
:value="dict.value"
/>
</el-select>
</el-form-item>
{% elif (column.htmlType == "select" or column.htmlType == "radio") and dictType %}
<el-form-item label="{{ comment }}" prop="{{ column.pythonField | snake_to_camel }}">
<el-select v-model="queryParams.{{ column.pythonField | snake_to_camel }}" placeholder="请选择{{ comment }}" clearable>
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
{% elif column.htmlType == "datetime" and column.queryType != "BETWEEN" %}
<el-form-item label="{{ comment }}" prop="{{ column.pythonField | snake_to_camel }}">
<el-date-picker clearable
v-model="queryParams.{{ column.pythonField | snake_to_camel }}"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择{{ comment }}">
</el-date-picker>
</el-form-item>
{% elif column.htmlType == "datetime" and column.queryType == "BETWEEN" %}
<el-form-item label="{{ comment }}" style="width: 308px">
<el-date-picker
v-model="daterange{{ column.pythonField | snake_to_pascal_case }}"
value-format="YYYY-MM-DD"
type="daterange"
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
></el-date-picker>
</el-form-item>
{% endif %}
{% endif %}
{% endfor %}
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<el-card class="base-table" ref="fullTable">
<TableSetup
ref="tSetup"
@onStripe="onStripe"
@onRefresh="onRefresh"
@onChange="onChange"
@onfullTable="onfullTable"
@onSearchChange="onSearchChange"
:columns="columns"
:isTable="isTable"
>
<template v-slot:operate>
<el-button
type="primary"
plain
icon="Plus"
@click="handleAdd"
v-hasPermi="['{{ moduleName }}:{{ businessName }}:add']"
>新增</el-button>
<el-button
type="success"
plain
icon="Edit"
:disabled="single"
@click="handleUpdate"
v-hasPermi="['{{ moduleName }}:{{ businessName }}:edit']"
>修改</el-button>
<el-button
type="danger"
plain
icon="Delete"
:disabled="multiple"
@click="handleDelete"
v-hasPermi="['{{ moduleName }}:{{ businessName }}:remove']"
>删除</el-button>
<el-button
type="primary"
plain
icon="Upload"
@click="handleImport"
v-hasPermi="['{{ moduleName }}:{{ businessName }}:import']"
>导入</el-button
>
<el-button
type="warning"
plain
icon="Download"
@click="handleExport"
v-hasPermi="['{{ moduleName }}:{{ businessName }}:export']"
>导出</el-button>
</template>
</TableSetup>
<auto-table
ref="multipleTable"
class="mytable"
:tableData="{{ businessName }}List"
:columns="columns"
:loading="loading"
:stripe="stripe"
:tableHeight="tableHeight"
@onColumnWidthChange="onColumnWidthChange"
@onSelectionChange="handleSelectionChange"
>
{% for column in columns %}
{% set pythonField = column.pythonField | snake_to_camel %}
{% set parentheseIndex = column.columnComment.find("(") %}
{% set comment = column.columnComment[:parentheseIndex] if parentheseIndex != -1 else column.columnComment %}
{% if column.isList and column.htmlType == "datetime" %}
<template #{{ pythonField }}="{ row }">
<span>{% raw %}{{{% endraw %} parseTime(row.{{ pythonField }}, '{y}-{m}-{d}') {% raw %}}}{% endraw %}</span>
</template>
{% elif column.isList == "1" and column.htmlType == "imageUpload" %}
<template #{{ pythonField }}="{ row }">
<image-preview :src="fullUrl(row.{{ pythonField }})" v-if="row.{{ pythonField }}" :width="50" :height="50"/>
</template>
{% elif column.isList == "1" and column.dictType != "" %}
<template #{{ pythonField }}="{ row }">
{% if column.htmlType == "checkbox" %}
<dict-tag :options="{{ column.dictType }}" :value="row.{{ pythonField }} ? row.{{ pythonField }}.split(',') : []"/>
{% else %}
<dict-tag :options="{{ column.dictType }}" :value="row.{{ pythonField }}"/>
{% endif %}
</template>
{% endif %}
{% endfor %}
<template #operate="{ row }">
<el-button link type="primary" icon="Edit" @click="handleUpdate(row)" v-hasPermi="['{{ moduleName }}:{{ businessName }}:edit']">修改</el-button>
<el-button link type="primary" icon="Delete" @click="handleDelete(row)" v-hasPermi="['{{ moduleName }}:{{ businessName }}:remove']">删除</el-button>
</template>
</auto-table>
<div class="table-pagination">
<pagination
v-show="total > 0"
:total="total"
v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize"
@pagination="getList"
/>
</div>
</el-card>
<!-- 添加或修改{{ functionName }}对话框 -->
<el-dialog :title="title" v-model="open" width="800px" append-to-body>
<el-form ref="{{ businessName }}Ref" :model="form" :rules="rules" label-width="80px">
{% for column in columns %}
{% set field = column.pythonField | snake_to_camel %}
{% if column.isInsert == "1" and not column.isPk == "1" %}
{% if column.usableColumn or not column.superColumn %}
{% set parentheseIndex = column.columnComment.find("(") %}
{% set comment = column.columnComment[:parentheseIndex] if parentheseIndex != -1 else column.columnComment %}
{% set dictType = column.dictType %}
{% if column.htmlType == "input" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-input v-model="form.{{ field }}" placeholder="请输入{{ comment }}" />
</el-form-item>
{% elif column.htmlType == "imageUpload" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<image-upload v-model="form.{{ field }}"/>
</el-form-item>
{% elif column.htmlType == "fileUpload" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<file-upload v-model="form.{{ field }}"/>
</el-form-item>
{% elif column.htmlType == "editor" %}
<el-form-item label="{{ comment }}">
<editor v-model="form.{{ field }}" :min-height="192"/>
</el-form-item>
{% elif column.htmlType == "select" and dictType != "" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-select v-model="form.{{ field }}" placeholder="请选择{{ comment }}">
<el-option
v-for="dict in {{ dictType }}"
:key="dict.value"
:label="dict.label"
{% if column.pythonType == "int" %}
:value="parseInt(dict.value)"
{% else %}
:value="dict.value"
{% endif %}
></el-option>
</el-select>
</el-form-item>
{% elif column.htmlType == "select" and dictType %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-select v-model="form.{{ field }}" placeholder="请选择{{ comment }}">
<el-option label="请选择字典生成" value="" />
</el-select>
</el-form-item>
{% elif column.htmlType == "checkbox" and dictType != "" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-checkbox-group v-model="form.{{ field }}">
<el-checkbox
v-for="dict in {{ dictType }}"
:key="dict.value"
:label="dict.value">
{{ dict.label }}
</el-checkbox>
</el-checkbox-group>
</el-form-item>
{% elif column.htmlType == "checkbox" and dictType %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-checkbox-group v-model="form.{{ field }}">
<el-checkbox>请选择字典生成</el-checkbox>
</el-checkbox-group>
</el-form-item>
{% elif column.htmlType == "radio" and dictType != "" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-radio-group v-model="form.{{ field }}">
<el-radio
v-for="dict in {{ dictType }}"
:key="dict.value"
{% if column.pythonType == "int" %}
:label="parseInt(dict.value)"
{% else %}
:label="dict.value"
{% endif %}
>{{ dict.label }}</el-radio>
</el-radio-group>
</el-form-item>
{% elif column.htmlType == "radio" and dictType %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-radio-group v-model="form.{{ field }}">
<el-radio label="1">请选择字典生成</el-radio>
</el-radio-group>
</el-form-item>
{% elif column.htmlType == "datetime" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-date-picker clearable
v-model="form.{{ field }}"
type="date"
value-format="YYYY-MM-DD"
placeholder="请选择{{ comment }}">
</el-date-picker>
</el-form-item>
{% elif column.htmlType == "textarea" %}
<el-form-item label="{{ comment }}" prop="{{ field }}">
<el-input v-model="form.{{ field }}" type="textarea" placeholder="请输入内容" />
</el-form-item>
{% endif %}
{% endif %}
{% endif %}
{% endfor %}
</el-form>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="submitForm">确 定</el-button>
<el-button @click="cancel">取 消</el-button>
</div>
</template>
</el-dialog>
<!-- 导入数据对话框 -->
<ImportData
v-if="openImport"
v-model="openImport"
tableName="{{ tableName }}"
@success="handleImportSuccess"
/>
</div>
</template>
<script setup name="{{ tableName|snake_to_pascal_case }}">
import { list{{ BusinessName }}, get{{ BusinessName }}, del{{ BusinessName }}, add{{ BusinessName }}, update{{ BusinessName }}, import{{ BusinessName }} } from "@/api/{{ moduleName }}/{{ businessName }}";
import { listAllTable } from '@/api/system/table'
import TableSetup from '@/components/TableSetup'
import AutoTable from '@/components/AutoTable'
import ImportData from '@/components/ImportData'
const { proxy } = getCurrentInstance();
{% if dicts != '' %}
{% set dictsNoSymbol = dicts.replace("'", "") %}
const { {{ dictsNoSymbol }} } = proxy.useDict({{ dicts }});
{% endif %}
const {{ businessName }}List = ref([]);
{#{% if table.sub %}#}
{# const {{ subclassName }}List = ref([]);#}
{#{% endif %}#}
const open = ref(false);
const loading = ref(true);
const showSearch = ref(true);
const ids = ref([]);
{#{% if table.sub %}#}
{# const checked{{ subClassName }} = ref([]);#}
{#{% endif %}#}
const single = ref(true);
const multiple = ref(true);
const total = ref(0);
const title = ref("");
{% for column in columns %}
{% if column.htmlType == "datetime" and column.queryType == "BETWEEN" %}
const daterange{{ column.pythonField | snake_to_pascal_case }} = ref([]);
{% endif %}
{% endfor %}
const columns = ref([])
const stripe = ref(true)
const isTable = ref(true)
const tableHeight = ref(500)
const fullScreen = ref(false)
const openImport = ref(false)
const data = reactive({
form: {},
queryParams: {
pageNum: 1,
pageSize: 10,
{% for column in columns %}
{% if column.isQuery == "1" %}
{{ column.pythonField | snake_to_camel }}: null{% if not loop.last %},{% endif %}
{% endif %}
{% endfor %}
},
rules: {
{% for column in columns %}
{% if column.isRequired == "1" %}
{% set parentheseIndex = column.columnComment.find("(") %}
{% set comment = column.columnComment[:parentheseIndex] if parentheseIndex != -1 else column.columnComment %}
{{ column.pythonField | snake_to_camel }}: [
{ required: true, message: "{{ comment }}不能为空", trigger: "{% if column.htmlType == "select" or column.htmlType == "radio" %}change{% else %}blur{% endif %}" }
]{% if not loop.last %},{% endif %}
{% endif %}
{% endfor %}
}
});
const { queryParams, form, rules } = toRefs(data);
/** 查询{{ functionName }}列表 */
function getList() {
loading.value = true;
{% for column in columns %}
{% if column.htmlType == "datetime" and column.queryType == "BETWEEN" %}
queryParams.value.params = {};
{% endif %}
{% endfor %}
{% for column in columns %}
{% if column.htmlType == "datetime" and column.queryType == "BETWEEN" %}
if (null != daterange{{ column.pythonField | snake_to_pascal_case }} && '' != daterange{{ column.pythonField | snake_to_pascal_case }}) {
queryParams.value.params["begin{{ column.pythonField | snake_to_pascal_case }}"] = daterange{{ column.pythonField | snake_to_pascal_case }}.value[0];
queryParams.value.params["end{{ column.pythonField | snake_to_pascal_case }}"] = daterange{{ column.pythonField | snake_to_pascal_case }}.value[1];
}
{% endif %}
{% endfor %}
list{{ BusinessName }}(queryParams.value).then(response => {
{{ businessName }}List.value = response.rows;
total.value = response.total;
loading.value = false;
});
}
function getColumns() {
listAllTable({ tableName: '{{ tableName }}' })
.then((response) => {
columns.value = response.data
})
.then(() => {
getList()
})
}
// 取消按钮
function cancel() {
open.value = false;
reset();
}
// 表单重置
function reset() {
form.value = {
{% for column in columns %}
{% if column.htmlType == "checkbox" %}
{{ column.pythonField | snake_to_camel }}: []{% if not loop.last %},{% endif %}
{% else %}
{{ column.pythonField | snake_to_camel }}: null{% if not loop.last %},{% endif %}
{% endif %}
{% endfor %}
};
{# {% if table.sub %}#}
{# {{ subclassName }}List.value = [];#}
{# {% endif %}#}
proxy.resetForm("{{ businessName }}Ref");
}
/** 搜索按钮操作 */
function handleQuery() {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
function resetQuery() {
{% for column in columns %}
{% if column.htmlType == "datetime" and column.queryType == "BETWEEN" %}
daterange{{ column.pythonField | snake_to_pascal_case }}.value = [];
{% endif %}
{% endfor %}
proxy.resetForm("queryRef");
handleQuery();
}
// 多选框选中数据
function handleSelectionChange(selection) {
ids.value = selection.map(item => item.{{ pkColumn.pythonField }});
single.value = selection.length != 1;
multiple.value = !selection.length;
}
/** 新增按钮操作 */
function handleAdd() {
reset();
open.value = true;
title.value = "添加{{ functionName }}";
}
/** 新增按钮操作 */
function handleImport() {
openImport.value = true
}
/** 修改按钮操作 */
function handleUpdate(row) {
reset();
const {{ tableName | snake_to_camel }}{{ pkColumn.pythonField | snake_to_pascal_case }} = row.{{ pkColumn.pythonField | snake_to_camel }} || ids.value
get{{ BusinessName }}({{ tableName | snake_to_camel }}{{ pkColumn.pythonField | snake_to_pascal_case }}).then(response => {
form.value = response.data;
{% for column in columns %}
{% if column.htmlType == "checkbox" %}
form.value.{{ column.pythonField | snake_to_camel }} = form.value.{{ column.pythonField | snake_to_camel }}.split(",");
{% endif %}
{% endfor %}
{# {% if table.sub %}#}
{# {{ subclassName }}List.value = response.data.{{ subclassName }}List;#}
{# {% endif %}#}
open.value = true;
title.value = "修改{{ functionName }}";
});
}
/** 提交按钮 */
function submitForm() {
proxy.$refs["{{ businessName }}Ref"].validate(valid => {
if (valid) {
{% for column in columns %}
{% if column.htmlType == "checkbox" %}
form.value.{{ column.pythonField | snake_to_camel }} = form.value.{{ column.pythonField | snake_to_camel }}.join(",");
{% endif %}
{% endfor %}
{# {% if table.sub %}#}
{# form.value.{{ subclassName }}List = {{ subclassName }}List.value;#}
{# {% endif %}#}
if (form.value.{{ pkColumn.pythonField }} != null) {
update{{ BusinessName }}(form.value).then(response => {
proxy.$modal.msgSuccess("修改成功");
open.value = false;
getList();
});
} else {
add{{ BusinessName }}(form.value).then(response => {
proxy.$modal.msgSuccess("新增成功");
open.value = false;
getList();
});
}
}
});
}
/** 删除按钮操作 */
function handleDelete(row) {
const _{{ pkColumn.pythonField }}s = row.{{ pkColumn.pythonField }} || ids.value;
proxy.$modal.confirm('是否确认删除{{ functionName }}编号为"' + _{{ pkColumn.pythonField }}s + '"的数据项?').then(function() {
return del{{ BusinessName }}(_{{ pkColumn.pythonField }}s);
}).then(() => {
getList();
proxy.$modal.msgSuccess("删除成功");
}).catch(() => {});
}
{#{% if table.sub %}#}
{# /** {{ subTable.functionName }}序号 */#}
{# function row{{ subClassName }}Index({ row, rowIndex }) {#}
{# row.index = rowIndex + 1;#}
{# }#}
{##}
{# /** {{ subTable.functionName }}添加按钮操作 */#}
{# function handleAdd{{ subClassName }}() {#}
{# let obj = {};#}
{# {% for column in subTable.columns %}#}
{# {% if column.pk or column.pythonField == subTableFkclassName %}#}
{# {% elif column.list and pythonField != "" %}#}
{# obj.{{ column.pythonField }} = "";#}
{# {% endif %}#}
{# {% endfor %}#}
{# {{ subclassName }}List.value.push(obj);#}
{# }#}
{##}
{# /** {{ subTable.functionName }}删除按钮操作 */#}
{# function handleDelete{{ subClassName }}() {#}
{# if (checked{{ subClassName }}.value.length == 0) {#}
{# proxy.$modal.msgError("请先选择要删除的{{ subTable.functionName }}数据");#}
{# } else {#}
{# const {{ subclassName }}s = {{ subclassName }}List.value;#}
{# const checked{{ subClassName }}s = checked{{ subClassName }}.value;#}
{# {{ subclassName }}List.value = {{ subclassName }}s.filter(function(item) {#}
{# return checked{{ subClassName }}s.indexOf(item.index) == -1#}
{# });#}
{# }#}
{# }#}
{##}
{# /** 复选框选中数据 */#}
{# function handle{{ subClassName }}SelectionChange(selection) {#}
{# checked{{ subClassName }}.value = selection.map(item => item.index)#}
{# }#}
{#{% endif %}#}
/** 导出按钮操作 */
function handleExport() {
proxy.download('{{ moduleName }}/{{ businessName }}/export', {
...queryParams.value
}, `{{ businessName }}_${new Date().getTime()}.xlsx`)
}
//表格全屏
function onfullTable() {
proxy.$refs.tSetup.onFull(proxy.$refs.fullTable.$el)
fullScreen.value = !fullScreen.value
updateTableHeight()
}
//表格刷新
function onRefresh() {
getList()
}
//搜索框显示隐藏
function onSearchChange() {
showSearch.value = !showSearch.value
}
function onStripe(val) {
stripe.value = val
}
//改变表头数据
function onChange(val) {
columns.value = val
}
//改变表格宽度
function onColumnWidthChange(column) {
proxy.$refs.tSetup.tableWidth(column)
}
//更新表格高度
function updateTableHeight() {
if (
proxy.$refs.tSetup &&
proxy.$refs.queryRef &&
document.querySelector('.table-pagination')
) {
if (fullScreen.value) {
tableHeight.value = window.innerHeight - 145
} else {
tableHeight.value =
window.innerHeight -
proxy.$refs.tSetup.$el.clientHeight -
proxy.$refs.queryRef.$el.clientHeight -
document.querySelector('.table-pagination').clientHeight -
220
}
}
}
//导入成功
function handleImportSuccess(sheetName, filedInfo, fileName) {
let data = {
tableName: '{{ tableName }}',
filedInfo: filedInfo,
fileName: fileName,
sheetName: sheetName
}
import{{ BusinessName }}(data).then(() => {
proxy.$modal.msgSuccess('导入成功')
openImport.value = false
getList()
})
getList()
}
onMounted(() => {
updateTableHeight() // 初始化计算高度
window.addEventListener('resize', updateTableHeight) // 监听窗口大小变化
})
onUnmounted(() => {
window.removeEventListener('resize', updateTableHeight) // 销毁监听
})
getColumns()
</script>