diff --git a/.gitignore b/.gitignore
index 129a39b..5686ba6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -136,3 +136,10 @@ dmypy.json
# Cython debug symbols
cython_debug/
+
+# PyCharm
+.idea/
+
+# VSCode
+.vscode/
+
diff --git a/README.md b/README.md
index 8bfde6b..123bfe3 100644
--- a/README.md
+++ b/README.md
@@ -1,12 +1,12 @@
-RuoYi-Vue3-FastAPI v1.6.1
+RuoYi-Vue3-FastAPI v1.6.2
基于RuoYi-Vue3+FastAPI前后端分离的快速开发框架
-
+
diff --git a/ruoyi-fastapi-backend/.env.dev b/ruoyi-fastapi-backend/.env.dev
index 73e227f..9ddf8f3 100644
--- a/ruoyi-fastapi-backend/.env.dev
+++ b/ruoyi-fastapi-backend/.env.dev
@@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
-APP_VERSION= '1.6.1'
+APP_VERSION= '1.6.2'
# 应用是否开启热重载
APP_RELOAD = true
# 应用是否开启IP归属区域查询
diff --git a/ruoyi-fastapi-backend/.env.prod b/ruoyi-fastapi-backend/.env.prod
index 3f97104..c7bf1f1 100644
--- a/ruoyi-fastapi-backend/.env.prod
+++ b/ruoyi-fastapi-backend/.env.prod
@@ -10,7 +10,7 @@ APP_HOST = '0.0.0.0'
# 应用端口
APP_PORT = 9099
# 应用版本
-APP_VERSION= '1.6.1'
+APP_VERSION= '1.6.2'
# 应用是否开启热重载
APP_RELOAD = false
# 应用是否开启IP归属区域查询
diff --git a/ruoyi-fastapi-backend/config/constant.py b/ruoyi-fastapi-backend/config/constant.py
index 1b124a0..eb77464 100644
--- a/ruoyi-fastapi-backend/config/constant.py
+++ b/ruoyi-fastapi-backend/config/constant.py
@@ -252,6 +252,8 @@ class GenConstant:
'double',
'decimal',
]
+ COLUMNNAME_NOT_ADD_SHOW = ['create_by', 'create_time']
+ COLUMNNAME_NOT_EDIT_SHOW = ['update_by', 'update_time']
COLUMNNAME_NOT_EDIT = ['id', 'create_by', 'create_time', 'del_flag']
COLUMNNAME_NOT_LIST = ['id', 'create_by', 'create_time', 'del_flag', 'update_by', 'update_time']
COLUMNNAME_NOT_QUERY = ['id', 'create_by', 'create_time', 'del_flag', 'update_by', 'update_time', 'remark']
diff --git a/ruoyi-fastapi-backend/config/get_scheduler.py b/ruoyi-fastapi-backend/config/get_scheduler.py
index 4473390..4b0c298 100644
--- a/ruoyi-fastapi-backend/config/get_scheduler.py
+++ b/ruoyi-fastapi-backend/config/get_scheduler.py
@@ -201,9 +201,12 @@ class SchedulerUtil:
job_executor = job_info.job_executor
if iscoroutinefunction(job_func):
job_executor = 'default'
+ job_trigger = DateTrigger()
+ if job_info.status == '0':
+ job_trigger = OrTrigger(triggers=[DateTrigger(), MyCronTrigger.from_crontab(job_info.cron_expression)])
scheduler.add_job(
func=eval(job_info.invoke_target),
- trigger=OrTrigger(triggers=[DateTrigger(), MyCronTrigger.from_crontab(job_info.cron_expression)]),
+ trigger=job_trigger,
args=job_info.job_args.split(',') if job_info.job_args else None,
kwargs=json.loads(job_info.job_kwargs) if job_info.job_kwargs else None,
id=str(job_info.job_id),
diff --git a/ruoyi-fastapi-backend/module_admin/dao/log_dao.py b/ruoyi-fastapi-backend/module_admin/dao/log_dao.py
index 1e4ad41..684f3d7 100644
--- a/ruoyi-fastapi-backend/module_admin/dao/log_dao.py
+++ b/ruoyi-fastapi-backend/module_admin/dao/log_dao.py
@@ -5,6 +5,7 @@ from module_admin.entity.do.log_do import SysLogininfor, SysOperLog
from module_admin.entity.vo.log_vo import LogininforModel, LoginLogPageQueryModel, OperLogModel, OperLogPageQueryModel
from utils.common_util import SnakeCaseUtil
from utils.page_util import PageUtil
+from utils.time_format_util import TimeFormatUtil
class OperationLogDao:
@@ -38,8 +39,8 @@ class OperationLogDao:
SysOperLog.business_type == query_object.business_type if query_object.business_type else True,
SysOperLog.status == query_object.status if query_object.status else True,
SysOperLog.oper_time.between(
- datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
- datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)),
+ datetime.combine(TimeFormatUtil.parse_date(query_object.begin_time), time(00, 00, 00)),
+ datetime.combine(TimeFormatUtil.parse_date(query_object.end_time), time(23, 59, 59)),
)
if query_object.begin_time and query_object.end_time
else True,
@@ -120,8 +121,8 @@ class LoginLogDao:
SysLogininfor.user_name.like(f'%{query_object.user_name}%') if query_object.user_name else True,
SysLogininfor.status == query_object.status if query_object.status else True,
SysLogininfor.login_time.between(
- datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
- datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)),
+ datetime.combine(TimeFormatUtil.parse_date(query_object.begin_time), time(00, 00, 00)),
+ datetime.combine(TimeFormatUtil.parse_date(query_object.end_time), time(23, 59, 59)),
)
if query_object.begin_time and query_object.end_time
else True,
diff --git a/ruoyi-fastapi-backend/module_admin/service/dict_service.py b/ruoyi-fastapi-backend/module_admin/service/dict_service.py
index bfe6489..0acfd73 100644
--- a/ruoyi-fastapi-backend/module_admin/service/dict_service.py
+++ b/ruoyi-fastapi-backend/module_admin/service/dict_service.py
@@ -103,9 +103,10 @@ class DictTypeService:
if dict_type_info.dict_type != page_object.dict_type:
for dict_data in dict_data_list:
edit_dict_data = DictDataModel(
- dictCode=dict_data.dict_code,
+ dictCode=dict_data.get('dict_code'),
dictType=page_object.dict_type,
updateBy=page_object.update_by,
+ updateTime=page_object.update_time,
).model_dump(exclude_unset=True)
await DictDataDao.edit_dict_data_dao(query_db, edit_dict_data)
await DictTypeDao.edit_dict_type_dao(query_db, edit_dict_type)
diff --git a/ruoyi-fastapi-backend/module_admin/service/user_service.py b/ruoyi-fastapi-backend/module_admin/service/user_service.py
index c149b56..60f77c6 100644
--- a/ruoyi-fastapi-backend/module_admin/service/user_service.py
+++ b/ruoyi-fastapi-backend/module_admin/service/user_service.py
@@ -494,6 +494,7 @@ class UserService:
}
for item in user_list:
+ item['deptName'] = item.get('dept').get('deptName')
if item.get('status') == '0':
item['status'] = '正常'
else:
diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2
index 6cf19a1..3b186c5 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/python/dao.py.jinja2
@@ -118,12 +118,12 @@ class {{ BusinessName }}Dao:
{{ 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.query_type == "BETWEEN" %}
+ {% elif column.html_type == "datetime" and column.query_type == "BETWEEN" %}
{{ ClassName }}.{{ field }}.between(
- datetime.combine(datetime.strptime(query_object.begin_time, '%Y-%m-%d'), time(00, 00, 00)),
- datetime.combine(datetime.strptime(query_object.end_time, '%Y-%m-%d'), time(23, 59, 59)),
+ datetime.combine(datetime.strptime(query_object.begin_{{ column.column_name }}, '%Y-%m-%d'), time(00, 00, 00)),
+ datetime.combine(datetime.strptime(query_object.end_{{ column.column_name }}, '%Y-%m-%d'), time(23, 59, 59)),
)
- if query_object.begin_time and query_object.end_time
+ if query_object.begin_{{ column.column_name }} and query_object.end_{{ column.column_name }}
else True,
{% endif %}
{% endif %}
@@ -145,7 +145,7 @@ class {{ BusinessName }}Dao:
:param {{ businessName }}: {{ functionName }}对象
:return:
"""
- db_{{ businessName }} = {{ ClassName }}(**{{ businessName }}.model_dump(exclude={% raw %}{{% endraw %}{% if table.sub %}'{{ subclassName }}_list', {% endif %}{% for column in columns %}{% if not column.insert %}'{{ column.python_field | camel_to_snake }}'{% if not loop.last %}, {% endif %}{% endif %}{% endfor %}{% raw %}}{% endraw %}))
+ db_{{ businessName }} = {{ ClassName }}(**{{ businessName }}.model_dump(exclude={% raw %}{{% endraw %}{% if table.sub %}'{{ subclassName }}_list', {% endif %}{% for column in columns %}{% if not column.insert and column.column_name not in column_not_add_show + column_not_edit_show %}'{{ column.python_field | camel_to_snake }}'{% if not loop.last %}, {% endif %}{% endif %}{% endfor %}{% raw %}}{% endraw %}))
db.add(db_{{ businessName }})
await db.flush()
diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2
index 27d6979..5726c5d 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/python/service.py.jinja2
@@ -103,7 +103,7 @@ class {{ BusinessName }}Service:
:param page_object: 编辑{{ functionName }}对象
:return: 编辑{{ functionName }}校验结果
"""
- edit_{{ businessName }} = page_object.model_dump(exclude_unset=True, exclude={% raw %}{{% endraw %}{% if table.sub %}'{{ subclassName }}_list', {% endif %}{% for column in columns %}{% if not column.edit and not column.pk %}'{{ column.python_field | camel_to_snake }}'{% if not loop.last %}, {% endif %}{% endif %}{% endfor %}{% raw %}}{% endraw %})
+ edit_{{ businessName }} = page_object.model_dump(exclude_unset=True, exclude={% raw %}{{% endraw %}{% if table.sub %}'{{ subclassName }}_list', {% endif %}{% for column in columns %}{% if not column.edit and not column.pk and column.column_name not in column_not_edit_show %}'{{ column.python_field | camel_to_snake }}'{% if not loop.last %}, {% endif %}{% endif %}{% endfor %}{% raw %}}{% endraw %})
{{ businessName }}_info = await cls.{{ businessName }}_detail_services(query_db, page_object.{{ pk_field }})
if {{ businessName }}_info.{{ pk_field }}:
{% for column in columns %}
diff --git a/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2
index 7634980..47abbf5 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/python/vo.py.jinja2
@@ -3,10 +3,14 @@
{% set pkParentheseIndex = pkColumn.column_comment.find("(") %}
{% set pk_field_comment = pkColumn.column_comment[:pkParentheseIndex] if pkParentheseIndex != -1 else pkColumn.column_comment %}
{% set vo_field_required = namespace(has_required=False) %}
+{% set vo_field_daterange = namespace(has_daterange=False) %}
{% for column in columns %}
{% if column.required %}
{% set vo_field_required.has_required = True %}
{% endif %}
+{% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
+ {% set vo_field_daterange.has_daterange = True %}
+{% endif %}
{% endfor %}
{% set sub_vo_field_required = namespace(has_required=False) %}
{% if table.sub %}
@@ -142,9 +146,16 @@ class {{ BusinessName }}QueryModel({% if table.sub %}{{ BusinessName }}BaseModel
"""
{{ functionName }}不分页查询模型
"""
-
- begin_time: Optional[str] = Field(default=None, description='开始时间')
- end_time: Optional[str] = Field(default=None, description='结束时间')
+ {% if vo_field_daterange.has_daterange %}
+ {% for column in columns %}
+ {% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
+ begin_{{ column.column_name }}: Optional[str] = Field(default=None, description='开始{{ column.column_comment }}')
+ end_{{ column.column_name }}: Optional[str] = Field(default=None, description='结束{{ column.column_comment }}')
+ {% endif %}
+ {% endfor %}
+ {% else %}
+ pass
+ {% endif %}
@as_query
diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/index-tree.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/index-tree.vue.jinja2
index 741f132..eb8ceaf 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/vue/index-tree.vue.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/vue/index-tree.vue.jinja2
@@ -35,12 +35,13 @@
{% elif column.html_type == "datetime" and column.query_type != "BETWEEN" %}
-
-
+ placeholder="请选择{{ comment }}"
+ clearable
+ />
{% elif column.html_type == "datetime" and column.query_type == "BETWEEN" %}
@@ -52,7 +53,7 @@
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
- >
+ />
{% endif %}
{% endif %}
@@ -161,33 +162,33 @@
{% for column in columns %}
{% set field = column.python_field %}
- {% if column.insert and not column.pk %}
+ {% if (column.insert or column.edit) and not column.pk and column.column_name not in column_not_add_show + column_not_edit_show %}
{% if column.usable_column or not column.super_column %}
{% set parentheseIndex = column.column_comment.find("(") %}
{% set comment = column.column_comment[:parentheseIndex] if parentheseIndex != -1 else column.column_comment %}
{% set dictType = column.dict_type %}
{% if treeParentCode and column.python_field == treeParentCode %}
-
+
{% elif column.html_type == "input" %}
-
+
{% elif column.html_type == "imageUpload" %}
-
+
{% elif column.html_type == "fileUpload" %}
-
+
{% elif column.html_type == "editor" %}
-
+
{% elif column.html_type == "select" and dictType %}
-
+
{% elif column.html_type == "select" and not dictType %}
-
+
{% elif column.html_type == "checkbox" and dictType %}
-
+
{% elif column.html_type == "checkbox" and not dictType %}
-
+
请选择字典生成
{% elif column.html_type == "radio" and dictType %}
-
+
{% elif column.html_type == "radio" and not dictType %}
-
+
{% elif column.html_type == "datetime" %}
-
+
{% elif column.html_type == "textarea" %}
-
+
{% endif %}
@@ -351,8 +352,8 @@ export default {
{% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
{% set AttrName = column.python_field[0] | upper + column.python_field[1:] %}
if (null != this.daterange{{ AttrName }} && '' != this.daterange{{ AttrName }}) {
- this.queryParams.params["begin{{ AttrName }}"] = this.daterange{{ AttrName }}[0];
- this.queryParams.params["end{{ AttrName }}"] = this.daterange{{ AttrName }}[1];
+ this.queryParams.begin{{ AttrName }} = this.daterange{{ AttrName }}[0];
+ this.queryParams.end{{ AttrName }} = this.daterange{{ AttrName }}[1];
}
{% endif %}
{% endfor %}
@@ -485,6 +486,10 @@ export default {
this.getList();
this.$modal.msgSuccess("删除成功");
}).catch(() => {});
+ },
+ /** 是否渲染字段 */
+ renderField(insert, edit) {
+ return this.form.{{ pkColumn.python_field }} == null ? insert : edit;
}
},
};
diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/index.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/index.vue.jinja2
index a1b7f4b..39f861d 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/vue/index.vue.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/vue/index.vue.jinja2
@@ -35,12 +35,13 @@
{% elif column.html_type == "datetime" and column.query_type != "BETWEEN" %}
-
-
+ placeholder="请选择{{ comment }}"
+ clearable
+ />
{% elif column.html_type == "datetime" and column.query_type == "BETWEEN" %}
@@ -52,7 +53,7 @@
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
- >
+ />
{% endif %}
{% endif %}
@@ -173,29 +174,29 @@
{% for column in columns %}
{% set field = column.python_field %}
- {% if column.insert and not column.pk %}
+ {% if (column.insert or column.edit) and not column.pk and column.column_name not in column_not_add_show + column_not_edit_show %}
{% if column.usable_column or not column.super_column %}
{% set parentheseIndex = column.column_comment.find("(") %}
{% set comment = column.column_comment[:parentheseIndex] if parentheseIndex != -1 else column.column_comment %}
{% set dictType = column.dict_type %}
{% if column.html_type == "input" %}
-
+
{% elif column.html_type == "imageUpload" %}
-
+
{% elif column.html_type == "fileUpload" %}
-
+
{% elif column.html_type == "editor" %}
-
+
{% elif column.html_type == "select" and dictType %}
-
+
{% elif column.html_type == "select" and not dictType %}
-
+
{% elif column.html_type == "checkbox" and dictType %}
-
+
{% elif column.html_type == "checkbox" and not dictType %}
-
+
请选择字典生成
{% elif column.html_type == "radio" and dictType %}
-
+
{% elif column.html_type == "radio" and not dictType %}
-
+
{% elif column.html_type == "datetime" %}
-
+
{% elif column.html_type == "textarea" %}
-
+
{% endif %}
@@ -426,8 +427,8 @@ export default {
{% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
{% set AttrName = column.python_field[0] | upper + column.python_field[1:] %}
if (null != this.daterange{{ AttrName }} && '' != this.daterange{{ AttrName }}) {
- this.queryParams.params["begin{{ AttrName }}"] = this.daterange{{ AttrName }}[0];
- this.queryParams.params["end{{ AttrName }}"] = this.daterange{{ AttrName }}[1];
+ this.queryParams.begin{{ AttrName }} = this.daterange{{ AttrName }}[0];
+ this.queryParams.end{{ AttrName }} = this.daterange{{ AttrName }}[1];
}
{% endif %}
{% endfor %}
@@ -580,6 +581,10 @@ export default {
this.download('{{ moduleName }}/{{ businessName }}/export', {
...this.queryParams
}, `{{ businessName }}_${new Date().getTime()}.xlsx`);
+ },
+ /** 是否渲染字段 */
+ renderField(insert, edit) {
+ return this.form.{{ pkColumn.python_field }} == null ? insert : edit;
}
},
};
diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2
index 433c162..52eeda9 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index-tree.vue.jinja2
@@ -13,12 +13,13 @@
v-model="queryParams.{{ column.python_field }}"
placeholder="请输入{{ comment }}"
clearable
+ style="width: 240px"
@keyup.enter="handleQuery"
/>
{% elif (column.html_type == "select" or column.html_type == "radio") and dictType %}
-
+
{% elif (column.html_type == "select" or column.html_type == "radio") and not dictType %}
-
+
{% elif column.html_type == "datetime" and column.query_type != "BETWEEN" %}
-
-
+ placeholder="请选择{{ comment }}"
+ clearable
+ style="width: 240px"
+ />
{% elif column.html_type == "datetime" and column.query_type == "BETWEEN" %}
@@ -51,7 +54,8 @@
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
- >
+ style="width: 240px"
+ />
{% endif %}
{% endif %}
@@ -136,13 +140,13 @@
{% for column in columns %}
{% set field = column.python_field %}
- {% if column.insert and not column.pk %}
+ {% if (column.insert or column.edit) and not column.pk and column.column_name not in column_not_add_show + column_not_edit_show %}
{% if column.usable_column or not column.super_column %}
{% set parentheseIndex = column.column_comment.find("(") %}
{% set comment = column.column_comment[:parentheseIndex] if parentheseIndex != -1 else column.column_comment %}
{% set dictType = column.dict_type %}
{% if treeParentCode and column.python_field == treeParentCode %}
-
+
{% elif column.html_type == "input" %}
-
+
{% elif column.html_type == "imageUpload" %}
-
+
{% elif column.html_type == "fileUpload" %}
-
+
{% elif column.html_type == "editor" %}
-
+
{% elif column.html_type == "select" and dictType %}
-
+
{% elif column.html_type == "select" and not dictType %}
-
+
{% elif column.html_type == "checkbox" and dictType %}
-
+
{% elif column.html_type == "checkbox" and not dictType %}
-
+
请选择字典生成
{% elif column.html_type == "radio" and dictType %}
-
+
{% elif column.html_type == "radio" and not dictType %}
-
+
{% elif column.html_type == "datetime" %}
-
+
{% elif column.html_type == "textarea" %}
-
+
{% endif %}
@@ -315,8 +319,8 @@ function getList() {
{% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
{% set AttrName = column.python_field[0] | upper + column.python_field[1:] %}
if (null != daterange{{ AttrName }} && '' != daterange{{ AttrName }}) {
- queryParams.value.params["begin{{ AttrName }}"] = daterange{{ AttrName }}.value[0];
- queryParams.value.params["end{{ AttrName }}"] = daterange{{ AttrName }}.value[1];
+ queryParams.value.begin{{ AttrName }} = daterange{{ AttrName }}.value[0];
+ queryParams.value.end{{ AttrName }} = daterange{{ AttrName }}.value[1];
}
{% endif %}
{% endfor %}
@@ -450,5 +454,10 @@ function handleDelete(row) {
}).catch(() => {});
}
+/** 是否渲染字段 */
+function renderField(insert, edit) {
+ return form.value.{{ pkColumn.python_field }} == null ? insert : edit;
+}
+
getList();
\ No newline at end of file
diff --git a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2 b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2
index 981124f..73dae7d 100644
--- a/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2
+++ b/ruoyi-fastapi-backend/module_generator/templates/vue/v3/index.vue.jinja2
@@ -13,12 +13,13 @@
v-model="queryParams.{{ column.python_field }}"
placeholder="请输入{{ comment }}"
clearable
+ style="width: 240px"
@keyup.enter="handleQuery"
/>
{% elif (column.html_type == "select" or column.html_type == "radio") and dictType %}
-
+
{% elif (column.html_type == "select" or column.html_type == "radio") and not dictType %}
-
+
{% elif column.html_type == "datetime" and column.query_type != "BETWEEN" %}
-
-
+ placeholder="请选择{{ comment }}"
+ clearable
+ style="width: 240px"
+ />
{% elif column.html_type == "datetime" and column.query_type == "BETWEEN" %}
@@ -51,7 +54,8 @@
range-separator="-"
start-placeholder="开始日期"
end-placeholder="结束日期"
- >
+ style="width: 240px"
+ />
{% endif %}
{% endif %}
@@ -159,29 +163,29 @@
{% for column in columns %}
{% set field = column.python_field %}
- {% if column.insert and not column.pk %}
+ {% if (column.insert or column.edit) and not column.pk and column.column_name not in column_not_add_show + column_not_edit_show %}
{% if column.usable_column or not column.super_column %}
{% set parentheseIndex = column.column_comment.find("(") %}
{% set comment = column.column_comment[:parentheseIndex] if parentheseIndex != -1 else column.column_comment %}
{% set dictType = column.dict_type %}
{% if column.html_type == "input" %}
-
+
{% elif column.html_type == "imageUpload" %}
-
+
{% elif column.html_type == "fileUpload" %}
-
+
{% elif column.html_type == "editor" %}
-
+
{% elif column.html_type == "select" and dictType %}
-
+
{% elif column.html_type == "select" and not dictType %}
-
+
{% elif column.html_type == "checkbox" and dictType %}
-
+
{% elif column.html_type == "checkbox" and not dictType %}
-
+
请选择字典生成
{% elif column.html_type == "radio" and dictType %}
-
+
{% elif column.html_type == "radio" and not dictType %}
-
+
{% elif column.html_type == "datetime" %}
-
+
{% elif column.html_type == "textarea" %}
-
+
{% endif %}
@@ -397,8 +401,8 @@ function getList() {
{% if column.html_type == "datetime" and column.query_type == "BETWEEN" %}
{% set AttrName = column.python_field[0] | upper + column.python_field[1:] %}
if (null != daterange{{ AttrName }} && '' != daterange{{ AttrName }}) {
- queryParams.value.params["begin{{ AttrName }}"] = daterange{{ AttrName }}.value[0];
- queryParams.value.params["end{{ AttrName }}"] = daterange{{ AttrName }}.value[1];
+ queryParams.value.begin{{ AttrName }} = daterange{{ AttrName }}.value[0];
+ queryParams.value.end{{ AttrName }} = daterange{{ AttrName }}.value[1];
}
{% endif %}
{% endfor %}
@@ -567,5 +571,10 @@ function handleExport() {
}, `{{ businessName }}_${new Date().getTime()}.xlsx`);
}
+/** 是否渲染字段 */
+function renderField(insert, edit) {
+ return form.value.{{ pkColumn.python_field }} == null ? insert : edit;
+}
+
getList();
\ No newline at end of file
diff --git a/ruoyi-fastapi-backend/requirements-pg.txt b/ruoyi-fastapi-backend/requirements-pg.txt
index 3caa988..095197f 100644
--- a/ruoyi-fastapi-backend/requirements-pg.txt
+++ b/ruoyi-fastapi-backend/requirements-pg.txt
@@ -14,4 +14,5 @@ psycopg2==2.9.10
redis==5.2.1
requests==2.32.3
SQLAlchemy[asyncio]==2.0.38
+sqlglot[rs]==26.6.0
user-agents==2.2.0
diff --git a/ruoyi-fastapi-backend/utils/template_util.py b/ruoyi-fastapi-backend/utils/template_util.py
index 55a8f87..6765bd0 100644
--- a/ruoyi-fastapi-backend/utils/template_util.py
+++ b/ruoyi-fastapi-backend/utils/template_util.py
@@ -91,6 +91,8 @@ class TemplateUtils:
'table': gen_table,
'dicts': cls.get_dicts(gen_table),
'dbType': DataBaseConfig.db_type,
+ 'column_not_add_show': GenConstant.COLUMNNAME_NOT_ADD_SHOW,
+ 'column_not_edit_show': GenConstant.COLUMNNAME_NOT_EDIT_SHOW,
}
# 设置菜单、树形结构、子表的上下文
diff --git a/ruoyi-fastapi-backend/utils/time_format_util.py b/ruoyi-fastapi-backend/utils/time_format_util.py
index 380537e..bfb0481 100644
--- a/ruoyi-fastapi-backend/utils/time_format_util.py
+++ b/ruoyi-fastapi-backend/utils/time_format_util.py
@@ -1,4 +1,7 @@
-import datetime
+from copy import deepcopy
+from datetime import datetime
+from dateutil.parser import parse
+from typing import Dict, List, Union
def object_format_datetime(obj):
@@ -8,7 +11,7 @@ def object_format_datetime(obj):
"""
for attr in dir(obj):
value = getattr(obj, attr)
- if isinstance(value, datetime.datetime):
+ if isinstance(value, datetime):
setattr(obj, attr, value.strftime('%Y-%m-%d %H:%M:%S'))
return obj
@@ -21,7 +24,7 @@ def list_format_datetime(lst):
for obj in lst:
for attr in dir(obj):
value = getattr(obj, attr)
- if isinstance(value, datetime.datetime):
+ if isinstance(value, datetime):
setattr(obj, attr, value.strftime('%Y-%m-%d %H:%M:%S'))
return lst
@@ -41,7 +44,7 @@ def format_datetime_dict_list(dicts):
if isinstance(v, dict):
# 递归遍历子字典
new_item[k] = format_datetime_dict_list([v])[0]
- elif isinstance(v, datetime.datetime):
+ elif isinstance(v, datetime):
# 如果值是 datetime 类型,则格式化为字符串
new_item[k] = v.strftime('%Y-%m-%d %H:%M:%S')
else:
@@ -50,3 +53,89 @@ def format_datetime_dict_list(dicts):
result.append(new_item)
return result
+
+
+class TimeFormatUtil:
+ """
+ 时间格式化工具类
+ """
+
+ @classmethod
+ def format_time(cls, time_info: Union[str, datetime], format: str = '%Y-%m-%d %H:%M:%S'):
+ """
+ 格式化时间字符串或datetime对象为指定格式
+
+ :param time_info: 时间字符串或datetime对象
+ :param format: 格式化格式,默认为'%Y-%m-%d %H:%M:%S'
+ :return: 格式化后的时间字符串
+ """
+ if isinstance(time_info, datetime):
+ format_date = time_info.strftime(format)
+ else:
+ try:
+ date = parse(time_info)
+ format_date = date.strftime(format)
+ except Exception:
+ format_date = time_info
+
+ return format_date
+
+ @classmethod
+ def parse_date(cls, time_str: str):
+ """
+ 解析时间字符串提取日期部分
+
+ :param time_str: 时间字符串
+ :return: 日期部分
+ """
+ try:
+ dt = parse(time_str)
+ return dt.date()
+ except Exception:
+ return time_str
+
+ @classmethod
+ def format_time_dict(cls, time_dict: Dict, format: str = '%Y-%m-%d %H:%M:%S'):
+ """
+ 格式化时间字典
+
+ :param time_dict: 时间字典
+ :param format: 格式化格式,默认为'%Y-%m-%d %H:%M:%S'
+ :return: 格式化后的时间字典
+ """
+ copy_time_dict = deepcopy(time_dict)
+ for k, v in copy_time_dict.items():
+ if isinstance(v, (str, datetime)):
+ copy_time_dict[k] = cls.format_time(v, format)
+ elif isinstance(v, dict):
+ copy_time_dict[k] = cls.format_time_dict(v, format)
+ elif isinstance(v, list):
+ copy_time_dict[k] = cls.format_time_list(v, format)
+ else:
+ copy_time_dict[k] = v
+
+ return copy_time_dict
+
+ @classmethod
+ def format_time_list(cls, time_list: List, format: str = '%Y-%m-%d %H:%M:%S'):
+ """
+ 格式化时间列表
+
+ :param time_list: 时间列表
+ :param format: 格式化格式,默认为'%Y-%m-%d %H:%M:%S'
+ :return: 格式化后的时间列表
+ """
+ format_time_list = []
+ for item in time_list:
+ if isinstance(item, (str, datetime)):
+ format_item = cls.format_time(item, format)
+ elif isinstance(item, dict):
+ format_item = cls.format_time_dict(item, format)
+ elif isinstance(item, list):
+ format_item = cls.format_time_list(item, format)
+ else:
+ format_item = item
+
+ format_time_list.append(format_item)
+
+ return format_time_list
diff --git a/ruoyi-fastapi-frontend/package.json b/ruoyi-fastapi-frontend/package.json
index 1e252db..92ef355 100644
--- a/ruoyi-fastapi-frontend/package.json
+++ b/ruoyi-fastapi-frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "vfadmin",
- "version": "1.6.1",
+ "version": "1.6.2",
"description": "vfadmin管理系统",
"author": "insistence",
"license": "MIT",
diff --git a/ruoyi-fastapi-frontend/src/assets/styles/index.scss b/ruoyi-fastapi-frontend/src/assets/styles/index.scss
index 2b8dca5..efc1ddd 100644
--- a/ruoyi-fastapi-frontend/src/assets/styles/index.scss
+++ b/ruoyi-fastapi-frontend/src/assets/styles/index.scss
@@ -131,10 +131,6 @@ aside {
position: relative;
}
-.pagination-container {
- margin-top: 30px;
-}
-
.text-center {
text-align: center
}
diff --git a/ruoyi-fastapi-frontend/src/assets/styles/ruoyi.scss b/ruoyi-fastapi-frontend/src/assets/styles/ruoyi.scss
index 4996ae5..db9b1f6 100755
--- a/ruoyi-fastapi-frontend/src/assets/styles/ruoyi.scss
+++ b/ruoyi-fastapi-frontend/src/assets/styles/ruoyi.scss
@@ -102,21 +102,12 @@
/** 表格布局 **/
.pagination-container {
- position: relative;
- height: 25px;
- margin-bottom: 10px;
- margin-top: 15px;
- padding: 10px 20px !important;
+ display: flex;
+ justify-content: flex-end;
+ margin-top: 20px;
background-color: transparent !important;
}
-/* 分页器定位 */
-.pagination-container .el-pagination {
- position: absolute;
- right: 0;
- top: 0;
-}
-
/* 弹窗中的分页器 */
.el-dialog .pagination-container {
position: static !important;
diff --git a/ruoyi-fastapi-frontend/src/components/FileUpload/index.vue b/ruoyi-fastapi-frontend/src/components/FileUpload/index.vue
index a860a40..9a07847 100644
--- a/ruoyi-fastapi-frontend/src/components/FileUpload/index.vue
+++ b/ruoyi-fastapi-frontend/src/components/FileUpload/index.vue
@@ -13,12 +13,13 @@
:headers="headers"
class="upload-file-uploader"
ref="fileUpload"
+ v-if="!disabled"
>
选取文件
-
+
请上传
大小不超过 {{ fileSize }}MB
格式为 {{ fileType.join("/") }}
@@ -31,7 +32,7 @@
{{ getFileName(file.name) }}
- 删除
+ 删除
@@ -46,22 +47,27 @@ const props = defineProps({
// 数量限制
limit: {
type: Number,
- default: 5,
+ default: 5
},
// 大小限制(MB)
fileSize: {
type: Number,
- default: 5,
+ default: 5
},
// 文件类型, 例如['png', 'jpg', 'jpeg']
fileType: {
type: Array,
- default: () => ["doc", "xls", "ppt", "txt", "pdf"],
+ default: () => ["doc", "docx", "xls", "xlsx", "ppt", "pptx", "txt", "pdf"]
},
// 是否显示提示
isShowTip: {
type: Boolean,
default: true
+ },
+ // 禁用组件(仅查看文件)
+ disabled: {
+ type: Boolean,
+ default: false
}
});
diff --git a/ruoyi-fastapi-frontend/src/components/Pagination/index.vue b/ruoyi-fastapi-frontend/src/components/Pagination/index.vue
index 38de953..11d4caf 100644
--- a/ruoyi-fastapi-frontend/src/components/Pagination/index.vue
+++ b/ruoyi-fastapi-frontend/src/components/Pagination/index.vue
@@ -97,7 +97,6 @@ function handleCurrentChange(val) {