From 667ab9c02a93b4625b2add47852a744afd120e1d Mon Sep 17 00:00:00 2001 From: XIE7654 <765462425@qq.com> Date: Sat, 27 Sep 2025 10:33:54 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E7=B3=BB=E7=BB=9F?= =?UTF-8?q?=E9=85=8D=E7=BD=AE=E8=A1=A8=E5=8D=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../management/commands/gen_menu_json.py | 6 + backend/system/migrations/0004_config.py | 128 +++++++++++++++ backend/system/models.py | 23 +++ backend/system/urls.py | 1 + backend/system/views/__init__.py | 2 + backend/system/views/config.py | 37 +++++ .../src/locales/langs/en-US/system.json | 4 + .../src/locales/langs/zh-CN/system.json | 4 + web/apps/web-antd/src/models/system/config.ts | 23 +++ .../web-antd/src/views/system/config/data.ts | 148 ++++++++++++++++++ .../web-antd/src/views/system/config/list.vue | 141 +++++++++++++++++ .../src/views/system/config/modules/form.vue | 79 ++++++++++ 12 files changed, 596 insertions(+) create mode 100644 backend/system/migrations/0004_config.py create mode 100644 backend/system/views/config.py create mode 100644 web/apps/web-antd/src/models/system/config.ts create mode 100644 web/apps/web-antd/src/views/system/config/data.ts create mode 100644 web/apps/web-antd/src/views/system/config/list.vue create mode 100644 web/apps/web-antd/src/views/system/config/modules/form.vue diff --git a/backend/system/management/commands/gen_menu_json.py b/backend/system/management/commands/gen_menu_json.py index 00c7e9e..be12e95 100644 --- a/backend/system/management/commands/gen_menu_json.py +++ b/backend/system/management/commands/gen_menu_json.py @@ -3,7 +3,13 @@ from datetime import datetime from django.core.management.base import BaseCommand from system.models import Menu, MenuMeta import re +""" +自动生成 菜单 代码的 Django 管理命令 +使用方法: python manage.py gen_menu_json +例如: python manage.py gen_menu_json system Config 系统管理 +""" +# gen_menu_json --app system --model Config --parent 系统管理 def camel_to_snake(name): s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() diff --git a/backend/system/migrations/0004_config.py b/backend/system/migrations/0004_config.py new file mode 100644 index 0000000..59dee32 --- /dev/null +++ b/backend/system/migrations/0004_config.py @@ -0,0 +1,128 @@ +# Generated by Django 5.2.1 on 2025-09-27 02:26 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("system", "0003_loginlog_location"), + ] + + operations = [ + migrations.CreateModel( + name="Config", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ( + "remark", + models.CharField( + blank=True, + db_comment="备注", + help_text="备注", + max_length=256, + null=True, + verbose_name="备注", + ), + ), + ( + "creator", + models.CharField( + blank=True, + db_comment="创建人", + help_text="创建人", + max_length=64, + null=True, + verbose_name="创建人", + ), + ), + ( + "modifier", + models.CharField( + blank=True, + db_comment="修改人", + help_text="修改人", + max_length=64, + null=True, + verbose_name="修改人", + ), + ), + ( + "update_time", + models.DateTimeField( + auto_now=True, + db_comment="修改时间", + help_text="修改时间", + null=True, + verbose_name="修改时间", + ), + ), + ( + "create_time", + models.DateTimeField( + auto_now_add=True, + db_comment="创建时间", + help_text="创建时间", + null=True, + verbose_name="创建时间", + ), + ), + ( + "is_deleted", + models.BooleanField( + db_comment="是否软删除", + default=False, + verbose_name="是否软删除", + ), + ), + ( + "name", + models.CharField( + db_comment="参数名称", + default="", + max_length=100, + verbose_name="参数名称", + ), + ), + ( + "key", + models.CharField( + db_comment="参数键名", + default="", + max_length=100, + verbose_name="参数键名", + ), + ), + ( + "value", + models.CharField( + db_comment="参数键值", + default="", + max_length=500, + verbose_name="参数键值", + ), + ), + ( + "config_type", + models.BooleanField( + db_comment="系统内置(1是 0否)", + default=False, + verbose_name="系统内置", + ), + ), + ], + options={ + "verbose_name": "参数配置", + "verbose_name_plural": "参数配置", + "ordering": ["-id"], + }, + ), + ] diff --git a/backend/system/models.py b/backend/system/models.py index 58e9ca1..8552811 100644 --- a/backend/system/models.py +++ b/backend/system/models.py @@ -306,3 +306,26 @@ class LoginLog(CoreModel): def __str__(self): return f"{self.username} - {self.user_ip}" + + +class Config(CoreModel): + """ + 参数配置表 + """ + name = models.CharField(max_length=100, default='', db_comment='参数名称', verbose_name='参数名称') + key = models.CharField(max_length=100, default='', db_comment='参数键名', verbose_name='参数键名') + value = models.CharField(max_length=500, default='', db_comment='参数键值', verbose_name='参数键值') + config_type = models.BooleanField( + default=False, + db_comment='系统内置(1是 0否)', + verbose_name='系统内置' + ) + + class Meta: + verbose_name = '参数配置' + verbose_name_plural = verbose_name + ordering = ['-id'] + + def __str__(self): + return f"{self.name}({self.key})" + diff --git a/backend/system/urls.py b/backend/system/urls.py index e221ac0..84e8a93 100644 --- a/backend/system/urls.py +++ b/backend/system/urls.py @@ -13,6 +13,7 @@ router.register(r'dict_type', views.DictTypeViewSet) router.register(r'post', views.PostViewSet) router.register(r'user', views.UserViewSet) router.register(r'login_log', views.LoginLogViewSet) +router.register(r'config', views.ConfigViewSet) urlpatterns = [ path('', include(router.urls)), diff --git a/backend/system/views/__init__.py b/backend/system/views/__init__.py index c738cfe..aaa2e4d 100644 --- a/backend/system/views/__init__.py +++ b/backend/system/views/__init__.py @@ -7,6 +7,7 @@ __all__ = [ 'DictTypeViewSet', 'PostViewSet', 'UserViewSet', + 'ConfigViewSet', 'LoginLogViewSet', ] @@ -18,4 +19,5 @@ from system.views.role import RoleViewSet from system.views.dept import DeptViewSet from system.views.post import PostViewSet from system.views.login_log import LoginLogViewSet +from system.views.config import ConfigViewSet from system.views.user import * \ No newline at end of file diff --git a/backend/system/views/config.py b/backend/system/views/config.py new file mode 100644 index 0000000..a77cf5d --- /dev/null +++ b/backend/system/views/config.py @@ -0,0 +1,37 @@ +from system.models import Config +from utils.serializers import CustomModelSerializer +from utils.custom_model_viewSet import CustomModelViewSet +from django_filters import rest_framework as filters, CharFilter + + +class ConfigSerializer(CustomModelSerializer): + """ + 参数配置 序列化器 + """ + class Meta: + model = Config + fields = '__all__' + read_only_fields = ['id', 'create_time', 'update_time'] + + +class ConfigFilter(filters.FilterSet): + name = CharFilter(field_name='name', lookup_expr='icontains') + key = CharFilter(field_name='key', lookup_expr='icontains') + value = CharFilter(field_name='value', lookup_expr='icontains') + remark = CharFilter(field_name='remark', lookup_expr='icontains') + + class Meta: + model = Config + fields = ['id', 'remark', 'creator', 'modifier', 'is_deleted', 'name', 'key', 'value', 'config_type'] + + +class ConfigViewSet(CustomModelViewSet): + """ + 参数配置 视图集 + """ + queryset = Config.objects.filter(is_deleted=False).order_by('-id') + serializer_class = ConfigSerializer + filterset_class = ConfigFilter + search_fields = ['name'] # 根据实际字段调整 + ordering_fields = ['create_time', 'id'] + ordering = ['-create_time'] diff --git a/web/apps/web-antd/src/locales/langs/en-US/system.json b/web/apps/web-antd/src/locales/langs/en-US/system.json index 1f62321..222238f 100644 --- a/web/apps/web-antd/src/locales/langs/en-US/system.json +++ b/web/apps/web-antd/src/locales/langs/en-US/system.json @@ -103,6 +103,10 @@ "login_log": { "name": "login log", "title": "login log" + }, + "config": { + "name": "System Config", + "title": "System Config" }, "status": "Status", "remark": "Remarks", diff --git a/web/apps/web-antd/src/locales/langs/zh-CN/system.json b/web/apps/web-antd/src/locales/langs/zh-CN/system.json index 4b13f14..56d494d 100644 --- a/web/apps/web-antd/src/locales/langs/zh-CN/system.json +++ b/web/apps/web-antd/src/locales/langs/zh-CN/system.json @@ -105,6 +105,10 @@ "name": "登录日志", "title": "登录日志" }, + "config": { + "name": "系统配置", + "title": "系统配置" + }, "status": "状态", "remark": "备注", "creator": "创建人", diff --git a/web/apps/web-antd/src/models/system/config.ts b/web/apps/web-antd/src/models/system/config.ts new file mode 100644 index 0000000..f330735 --- /dev/null +++ b/web/apps/web-antd/src/models/system/config.ts @@ -0,0 +1,23 @@ +import { BaseModel } from '#/models/base'; + +export namespace SystemConfigApi { + export interface SystemConfig { + id: number; + remark: string; + creator: string; + modifier: string; + update_time: string; + create_time: string; + is_deleted: boolean; + name: string; + key: string; + value: string; + config_type: boolean; + } +} + +export class SystemConfigModel extends BaseModel { + constructor() { + super('/system/config/'); + } +} diff --git a/web/apps/web-antd/src/views/system/config/data.ts b/web/apps/web-antd/src/views/system/config/data.ts new file mode 100644 index 0000000..a82ef75 --- /dev/null +++ b/web/apps/web-antd/src/views/system/config/data.ts @@ -0,0 +1,148 @@ +import type { VxeTableGridOptions } from '@vben/plugins/vxe-table'; + +import type { VbenFormSchema } from '#/adapter/form'; +import type { OnActionClickFn } from '#/adapter/vxe-table'; +import type { SystemConfigApi } from '#/models/system/config'; + +import { z } from '#/adapter/form'; +import { $t } from '#/locales'; +import { format_datetime } from '#/utils/date'; +import { op } from '#/utils/permission'; + +/** + * 获取编辑表单的字段配置 + */ +export function useSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'name', + label: '参数名称', + rules: z + .string() + .min(1, $t('ui.formRules.required', ['参数名称'])) + .max(100, $t('ui.formRules.maxLength', ['参数名称', 100])), + }, + { + component: 'Input', + fieldName: 'key', + label: '参数键名', + rules: z + .string() + .min(1, $t('ui.formRules.required', ['参数键名'])) + .max(100, $t('ui.formRules.maxLength', ['参数键名', 100])), + }, + { + component: 'Input', + fieldName: 'value', + label: '参数键值', + rules: z + .string() + .min(1, $t('ui.formRules.required', ['参数键值'])) + .max(100, $t('ui.formRules.maxLength', ['参数键值', 100])), + }, + { + component: 'RadioGroup', + componentProps: { + buttonStyle: 'solid', + options: [ + { label: '开启', value: 1 }, + { label: '关闭', value: 0 }, + ], + optionType: 'button', + }, + defaultValue: 1, + fieldName: 'config_type', + label: '系统内置', + }, + { + component: 'Input', + fieldName: 'remark', + label: '备注' + }, + ]; +} + +/** + * 获取编辑表单的字段配置 + */ +export function useGridFormSchema(): VbenFormSchema[] { + return [ + { + component: 'Input', + fieldName: 'name', + label: '参数名称', + }, + { + component: 'Input', + fieldName: 'key', + label: '参数键名', + }, + { + component: 'Input', + fieldName: 'value', + label: '参数键值', + }, + ]; +} + +/** + * 获取表格列配置 + * @description 使用函数的形式返回列数据而不是直接export一个Array常量,是为了响应语言切换时重新翻译表头 + * @param onActionClick 表格操作按钮点击事件 + */ +export function useColumns( + onActionClick?: OnActionClickFn, +): VxeTableGridOptions['columns'] { + return [ + { + field: 'id', + title: 'ID', + }, + { + field: 'name', + title: '参数名称', + }, + { + field: 'key', + title: '参数键名', + }, + { + field: 'value', + title: '参数键值', + }, + { + field: 'config_type', + title: '系统内置', + }, + { + field: 'remark', + title: '备注', + }, + { + field: 'create_time', + title: '创建时间', + width: 150, + formatter: ({ cellValue }) => format_datetime(cellValue), + }, + { + align: 'center', + cellRender: { + attrs: { + nameField: 'name', + nameTitle: $t('system.config.name'), + onClick: onActionClick, + }, + name: 'CellOperation', + options: [ + op('system:config:edit', 'edit'), + op('system:config:delete', 'delete'), + ], + }, + field: 'action', + fixed: 'right', + title: '操作', + width: 120, + }, + ]; +} diff --git a/web/apps/web-antd/src/views/system/config/list.vue b/web/apps/web-antd/src/views/system/config/list.vue new file mode 100644 index 0000000..c20e8d2 --- /dev/null +++ b/web/apps/web-antd/src/views/system/config/list.vue @@ -0,0 +1,141 @@ + + + diff --git a/web/apps/web-antd/src/views/system/config/modules/form.vue b/web/apps/web-antd/src/views/system/config/modules/form.vue new file mode 100644 index 0000000..48b82d7 --- /dev/null +++ b/web/apps/web-antd/src/views/system/config/modules/form.vue @@ -0,0 +1,79 @@ + + + +