Files
RuoYi-Vue3-FastAPI/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2
T
insistence 726883f68a feat: 新增跨时区支持并完善定时任务调度 (#127)
* feat: 新增跨时区支持

* perf: 优化代码

* fix: 修复测试

* perf: 优化调度器日志打印
2026-09-12 17:01:05 +08:00

274 lines
13 KiB
Django/Jinja
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{% set pkField = pkColumn.python_field %}
{% set pk_field = pkColumn.python_field | camel_to_snake %}
{% set pkParentheseIndex = pkColumn.column_comment.find("(") %}
{% set pk_field_comment = pkColumn.column_comment[:pkParentheseIndex] if pkParentheseIndex != -1 else pkColumn.column_comment %}
{% set add_exclude_fields = namespace(fields=[]) %}
{% if table.sub %}
{% set add_exclude_fields.fields = add_exclude_fields.fields + [subclassName ~ '_list'] %}
{% endif %}
{% for column in columns %}
{% if column.column_name in ["create_time", "update_time"] %}
{% set add_exclude_fields.fields = add_exclude_fields.fields + [column.column_name] %}
{% elif not column.insert and column.column_name not in column_not_add_show + column_not_edit_show %}
{% set add_exclude_fields.fields = add_exclude_fields.fields + [column.python_field | camel_to_snake] %}
{% endif %}
{% endfor %}
{% set edit_audit_fields = namespace(fields=[]) %}
{% for column in columns %}
{% if column.column_name in ["create_time", "update_time"] %}
{% set edit_audit_fields.fields = edit_audit_fields.fields + [column.column_name] %}
{% endif %}
{% endfor %}
{% set edit_audit_values = namespace(value='') %}
{% for field in edit_audit_fields.fields %}
{% set edit_audit_values.value = edit_audit_values.value ~ "'" ~ field ~ "'" ~ (", " if not loop.last else "") %}
{% endfor %}
{% set sub_edit_audit_fields = namespace(fields=[]) %}
{% if table.sub %}
{% for column in subTable.columns %}
{% if column.column_name in ["create_time", "update_time"] %}
{% set sub_edit_audit_fields.fields = sub_edit_audit_fields.fields + [column.column_name] %}
{% endif %}
{% endfor %}
{% endif %}
{% set sub_edit_audit_values = namespace(value='') %}
{% for field in sub_edit_audit_fields.fields %}
{% set sub_edit_audit_values.value = sub_edit_audit_values.value ~ "'" ~ field ~ "'" ~ (", " if not loop.last else "") %}
{% endfor %}
{% set has_datetime_range = namespace(value=False) %}
{% for column in columns %}
{% if column.query and column.time_kind == "instant" and column.query_type == "BETWEEN" %}
{% set has_datetime_range.value = True %}
{% endif %}
{% endfor %}
from typing import Any
from sqlalchemy import delete, select, update
from sqlalchemy.ext.asyncio import AsyncSession
{% if table.sub %}
from sqlalchemy.orm import selectinload
{% endif %}
from common.vo import PageModel
{% if table.sub %}
from {{ packageName }}.entity.do.{{ businessName }}_do import {{ [ClassName, subClassName] | sort | join(', ') }}
from {{ packageName }}.entity.vo.{{ businessName }}_vo import {{ [BusinessName ~ 'Model', BusinessName ~ 'PageQueryModel', (subTable.business_name | capitalize) ~ 'Model'] | sort | join(', ') }}
{% else %}
from {{ packageName }}.entity.do.{{ businessName }}_do import {{ ClassName }}
from {{ packageName }}.entity.vo.{{ businessName }}_vo import {{ BusinessName }}Model, {{ BusinessName }}PageQueryModel
{% endif %}
from utils.page_util import PageUtil
{% if has_datetime_range.value %}
from utils.time_util import TimezoneUtil
{% endif %}
class {{ BusinessName }}Dao:
"""
{{ functionName }}模块数据库操作层
"""
@classmethod
async def get_{{ businessName }}_detail_by_id(cls, db: AsyncSession, {{ pk_field }}: int) -> {{ ClassName }} | None:
"""
根据{{ pk_field_comment }}获取{{ functionName }}详细信息
:param db: orm对象
:param {{ pk_field }}: {{ pk_field_comment }}
:return: {{ functionName }}信息对象
"""
{{ businessName }}_info = (
(
await db.execute(
{% if table.sub %}
select({{ ClassName }})
.options(selectinload({{ ClassName }}.{{ subclassName }}_list))
{% else %}
select({{ ClassName }})
{% endif %}
.where(
{{ ClassName }}.{{ pk_field }} == {{ pk_field }}
)
)
)
.scalars()
.first()
)
return {{ businessName }}_info
@classmethod
async def get_{{ businessName }}_detail_by_info(cls, db: AsyncSession, {{ businessName }}: {{ BusinessName }}Model) -> {{ ClassName }} | None:
"""
根据{{ functionName }}参数获取{{ functionName }}信息
:param db: orm对象
:param {{ businessName }}: {{ functionName }}参数对象
:return: {{ functionName }}信息对象
"""
{{ businessName }}_info = (
(
await db.execute(
select({{ ClassName }}).where(
{% for column in columns %}
{% if column.unique %}
{{ ClassName }}.{{ column.python_field | camel_to_snake }} == {{ businessName }}.{{ column.python_field | camel_to_snake }} if {{ businessName }}.{{ column.python_field | camel_to_snake }} else True,
{% endif %}
{% endfor %}
)
)
)
.scalars()
.first()
)
return {{ businessName }}_info
@classmethod
async def get_{{ businessName }}_list(
cls, db: AsyncSession, query_object: {{ BusinessName }}PageQueryModel, is_page: bool = False
) -> PageModel | list[dict[str, Any]]:
"""
根据查询参数获取{{ functionName }}列表信息
:param db: orm对象
:param query_object: 查询参数对象
:param is_page: 是否开启分页
:return: {{ functionName }}列表信息对象
"""
{% for column in columns %}
{% if column.query and column.time_kind == "instant" and column.query_type == "BETWEEN" %}
{{ column.column_name }}_range = TimezoneUtil.local_date_strings_to_utc(
query_object.begin_{{ column.column_name }}, query_object.end_{{ column.column_name }},
timezone_name=TimezoneUtil.get_request_timezone(),
)
{% endif %}
{% endfor %}
query = (
{% if table.sub %}
select({{ ClassName }})
.options(selectinload({{ ClassName }}.{{ subclassName }}_list))
{% else %}
select({{ ClassName }})
{% endif %}
.where(
{% for column in columns %}
{% set field = column.python_field | camel_to_snake %}
{% if column.query %}
{% if column.query_type == "EQ" %}
{{ ClassName }}.{{ field }} == query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "NE" %}
{{ ClassName }}.{{ field }} != query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "GT" %}
{{ ClassName }}.{{ field }} > query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "GTE" %}
{{ ClassName }}.{{ field }} >= query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "LT" %}
{{ ClassName }}.{{ field }} < query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "LTE" %}
{{ ClassName }}.{{ field }} <= query_object.{{ field }} if query_object.{{ field }} else True,
{% elif column.query_type == "LIKE" %}
{{ ClassName }}.{{ field }}.like(f'%{% raw %}{{% endraw %}query_object.{{ field }}{% raw %}}{% endraw %}%') if query_object.{{ field }} else True,
{% elif column.time_kind in ['date', 'time'] and column.query_type == "BETWEEN" %}
{{ ClassName }}.{{ field }} >= query_object.begin_{{ column.column_name }} if query_object.begin_{{ column.column_name }} is not None else True,
{{ ClassName }}.{{ field }} <= query_object.end_{{ column.column_name }} if query_object.end_{{ column.column_name }} is not None else True,
{% elif column.time_kind == "instant" and column.query_type == "BETWEEN" %}
{{ ClassName }}.{{ field }} >= {{ column.column_name }}_range[0] if {{ column.column_name }}_range and {{ column.column_name }}_range[0] is not None else True,
{{ ClassName }}.{{ field }} < {{ column.column_name }}_range[1] if {{ column.column_name }}_range and {{ column.column_name }}_range[1] is not None else True,
{% endif %}
{% endif %}
{% endfor %}
)
.order_by({{ ClassName }}.{{ pk_field }})
.distinct()
)
{{ businessName }}_list: PageModel | list[dict[str, Any]] = await PageUtil.paginate(
db, query, query_object.page_num, query_object.page_size, is_page
)
return {{ businessName }}_list
@classmethod
async def add_{{ businessName }}_dao(cls, db: AsyncSession, {{ businessName }}: {{ BusinessName }}Model) -> {{ ClassName }}:
"""
新增{{ functionName }}数据库操作
:param db: orm对象
:param {{ businessName }}: {{ functionName }}对象
:return:
"""
db_{{ businessName }} = {{ ClassName }}(**{{ businessName }}.model_dump(exclude={% raw %}{{% endraw %}{% for field in add_exclude_fields.fields %}'{{ field }}'{% if not loop.last %}, {% endif %}{% endfor %}{% raw %}}{% endraw %}))
db.add(db_{{ businessName }})
await db.flush()
return db_{{ businessName }}
@classmethod
async def edit_{{ businessName }}_dao(cls, db: AsyncSession, {{ businessName }}: dict) -> None:
"""
编辑{{ functionName }}数据库操作
:param db: orm对象
:param {{ businessName }}: 需要更新的{{ functionName }}字典
:return:
"""
safe_{{ businessName }} = {
key: value
for key, value in {{ businessName }}.items()
if key not in {% if edit_audit_values.value %}{{ "{" }}{{ edit_audit_values.value }}{{ "}" }}{% else %}set(){% endif %}{{ "\n" }} }
await db.execute(update({{ ClassName }}), [safe_{{ businessName }}])
@classmethod
async def delete_{{ businessName }}_dao(cls, db: AsyncSession, {{ businessName }}: {{ BusinessName }}Model) -> None:
"""
删除{{ functionName }}数据库操作
:param db: orm对象
:param {{ businessName }}: {{ functionName }}对象
:return:
"""
await db.execute(delete({{ ClassName }}).where({{ ClassName }}.{{ pk_field }}.in_([{{ businessName }}.{{ pk_field }}])))
{% if table.sub %}
@classmethod
async def add_{{ subTable.business_name }}_dao(cls, db: AsyncSession, {{ subTable.business_name }}: {{ subTable.business_name | capitalize }}Model) -> {{ subClassName }}:
"""
新增{{ subTable.function_name }}数据库操作
:param db: orm对象
:param {{ subTable.business_name }}: {{ subTable.function_name }}对象
:return:
"""
db_{{ subTable.business_name }} = {{ subClassName }}(**{{ subTable.business_name }}.model_dump(exclude={% raw %}{{% endraw %}{% for field in sub_edit_audit_fields.fields %}'{{ field }}'{% if not loop.last %}, {% endif %}{% endfor %}{% raw %}}{% endraw %}))
db.add(db_{{ subTable.business_name }})
await db.flush()
return db_{{ subTable.business_name }}
@classmethod
async def edit_{{ subTable.business_name }}_dao(cls, db: AsyncSession, {{ subTable.business_name }}: dict) -> None:
"""
编辑{{ subTable.function_name }}数据库操作
:param db: orm对象
:param {{ subTable.business_name }}: 需要更新的{{ subTable.function_name }}字典
:return:
"""
safe_{{ subTable.business_name }} = {
key: value
for key, value in {{ subTable.business_name }}.items()
if key not in {% if sub_edit_audit_values.value %}{{ "{" }}{{ sub_edit_audit_values.value }}{{ "}" }}{% else %}set(){% endif %}{{ "\n" }} }
await db.execute(update({{ subClassName }}), [safe_{{ subTable.business_name }}])
@classmethod
async def delete_{{ subTable.business_name }}_dao(cls, db: AsyncSession, {{ subTable.business_name }}: {{ subTable.business_name | capitalize }}Model) -> None:
"""
删除{{ subTable.function_name }}数据库操作
:param db: orm对象
:param {{ subTable.business_name }}: {{ subTable.function_name }}对象
:return:
"""
await db.execute(delete({{ subClassName }}).where({{ subClassName }}.{{ subTable.pk_column.python_field | camel_to_snake }}.in_([{{ subTable.business_name }}.{{ subTable.pk_column.python_field | camel_to_snake }}])))
{% endif %}