diff --git a/backend/application/settings.py b/backend/application/settings.py index a635010..8fc6e8d 100644 --- a/backend/application/settings.py +++ b/backend/application/settings.py @@ -12,8 +12,8 @@ https://docs.djangoproject.com/en/4.1/ref/settings/ import os import sys -from pathlib import Path from datetime import timedelta +from pathlib import Path # Build paths inside the project like this: BASE_DIR / 'subdir'. BASE_DIR = Path(__file__).resolve().parent.parent @@ -44,7 +44,7 @@ DEBUG = locals().get("DEBUG", True) ALLOWED_HOSTS = locals().get("ALLOWED_HOSTS", ["*"]) # 列权限需要排除的App应用 -COLUMN_EXCLUDE_APPS = ['channels', 'captcha'] + locals().get("COLUMN_EXCLUDE_APPS", []) +COLUMN_EXCLUDE_APPS = ["channels", "captcha"] + locals().get("COLUMN_EXCLUDE_APPS", []) INSTALLED_APPS = [ "django.contrib.auth", @@ -66,6 +66,7 @@ INSTALLED_APPS = [ "apps.pisadmin.dashboard", "apps.pissupplier", "sync", + "dvadmin_ak_sk", ] MIDDLEWARE = [ @@ -74,6 +75,7 @@ MIDDLEWARE = [ "whitenoise.middleware.WhiteNoiseMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "corsheaders.middleware.CorsMiddleware", # 跨域中间件 + "dvadmin.utils.middleware.LocaleMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", @@ -115,8 +117,8 @@ DATABASES = { "PORT": DATABASE_PORT, "OPTIONS": { "driver": "ODBC Driver 18 for SQL Server", - "extra_params": "Encrypt=yes;TrustServerCertificate=yes" - } + "extra_params": "Encrypt=yes;TrustServerCertificate=yes", + }, } } AUTH_USER_MODEL = "system.Users" @@ -153,6 +155,22 @@ USE_L10N = True USE_TZ = False +# ================================================= # +# *************** 国际化配置 (i18n) *************** # +# ================================================= # + +# Supported languages — maps frontend codes to Django locale names (D-07) +LANGUAGES = [ + ("zh-hans", "Simplified Chinese"), + ("en", "English"), + ("zh-hant", "Traditional Chinese"), +] + +# Locale file paths for Django .po/.mo files (BEI-04) +LOCALE_PATHS = [ + os.path.join(BASE_DIR, "locale"), +] + # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/3.2/howto/static-files/ @@ -165,10 +183,10 @@ STATICFILES_DIRS = [ MEDIA_ROOT = "media" # 项目下的目录 MEDIA_URL = "/media/" # 跟STATIC_URL类似,指定用户可以通过这个url找到文件 -#添加以下代码以后就不用写{% load staticfiles %},可以直接引用 +# 添加以下代码以后就不用写{% load staticfiles %},可以直接引用 STATICFILES_FINDERS = ( "django.contrib.staticfiles.finders.FileSystemFinder", - "django.contrib.staticfiles.finders.AppDirectoriesFinder" + "django.contrib.staticfiles.finders.AppDirectoriesFinder", ) # 收集静态文件,必须将 MEDIA_ROOT,STATICFILES_DIRS先注释 # python manage.py collectstatic @@ -186,12 +204,8 @@ CORS_ALLOW_CREDENTIALS = True # 指明在跨域访问中,后端是否支持 # ===================================================== # # ********************* channels配置 ******************* # # ===================================================== # -ASGI_APPLICATION = 'application.asgi.application' -CHANNEL_LAYERS = { - "default": { - "BACKEND": "channels.layers.InMemoryChannelLayer" - } -} +ASGI_APPLICATION = "application.asgi.application" +CHANNEL_LAYERS = {"default": {"BACKEND": "channels.layers.InMemoryChannelLayer"}} # CHANNEL_LAYERS = { # 'default': { # 'BACKEND': 'channels_redis.core.RedisChannelLayer', @@ -258,7 +272,6 @@ LOGGING = { "class": "logging.StreamHandler", "formatter": "console", }, - }, "loggers": { "": { @@ -270,19 +283,16 @@ LOGGING = { "level": "INFO", "propagate": False, }, - 'django.db.backends': { - 'handlers': ["console", "error", "file"], - 'propagate': False, - 'level': "INFO" + "django.db.backends": { + "handlers": ["console", "error", "file"], + "propagate": False, + "level": "INFO", }, "uvicorn.error": { "level": "INFO", "handlers": ["console", "error", "file"], }, - "uvicorn.access": { - "handlers": ["console", "error", "file"], - "level": "INFO" - }, + "uvicorn.access": {"handlers": ["console", "error", "file"], "level": "INFO"}, }, } @@ -291,9 +301,9 @@ LOGGING = { # ================================================= # REST_FRAMEWORK = { - 'DEFAULT_PARSER_CLASSES': ( - 'rest_framework.parsers.JSONParser', - 'rest_framework.parsers.MultiPartParser', + "DEFAULT_PARSER_CLASSES": ( + "rest_framework.parsers.JSONParser", + "rest_framework.parsers.MultiPartParser", ), "DATETIME_FORMAT": "%Y-%m-%d %H:%M:%S", # 日期时间格式配置 "DATE_FORMAT": "%Y-%m-%d", @@ -408,7 +418,7 @@ ALL_MODELS_OBJECTS = [] # 所有app models 对象 INITIALIZE_LIST = [] INITIALIZE_RESET_LIST = [] # 表前缀 -TABLE_PREFIX = locals().get('TABLE_PREFIX', "") +TABLE_PREFIX = locals().get("TABLE_PREFIX", "") # 系统配置 SYSTEM_CONFIG = {} # 字典配置 @@ -428,11 +438,11 @@ SHARED_APPS = [] # ********** 一键导入插件配置开始 ********** # 例如: # from dvadmin_upgrade_center.settings import * # 升级中心 -from dvadmin3_celery.settings import * # celery 异步任务 +from dvadmin3_celery.settings import * # celery 异步任务 # from dvadmin_third.settings import * # 第三方用户管理 # from dvadmin_ak_sk.settings import * # 秘钥管理管理 # from dvadmin_tenants.settings import * # 租户管理 -#from dvadmin_social_auth.settings import * -#from dvadmin_uniapp.settings import * +# from dvadmin_social_auth.settings import * +# from dvadmin_uniapp.settings import * # ... # ********** 一键导入插件配置结束 ********** diff --git a/backend/apps/pisadmin/basicinfo/migrations/0005_company_company_name_en_company_company_name_zh_tw_and_more.py b/backend/apps/pisadmin/basicinfo/migrations/0005_company_company_name_en_company_company_name_zh_tw_and_more.py new file mode 100644 index 0000000..1ae1a63 --- /dev/null +++ b/backend/apps/pisadmin/basicinfo/migrations/0005_company_company_name_en_company_company_name_zh_tw_and_more.py @@ -0,0 +1,76 @@ +# Generated by Django 4.2.14 on 2026-04-08 20:38 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('basicinfo', '0004_emailnotice'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='company_name_en', + field=models.CharField(blank=True, help_text='公司全称英文', max_length=100, null=True, verbose_name='公司全称英文'), + ), + migrations.AddField( + model_name='company', + name='company_name_zh_tw', + field=models.CharField(blank=True, help_text='公司全称繁体', max_length=100, null=True, verbose_name='公司全称繁体'), + ), + migrations.AddField( + model_name='company', + name='company_short_name_en', + field=models.CharField(blank=True, help_text='公司简称英文', max_length=50, null=True, verbose_name='公司简称英文'), + ), + migrations.AddField( + model_name='company', + name='company_short_name_zh_tw', + field=models.CharField(blank=True, help_text='公司简称繁体', max_length=50, null=True, verbose_name='公司简称繁体'), + ), + migrations.AddField( + model_name='currency', + name='currencyname_en', + field=models.CharField(blank=True, help_text='货币英文名', max_length=50, null=True, verbose_name='货币英文名'), + ), + migrations.AddField( + model_name='currency', + name='currencyname_zh_tw', + field=models.CharField(blank=True, help_text='货币繁体名', max_length=50, null=True, verbose_name='货币繁体名'), + ), + migrations.AddField( + model_name='supplier', + name='supplier_name_en', + field=models.CharField(blank=True, help_text='供应商全称英文', max_length=100, null=True, verbose_name='供应商全称英文'), + ), + migrations.AddField( + model_name='supplier', + name='supplier_name_zh_tw', + field=models.CharField(blank=True, help_text='供应商全称繁体', max_length=100, null=True, verbose_name='供应商全称繁体'), + ), + migrations.AddField( + model_name='supplier', + name='supplier_short_name_en', + field=models.CharField(blank=True, help_text='供应商简称英文', max_length=50, null=True, verbose_name='供应商简称英文'), + ), + migrations.AddField( + model_name='supplier', + name='supplier_short_name_zh_tw', + field=models.CharField(blank=True, help_text='供应商简称繁体', max_length=50, null=True, verbose_name='供应商简称繁体'), + ), + migrations.AddField( + model_name='unit', + name='unitname_en', + field=models.CharField(blank=True, help_text='计量单位英文名', max_length=50, null=True, verbose_name='计量单位英文名'), + ), + migrations.AddField( + model_name='unit', + name='unitname_zh_tw', + field=models.CharField(blank=True, help_text='计量单位繁体名', max_length=50, null=True, verbose_name='计量单位繁体名'), + ), + ] diff --git a/backend/apps/pisadmin/miscprocurement/migrations/0008_add_i18n_fields.py b/backend/apps/pisadmin/miscprocurement/migrations/0008_add_i18n_fields.py new file mode 100644 index 0000000..6777798 --- /dev/null +++ b/backend/apps/pisadmin/miscprocurement/migrations/0008_add_i18n_fields.py @@ -0,0 +1,188 @@ +# Generated by Django 4.2.14 on 2026-04-08 20:41 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + migrations.swappable_dependency(settings.AUTH_USER_MODEL), + ('miscprocurement', '0007_alter_misclowpriceheader_item_no'), + ] + + operations = [ + migrations.CreateModel( + name='MiscProcMaterialMinPrices', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('part_id', models.CharField(db_column='partid', max_length=50, verbose_name='采购价料号')), + ('material_spec', models.CharField(db_column='material_spec', max_length=20, verbose_name='材料规格')), + ('currency_code', models.CharField(db_column='currency_code', max_length=50, verbose_name='货币代码')), + ('item_num', models.CharField(db_column='item_num', max_length=20, verbose_name='项次名')), + ('lowest_value', models.CharField(db_column='lowest_value', max_length=20, verbose_name='最低值')), + ('source_number', models.CharField(db_column='source_number', max_length=50, verbose_name='报价来源单号')), + ('quotation_time', models.DateTimeField(db_column='quotation_time', verbose_name='报价时间')), + ], + options={ + 'verbose_name': '杂采材料制程最低价信息表', + 'verbose_name_plural': '杂采材料制程最低价信息表', + 'db_table': 'pis_misc_proc_material_min_prices', + 'ordering': ('-create_datetime', 'id'), + }, + ), + migrations.CreateModel( + name='MiscProcProcessingMinPrices', + fields=[ + ('id', models.BigAutoField(help_text='Id', primary_key=True, serialize=False, verbose_name='Id')), + ('description', models.CharField(blank=True, help_text='描述', max_length=255, null=True, verbose_name='描述')), + ('modifier', models.CharField(blank=True, help_text='修改人', max_length=255, null=True, verbose_name='修改人')), + ('dept_belong_id', models.CharField(blank=True, help_text='数据归属部门', max_length=255, null=True, verbose_name='数据归属部门')), + ('update_datetime', models.DateTimeField(auto_now=True, help_text='修改时间', null=True, verbose_name='修改时间')), + ('create_datetime', models.DateTimeField(auto_now_add=True, help_text='创建时间', null=True, verbose_name='创建时间')), + ('part_id', models.CharField(db_column='partid', max_length=50, verbose_name='采购件料号')), + ('currency_code', models.CharField(db_column='currencycode', max_length=50, verbose_name='货币代码')), + ('lowest_value', models.CharField(db_column='lowest_vaule', max_length=20, verbose_name='加工费用最低价')), + ('source_number', models.CharField(blank=True, db_column='sourcenumber', max_length=50, null=True, verbose_name='报价来源单号')), + ('quotation_time', models.DateTimeField(blank=True, db_column='quotationtime', null=True, verbose_name='报价时间')), + ], + options={ + 'verbose_name': '杂采加工费用最低价信息表', + 'verbose_name_plural': '杂采加工费用最低价信息表', + 'db_table': 'pis_misc_proc_processing_min_prices', + 'ordering': ('-create_datetime', 'id'), + }, + ), + migrations.RenameIndex( + model_name='inquirymaterialcost', + new_name='pis_misc_pr_PartId_1213f3_idx', + old_name='pis_proc_in_PartId_4bedee_idx', + ), + migrations.RenameIndex( + model_name='inquiryothercost', + new_name='pis_misc_pr_PartId_d3323e_idx', + old_name='pis_proc_in_PartId_33e9d8_idx', + ), + migrations.RenameIndex( + model_name='inquiryprocesscost', + new_name='pis_misc_pr_PartId_cebba1_idx', + old_name='pis_proc_in_PartId_65ad97_idx', + ), + migrations.RenameIndex( + model_name='inquiryprofitcost', + new_name='pis_misc_pr_PartId_313c85_idx', + old_name='pis_proc_in_PartId_aaa0eb_idx', + ), + migrations.AddField( + model_name='costestimatetemplatehead', + name='template_name_en', + field=models.CharField(blank=True, db_column='TemplateNameEn', max_length=50, null=True, verbose_name='模板英文名'), + ), + migrations.AddField( + model_name='costestimatetemplatehead', + name='template_name_zh_tw', + field=models.CharField(blank=True, db_column='TemplateNameZhTw', max_length=50, null=True, verbose_name='模板繁体名'), + ), + migrations.AddField( + model_name='inquiry', + name='title_en', + field=models.CharField(blank=True, max_length=20, null=True, verbose_name='询价单英文名'), + ), + migrations.AddField( + model_name='inquiry', + name='title_zh_tw', + field=models.CharField(blank=True, max_length=20, null=True, verbose_name='询价单繁体名'), + ), + migrations.AddField( + model_name='miscprocurementmaterialinfo', + name='materialtype_en', + field=models.CharField(blank=True, help_text='材质英文名', max_length=50, null=True, verbose_name='材质英文名'), + ), + migrations.AddField( + model_name='miscprocurementmaterialinfo', + name='materialtype_zh_tw', + field=models.CharField(blank=True, help_text='材质繁体名', max_length=50, null=True, verbose_name='材质繁体名'), + ), + migrations.AddField( + model_name='miscprocurementstationinfo', + name='stationname_en', + field=models.CharField(blank=True, help_text='工站英文名', max_length=50, null=True, verbose_name='工站英文名'), + ), + migrations.AddField( + model_name='miscprocurementstationinfo', + name='stationname_zh_tw', + field=models.CharField(blank=True, help_text='工站繁体名', max_length=50, null=True, verbose_name='工站繁体名'), + ), + migrations.AlterField( + model_name='misclowpricedetail', + name='item_no', + field=models.CharField(choices=[('1', '重量'), ('2', '单价')], db_column='ItemNo', help_text='策采:重量、损耗、单价;杂采:重量、单价', max_length=100, verbose_name='项次名'), + ), + migrations.AlterField( + model_name='misclowpricedetail', + name='souce_no', + field=models.CharField(db_column='SouceNo', help_text='重量/单价取最小值时对应报价单单号;单价来自杂采材料信息时存交易厂区代码', max_length=200, verbose_name='来源单号(报价单号或交易厂区)'), + ), + migrations.AlterField( + model_name='misclowpriceheader', + name='souce_no', + field=models.CharField(blank=True, db_column='SouceNo', max_length=200, null=True, verbose_name='来源单号(报价单&询价单)'), + ), + migrations.AlterField( + model_name='rfqoperationlogs', + name='operation_type', + field=models.CharField(choices=[(1, '询价单创建'), (2, '询价单确认'), (3, '询价单发布'), (4, '询价单还原'), (5, '报价截止'), (6, '供应商报价'), (7, '比议价'), (8, '议价审核提交'), (9, '议价审核完成'), (10, '议价审核驳回')], db_column='OperationType', max_length=20, verbose_name='操作类型'), + ), + migrations.AlterModelTable( + name='inquiry', + table='pis_misc_proc_inquiry_master', + ), + migrations.AlterModelTable( + name='inquiryattachment', + table='pis_misc_proc_inquiry_attachment', + ), + migrations.AlterModelTable( + name='inquirymaterialcost', + table='pis_misc_proc_inquiry_material_cost', + ), + migrations.AlterModelTable( + name='inquiryothercost', + table='pis_misc_proc_inquiry_other_cost', + ), + migrations.AlterModelTable( + name='inquiryprocesscost', + table='pis_misc_proc_inquiry_process_cost', + ), + migrations.AlterModelTable( + name='inquiryprofitcost', + table='pis_misc_proc_inquiry_profit_cost', + ), + migrations.AlterModelTable( + name='inquirysupplier', + table='pis_misc_proc_inquiry_supplier', + ), + migrations.AddField( + model_name='miscprocprocessingminprices', + name='creator', + field=models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人'), + ), + migrations.AddField( + model_name='miscprocmaterialminprices', + name='creator', + field=models.ForeignKey(db_constraint=False, help_text='创建人', null=True, on_delete=django.db.models.deletion.SET_NULL, related_query_name='creator_query', to=settings.AUTH_USER_MODEL, verbose_name='创建人'), + ), + migrations.AddIndex( + model_name='miscprocprocessingminprices', + index=models.Index(fields=['part_id', 'currency_code'], name='pis_misc_pr_partid_116944_idx'), + ), + migrations.AddIndex( + model_name='miscprocmaterialminprices', + index=models.Index(fields=['part_id', 'material_spec', 'currency_code', 'item_num'], name='pis_misc_pr_partid_0a5142_idx'), + ), + ] diff --git a/backend/apps/pissupplier/migrations/0006_rename_pis_sup_quo_partid_99a155_idx_pis_misc_su_partid_526e30_idx_and_more.py b/backend/apps/pissupplier/migrations/0006_rename_pis_sup_quo_partid_99a155_idx_pis_misc_su_partid_526e30_idx_and_more.py new file mode 100644 index 0000000..825a413 --- /dev/null +++ b/backend/apps/pissupplier/migrations/0006_rename_pis_sup_quo_partid_99a155_idx_pis_misc_su_partid_526e30_idx_and_more.py @@ -0,0 +1,76 @@ +# Generated by Django 4.2.14 on 2026-04-08 20:38 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('pissupplier', '0005_alter_quotationmaster_quote_deadline_and_more'), + ] + + operations = [ + migrations.RenameIndex( + model_name='quotationitem', + new_name='pis_misc_su_Partid_526e30_idx', + old_name='pis_sup_quo_Partid_99a155_idx', + ), + migrations.RenameIndex( + model_name='quotationmaterial', + new_name='pis_misc_su_Partid_8d3a7c_idx', + old_name='pis_sup_quo_Partid_cf933e_idx', + ), + migrations.RenameIndex( + model_name='quotationother', + new_name='pis_misc_su_Partid_68c79f_idx', + old_name='pis_sup_quo_Partid_f50af0_idx', + ), + migrations.RenameIndex( + model_name='quotationprocess', + new_name='pis_misc_su_Partid_28aa7a_idx', + old_name='pis_sup_quo_Partid_e14a9f_idx', + ), + migrations.RenameIndex( + model_name='quotationprofit', + new_name='pis_misc_su_Partid_e7fb57_idx', + old_name='pis_sup_quo_Partid_b34018_idx', + ), + migrations.AddField( + model_name='quotationmaster', + name='supplier_name_en', + field=models.CharField(blank=True, help_text='供应商英文名', max_length=20, null=True, verbose_name='供应商英文名'), + ), + migrations.AddField( + model_name='quotationmaster', + name='supplier_name_zh_tw', + field=models.CharField(blank=True, help_text='供应商繁体名', max_length=20, null=True, verbose_name='供应商繁体名'), + ), + migrations.AlterModelTable( + name='quotationattachment', + table='pis_misc_sup_quotation_attachment', + ), + migrations.AlterModelTable( + name='quotationitem', + table='pis_misc_sup_quot_items', + ), + migrations.AlterModelTable( + name='quotationmaster', + table='pis_misc_sup_quotation_master', + ), + migrations.AlterModelTable( + name='quotationmaterial', + table='pis_misc_sup_quotation_material', + ), + migrations.AlterModelTable( + name='quotationother', + table='pis_misc_sup_quotation_other', + ), + migrations.AlterModelTable( + name='quotationprocess', + table='pis_misc_sup_quotation_process', + ), + migrations.AlterModelTable( + name='quotationprofit', + table='pis_misc_sup_quotation_profit', + ), + ] diff --git a/backend/dvadmin/system/fixtures/init_menu.json b/backend/dvadmin/system/fixtures/init_menu.json index ec9742a..034ce72 100644 --- a/backend/dvadmin/system/fixtures/init_menu.json +++ b/backend/dvadmin/system/fixtures/init_menu.json @@ -30,61 +30,81 @@ "name": "查询", "value": "user:Search", "api": "/api/system/user/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "新增", "value": "user:Create", "api": "/api/system/user/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "user:Update", "api": "/api/system/user/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "user:Delete", "api": "/api/system/user/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" }, { "name": "导出", "value": "user:Export", "api": "/api/system/user/export/", - "method": 1 + "method": 1, + "name_en": "Export", + "name_zh_tw": "導出" }, { "name": "导入", "value": "user:Import", "api": "/api/system/user/import/", - "method": 1 + "method": 1, + "name_en": "Import", + "name_zh_tw": "導入" }, { "name": "获取导入模板", "value": "user:ImportTemplate", "api": "/api/system/user/import/", - "method": 0 + "method": 0, + "name_en": "Get Import Template", + "name_zh_tw": "獲取導入模板" }, { "name": "批量更新模板", "value": "user:BatchUpdateTemplate", "api": "/api/system/user/update_template/", - "method": 0 + "method": 0, + "name_en": "Batch Update Template", + "name_zh_tw": "批量更新模板" }, { "name": "重设密码", "value": "user:ResetPassword", "api": "/api/system/user/{id}/reset_password/", - "method": 2 + "method": 2, + "name_en": "Reset Password", + "name_zh_tw": "重設密碼" }, { "name": "重置密码", "value": "user:ResetDefaultPassword", "api": "/api/system/user/{id}/reset_to_default_password/", - "method": 2 + "method": 2, + "name_en": "Reset Password", + "name_zh_tw": "重置密碼" } ], "menu_field": [ @@ -163,7 +183,9 @@ "title": "用户类型", "model": "Users" } - ] + ], + "name_en": "User Management", + "name_zh_tw": "用戶管理" }, { "name": "菜单管理", @@ -183,112 +205,150 @@ "name": "查询", "value": "menu:Search", "api": "/api/system/menu/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "单例", "value": "menu:Retrieve", "api": "/api/system/menu/{id}/", - "method": 0 + "method": 0, + "name_en": "Retrieve", + "name_zh_tw": "單例" }, { "name": "新增", "value": "menu:Create", "api": "/api/system/menu/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "menu:Update", "api": "/api/system/menu/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "menu:Delete", "api": "/api/system/menu/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" }, { "name": "查询所有", "value": "menu:SearchAll", "api": "/api/system/menu/get_all_menu/", - "method": 0 + "method": 0, + "name_en": "Query All", + "name_zh_tw": "查詢所有" }, { "name": "路由", "value": "menu:router", "api": "/api/system/menu/web_router/", - "method": 0 + "method": 0, + "name_en": "Route", + "name_zh_tw": "路由" }, { "name": "查询按钮", "value": "menu:SearchButton", "api": "/api/system/menu_button/", - "method": 0 + "method": 0, + "name_en": "Query Buttons", + "name_zh_tw": "查詢按鈕" }, { "name": "新增按钮", "value": "menu:CreateButton", "api": "/api/system/menu_button/", - "method": 1 + "method": 1, + "name_en": "Add Button", + "name_zh_tw": "新增按鈕" }, { "name": "编辑按钮", "value": "menu:UpdateButton", "api": "/api/system/menu_button/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit Button", + "name_zh_tw": "編輯按鈕" }, { "name": "删除按钮", "value": "menu:DeleteButton", "api": "/api/system/menu_button/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete Button", + "name_zh_tw": "刪除按鈕" }, { "name": "上移", "value": "menu:MoveUp", "api": "/api/system/menu/mode_up/", - "method": 1 + "method": 1, + "name_en": "Move Up", + "name_zh_tw": "上移" }, { "name": "下移", "value": "menu:MoveDown", "api": "/api/system/menu/mode_down/", - "method": 1 + "method": 1, + "name_en": "Move Down", + "name_zh_tw": "下移" }, { "name": "查询列权限", "value": "column:Search", "api": "/api/system/column/", - "method": 0 + "method": 0, + "name_en": "Query Column Perms", + "name_zh_tw": "查詢列權限" }, { "name": "新增列权限", "value": "column:Create", "api": "/api/system/column/", - "method": 1 + "method": 1, + "name_en": "Add Column Perms", + "name_zh_tw": "新增列權限" }, { "name": "编辑列权限", "value": "column:Update", "api": "/api/system/column/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit Column Perms", + "name_zh_tw": "編輯列權限" }, { "name": "删除列权限", "value": "column:Delete", "api": "/api/system/column/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete Column Perms", + "name_zh_tw": "刪除列權限" }, { "name": "自动匹配列权限", "value": "column:Match", "api": "/api/system/column/auto_match_fields/", - "method": 1 + "method": 1, + "name_en": "Auto Match Col Perms", + "name_zh_tw": "自動匹配列權限" } ], - "menu_field": [] + "menu_field": [], + "name_en": "Menu Management", + "name_zh_tw": "選單管理" }, { "name": "部门管理", @@ -308,58 +368,78 @@ "name": "查询", "value": "dept:Search", "api": "/api/system/dept/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "dept:Retrieve", "api": "/api/system/dept/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "获取所有部门", "value": "dept:SearchAll", "api": "/api/system/dept/all_dept/", - "method": 0 + "method": 0, + "name_en": "Get All Depts", + "name_zh_tw": "獲取所有部門" }, { "name": "部门顶部信息", "value": "dept:HeaderInfo", "api": "/api/system/dept/dept_info/", - "method": 0 + "method": 0, + "name_en": "Dept Header Info", + "name_zh_tw": "部門頂部資訊" }, { "name": "新增", "value": "dept:Create", "api": "/api/system/dept/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "上移", "value": "dept:MoveUp", "api": "/api/system/dept/mode_up/", - "method": 1 + "method": 1, + "name_en": "Move Up", + "name_zh_tw": "上移" }, { "name": "下移", "value": "dept:MoveDown", "api": "/api/system/dept/mode_down/", - "method": 1 + "method": 1, + "name_en": "Move Down", + "name_zh_tw": "下移" }, { "name": "编辑", "value": "dept:Update", "api": "/api/system/dept/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "dept:Delete", "api": "/api/system/dept/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], - "menu_field": [] + "menu_field": [], + "name_en": "Department Management", + "name_zh_tw": "部門管理" }, { "name": "角色管理", @@ -379,85 +459,113 @@ "name": "查询", "value": "role:Search", "api": "/api/system/role/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "单例", "value": "role:Retrieve", "api": "/api/system/role/{id}/", - "method": 0 + "method": 0, + "name_en": "Retrieve", + "name_zh_tw": "單例" }, { "name": "新增", "value": "role:Create", "api": "/api/system/role/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "role:Update", "api": "/api/system/role/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "role:Delete", "api": "/api/system/role/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" }, { "name": "获取所有可授权数据范围的部门", "value": "role:AllDataRangeDept", "api": "/api/system/role_menu_button_permision/role_to_dept_all/", - "method": 0 + "method": 0, + "name_en": "Get Assignable Depts", + "name_zh_tw": "獲取所有可授權數據範圍的部門" }, { "name": "获取所有可授权菜单", "value": "role:AllCanMenu", "api": "/api/system/role_menu_button_permision/get_role_menu/", - "method": 0 + "method": 0, + "name_en": "Get All Assignable Menus", + "name_zh_tw": "獲取所有可授權選單" }, { "name": "获取所有已授权用户", "value": "role:AllAuthorizedUser", "api": "/api/system/role/get_role_users/", - "method": 0 + "method": 0, + "name_en": "Get Authorized Users", + "name_zh_tw": "獲取所有已授權用戶" }, { "name": "获取菜单所有可授权按钮", "value": "role:AllMenuButton", "api": "/api/system/role_menu_button_permision/get_role_menu_btn_field/", - "method": 0 + "method": 0, + "name_en": "Get All Assignable Buttons", + "name_zh_tw": "獲取選單所有可授權按鈕" }, { "name": "授权菜单", "value": "role:SetMenu", "api": "/api/system/role_menu_button_permision/set_role_menu/", - "method": 2 + "method": 2, + "name_en": "Assign Menu", + "name_zh_tw": "授權選單" }, { "name": "授权菜单按钮", "value": "role:SetMenuButton", "api": "/api/system/role_menu_button_permision/set_role_menu_btn/", - "method": 2 + "method": 2, + "name_en": "Assign Menu Buttons", + "name_zh_tw": "授權選單按鈕" }, { "name": "授权数据范围", "value": "role:SetDataRange", "api": "/api/system/role_menu_button_permision/set_role_menu_btn_data_range/", - "method": 2 + "method": 2, + "name_en": "Assign Data Range", + "name_zh_tw": "授權數據範圍" }, { "name": "获取所有用户", "value": "role:AllUser", "api": "/api/system/user/", - "method": 0 + "method": 0, + "name_en": "Get All Users", + "name_zh_tw": "獲取所有用戶" }, { "name": "授权用户予角色", "value": "role:SetUserRole", "api": "/api/system/role/{id}/set_role_users/", - "method": 2 + "method": 2, + "name_en": "Assign Users to Role", + "name_zh_tw": "授權用戶予角色" } ], "menu_field": [ @@ -516,7 +624,9 @@ "title": "修改时间", "model": "Role" } - ] + ], + "name_en": "Role Management", + "name_zh_tw": "角色管理" }, { "name": "消息中心", @@ -537,31 +647,41 @@ "name": "查询", "value": "messageCenter:Search", "api": "/api/system/message_center/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "messageCenter:Retrieve", "api": "/api/system/message_center/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "新增", "value": "messageCenter:Create", "api": "/api/system/message_center/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "messageCenter:Update", "api": "/api/system/message_center/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "messageCenter:Delete", "api": "/api/system/menu/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], "menu_field": [ @@ -615,7 +735,9 @@ "title": "修改时间", "model": "MessageCenter" } - ] + ], + "name_en": "Notification Center", + "name_zh_tw": "通知中心" }, { "name": "接口白名单", @@ -636,31 +758,41 @@ "name": "查询", "value": "api_white_list:Search", "api": "/api/system/api_white_list/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "api_white_list:Retrieve", "api": "/api/system/api_white_list/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "新增", "value": "api_white_list:Create", "api": "/api/system/api_white_list/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "api_white_list:Update", "api": "/api/system/api_white_list/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "api_white_list:Delete", "api": "/api/system/api_white_list/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], "menu_field": [ @@ -714,7 +846,9 @@ "title": "url", "model": "ApiWhiteList" } - ] + ], + "name_en": "API Whitelist", + "name_zh_tw": "接口白名單" }, { "name": "下载中心", @@ -734,14 +868,20 @@ { "name": "查询", "value": "downloadCenter:Search", - "api": "/api/system/download_center/" + "api": "/api/system/download_center/", + "name_en": "Search", + "name_zh_tw": "查詢" } ], - "menu_field": [] + "menu_field": [], + "name_en": "Download Center", + "name_zh_tw": "下載中心" } ], "menu_button": [], - "menu_field": [] + "menu_field": [], + "name_en": "System Management", + "name_zh_tw": "系統設置" }, { "name": "常规配置", @@ -776,34 +916,46 @@ "name": "查询", "value": "system_config:Search", "api": "/api/system/system_config/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "system_config:Retrieve", "api": "/api/system/system_config/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "新增", "value": "system_config:Create", "api": "/api/system/system_config/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "system_config:Update", "api": "/api/system/system_config/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "system_config:Delete", "api": "/api/system/system_config/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], - "menu_field": [] + "menu_field": [], + "name_en": "System Config", + "name_zh_tw": "系統配置" }, { "name": "字典管理", @@ -824,31 +976,41 @@ "name": "查询", "value": "dictionary:Search", "api": "/api/system/dictionary/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "dictionary:Retrieve", "api": "/api/system/dictionary/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "新增", "value": "dictionary:Create", "api": "/api/system/dictionary/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "dictionary:Update", "api": "/api/system/dictionary/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "dictionary:Delete", "api": "/api/system/dictionary/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], "menu_field": [ @@ -932,7 +1094,9 @@ "title": "字典编号", "model": "Dictionary" } - ] + ], + "name_en": "Dictionary Management", + "name_zh_tw": "字典管理" }, { "name": "地区管理", @@ -953,31 +1117,41 @@ "name": "查询", "value": "area:Search", "api": "/api/system/area/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "area:Retrieve", "api": "/api/system/area/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "新增", "value": "area:Create", "api": "/api/system/area/", - "method": 1 + "method": 1, + "name_en": "Add", + "name_zh_tw": "新增" }, { "name": "编辑", "value": "area:Update", "api": "/api/system/area/{id}/", - "method": 2 + "method": 2, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "area:Delete", "api": "/api/system/area/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], "menu_field": [ @@ -1051,7 +1225,9 @@ "title": "修改时间", "model": "Area" } - ] + ], + "name_en": "Area Management", + "name_zh_tw": "地區管理" }, { "name": "附件管理", @@ -1072,25 +1248,33 @@ "name": "详情", "value": "file:Retrieve", "api": "/api/system/file/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "查询", "value": "file:Search", "api": "/api/system/file/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "编辑", "value": "file:Update", "api": "/api/system/file/{id}/", - "method": 1 + "method": 1, + "name_en": "Edit", + "name_zh_tw": "編輯" }, { "name": "删除", "value": "file:Delete", "api": "/api/system/file/{id}/", - "method": 3 + "method": 3, + "name_en": "Delete", + "name_zh_tw": "刪除" } ], "menu_field": [ @@ -1164,11 +1348,15 @@ "title": "url", "model": "FileList" } - ] + ], + "name_en": "File Management", + "name_zh_tw": "附件管理" } ], "menu_button": [], - "menu_field": [] + "menu_field": [], + "name_en": "General Config", + "name_zh_tw": "常規配置" }, { "name": "日志管理", @@ -1203,13 +1391,17 @@ "name": "查询", "value": "login_log:Search", "api": "/api/system/login_log/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" }, { "name": "详情", "value": "login_log:Retrieve", "api": "/api/system/login_log/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" } ], "menu_field": [ @@ -1333,7 +1525,9 @@ "title": "登录用户名", "model": "LoginLog" } - ] + ], + "name_en": "Login Logs", + "name_zh_tw": "登錄日誌" }, { "name": "操作日志", @@ -1354,13 +1548,17 @@ "name": "详情", "value": "operation_log:Retrieve", "api": "/api/system/operation_log/{id}/", - "method": 0 + "method": 0, + "name_en": "Detail", + "name_zh_tw": "詳情" }, { "name": "查询", "value": "operation_log:Search", "api": "/api/system/operation_log/", - "method": 0 + "method": 0, + "name_en": "Search", + "name_zh_tw": "查詢" } ], "menu_field": [ @@ -1454,10 +1652,59 @@ "title": "修改时间", "model": "OperationLog" } - ] + ], + "name_en": "Operation Logs", + "name_zh_tw": "操作日誌" } ], "menu_button": [], - "menu_field": [] + "menu_field": [], + "name_en": "Log Management", + "name_zh_tw": "日誌管理" + }, + { + "name": "定时任务", + "web_path": "/celeryManage", + "icon": "iconfont icon-", + "sort": 99, + "is_link": false, + "is_catalog": true, + "status": true, + "cache": false, + "visible": true, + "children": [ + { + "name": "任务管理", + "web_path": "/taskManage", + "component": "celery/task/index", + "icon": "iconfont icon-", + "sort": 1, + "is_link": false, + "is_catalog": false, + "status": true, + "cache": false, + "visible": true, + "children": [], + "name_en": "Task Management", + "name_zh_tw": "任務管理" + }, + { + "name": "任务日志", + "web_path": "/taskLog", + "component": "celery/taskLog/index", + "icon": "iconfont icon-", + "sort": 2, + "is_link": false, + "is_catalog": false, + "status": true, + "cache": false, + "visible": true, + "children": [], + "name_en": "Task Logs", + "name_zh_tw": "任務日誌" + } + ], + "name_en": "Scheduled Tasks", + "name_zh_tw": "定時任務" } ] \ No newline at end of file diff --git a/backend/dvadmin/system/management/commands/sync_menu_i18n.py b/backend/dvadmin/system/management/commands/sync_menu_i18n.py new file mode 100644 index 0000000..6778fe6 --- /dev/null +++ b/backend/dvadmin/system/management/commands/sync_menu_i18n.py @@ -0,0 +1,95 @@ +# -*- coding: utf-8 -*- +""" +同步菜单多语言数据 +用法: python manage.py sync_menu_i18n +""" +import os +import json + +from django.core.management.base import BaseCommand + +from dvadmin.system.models import Menu, MenuButton + + +class Command(BaseCommand): + help = '同步菜单多语言数据从init_menu.json' + + def add_arguments(self, parser): + parser.add_argument( + '--reset', + action='store_true', + help='重置所有现有菜单的i18n字段为空后再同步', + ) + + def handle(self, *args, **options): + reset = options.get('reset', False) + + # 获取init_menu.json路径 + # sync_menu_i18n.py -> commands(1) -> management(2) -> system(3) -> dvadmin(4) -> backend(5) + backend_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))) + json_path = os.path.join(backend_dir, 'dvadmin', 'system', 'fixtures', 'init_menu.json') + + if not os.path.exists(json_path): + self.stderr.write(f'文件不存在: {json_path}') + return + + with open(json_path, 'r', encoding='utf-8') as f: + menu_data = json.load(f) + + menu_count = 0 + button_count = 0 + + def process_menus(menus, parent_id=None): + nonlocal menu_count, button_count + + for menu in menus: + name_en = menu.get('name_en', '') + name_zh_tw = menu.get('name_zh_tw', '') + + # 更新菜单 + filter_data = { + 'name': menu['name'], + 'web_path': menu.get('web_path', ''), + 'component': menu.get('component', ''), + 'component_name': menu.get('component_name', ''), + } + + db_menu = Menu.objects.filter(**filter_data).first() + if db_menu: + if reset or not db_menu.name_en: + db_menu.name_en = name_en + if reset or not db_menu.name_zh_tw: + db_menu.name_zh_tw = name_zh_tw + db_menu.save(update_fields=['name_en', 'name_zh_tw']) + menu_count += 1 + self.stdout.write(f" 更新菜单: {menu['name']} -> en: {name_en}, zh_tw: {name_zh_tw}") + + # 处理菜单按钮 + for btn in menu.get('menu_button', []): + btn_name_en = btn.get('name_en', '') + btn_name_zh_tw = btn.get('name_zh_tw', '') + + if db_menu: + db_btn = MenuButton.objects.filter(menu=db_menu, value=btn.get('value', '')).first() + if db_btn: + if reset or not db_btn.name_en: + db_btn.name_en = btn_name_en + if reset or not db_btn.name_zh_tw: + db_btn.name_zh_tw = btn_name_zh_tw + db_btn.save(update_fields=['name_en', 'name_zh_tw']) + button_count += 1 + self.stdout.write(f" 更新按钮: {btn['name']} -> en: {btn_name_en}, zh_tw: {btn_name_zh_tw}") + + # 递归处理子菜单 + if menu.get('children'): + process_menus(menu['children'], menu.get('id')) + + self.stdout.write('开始同步菜单多语言数据...\n') + + for top_menu in menu_data: + self.stdout.write(f"\n处理顶级菜单: {top_menu['name']}") + process_menus([top_menu]) + + self.stdout.write(self.style.SUCCESS(f'\n同步完成!')) + self.stdout.write(f' 更新菜单数: {menu_count}') + self.stdout.write(f' 更新按钮数: {button_count}') diff --git a/backend/dvadmin/system/migrations/0002_menu_name_en_menu_name_zh_tw_menubutton_name_en_and_more.py b/backend/dvadmin/system/migrations/0002_menu_name_en_menu_name_zh_tw_menubutton_name_en_and_more.py new file mode 100644 index 0000000..1b12516 --- /dev/null +++ b/backend/dvadmin/system/migrations/0002_menu_name_en_menu_name_zh_tw_menubutton_name_en_and_more.py @@ -0,0 +1,43 @@ +# Generated by Django 4.2.14 on 2026-04-08 17:19 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0001_initial'), + ] + + operations = [ + migrations.AddField( + model_name='menu', + name='name_en', + field=models.CharField(blank=True, help_text='菜单名称(English)', max_length=64, null=True, verbose_name='菜单名称(English)'), + ), + migrations.AddField( + model_name='menu', + name='name_zh_tw', + field=models.CharField(blank=True, help_text='菜单名称(繁體中文)', max_length=64, null=True, verbose_name='菜单名称(繁體中文)'), + ), + migrations.AddField( + model_name='menubutton', + name='name_en', + field=models.CharField(blank=True, help_text='名称(English)', max_length=64, null=True, verbose_name='名称(English)'), + ), + migrations.AddField( + model_name='menubutton', + name='name_zh_tw', + field=models.CharField(blank=True, help_text='名称(繁體中文)', max_length=64, null=True, verbose_name='名称(繁體中文)'), + ), + migrations.AddField( + model_name='users', + name='language', + field=models.CharField(blank=True, default='zh-cn', help_text='界面语言', max_length=10, null=True, verbose_name='界面语言'), + ), + migrations.AlterField( + model_name='menu', + name='name', + field=models.CharField(help_text='菜单名称(默认语言)', max_length=64, verbose_name='菜单名称(默认)'), + ), + ] diff --git a/backend/dvadmin/system/migrations/0003_fill_menu_i18n_name.py b/backend/dvadmin/system/migrations/0003_fill_menu_i18n_name.py new file mode 100644 index 0000000..13ed4b8 --- /dev/null +++ b/backend/dvadmin/system/migrations/0003_fill_menu_i18n_name.py @@ -0,0 +1,67 @@ +# -*- coding: utf-8 -*- +""" +填充菜单名称多语言翻译 +用法: python manage.py migrate system 0003 +""" +from django.db import migrations + + +def fill_menu_i18n(apps, schema_editor): + Menu = apps.get_model('system', 'Menu') + + name_translations = { + '系统管理': {'en': 'System Management', 'zh_tw': '系統設置'}, + '用户管理': {'en': 'User Management', 'zh_tw': '用戶管理'}, + '菜单管理': {'en': 'Menu Management', 'zh_tw': '選單管理'}, + '部门管理': {'en': 'Department Management', 'zh_tw': '部門管理'}, + '角色管理': {'en': 'Role Management', 'zh_tw': '角色管理'}, + '消息中心': {'en': 'Notification Center', 'zh_tw': '通知中心'}, + '接口白名单': {'en': 'API Whitelist', 'zh_tw': '接口白名單'}, + '下载中心': {'en': 'Download Center', 'zh_tw': '下載中心'}, + '常规配置': {'en': 'General Config', 'zh_tw': '常規配置'}, + '系统配置': {'en': 'System Config', 'zh_tw': '系統配置'}, + '字典管理': {'en': 'Dictionary Management', 'zh_tw': '字典管理'}, + '地区管理': {'en': 'Area Management', 'zh_tw': '地區管理'}, + '附件管理': {'en': 'File Management', 'zh_tw': '附件管理'}, + '日志管理': {'en': 'Log Management', 'zh_tw': '日誌管理'}, + '登录日志': {'en': 'Login Logs', 'zh_tw': '登錄日誌'}, + '操作日志': {'en': 'Operation Logs', 'zh_tw': '操作日誌'}, + '定时任务': {'en': 'Scheduled Tasks', 'zh_tw': '定時任務'}, + '任务管理': {'en': 'Task Management', 'zh_tw': '任務管理'}, + '任务日志': {'en': 'Task Logs', 'zh_tw': '任務日誌'}, + '个人信息': {'en': 'Personal Info', 'zh_tw': '個人信息'}, + '个人中心': {'en': 'Personal Center', 'zh_tw': '個人中心'}, + '修改密码': {'en': 'Change Password', 'zh_tw': '修改密碼'}, + '首页': {'en': 'Dashboard', 'zh_tw': '首頁'}, + } + + updated_count = 0 + for menu in Menu.objects.all(): + if menu.name in name_translations: + trans = name_translations[menu.name] + update_fields = [] + if not menu.name_en: + menu.name_en = trans['en'] + update_fields.append('name_en') + if not menu.name_zh_tw: + menu.name_zh_tw = trans['zh_tw'] + update_fields.append('name_zh_tw') + if update_fields: + menu.save(update_fields=update_fields) + updated_count += 1 + print(f"Updated {updated_count} menu translations") + + +def reverse_func(apps, schema_editor): + pass + + +class Migration(migrations.Migration): + + dependencies = [ + ('system', '0002_menu_name_en_menu_name_zh_tw_menubutton_name_en_and_more'), + ] + + operations = [ + migrations.RunPython(fill_menu_i18n, reverse_func), + ] diff --git a/backend/dvadmin/system/models.py b/backend/dvadmin/system/models.py index 4dca9c9..da9a0a9 100644 --- a/backend/dvadmin/system/models.py +++ b/backend/dvadmin/system/models.py @@ -84,6 +84,14 @@ class Users(CoreModel, AbstractUser): ) login_error_count = models.IntegerField(default=0, verbose_name="登录错误次数", help_text="登录错误次数") pwd_change_count = models.IntegerField(default=0,blank=True, verbose_name="密码修改次数", help_text="密码修改次数") + language = models.CharField( + max_length=10, + default='zh-cn', + blank=True, + null=True, + verbose_name="界面语言", + help_text="界面语言" + ) objects = CustomUserManager() def set_password(self, raw_password): @@ -213,7 +221,9 @@ class Menu(CoreModel): help_text="上级菜单", ) icon = models.CharField(max_length=64, verbose_name="菜单图标", null=True, blank=True, help_text="菜单图标") - name = models.CharField(max_length=64, verbose_name="菜单名称", help_text="菜单名称") + name = models.CharField(max_length=64, verbose_name="菜单名称(默认)", help_text="菜单名称(默认语言)") + name_en = models.CharField(max_length=64, verbose_name="菜单名称(English)", blank=True, null=True, help_text="菜单名称(English)") + name_zh_tw = models.CharField(max_length=64, verbose_name="菜单名称(繁體中文)", blank=True, null=True, help_text="菜单名称(繁體中文)") sort = models.IntegerField(default=1, verbose_name="显示排序", null=True, blank=True, help_text="显示排序") ISLINK_CHOICES = ( (0, "否"), @@ -294,6 +304,8 @@ class MenuButton(CoreModel): help_text="关联菜单", ) name = models.CharField(max_length=64, verbose_name="名称", help_text="名称") + name_en = models.CharField(max_length=64, verbose_name="名称(English)", blank=True, null=True, help_text="名称(English)") + name_zh_tw = models.CharField(max_length=64, verbose_name="名称(繁體中文)", blank=True, null=True, help_text="名称(繁體中文)") value = models.CharField(unique=True, max_length=64, verbose_name="权限值", help_text="权限值") api = models.CharField(max_length=200, verbose_name="接口地址", help_text="接口地址") METHOD_CHOICES = ( diff --git a/backend/dvadmin/system/views/menu.py b/backend/dvadmin/system/views/menu.py index 33ed979..3ae4449 100644 --- a/backend/dvadmin/system/views/menu.py +++ b/backend/dvadmin/system/views/menu.py @@ -24,7 +24,7 @@ class MenuSerializer(CustomModelSerializer): hasChild = serializers.SerializerMethodField() def get_menuPermission(self, instance): - queryset = instance.menuPermission.order_by('-name').values('id', 'name', 'value') + queryset = instance.menuPermission.order_by('-name').values('id', 'name', 'name_en', 'name_zh_tw', 'value') # MenuButtonSerializer(instance.menuPermission.all(), many=True) if queryset: return queryset @@ -66,13 +66,36 @@ class WebRouterSerializer(CustomModelSerializer): 前端菜单路由的简单序列化器 """ path = serializers.CharField(source="web_path") - title = serializers.CharField(source="name") + title = serializers.SerializerMethodField() + + def get_title(self, obj): + lang = None + req = getattr(self, 'request', None) + if req: + user = getattr(req, 'user', None) + if user and getattr(user, 'is_authenticated', False): + lang = getattr(user, 'language', None) + # query_params.get() returns string (DRF QueryDict), or list if same param sent multiple times + _qp_lang = req.query_params.get('language', None) + if _qp_lang: + lang = _qp_lang[0] if isinstance(_qp_lang, list) else _qp_lang + if not lang: + meta_lang = req.META.get('HTTP_ACCEPT_LANGUAGE', '') + if meta_lang.startswith('en'): + lang = 'en' + elif 'zh-tw' in meta_lang or 'zh-hant' in meta_lang: + lang = 'zh-tw' + if lang == 'en': + return obj.name_en or obj.name + elif lang == 'zh-tw': + return obj.name_zh_tw or obj.name + return obj.name class Meta: model = Menu fields = ( 'id', 'parent', 'icon', 'sort', 'path', 'name', 'title', 'is_link','link_url', 'is_catalog', 'web_path', 'component', - 'component_name', 'cache', 'visible','is_iframe','is_affix', 'status') + 'component_name', 'cache', 'visible','is_iframe','is_affix', 'status', 'name_en', 'name_zh_tw') read_only_fields = ["id"] diff --git a/backend/dvadmin/system/views/menu_button.py b/backend/dvadmin/system/views/menu_button.py index c1ca7c9..1d917a1 100644 --- a/backend/dvadmin/system/views/menu_button.py +++ b/backend/dvadmin/system/views/menu_button.py @@ -25,7 +25,7 @@ class MenuButtonSerializer(CustomModelSerializer): class Meta: model = MenuButton - fields = ['id', 'name', 'value', 'api', 'method','menu'] + fields = ['id', 'name', 'name_en', 'name_zh_tw', 'value', 'api', 'method', 'menu'] read_only_fields = ["id"] @@ -94,14 +94,14 @@ class MenuButtonViewSet(CustomModelViewSet): """ menu_obj = Menu.objects.filter(id=request.data['menu']).first() result_list = [ - {'menu': menu_obj.id, 'name': '新增', 'value': f'{menu_obj.component_name}:Create', 'api': f'/api/{menu_obj.component_name}/', 'method': 1}, - {'menu': menu_obj.id, 'name': '删除', 'value': f'{menu_obj.component_name}:Delete', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 3}, - {'menu': menu_obj.id, 'name': '编辑', 'value': f'{menu_obj.component_name}:Update', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 2}, - {'menu': menu_obj.id, 'name': '查询', 'value': f'{menu_obj.component_name}:Search', 'api': f'/api/{menu_obj.component_name}/', 'method': 0}, - {'menu': menu_obj.id, 'name': '详情', 'value': f'{menu_obj.component_name}:Retrieve', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 0}, - {'menu': menu_obj.id, 'name': '复制', 'value': f'{menu_obj.component_name}:Copy', 'api': f'/api/{menu_obj.component_name}/', 'method': 1}, - {'menu': menu_obj.id, 'name': '导入', 'value': f'{menu_obj.component_name}:Import', 'api': f'/api/{menu_obj.component_name}/import_data/', 'method': 1}, - {'menu': menu_obj.id, 'name': '导出', 'value': f'{menu_obj.component_name}:Export', 'api': f'/api/{menu_obj.component_name}/export_data/', 'method': 1},] + {'menu': menu_obj.id, 'name': '新增', 'name_en': 'Add', 'name_zh_tw': '新增', 'value': f'{menu_obj.component_name}:Create', 'api': f'/api/{menu_obj.component_name}/', 'method': 1}, + {'menu': menu_obj.id, 'name': '删除', 'name_en': 'Delete', 'name_zh_tw': '刪除', 'value': f'{menu_obj.component_name}:Delete', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 3}, + {'menu': menu_obj.id, 'name': '编辑', 'name_en': 'Edit', 'name_zh_tw': '編輯', 'value': f'{menu_obj.component_name}:Update', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 2}, + {'menu': menu_obj.id, 'name': '查询', 'name_en': 'Search', 'name_zh_tw': '查詢', 'value': f'{menu_obj.component_name}:Search', 'api': f'/api/{menu_obj.component_name}/', 'method': 0}, + {'menu': menu_obj.id, 'name': '详情', 'name_en': 'Detail', 'name_zh_tw': '詳情', 'value': f'{menu_obj.component_name}:Retrieve', 'api': f'/api/{menu_obj.component_name}/{{id}}/', 'method': 0}, + {'menu': menu_obj.id, 'name': '复制', 'name_en': 'Copy', 'name_zh_tw': '複製', 'value': f'{menu_obj.component_name}:Copy', 'api': f'/api/{menu_obj.component_name}/', 'method': 1}, + {'menu': menu_obj.id, 'name': '导入', 'name_en': 'Import', 'name_zh_tw': '導入', 'value': f'{menu_obj.component_name}:Import', 'api': f'/api/{menu_obj.component_name}/import_data/', 'method': 1}, + {'menu': menu_obj.id, 'name': '导出', 'name_en': 'Export', 'name_zh_tw': '導出', 'value': f'{menu_obj.component_name}:Export', 'api': f'/api/{menu_obj.component_name}/export_data/', 'method': 1},] serializer = self.get_serializer(data=result_list, many=True) serializer.is_valid(raise_exception=True) serializer.save() diff --git a/backend/dvadmin/system/views/user.py b/backend/dvadmin/system/views/user.py index 89b6533..c2919da 100644 --- a/backend/dvadmin/system/views/user.py +++ b/backend/dvadmin/system/views/user.py @@ -10,6 +10,7 @@ from django.db.models import Q from application import dispatch from dvadmin.system.models import Users, Role, Dept from dvadmin.system.views.role import RoleSerializer +from django.utils import translation from dvadmin.utils.json_response import ErrorResponse, DetailResponse, SuccessResponse from dvadmin.utils.serializers import CustomModelSerializer from dvadmin.utils.validator import CustomUniqueValidator @@ -361,6 +362,18 @@ class UserViewSet(CustomModelViewSet): request.user.save() return DetailResponse(data=None, msg="修改成功") + @action(methods=["PUT"], detail=False, permission_classes=[IsAuthenticated]) + def update_language(self, request, *args, **kwargs): + """更新当前用户语言偏好""" + lang = request.data.get("language", "zh-cn") + valid_locales = ["zh-cn", "en", "zh-tw"] + if lang not in valid_locales: + return ErrorResponse(msg="Invalid language code") + user = request.user + user.language = lang + user.save(update_fields=["language", "modifier", "update_datetime"]) + return DetailResponse(data={"language": lang}, msg="Language updated successfully") + @action(methods=["PUT"], detail=True, permission_classes=[IsAuthenticated]) def reset_to_default_password(self, request,pk): """恢复默认密码""" diff --git a/backend/dvadmin/utils/middleware.py b/backend/dvadmin/utils/middleware.py index 1185060..4e729fe 100644 --- a/backend/dvadmin/utils/middleware.py +++ b/backend/dvadmin/utils/middleware.py @@ -8,6 +8,8 @@ from django.conf import settings from django.contrib.auth.models import AnonymousUser from django.core.exceptions import MultipleObjectsReturned from django.http import HttpResponse, HttpResponseServerError +from django.utils import translation +from django.utils.translation.trans_real import parse_accept_lang_header from django.utils.deprecation import MiddlewareMixin from dvadmin.system.models import OperationLog @@ -166,3 +168,54 @@ class HealthCheckMiddleware(object): return HttpResponseServerError("cache: cannot connect to cache.") return HttpResponse("OK") + + +class LocaleMiddleware: + """Set request locale from Accept-Language header (D-03: header always wins).""" + + # Map frontend locale codes to Django locale codes (D-07 fallback order) + LOCALE_MAP = { + 'en': 'en', + 'zh-cn': 'zh-hans', + 'zh-tw': 'zh-hant', + } + + def __init__(self, get_response): + self.get_response = get_response + + def __call__(self, request): + lang_code = None + + # 1. Accept-Language header always wins (D-03) + accept_lang = request.META.get('HTTP_ACCEPT_LANGUAGE', '') + if accept_lang: + try: + for code, _priority in parse_accept_lang_header(accept_lang): + if code == '*': + continue + # Normalize: 'zh-CN' -> 'zh-cn' + normalized = code.lower().replace('_', '-') + if normalized in self.LOCALE_MAP: + lang_code = self.LOCALE_MAP[normalized] + break + elif code in dict(settings.LANGUAGES): + lang_code = code + break + except Exception: + pass + + # 2. Authenticated user DB preference as fallback (D-01: header wins) + if not lang_code and hasattr(request, 'user') and request.user.is_authenticated: + user_lang = getattr(request.user, 'language', None) or 'zh-cn' + lang_code = self.LOCALE_MAP.get(user_lang, user_lang) + + # 3. Default for unauthenticated/unknown (D-06: zh-CN default) + if not lang_code: + lang_code = 'zh-hans' + + translation.activate(lang_code) + request.LANGUAGE_CODE = lang_code + + response = self.get_response(request) + translation.deactivate() + return response diff --git a/backend/locale/en/LC_MESSAGES/django.po b/backend/locale/en/LC_MESSAGES/django.po new file mode 100644 index 0000000..373dfbf --- /dev/null +++ b/backend/locale/en/LC_MESSAGES/django.po @@ -0,0 +1,259 @@ +# English translations for Django. +# Copyright (C) 2026 +# This file is distributed under the same license as the Django project. +# +msgid "" +msgstr "" +"Project-Id-Version: django-vue3-admin\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-31 00:00+0000\n" +"PO-Revision-Date: 2026-03-31 00:00+0000\n" +"Last-Translator: \n" +"Language: en\n" +"Language-Team: English\n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: django-vue3-admin i18n phase 1\n" + +msgid "error" +msgstr "error" + +msgid "Endpoint address is incorrect" +msgstr "Endpoint address is incorrect" + +msgid "Delete failed: this record has related data bindings" +msgstr "Delete failed: this record has related data bindings" + +msgid "This account has been disabled. Contact an administrator to unlock it." +msgstr "This account has been disabled. Contact an administrator to unlock it." + +msgid "Date format is incorrect" +msgstr "Date format is incorrect" + +msgid "No." +msgstr "No." + +msgid "Import" +msgstr "Import" + +msgid "Template" +msgstr "Template" + +msgid "Export" +msgstr "Export" + +msgid "Update primary key (do not modify)" +msgstr "Update primary key (do not modify)" + +msgid "Please configure the corresponding export template fields." +msgstr "Please configure the corresponding export template fields." + +msgid "Please configure the corresponding import template fields." +msgstr "Please configure the corresponding import template fields." + +msgid "Please configure the corresponding import serializer." +msgstr "Please configure the corresponding import serializer." + +msgid "Please configure the corresponding export serializer." +msgstr "Please configure the corresponding export serializer." + +msgid "Import successful" +msgstr "Import successful" + +msgid "Data export task" +msgstr "Data export task" + +msgid "Import task has been created. Please go to 'Download Center' to wait for download" +msgstr "Import task has been created. Please go to 'Download Center' to wait for download" + +msgid "Create successful" +msgstr "Create successful" + +msgid "Query successful" +msgstr "Query successful" + +msgid "Update successful" +msgstr "Update successful" + +msgid "Delete successful" +msgstr "Delete successful" + +msgid "keys field not provided" +msgstr "keys field not provided" + +msgid "Verification code is required" +msgstr "Verification code is required" + +msgid "Verification code has expired" +msgstr "Verification code has expired" + +msgid "Image verification code is incorrect" +msgstr "Image verification code is incorrect" + +msgid "The account you are logging in with does not exist" +msgstr "The account you are logging in with does not exist" + +msgid "Multiple accounts found for this login. Contact an administrator to check account uniqueness" +msgstr "Multiple accounts found for this login. Contact an administrator to check account uniqueness" + +msgid "Account has been locked. Contact an administrator to unlock" +msgstr "Account has been locked. Contact an administrator to unlock" + +msgid "Username/password incorrect. Account will be locked after {} failed attempts~" +msgstr "Username/password incorrect. Account will be locked after {} failed attempts~" + +msgid "Request successful" +msgstr "Request successful" + +msgid "This interface is not yet available" +msgstr "This interface is not yet available" + +msgid "Logout successful" +msgstr "Logout successful" + +msgid "Username/password incorrect" +msgstr "Username/password incorrect" + +msgid "Username must be unique" +msgstr "Username must be unique" + +msgid "Mobile number must be unique" +msgstr "Mobile number must be unique" + +msgid "Enabled" +msgstr "Enabled" + +msgid "Disabled" +msgstr "Disabled" + +msgid "Username" +msgstr "Username" + +msgid "Full name" +msgstr "Full name" + +msgid "Email" +msgstr "Email" + +msgid "Mobile" +msgstr "Mobile" + +msgid "Gender" +msgstr "Gender" + +msgid "Account status" +msgstr "Account status" + +msgid "Last login time" +msgstr "Last login time" + +msgid "Department name" +msgstr "Department name" + +msgid "Department head" +msgstr "Department head" + +msgid "Login username" +msgstr "Login username" + +msgid "Department" +msgstr "Department" + +msgid "Role" +msgstr "Role" + +msgid "No department" +msgstr "No department" + +msgid "Parameters cannot be empty" +msgstr "Parameters cannot be empty" + +msgid "Passwords do not match" +msgstr "Passwords do not match" + +msgid "Old password is incorrect" +msgstr "Old password is incorrect" + +msgid "Invalid language code" +msgstr "Invalid language code" + +msgid "Language updated successfully" +msgstr "Language updated successfully" + +msgid "Only super administrators can reset passwords" +msgstr "Only super administrators can reset passwords" + +msgid "Password reset successful" +msgstr "Password reset successful" + +msgid "User not found" +msgstr "User not found" + +#: dvadmin/system/views/role.py +msgid "Permission key must be unique" +msgstr "Permission key must be unique" +#: dvadmin/system/views/role.py +msgid "Please select a role" +msgstr "Please select a role" +#: dvadmin/system/views/role.py +msgid "Please select a user" +msgstr "Please select a user" +#: dvadmin/system/views/role.py +msgid "Add successful" +msgstr "Add successful" +#: dvadmin/system/views/menu.py +msgid "Menu does not exist" +msgstr "Menu does not exist" +#: dvadmin/system/views/menu.py +msgid "Move up successful" +msgstr "Move up successful" +#: dvadmin/system/views/menu.py +msgid "Move down successful" +msgstr "Move down successful" +#: dvadmin/system/views/dept.py +msgid "Department does not exist" +msgstr "Department does not exist" +#: dvadmin/system/views/role_menu.py +msgid "Role parameter not provided" +msgstr "Role parameter not provided" +#: dvadmin/system/views/role_menu.py +msgid "Menu parameter not provided" +msgstr "Menu parameter not provided" +#: dvadmin/system/views/role_menu.py +msgid "Save successful" +msgstr "Save successful" +#: dvadmin/system/views/system_config.py +msgid "Variable name already exists" +msgstr "Variable name already exists" +#: dvadmin/system/views/system_config.py +msgid "Query error~" +msgstr "Query error~" +#: dvadmin/system/views/system_config.py +msgid "Association information not found" +msgstr "Association information not found" +#: dvadmin/system/views/menu_button.py +msgid "Batch creation successful" +msgstr "Batch creation successful" +#: dvadmin/system/views/menu_button.py +msgid "Add" +msgstr "Add" +#: dvadmin/system/views/menu_button.py +msgid "Edit" +msgstr "Edit" +#: dvadmin/system/views/menu_field.py +msgid "Model table does not exist" +msgstr "Model table does not exist" +#: dvadmin/system/views/menu_field.py +msgid "Field permission for '%s' already exists and cannot be duplicated" +msgstr "Field permission for '%s' already exists and cannot be duplicated" +#: dvadmin/system/views/menu_field.py +msgid "Match successful" +msgstr "Match successful" +#: dvadmin/system/views/message_center.py +msgid "You have a new message~" +msgstr "You have a new message~" +#: dvadmin/system/views/message_center.py +msgid "You viewed a message~" +msgstr "You viewed a message~" diff --git a/backend/locale/zh_Hans/LC_MESSAGES/django.po b/backend/locale/zh_Hans/LC_MESSAGES/django.po new file mode 100644 index 0000000..e9aaae8 --- /dev/null +++ b/backend/locale/zh_Hans/LC_MESSAGES/django.po @@ -0,0 +1,267 @@ +# Simplified Chinese translations for Django. +# Copyright (C) 2026 +# This file is distributed under the same license as the Django project. +# +msgid "" +msgstr "" +"Project-Id-Version: django-vue3-admin\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2026-03-31 00:00+0000\n" +"PO-Revision-Date: 2026-03-31 00:00+0000\n" +"Last-Translator: \n" +"Language: zh_Hans\n" +"Language-Team: \n" +"Plural-Forms: nplurals=1; plural=0;\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Generated-By: django-vue3-admin i18n phase 1\n" + +#: dvadmin/utils/json_response.py +msgid "error" +msgstr "错误" + +#: dvadmin/utils/exception.py +msgid "Endpoint address is incorrect" +msgstr "接口地址不正确" + +msgid "Delete failed: this record has related data bindings" +msgstr "删除失败:该条数据与其他数据有相关绑定" + +#: dvadmin/utils/backends.py +msgid "This account has been disabled. Contact an administrator to unlock it." +msgstr "当前用户已被禁用,请联系管理员!" + +#: dvadmin/utils/import_export.py +msgid "Date format is incorrect" +msgstr "日期格式不正确" + +#: dvadmin/utils/import_export_mixin.py +msgid "No." +msgstr "序号" + +msgid "Import" +msgstr "导入" + +msgid "Template" +msgstr "模板" + +msgid "Export" +msgstr "导出" + +msgid "Update primary key (do not modify)" +msgstr "更新主键(勿改)" + +msgid "Please configure the corresponding export template fields." +msgstr "请配置对应的导出模板字段。" + +msgid "Please configure the corresponding import template fields." +msgstr "请配置对应的导入模板字段。" + +msgid "Please configure the corresponding import serializer." +msgstr "请配置对应的导入序列化器。" + +msgid "Please configure the corresponding export serializer." +msgstr "请配置对应的导出序列化器。" + +msgid "Import successful" +msgstr "导入成功" + +msgid "Data export task" +msgstr "数据导出任务" + +msgid "Import task has been created. Please go to 'Download Center' to wait for download" +msgstr "导入任务已创建,请前往'下载中心'等待下载" + +#: dvadmin/utils/viewset.py +msgid "Create successful" +msgstr "新增成功" + +msgid "Query successful" +msgstr "获取成功" + +msgid "Update successful" +msgstr "更新成功" + +msgid "Delete successful" +msgstr "删除成功" + +msgid "keys field not provided" +msgstr "未获取到keys字段" + +#: dvadmin/system/views/login.py +msgid "Verification code is required" +msgstr "验证码不能为空" + +msgid "Verification code has expired" +msgstr "验证码已过期" + +msgid "Image verification code is incorrect" +msgstr "图片验证码错误" + +msgid "The account you are logging in with does not exist" +msgstr "您登录的账号不存在" + +msgid "Multiple accounts found for this login. Contact an administrator to check account uniqueness" +msgstr "您登录的账号存在多个,请联系管理员检查登录账号唯一性" + +msgid "Account has been locked. Contact an administrator to unlock" +msgstr "账号已被锁定,联系管理员解锁" + +msgid "Username/password incorrect. Account will be locked after {} failed attempts~" +msgstr "账号/密码错误;重试{}次后将被锁定~" + +msgid "Request successful" +msgstr "请求成功" + +msgid "This interface is not yet available" +msgstr "该接口暂未开通!" + +msgid "Logout successful" +msgstr "注销成功" + +msgid "Username/password incorrect" +msgstr "账号/密码错误" + +#: dvadmin/system/views/user.py +msgid "Username must be unique" +msgstr "账号必须唯一" + +msgid "Mobile number must be unique" +msgstr "手机号必须唯一" + +msgid "Enabled" +msgstr "启用" + +msgid "Disabled" +msgstr "停用" + +msgid "Username" +msgstr "用户账号" + +msgid "Full name" +msgstr "用户名称" + +msgid "Email" +msgstr "用户邮箱" + +msgid "Mobile" +msgstr "手机号码" + +msgid "Gender" +msgstr "用户性别" + +msgid "Account status" +msgstr "帐号状态" + +msgid "Last login time" +msgstr "最后登录时间" + +msgid "Department name" +msgstr "部门名称" + +msgid "Department head" +msgstr "部门负责人" + +msgid "Login username" +msgstr "登录账号" + +msgid "Department" +msgstr "部门" + +msgid "Role" +msgstr "角色" + +msgid "No department" +msgstr "暂无部门" + +msgid "Parameters cannot be empty" +msgstr "参数不能为空" + +msgid "Passwords do not match" +msgstr "两次密码不匹配" + +msgid "Old password is incorrect" +msgstr "旧密码不正确" + +msgid "Invalid language code" +msgstr "无效的语言代码" + +msgid "Language updated successfully" +msgstr "语言更新成功" + +msgid "Only super administrators can reset passwords" +msgstr "只允许超级管理员对其进行密码重置" + +msgid "Password reset successful" +msgstr "密码重置成功" + +msgid "User not found" +msgstr "未获取到用户" + +#: dvadmin/system/views/role.py +msgid "Permission key must be unique" +msgstr "权限字符必须唯一" +#: dvadmin/system/views/role.py +msgid "Please select a role" +msgstr "请选择角色" +#: dvadmin/system/views/role.py +msgid "Please select a user" +msgstr "请选择用户" +#: dvadmin/system/views/role.py +msgid "Add successful" +msgstr "添加成功" +#: dvadmin/system/views/menu.py +msgid "Menu does not exist" +msgstr "菜单不存在" +#: dvadmin/system/views/menu.py +msgid "Move up successful" +msgstr "上移成功" +#: dvadmin/system/views/menu.py +msgid "Move down successful" +msgstr "下移成功" +#: dvadmin/system/views/dept.py +msgid "Department does not exist" +msgstr "部门不存在" +#: dvadmin/system/views/role_menu.py +msgid "Role parameter not provided" +msgstr "未获取到角色参数" +#: dvadmin/system/views/role_menu.py +msgid "Menu parameter not provided" +msgstr "未获取到菜单参数" +#: dvadmin/system/views/role_menu.py +msgid "Save successful" +msgstr "保存成功" +#: dvadmin/system/views/system_config.py +msgid "Variable name already exists" +msgstr "已存在相同变量名" +#: dvadmin/system/views/system_config.py +msgid "Query error~" +msgstr "查询出错了~" +#: dvadmin/system/views/system_config.py +msgid "Association information not found" +msgstr "未获取到关联信息" +#: dvadmin/system/views/menu_button.py +msgid "Batch creation successful" +msgstr "批量创建成功" +#: dvadmin/system/views/menu_button.py +msgid "Add" +msgstr "新增" +#: dvadmin/system/views/menu_button.py +msgid "Edit" +msgstr "编辑" +#: dvadmin/system/views/menu_field.py +msgid "Model table does not exist" +msgstr "模型表不存在" +#: dvadmin/system/views/menu_field.py +msgid "Field permission for '%s' already exists and cannot be duplicated" +msgstr "'%s' 字段权限已有,不可重复创建" +#: dvadmin/system/views/menu_field.py +msgid "Match successful" +msgstr "匹配成功" +#: dvadmin/system/views/message_center.py +msgid "You have a new message~" +msgstr "您有一条新消息~" +#: dvadmin/system/views/message_center.py +msgid "You viewed a message~" +msgstr "您查看了一条消息~" diff --git a/web/src/i18n/fs/zh-tw.ts b/web/src/i18n/fs/zh-tw.ts new file mode 100644 index 0000000..e71eb19 --- /dev/null +++ b/web/src/i18n/fs/zh-tw.ts @@ -0,0 +1,115 @@ +// Fast-crud zh-tw locale (traditional Chinese) +export default { + name: "zh-tw", + fs: { + component: { + select: { + placeholder: "請選擇" + } + }, + addForm: { title: "新增" }, + editForm: { title: "編輯" }, + viewForm: { title: "查看" }, + rowHandle: { + title: "操作", + remove: { + text: "刪除", + confirmTitle: "刪除提示", + confirmMessage: "您確定要刪除該記錄嗎?", + success: "刪除成功!", + confirmText: "確定", + cancelText: "取消" + }, + copy: { + text: "複製" + }, + edit: { + text: "編輯" + }, + view: { + text: "查看" + } + }, + form: { + cancel: "取消", + ok: "確定", + reset: "重設", + saveRemind: { + title: "提示", + content: "表單數據有變更,是否保存", + cancel: "不保存", + ok: "保存" + }, + copy: "複製", + paste: "貼上", + copySuccess: "表單數據已複製,您可以在新增對話框中貼上" + }, + actionbar: { add: "新增" }, + toolbar: { + columnFilter: { + title: "欄位設定", + fixed: "固定", + order: "排序", + reset: "還原", + confirm: "確定", + unnamed: "未命名" + }, + search: { title: "查詢顯示" }, + refresh: { title: "重新整理" }, + compact: { title: "緊湊模式" }, + export: { title: "導出" }, + columns: { title: "欄位設定" } + }, + search: { + container: { + collapseButton: { + text: { + collapse: "收起", + expand: "展開" + } + } + }, + search: { text: "查詢" }, + reset: { text: "重設" }, + error: { + message: "查詢表單校驗失敗" + } + }, + pagination: { + showTotal: "共 {0} 條" + }, + date: { + formatter: { to: "至" } + }, + extends: { + tableSelect: { + view: "查看", + select: "選擇", + ok: "確定", + cancel: "取消" + }, + cropper: { + title: "圖片裁剪", + preview: "預覽", + reChoose: "重新選擇", + flipX: "左右翻轉", + flipY: "上下翻轉", + reset: "重設", + cancel: "取消", + confirm: "確定", + chooseImage: "+ 選擇圖片", + onlySupport: "僅支援", + sizeLimit: "大小不能超過", + sizeNoLimit: "大小不限制" + }, + fileUploader: { + text: "文件上傳", + limitTip: "文件數量不能超過 {0}", + sizeLimitTip: "文件大小不能超過 {0},當前大小:{1}", + loadError: "圖片載入失敗", + pixelLimitTip: "圖片像素尺寸不能超過 寬:{0},高:{1}", + hasUploading: "還有文件正在上傳,請等待上傳完成,或刪除它" + } + } + } +} as any; diff --git a/web/src/i18n/index.ts b/web/src/i18n/index.ts index cd0f987..01b1e91 100644 --- a/web/src/i18n/index.ts +++ b/web/src/i18n/index.ts @@ -3,50 +3,74 @@ import pinia from '/@/stores/index'; import { storeToRefs } from 'pinia'; import { useThemeConfig } from '/@/stores/themeConfig'; -// 定义语言国际化内容 - -/** - * 说明: - * 须在 pages 下新建文件夹(建议 `要国际化界面目录` 与 `i18n 目录` 相同,方便查找), - * 注意国际化定义的字段,不要与原有的定义字段相同。 - * 1、/src/i18n/lang 下的 ts 为框架的国际化内容 - * 2、/src/i18n/pages 下的 ts 为各界面的国际化内容 - */ - // element plus 自带国际化 import enLocale from 'element-plus/es/locale/lang/en'; import zhcnLocale from 'element-plus/es/locale/lang/zh-cn'; import zhtwLocale from 'element-plus/es/locale/lang/zh-tw'; +// fast-crud 国际化 +import enFsLocale from '@fast-crud/fast-crud/dist/locale/lang/en'; +import zhcnFsLocale from '@fast-crud/fast-crud/dist/locale/lang/zh-cn'; +import zhcnFsTwLocale from './fs/zh-tw'; + // 定义变量内容 const messages = {}; const element = { en: enLocale, 'zh-cn': zhcnLocale, 'zh-tw': zhtwLocale }; -const itemize = { en: [], 'zh-cn': [], 'zh-tw': [] }; +const itemize: Record = { en: [], 'zh-cn': [], 'zh-tw': [] }; const modules: Record = import.meta.glob('./**/*.ts', { eager: true }); // 对自动引入的 modules 进行分类 en、zh-cn、zh-tw -// https://vitejs.cn/vite3-cn/guide/features.html#glob-import +// glob 返回路径如: ./pages/login/zh-cn.ts +// 提取语言代码: 按 / 分割,取最后一段去掉 .ts for (const path in modules) { - const key = path.match(/(\S+)\/(\S+).ts/); - if (itemize[key![2]]) itemize[key![2]].push(modules[path].default); - else itemize[key![2]] = modules[path]; + const withoutExt = path.replace(/^\.\//, '').replace(/\.ts$/, ''); + const segs = withoutExt.split('/'); + const lang = segs[segs.length - 1]; + if (itemize[lang]) { + itemize[lang].push(modules[path].default); + } } -// 合并数组对象(非标准数组对象,数组中对象的每项 key、value 都不同) -function mergeArrObj(list: T, key: string) { - let obj = {}; - list[key].forEach((i: EmptyObjectType) => { - obj = Object.assign({}, obj, i); +// 合并数组对象(深度合并 — 深层 key 冲突时后一个文件的 value 覆盖前一个的 value) +function isObject(val: unknown): val is Record { + return val !== null && typeof val === 'object' && !Array.isArray(val); +} + +function deepMerge(target: Record, ...sources: Record[]): Record { + for (const source of sources) { + for (const key in source) { + if (isObject(target[key]) && isObject(source[key])) { + deepMerge(target[key], source[key]); + } else { + target[key] = source[key]; + } + } + } + return target; +} + +function mergeArrObj(list: any[], key: string) { + let obj: Record = {}; + list[key].forEach((i: Record) => { + deepMerge(obj, i); }); return obj; } -// 处理最终格式 +// fast-crud 原始语言标识 -> 项目语言标识映射 +const fsLocaleMap: Record = { + 'zh-cn': zhcnFsLocale, + 'en': enFsLocale, + 'zh-tw': zhcnFsTwLocale, +}; + for (const key in itemize) { messages[key] = { name: key, el: element[key].el, - message: mergeArrObj(itemize, key), + ...mergeArrObj(itemize, key), + // fast-crud 内部组件的国际化(search/reset 按钮、操作列、列设置等) + ...fsLocaleMap[key], }; } @@ -55,14 +79,13 @@ const stores = useThemeConfig(pinia); const { themeConfig } = storeToRefs(stores); // 导出语言国际化 -// https://vue-i18n.intlify.dev/guide/essentials/fallback.html#explicit-fallback-with-one-locale export const i18n = createI18n({ legacy: false, - silentTranslationWarn: true, - missingWarn: false, - silentFallbackWarn: true, + silentTranslationWarn: false, + missingWarn: true, + silentFallbackWarn: false, fallbackWarn: false, locale: themeConfig.value.globalI18n, - fallbackLocale: zhcnLocale.name, + fallbackLocale: ['zh-CN', 'en', 'zh-TW'], messages, }); diff --git a/web/src/i18n/lang/en.ts b/web/src/i18n/lang/en.ts index 01467c9..6aff4e5 100644 --- a/web/src/i18n/lang/en.ts +++ b/web/src/i18n/lang/en.ts @@ -1,34 +1,324 @@ // Define content export default { - router: { - home: 'Home', - system: 'System MGT', - config: 'General MGT', - log: 'Log MGT', - /* General Configuration */ - configSystem: 'SystemGMT', - configDict: 'DictGMT', - configArea: 'AreaGMT', - configFile: 'AttachmentGMT', - /* System Management */ - systemMenu: 'MenuGMT', - systemRole: 'RoleGMT', - systemUser: 'UserGMT', - systemDept: 'DeptMGT', - systemNotice: 'Notice Center', - systemNotice1: 'MSG-MGT', - /* Log Management */ - loginLog: 'Login Log', - operationLog: 'Operation Log', - systemApiWhiteList: 'API Whitelist', - limits: 'Permission Management', - limitsFrontEnd: 'Frontend Control', - limitsFrontEndPage: 'Page Permissions', - limitsFrontEndBtn: 'Button Permissions', - limitsBackEnd: 'Backend Control', - limitsBackEndEndPage: 'Page Permissions', - personal: 'Personal Center', - dashboard: 'Dashboard', + message: { + home: { + more: 'More', + welcomeInfo: 'Welcome back, ', + welcomeInfo1: ' This is your workspace, please work happily!', + quickNavigationTool: 'Quick Navigation Tools', + }, + footer: { + copyright: ' ❤️ Powered by tiantianxiangshang Copyright © DVAdmin Team ❤️', + }, + router: { + home: 'Home', + system: 'System MGT', + config: 'General MGT', + log: 'Log MGT', + configSystem: 'System Config', + configDict: 'Dictionary', + configArea: 'Area', + configFile: 'Attachments', + systemMenu: 'Menu Management', + systemRole: 'Role Management', + systemUser: 'User Management', + systemDept: 'Department Management', + systemNotice: 'Notification Center', + systemNotice1: 'Notification Center', + loginLog: 'Login Log', + operationLog: 'Operation Log', + systemApiWhiteList: 'API Whitelist', + limits: 'Permission Management', + limitsFrontEnd: 'Frontend Control', + limitsFrontEndPage: 'Page Permissions', + limitsFrontEndBtn: 'Button Permissions', + limitsBackEnd: 'Backend Control', + limitsBackEndEndPage: 'Page Permissions', + personal: 'Personal Center', + }, + notFound: { + foundTitle: 'Address input error, please re-enter the address~', + foundMsg: 'You can check the URL first, then re-enter or give us feedback.', + foundBtn: 'Back to Home', + }, + noAccess: { + accessTitle: 'You are not authorized, no operation permission~', + accessMsg: 'Please contact administrator', + accessBtn: 'Re-authorize', + }, + tagsView: { + refresh: 'Refresh', + close: 'Close Current', + closeOther: 'Close Other', + closeAll: 'Close All', + fullscreen: 'Fullscreen', + }, + user: { + newTitle: 'Message Center', + newDesc: 'No new messages', + title0: 'Switch Component Size', + title1: 'Switch Language', + title2: 'Search', + title3: 'Layout Settings', + title4: 'Message Center', + title5: 'Fullscreen', + title6: 'Exit Fullscreen', + dropdown1: 'Home', + dropdown2: 'Personal Center', + versionLog: 'Version Upgrade Log', + dropdownLarge: 'Large', + dropdownDefault: 'Default', + dropdownSmall: 'Small', + langZhCn: '简体中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: 'Log Out', + fullscreenNotSupported: 'Your browser does not support fullscreen!', + logOutTitle: 'Notice', + logOutMessage: 'You are about to log out. Continue?', + logOutConfirm: 'Confirm', + logOutCancel: 'Cancel', + logOutExit: 'Exiting...', + retry: 'Retry', + onlinePrompt: 'Reconnecting to server...', + defaultUsername: 'User', + }, + common: { + logoutPrompt: 'You have been logged out, please log in again', + prompt: 'Prompt', + networkTimeout: 'Network timeout', + networkError: 'Network connection error', + endpointNotFound: 'Endpoint not found', + authFailed: 'Authentication failed, please log in again', + requestError: 'Request error', + authExpired: 'Login authorization expired, please log in again', + accessDenied: 'Access denied', + requestAddressError: 'Request address error: {url}', + requestTimeout: 'Request timeout', + serverError: 'Internal server error', + serviceNotImplemented: 'Service not implemented', + gatewayError: 'Gateway error', + serviceUnavailable: 'Service unavailable', + gatewayTimeout: 'Gateway timeout', + httpVersionNotSupported: 'HTTP version not supported', + importTaskCreated: 'Import task created, please go to "Download Center" to wait for download', + defaultExportFilename: 'Export File', + logoutSuccess: 'Logged out successfully', + formValidationFailed: 'Form validation failed, please check', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + deleteConfirm: 'Are you sure you want to delete?', + weekday: { + sunday: 'Sun', + monday: 'Mon', + tuesday: 'Tue', + wednesday: 'Wed', + thursday: 'Thu', + friday: 'Fri', + saturday: 'Sat', + }, + quarter: { + first: 'I', + second: 'II', + third: 'III', + fourth: 'IV', + }, + weekdayLongPrefix: 'Day', + weekdayShortPrefix: '', + quarterLongPrefix: '', + quarterSuffix: '', + weekPrefix: 'Week', + weekSuffix: '', + greeting: { + dawn: 'Good dawn', + morning: 'Good morning', + lateMorning: 'Good late morning', + noon: 'Good noon', + afternoon: 'Good afternoon', + evening: 'Good evening', + night: 'Good evening', + lateNight: 'Good night', + }, + time: { + justNow: 'Just now', + secondsAgo: '{n}s ago', + minutesAgo: '{n}m ago', + hoursAgo: '{n}h ago', + daysAgo: '{n}d ago', + }, + }, + components: { + table: { + serialNo: 'No.', + operation: 'Operation', + deleteConfirm: 'Are you sure you want to delete?', + delete: 'Delete', + noData: 'No Data', + export: 'Export', + refresh: 'Refresh', + setting: 'Setting', + columnDisplay: 'Column Display', + dragSort: 'Drag to reorder', + selectExportData: 'Please select data to export first', + multiSelect: 'Multi-select', + }, + calendar: { + selected: 'Selected:', + clear: 'Clear', + today: 'Today:', + holidaySettings: 'Holiday Settings', + showHoliday: 'Show Holidays', + closeHoliday: 'Hide Holidays', + lunarHoliday: 'Lunar Holidays', + solarTerm: 'Solar Terms', + moreHoliday: 'More Holidays', + prevYear: 'Prev Year', + nextYear: 'Next Year', + prevMonth: 'Prev Month', + nextMonth: 'Next Month', + todayBtn: 'Today', + todayCell: 'Today', + }, + fileSelector: { + image: 'Image', + video: 'Video', + audio: 'Audio', + file: 'File', + systemImage: 'System Image', + systemVideo: 'System Video', + systemAudio: 'System Audio', + systemOther: 'System Other', + inputPlaceholder: 'Enter {name} name', + selectedCount: '{n} file(s) selected', + upload: 'Upload {type}', + netFile: 'Net {type}', + netUploadTitle: 'Network {type} Upload', + netLinkLabel: '{type} Link', + netLinkPlaceholder: 'Enter network link', + netLoading: 'Fetching network file...', + confirm: 'Confirm', + cancel: 'Cancel', + netFetchFailed: 'Failed to fetch network {type}!', + netUploadSuccess: 'Network file uploaded successfully!', + netUploadFailed: 'Network file upload failed!', + uploadSuccess: 'Uploaded successfully', + uploadFailed: 'Upload failed', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + emptyContent: 'No content, please upload', + selectFile: 'Please select file', + }, + iconSelector: { + searchPlaceholder: 'Search icons or click to select', + title: 'Select Icon', + noIcon: 'No matching icons', + }, + importExcel: { + title: 'Import Data', + import: 'Import', + dragDrop: 'Drop Excel file here, or', + clickUpload: 'click to upload', + uploadTip: 'Note: Only "xls" or "xlsx" format files are allowed!', + downloadTemplate: 'Download Template', + batchUpdateTemplate: 'Batch Update Template', + uploading: 'Uploading...', + confirm: 'Confirm', + cancel: 'Cancel', + importSuccess: 'Import Complete', + importSuccessMsg: 'Import successful', + }, + noticeBar: { + content: 'Notice content', + }, + editor: { + placeholder: 'Enter content...', + }, + cropper: { + title: 'Change Avatar', + preview: 'Preview', + select: 'Select', + cancel: 'Cancel', + confirm: 'Confirm', + uploadAvatar: 'Upload Avatar', + fileTypeError: 'File format error, please upload an image type such as: JPG, PNG', + }, + avatarSelector: { + title: 'Change Avatar', + select: 'Select', + preview: 'Preview', + confirm: 'Confirm', + cancel: 'Cancel', + cropper: 'Crop', + uploadAvatar: 'Upload Avatar', + selectFromGallery: 'Select from Gallery', + fileTypeError: 'File format error, please upload an image type such as: JPG, PNG', + }, + select: { + search: 'Search', + noData: 'No data', + loading: 'Loading...', + }, + svgIcon: { + selectIcon: 'Select Icon', + confirm: 'Confirm', + cancel: 'Cancel', + }, + foreignKey: { + select: 'Select', + search: 'Search', + noData: 'No data', + }, + manyToMany: { + select: 'Select', + selected: 'Selected', + available: 'Available', + add: 'Add', + addAll: 'Add All', + remove: 'Remove', + removeAll: 'Remove All', + }, + tableSelector: { + select: 'Select', + search: 'Search', + confirm: 'Confirm', + cancel: 'Cancel', + noData: 'No data', + inputPlaceholder: 'Enter keyword', + }, + }, + pages: { + common: { + updateSuccess: 'Updated successfully', + logoutSuccess: 'Logged out successfully', + }, + }, + personal: { + PersonalInfo: 'Personal Information', + PersonalInfo1: ' Idleness is the root of all evil.', + PersonalInfo2: 'DVAdmin is an efficient and user-friendly backend management system developed based on Django and Vue.js, primarily designed for rapidly building management backends for enterprise-level web applications. Utilizing a front-end and back-end separation architecture, it provides a comprehensive set of out-of-the-box functional modules, assisting developers and businesses in reducing development costs and enhancing management efficiency. (Note: The prompt text can be changed by modifying the personal.PersonalInfo2 file located in the src/i18n/lang/ directory under the frontend directory.)', + MyInfo: 'My Info', + UpdateInfo: 'Update My Info', + AccountSecurity: 'Account Security', + ChangePassword: 'Change Password', + Name: 'Name', + Dept: 'Dept', + Role: 'Role', + Mail: 'Mail', + Phone: 'Phone', + Sex: 'Sex', + PswdInfo: 'Password strength: Strong', + PhoneInfo: 'Mobile phone number linked', + MailInfo: 'Email linked', + NamePlaceholder: 'Please enter your name', + MailPlaceholder: 'Please enter your email', + PhonePlaceholder: 'Please enter your phone number', + }, + systemMenu: { + MenuList: 'Menu List', + MenuListNote: '1. A red menu indicates that it is disabled; 2. When adding a menu, if it is a directory, the component address can be left blank; 3. When adding a root node menu, the parent ID can be left blank;', + welcomeInfo1: ' 这里是您的工作台,请愉快的工作吧!', + quickNavigationTool: '快捷导航工具', + }, }, staticRoutes: { signIn: 'Login', @@ -146,18 +436,10 @@ export default { btnTwo: 'Update Now', btnTwoLoading: 'Updating', }, - home:{ - more:'More', - welcomeInfo:'Welcome back, ', - welcomeInfo1:' This is your workspace, please work happily!', - quickNavigationTool:'Quick Navigation Tools', + home: { + more: 'More', + welcomeInfo: 'Welcome back, ', + welcomeInfo1: ' This is your workspace, please work happily!', + quickNavigationTool: 'Quick Navigation Tools', }, - personal:{ - PersonalInfo:'Personal Information', - PersonalInfo1:' Idleness is the root of all evil.', - PersonalInfo2:'DVAdmin is an efficient and user-friendly backend management system developed based on Django and Vue.js, primarily designed for rapidly building management backends for enterprise-level web applications. Utilizing a front-end and back-end separation architecture, it provides a comprehensive set of out-of-the-box functional modules, assisting developers and businesses in reducing development costs and enhancing management efficiency. (Note: The prompt text can be changed by modifying the personal.PersonalInfo2 file located in the src/i18n/lang/ directory under the frontend directory.)', - MyInfo:'My Info', - UpdateInfo:'Update My Info', - AccountSecurity:'Account Security', - } }; diff --git a/web/src/i18n/lang/zh-cn.ts b/web/src/i18n/lang/zh-cn.ts index 3d28ff1..cf6fb4d 100644 --- a/web/src/i18n/lang/zh-cn.ts +++ b/web/src/i18n/lang/zh-cn.ts @@ -1,34 +1,328 @@ // 定义内容 export default { - router: { - home: '首页', - system: '系统管理', - config: '常规配置', - log: '日志管理', - /* 常规配置 */ - configSystem: '系统配置', - configDict: '字典管理', - configArea: '地区管理', - configFile: '附件管理', - /* 系统管理 */ - systemMenu: '菜单管理', - systemRole: '角色管理', - systemUser: '用户管理', - systemDept: '部门管理', - systemNotice: '通知中心', - systemNotice1: '通知中心', - /* 日志管理 */ - loginLog: '登录日志', - operationLog: '操作日志', - systemApiWhiteList: '接口白名单', - limits: '权限管理', - limitsFrontEnd: '前端控制', - limitsFrontEndPage: '页面权限', - limitsFrontEndBtn: '按钮权限', - limitsBackEnd: '后端控制', - limitsBackEndEndPage: '页面权限', - personal: '个人中心', - dashboard: '看板', + message: { + tagsView: { + refresh: '刷新', + close: '关闭当前', + closeOther: '关闭其他', + closeAll: '关闭全部', + fullscreen: '全屏', + }, + user: { + newTitle: '消息中心', + newDesc: '暂无新消息', + title0: '切换组件大小', + title1: '切换语言', + title2: '搜索', + title3: '布局配置', + title4: '消息中心', + title5: '全屏', + title6: '退出全屏', + dropdown1: '首页', + dropdown2: '个人中心', + versionLog: '版本升级日志', + dropdownLarge: '大号', + dropdownDefault: '默认', + dropdownSmall: '小号', + langZhCn: '简体中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: '退出登录', + fullscreenNotSupported: '您的浏览器不支持全屏!', + logOutTitle: '提示', + logOutMessage: '即将退出系统,是否继续?', + logOutConfirm: '确定', + logOutCancel: '取消', + logOutExit: '正在退出...', + retry: '重试', + onlinePrompt: '正在重新连接服务器...', + defaultUsername: '用户', + }, + home: { + more: '更多', + welcomeInfo: '欢迎回来,', + welcomeInfo1: ' 这里是您的工作台,请愉快的工作吧!', + quickNavigationTool: '快捷导航工具', + }, + footer: { + copyright: ' ❤️ Powered by tiantianxiangshang Copyright © 巨梦·DVAdmin团队 ❤️', + }, + router: { + home: '首页', + system: '系统管理', + config: '常规配置', + log: '日志管理', + /* 常规配置 */ + configSystem: '系统配置', + configDict: '字典管理', + configArea: '地区管理', + configFile: '附件管理', + /* 系统管理 */ + systemMenu: '菜单管理', + systemRole: '角色管理', + systemUser: '用户管理', + systemDept: '部门管理', + systemNotice: '通知中心', + systemNotice1: '通知中心', + /* 日志管理 */ + loginLog: '登录日志', + operationLog: '操作日志', + systemApiWhiteList: '接口白名单', + limits: '权限管理', + limitsFrontEnd: '前端控制', + limitsFrontEndPage: '页面权限', + limitsFrontEndBtn: '按钮权限', + limitsBackEnd: '后端控制', + limitsBackEndEndPage: '页面权限', + personal: '个人中心', + }, + notFound: { + foundTitle: '地址输入错误,请重新输入地址~', + foundMsg: '您可以先检查网址,然后重新输入或给我们反馈问题。', + foundBtn: '返回首页', + }, + noAccess: { + accessTitle: '您未被授权,没有操作权限~', + accessMsg: '请联系管理员', + accessBtn: '重新授权', + }, + common: { + logoutPrompt: '你已被登出,请重新登录', + prompt: '提示', + networkTimeout: '网络超时', + networkError: '网络连接错误', + endpointNotFound: '接口路径找不到', + authFailed: '登录认证失败,请重新登录', + requestError: '请求错误', + authExpired: '登录授权过期,请重新登录', + accessDenied: '拒绝访问', + requestAddressError: '请求地址出错: {url}', + requestTimeout: '请求超时', + serverError: '服务器内部错误', + serviceNotImplemented: '服务未实现', + gatewayError: '网关错误', + serviceUnavailable: '服务不可用', + gatewayTimeout: '网关超时', + httpVersionNotSupported: 'HTTP版本不受支持', + importTaskCreated: '导入任务已创建,请前往"下载中心"等待下载', + defaultExportFilename: '文件导出', + logoutSuccess: '退出登录成功', + formValidationFailed: '表单验证失败,请检查', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + deleteConfirm: '确定删除吗?', + weekday: { + sunday: '日', + monday: '一', + tuesday: '二', + wednesday: '三', + thursday: '四', + friday: '五', + saturday: '六', + }, + quarter: { + first: '一', + second: '二', + third: '三', + fourth: '四', + }, + weekdayLongPrefix: '星期', + weekdayShortPrefix: '周', + quarterLongPrefix: '第', + quarterSuffix: '季度', + weekPrefix: '第', + weekSuffix: '周', + greeting: { + dawn: '凌晨好', + morning: '早上好', + lateMorning: '上午好', + noon: '中午好', + afternoon: '下午好', + evening: '傍晚好', + night: '晚上好', + lateNight: '夜里好', + }, + time: { + justNow: '刚刚', + secondsAgo: '{n}秒前', + minutesAgo: '{n}分钟前', + hoursAgo: '{n}小时前', + daysAgo: '{n}天前', + }, + }, + components: { + table: { + serialNo: '序号', + operation: '操作', + deleteConfirm: '确定删除吗?', + delete: '删除', + noData: '暂无数据', + export: '导出', + refresh: '刷新', + setting: '设置', + columnDisplay: '列显示', + dragSort: '拖动进行排序', + selectExportData: '请先选择要导出的数据', + multiSelect: '多选', + }, + calendar: { + selected: '已选择:', + clear: '清空', + today: '今天:', + holidaySettings: '节假日设置', + showHoliday: '显示节日', + closeHoliday: '关闭节日', + lunarHoliday: '农历节日', + solarTerm: '节气', + moreHoliday: '更多节日', + prevYear: '上年', + nextYear: '下年', + prevMonth: '上月', + nextMonth: '下月', + todayBtn: '今天', + todayCell: '今天', + }, + fileSelector: { + title: '文件选择', + image: '图片', + video: '视频', + audio: '音频', + file: '文件', + systemImage: '系统图片', + systemVideo: '系统视频', + systemAudio: '系统音频', + systemOther: '系统其他', + inputPlaceholder: '请输入{name}名', + selectedCount: '一共选中 {n} 个文件', + upload: '上传{type}', + netFile: '网络{type}', + netUploadTitle: '网络{type}上传', + netLinkLabel: '{type}链接', + netLinkPlaceholder: '请输入网络连接', + netLoading: '网络文件获取中...', + confirm: '确定', + cancel: '取消', + netFetchFailed: '网络{type}获取失败!', + netUploadSuccess: '网络文件上传成功!', + netUploadFailed: '网络文件上传失败!', + uploadSuccess: '上传成功', + uploadFailed: '上传失败', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + emptyContent: '无内容,请上传', + selectFile: '请选择文件', + }, + iconSelector: { + searchPlaceholder: '请输入内容搜索图标或者选择图标', + title: '请选择图标', + noIcon: '无相关图标', + }, + importExcel: { + title: '导入数据', + import: '导入', + dragDrop: '将文件拖到此处,或', + clickUpload: '点击上传', + uploadTip: '提示:仅允许导入"xls"或"xlsx"格式文件!', + downloadTemplate: '下载导入模板', + batchUpdateTemplate: '批量更新模板', + uploading: '上传中...', + confirm: '确 定', + cancel: '取 消', + importSuccess: '导入完成', + importSuccessMsg: '导入成功', + }, + noticeBar: { + content: '公告内容', + }, + editor: { + placeholder: '请输入内容...', + }, + cropper: { + title: '更换头像', + preview: '预览', + select: '选择', + cancel: '取 消', + confirm: '更 换', + uploadAvatar: '更新头像', + fileTypeError: '文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。', + }, + avatarSelector: { + title: '修改头像', + select: '选择', + preview: '预览', + confirm: '确认', + cancel: '取消', + cropper: '裁剪', + uploadAvatar: '上传头像', + selectFromGallery: '从相册选择', + fileTypeError: '文件格式错误,请上传图片类型,如:JPG,PNG后缀的文件。', + }, + select: { + search: '搜索', + noData: '无数据', + loading: '加载中...', + }, + svgIcon: { + selectIcon: '选择图标', + confirm: '确定', + cancel: '取消', + }, + foreignKey: { + select: '选择', + search: '搜索', + noData: '无数据', + }, + manyToMany: { + select: '选择', + selected: '已选', + available: '可选', + add: '添加', + addAll: '添加全部', + remove: '移除', + removeAll: '移除全部', + }, + tableSelector: { + select: '选择', + search: '搜索', + confirm: '确定', + cancel: '取消', + noData: '无数据', + inputPlaceholder: '请输入关键词', + }, + }, + pages: { + common: { + updateSuccess: '更新成功', + logoutSuccess: '退出登录成功', + }, + }, + personal: { + PersonalInfo: '个人信息', + PersonalInfo1: ' 生活变的再糟糕,也不妨碍我变得更好!', + PersonalInfo2: 'DVAdmin 是一款基于 Django 和 Vue.js 开发的高效、易用的后台管理系统,主要用于快速构建企业级 Web 应用的管理后台。它通过前后端分离架构,提供了一整套开箱即用的功能模块,帮助开发者和企业降低开发成本、提升管理效率。(更改前端目录下src/i18n/lang/下的翻译文件中personal.PersonalInfo2可更改此提示文字)', + MyInfo: '个人信息', + UpdateInfo: '更新信息', + AccountSecurity: '账号安全', + ChangePassword: '修改密码', + Name: '昵称', + Dept: '部门', + Role: '角色', + Mail: '邮箱', + Phone: '手机', + Sex: '性别', + PswdInfo: '当前密码强度:强', + PhoneInfo: '已绑定手机', + MailInfo: '已绑定邮箱', + NamePlaceholder: '请输入姓名', + MailPlaceholder: '请输入邮箱', + PhonePlaceholder: '请输入手机号', + }, + systemMenu: { + MenuList: '菜单列表', + MenuListNote: '1.红色菜单代表状态禁用; 2.添加菜单,如果是目录,组件地址为空即可; 3.添加根节点菜单,父级ID为空即可;', + welcomeInfo1: ' 这里是您的工作台,请愉快的工作吧!', + quickNavigationTool: '快捷导航工具', + }, }, staticRoutes: { signIn: '登录', @@ -146,18 +440,10 @@ export default { btnTwo: '马上更新', btnTwoLoading: '更新中', }, - home:{ - more:'更多', - welcomeInfo:'欢迎回来,', - welcomeInfo1:' 这里是您的工作台,请愉快的工作吧!', - quickNavigationTool:'快捷导航工具', + home: { + more: '更多', + welcomeInfo: '欢迎回来,', + welcomeInfo1: ' 这里是您的工作台,请愉快的工作吧!', + quickNavigationTool: '快捷导航工具', }, - personal:{ - PersonalInfo:'个人信息', - PersonalInfo1:' 生活变的再糟糕,也不妨碍我变得更好!', - PersonalInfo2:'DVAdmin 是一款基于 Django 和 Vue.js 开发的高效、易用的后台管理系统,主要用于快速构建企业级 Web 应用的管理后台。它通过前后端分离架构,提供了一整套开箱即用的功能模块,帮助开发者和企业降低开发成本、提升管理效率。(更改前端目录下src/i18n/lang/下的翻译文件中personal.PersonalInfo2可更改此提示文字)', - MyInfo:'个人信息', - UpdateInfo:'更新信息', - AccountSecurity:'账号安全', - } }; diff --git a/web/src/i18n/lang/zh-tw.ts b/web/src/i18n/lang/zh-tw.ts index a19e526..01cc961 100644 --- a/web/src/i18n/lang/zh-tw.ts +++ b/web/src/i18n/lang/zh-tw.ts @@ -1,34 +1,325 @@ // 定義內容 export default { - router: { - home: '首頁', - system: '系統設置', - config: '常規配置', - log: '日誌管理', - /* 常規配置 */ - configSystem: '系統配置', - configDict: '字典管理', - configArea: '地區管理', - configFile: '附件管理', - /* 系統管理 */ - systemMenu: '選單管理', - systemRole: '角色管理', - systemUser: '用戶管理', - systemDept: '部門管理', - systemNotice: '通知中心', - systemNotice1: '通知中心', - /* 日誌管理 */ - loginLog: '登錄日誌', - operationLog: '操作日誌', - systemApiWhiteList: '接口白名單', - limits: '權限管理', - limitsFrontEnd: '前端控制', - limitsFrontEndPage: '頁面權限', - limitsFrontEndBtn: '按鈕權限', - limitsBackEnd: '後端控制', - limitsBackEndEndPage: '頁面權限', - personal: '個人中心', - dashboard: '看板', + message: { + home: { + more: '更多', + welcomeInfo: '歡迎回來,', + welcomeInfo1: ' 這裏是您的工作台,請愉快的工作吧!', + quickNavigationTool: '快捷導航工具', + }, + footer: { + copyright: ' ❤️ Powered by tiantianxiangshang Copyright © 巨夢·DVAmin團隊 ❤️', + }, + router: { + home: '首頁', + system: '系統設置', + config: '常規配置', + log: '日誌管理', + configSystem: '系統配置', + configDict: '字典管理', + configArea: '地區管理', + configFile: '附件管理', + systemMenu: '選單管理', + systemRole: '角色管理', + systemUser: '用戶管理', + systemDept: '部門管理', + systemNotice: '通知中心', + systemNotice1: '通知中心', + loginLog: '登錄日誌', + operationLog: '操作日誌', + systemApiWhiteList: '接口白名單', + limits: '權限管理', + limitsFrontEnd: '前端控制', + limitsFrontEndPage: '頁面權限', + limitsFrontEndBtn: '按鈕權限', + limitsBackEnd: '後端控制', + limitsBackEndEndPage: '頁面權限', + personal: '個人中心', + }, + notFound: { + foundTitle: '地址輸入錯誤,請重新輸入地址~', + foundMsg: '您可以先檢查網址,然後重新輸入或給我們反饋問題。', + foundBtn: '返回首頁', + }, + noAccess: { + accessTitle: '您未被授權,沒有操作權限~', + accessMsg: '請聯繫管理員', + accessBtn: '重新授權', + }, + tagsView: { + refresh: '重新整理', + close: '關閉當前', + closeOther: '關閉其他', + closeAll: '關閉全部', + fullscreen: '全螢幕', + }, + user: { + newTitle: '訊息中心', + newDesc: '暫無新訊息', + title0: '切換元件大小', + title1: '切換語言', + title2: '搜尋', + title3: '版面設定', + title4: '訊息中心', + title5: '全螢幕', + title6: '退出全螢幕', + dropdown1: '首頁', + dropdown2: '個人中心', + versionLog: '版本升級日誌', + dropdownLarge: '大', + dropdownDefault: '預設', + dropdownSmall: '小', + langZhCn: '簡體中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: '退出登入', + fullscreenNotSupported: '您的瀏覽器不支援全螢幕!', + logOutTitle: '提示', + logOutMessage: '即將退出系統,是否繼續?', + logOutConfirm: '確定', + logOutCancel: '取消', + logOutExit: '正在退出...', + retry: '重試', + onlinePrompt: '正在重新連線伺服器...', + defaultUsername: '使用者', + }, + common: { + logoutPrompt: '你已被登出,請重新登錄', + prompt: '提示', + networkTimeout: '網路超時', + networkError: '網路連接錯誤', + endpointNotFound: '接口路徑找不到', + authFailed: '登錄認證失敗,請重新登錄', + requestError: '請求錯誤', + authExpired: '登錄授權過期,請重新登錄', + accessDenied: '拒絕訪問', + requestAddressError: '請求地址出錯: {url}', + requestTimeout: '請求超時', + serverError: '伺服器內部錯誤', + serviceNotImplemented: '服務未實現', + gatewayError: '網關錯誤', + serviceUnavailable: '服務不可用', + gatewayTimeout: '網關超時', + httpVersionNotSupported: 'HTTP版本不受支持', + importTaskCreated: '導入任務已創建,請前往"下載中心"等待下載', + defaultExportFilename: '文件導出', + logoutSuccess: '退出登錄成功', + formValidationFailed: '表單驗證失敗,請檢查', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + deleteConfirm: '確定刪除嗎?', + weekday: { + sunday: '日', + monday: '一', + tuesday: '二', + wednesday: '三', + thursday: '四', + friday: '五', + saturday: '六', + }, + quarter: { + first: '一', + second: '二', + third: '三', + fourth: '四', + }, + weekdayLongPrefix: '星期', + weekdayShortPrefix: '周', + quarterLongPrefix: '第', + quarterSuffix: '季度', + weekPrefix: '第', + weekSuffix: '周', + greeting: { + dawn: '凌晨好', + morning: '早上好', + lateMorning: '上午好', + noon: '中午好', + afternoon: '下午好', + evening: '傍晚好', + night: '晚上好', + lateNight: '夜裏好', + }, + time: { + justNow: '剛剛', + secondsAgo: '{n}秒前', + minutesAgo: '{n}分鐘前', + hoursAgo: '{n}小時前', + daysAgo: '{n}天前', + }, + }, + components: { + table: { + serialNo: '序號', + operation: '操作', + deleteConfirm: '確定刪除嗎?', + delete: '刪除', + noData: '暫無數據', + export: '導出', + refresh: '刷新', + setting: '設置', + columnDisplay: '列顯示', + dragSort: '拖動進行排序', + selectExportData: '請先選擇要導出的數據', + multiSelect: '多選', + }, + calendar: { + selected: '已選擇:', + clear: '清空', + today: '今天:', + holidaySettings: '節假日設置', + showHoliday: '顯示節日', + closeHoliday: '關閉節日', + lunarHoliday: '農曆節日', + solarTerm: '節氣', + moreHoliday: '更多節日', + prevYear: '上年', + nextYear: '下年', + prevMonth: '上月', + nextMonth: '下月', + todayBtn: '今天', + todayCell: '今天', + }, + fileSelector: { + title: '文件選擇', + image: '圖片', + video: '視頻', + audio: '音頻', + file: '文件', + systemImage: '系統圖片', + systemVideo: '系統視頻', + systemAudio: '系統音頻', + systemOther: '系統其他', + inputPlaceholder: '請輸入{name}名', + selectedCount: '一共選中 {n} 個文件', + upload: '上傳{type}', + netFile: '網絡{type}', + netUploadTitle: '網絡{type}上傳', + netLinkLabel: '{type}連結', + netLinkPlaceholder: '請輸入網絡連接', + netLoading: '網絡文件獲取中...', + confirm: '確定', + cancel: '取消', + netFetchFailed: '網絡{type}獲取失敗!', + netUploadSuccess: '網絡文件上傳成功!', + netUploadFailed: '網絡文件上傳失敗!', + uploadSuccess: '上傳成功', + uploadFailed: '上傳失敗', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + emptyContent: '無內容,請上傳', + selectFile: '請選擇文件', + }, + iconSelector: { + searchPlaceholder: '請輸入內容搜索圖標或者選擇圖標', + title: '請選擇圖標', + noIcon: '無相關圖標', + }, + importExcel: { + title: '導入數據', + import: '導入', + dragDrop: '將文件拖到此處,或', + clickUpload: '點擊上傳', + uploadTip: '提示:僅允許導入"xls"或"xlsx"格式文件!', + downloadTemplate: '下載導入模板', + batchUpdateTemplate: '批量更新模板', + uploading: '上傳中...', + confirm: '確 定', + cancel: '取 消', + importSuccess: '導入完成', + importSuccessMsg: '導入成功', + }, + noticeBar: { + content: '公告內容', + }, + editor: { + placeholder: '請輸入內容...', + }, + cropper: { + title: '更換頭像', + preview: '預覽', + select: '選擇', + cancel: '取 消', + confirm: '更 換', + uploadAvatar: '更新頭像', + fileTypeError: '文件格式錯誤,請上傳圖片類型,如:JPG,PNG後綴的文件。', + }, + avatarSelector: { + title: '修改頭像', + select: '選擇', + preview: '預覽', + confirm: '確認', + cancel: '取消', + cropper: '裁剪', + uploadAvatar: '上傳頭像', + selectFromGallery: '從相冊選擇', + fileTypeError: '文件格式錯誤,請上傳圖片類型,如:JPG,PNG後綴的文件。', + }, + select: { + search: '搜索', + noData: '無數據', + loading: '加載中...', + }, + svgIcon: { + selectIcon: '選擇圖標', + confirm: '確定', + cancel: '取消', + }, + foreignKey: { + select: '選擇', + search: '搜索', + noData: '無數據', + }, + manyToMany: { + select: '選擇', + selected: '已選', + available: '可選', + add: '添加', + addAll: '添加全部', + remove: '移除', + removeAll: '移除全部', + }, + tableSelector: { + select: '選擇', + search: '搜索', + confirm: '確定', + cancel: '取消', + noData: '無數據', + inputPlaceholder: '請輸入關鍵詞', + }, + }, + pages: { + common: { + updateSuccess: '更新成功', + logoutSuccess: '退出登錄成功', + }, + }, + personal: { + PersonalInfo: '個人資訊', + PersonalInfo1: ' 生活變得再糟糕,也不妨礙我變得更好!', + PersonalInfo2: 'DVAdmin是一款基於Django和Vue.js開發的高效、易用的後台管理系統,主要用於快速構建企業級Web應用的管理後台,它透過前後端分離架構,提供了一整套開箱即用的功能模組,幫助開發者和企業降低開發成本、提升管理效率。(更改前端目錄下src/i18n/lang/下的翻譯文件中personal.PersonalInfo2可更改此提示文字)', + MyInfo: '個人信息', + UpdateInfo: '更新資訊', + AccountSecurity: '帳號安全', + ChangePassword: '修改密碼', + Name: '昵稱', + Dept: '部門', + Role: '角色', + Mail: '電郵信箱', + Phone: '手機', + Sex: '性別', + PswdInfo: '當前密碼強度:強', + PhoneInfo: '已綁定手機', + MailInfo: '已綁定郵箱', + NamePlaceholder: '請輸入姓名', + MailPlaceholder: '請輸入郵箱', + PhonePlaceholder: '請輸入手機號', + }, + systemMenu: { + MenuList: '菜單列表', + MenuListNote: '1.紅色菜單代表狀態禁用; 2.添加菜單,如果是目錄,組件地址為空即可; 3.添加根節點菜單,父級ID為空即可;', + welcomeInfo1: ' 这里是您的工作台,请愉快的工作吧!', + quickNavigationTool: '快捷导航工具', + }, }, staticRoutes: { signIn: '登錄', @@ -146,18 +437,10 @@ export default { btnTwo: '馬上更新', btnTwoLoading: '更新中', }, - home:{ - more:'更多', - welcomeInfo:'歡迎回來,', - welcomeInfo1:' 這裏是您的工作台,請愉快的工作吧!', - quickNavigationTool:'快捷導航工具', + home: { + more: '更多', + welcomeInfo: '歡迎回來,', + welcomeInfo1: ' 這裏是您的工作台,請愉快的工作吧!', + quickNavigationTool: '快捷導航工具', }, - personal:{ - PersonalInfo:'個人資訊', - PersonalInfo1:' 生活變得再糟糕,也不妨礙我變得更好!', - PersonalInfo2:'DVAdmin是一款基於Django和Vue.js開發的高效、易用的後台管理系統,主要用於快速構建企業級Web應用的管理後台。它透過前後端分離架構,提供了一整套開箱即用的功能模組,幫助開發者和企業降低開發成本、提升管理效率。(更改前端目錄下src/i18n/lang/下的翻譯文件中personal.PersonalInfo2可更改此提示文字)', - MyInfo:'個人信息', - UpdateInfo:'更新資訊', - AccountSecurity:'帳號安全', - } -}; \ No newline at end of file +}; diff --git a/web/src/i18n/pages/areas/en.ts b/web/src/i18n/pages/areas/en.ts new file mode 100644 index 0000000..0f14962 --- /dev/null +++ b/web/src/i18n/pages/areas/en.ts @@ -0,0 +1,62 @@ +// Define content +export default { + message: { + pages: { + areas: { + table: { + columns: { + index: 'No.', + areaName: 'Area Name', + areaCode: 'Area Code', + parentArea: 'Parent Area', + sort: 'Sort', + status: 'Status', + createTime: 'Create Time', + actions: 'Actions', + }, + }, + form: { + areaName: 'Area Name', + areaCode: 'Area Code', + parentArea: 'Parent Area', + sort: 'Sort', + status: 'Status', + areaNamePlaceholder: 'Enter area name', + areaCodePlaceholder: 'Enter area code', + sortPlaceholder: 'Enter sort', + }, + validation: { + areaNameRequired: 'Area name is required', + areaNameMaxLength: 'Area name must be 50 characters or less', + areaNameDuplicate: 'Area name already exists', + areaCodeRequired: 'Area code is required', + areaCodeMaxLength: 'Area code must be 50 characters or less', + areaCodeFormat: 'Invalid area code format', + areaCodeDuplicate: 'Area code already exists', + }, + dialog: { + addArea: 'Add Area', + editArea: 'Edit Area', + deleteConfirm: 'Delete this area?', + }, + messages: { + addSuccess: 'Added successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + }, + buttons: { + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + query: 'Query', + refresh: 'Refresh', + expandAll: 'Expand All', + collapseAll: 'Collapse All', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/areas/zh-cn.ts b/web/src/i18n/pages/areas/zh-cn.ts new file mode 100644 index 0000000..4ac86d2 --- /dev/null +++ b/web/src/i18n/pages/areas/zh-cn.ts @@ -0,0 +1,62 @@ +// 定义内容 +export default { + message: { + pages: { + areas: { + table: { + columns: { + index: '序号', + areaName: '区域名称', + areaCode: '区域编码', + parentArea: '上级区域', + sort: '排序', + status: '状态', + createTime: '创建时间', + actions: '操作', + }, + }, + form: { + areaName: '区域名称', + areaCode: '区域编码', + parentArea: '上级区域', + sort: '排序', + status: '状态', + areaNamePlaceholder: '请输入区域名称', + areaCodePlaceholder: '请输入区域编码', + sortPlaceholder: '请输入排序', + }, + validation: { + areaNameRequired: '区域名称必填', + areaNameMaxLength: '区域名称不能超过50个字符', + areaNameDuplicate: '区域名称已存在', + areaCodeRequired: '区域编码必填', + areaCodeMaxLength: '区域编码不能超过50个字符', + areaCodeFormat: '区域编码格式不正确', + areaCodeDuplicate: '区域编码已存在', + }, + dialog: { + addArea: '新增区域', + editArea: '编辑区域', + deleteConfirm: '确定删除该区域吗?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + query: '查询', + refresh: '刷新', + expandAll: '展开全部', + collapseAll: '收起全部', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/areas/zh-tw.ts b/web/src/i18n/pages/areas/zh-tw.ts new file mode 100644 index 0000000..0b791df --- /dev/null +++ b/web/src/i18n/pages/areas/zh-tw.ts @@ -0,0 +1,62 @@ +// 定義內容 +export default { + message: { + pages: { + areas: { + table: { + columns: { + index: '序號', + areaName: '區域名稱', + areaCode: '區域編碼', + parentArea: '上級區域', + sort: '排序', + status: '狀態', + createTime: '創建時間', + actions: '操作', + }, + }, + form: { + areaName: '區域名稱', + areaCode: '區域編碼', + parentArea: '上級區域', + sort: '排序', + status: '狀態', + areaNamePlaceholder: '請輸入區域名稱', + areaCodePlaceholder: '請輸入區域編碼', + sortPlaceholder: '請輸入排序', + }, + validation: { + areaNameRequired: '區域名稱必填', + areaNameMaxLength: '區域名稱不能超過50個字符', + areaNameDuplicate: '區域名稱已存在', + areaCodeRequired: '區域編碼必填', + areaCodeMaxLength: '區域編碼不能超過50個字符', + areaCodeFormat: '區域編碼格式不正確', + areaCodeDuplicate: '區域編碼已存在', + }, + dialog: { + addArea: '新增區域', + editArea: '編輯區域', + deleteConfirm: '確定刪除該區域嗎?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + }, + buttons: { + add: '新增', + edit: '編輯', + delete: '刪除', + save: '保存', + cancel: '取消', + query: '查詢', + refresh: '刷新', + expandAll: '展開全部', + collapseAll: '收起全部', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/basicinfo/en.ts b/web/src/i18n/pages/basicinfo/en.ts new file mode 100644 index 0000000..f5c0be2 --- /dev/null +++ b/web/src/i18n/pages/basicinfo/en.ts @@ -0,0 +1,142 @@ +// Definition +export default { + message: { + pages: { + basicinfo: { + unit: { + title: 'Unit of Measure', + unitname: 'Unit Name', + unitcode: 'Unit Code', + unitnameEn: 'Unit Name (English)', + unitnameZhTw: 'Unit Name (Traditional Chinese)', + status: 'Status', + enabled: 'Enabled', + disabled: 'Disabled', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + currency: { + title: 'Currency', + currencyname: 'Currency Name', + currencycode: 'Currency Code', + currencysymbol: 'Currency Symbol', + factory: 'Factory', + tax: 'Tax Rate', + currencynameEn: 'Currency Name (English)', + currencynameZhTw: 'Currency Name (Traditional Chinese)', + status: 'Status', + enabled: 'Enabled', + disabled: 'Disabled', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + supplier: { + title: 'Supplier Information', + companyCode: 'Company Code', + supplierId: 'Supplier ID', + supplierName: 'Supplier Full Name', + supplierShortName: 'Supplier Short Name', + vendorType: 'Vendor Type', + paymentTerms: 'Payment Terms', + transactionCurrency: 'Transaction Currency', + incoterms: 'Incoterms', + supplierLevel: 'Supplier Level', + contactPerson: 'Contact Person', + contactPhone: 'Contact Phone', + contactEmail: 'Contact Email', + country: 'Country', + province: 'Province', + city: 'City', + address: 'Address', + postalCode: 'Postal Code', + status: 'Status', + enabled: 'Enabled', + disabled: 'Disabled', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + company: { + title: 'Company Information', + companyCode: 'Company Code', + companyName: 'Company Full Name', + companyShortName: 'Company Short Name', + companyAddress: 'Company Address', + status: 'Status', + createTime: 'Create Time', + updateTime: 'Update Time', + createUser: 'Creator', + updateUser: 'Modifier', + }, + emailnotice: { + title: 'Email Notification Log', + subject: 'Email Subject', + bizType: 'Business Type', + bizId: 'Business ID', + toEmails: 'To', + ccEmails: 'CC', + bccEmails: 'BCC', + status: 'Send Status', + sentAt: 'Sent At', + attachments: 'Attachments', + lastError: 'Error Info', + messageId: 'Message ID', + retryCount: 'Retry Count', + statusPending: 'Pending', + statusSending: 'Sending', + statusSuccess: 'Sent', + statusFailed: 'Failed', + resend: 'Resend', + selectOrSearch: 'Select or search', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + supplierUser: { + title: 'Supplier User', + supplierId: 'Supplier ID', + supplierName: 'Supplier Full Name', + supplierRole: 'Supplier Role', + userEmail: 'Contact Email', + userName: 'Contact Person', + userPhone: 'Contact Phone', + status: 'Status', + statusValid: 'Valid', + statusInvalid: 'Invalid', + autoFillNote: 'Auto-fill', + roleQuote: 'Quote', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + systemNo: { + title: 'Document Number Rule', + companyCode: 'Company Code', + ruleCode: 'Rule Code', + resetCycle: 'Reset Cycle', + resetCycleYy2: 'Yearly 2 (YY)', + resetCycleYyyy4: 'Yearly 4 (YYYY)', + resetCycleYymm4: 'Monthly 4 (YYMM)', + resetCycleYyyymm6: 'Monthly 6 (YYYYMM)', + resetCycleYymmdd6: 'Daily 6 (YYMMDD)', + resetCycleYyyymmdd8: 'Daily 8 (YYYYMMDD)', + ruleCodeMiscQts: 'miscQTS (Misc Quote)', + ruleCodeMiscRfs: 'miscRFS (Misc RFQ)', + prefix: 'Prefix', + factoryCode: 'Factory Code', + seqLength: 'Sequence Length', + createUser: 'Creator', + updateUser: 'Modifier', + createTime: 'Create Time', + updateTime: 'Update Time', + general: 'General', + sequenceDate: 'Sequence Date', + prevSequence: 'Previous Sequence', + currentSequence: 'Current Sequence', + lastGenerateUser: 'Last Generator', + lastGenerateTime: 'Last Generate Time', + status: 'Status', + statusAvailable: 'Available', + statusUnavailable: 'Unavailable', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/basicinfo/zh-cn.ts b/web/src/i18n/pages/basicinfo/zh-cn.ts new file mode 100644 index 0000000..06ee787 --- /dev/null +++ b/web/src/i18n/pages/basicinfo/zh-cn.ts @@ -0,0 +1,142 @@ +// 定义内容 +export default { + message: { + pages: { + basicinfo: { + unit: { + title: '计量单位', + unitname: '计量单位名称', + unitcode: '计量单位代码', + unitnameEn: '计量单位英文名', + unitnameZhTw: '计量单位繁体名', + status: '状态', + enabled: '可用', + disabled: '不可用', + createTime: '创建时间', + updateTime: '更新时间', + }, + currency: { + title: '货币', + currencyname: '货币名称', + currencycode: '货币代码', + currencysymbol: '货币符号', + factory: '交易厂区', + tax: '税率', + currencynameEn: '货币英文名', + currencynameZhTw: '货币繁体名', + status: '状态', + enabled: '可用', + disabled: '不可用', + createTime: '创建时间', + updateTime: '更新时间', + }, + supplier: { + title: '供应商信息', + companyCode: '交易厂区', + supplierId: '供应商唯一ID', + supplierName: '供应商全称', + supplierShortName: '供应商简称', + vendorType: '厂商性质', + paymentTerms: '付款条件', + transactionCurrency: '交易货币', + incoterms: '国际条款', + supplierLevel: '供应商等级', + contactPerson: '联络人', + contactPhone: '联络人电话', + contactEmail: '联络人邮箱', + country: '国家', + province: '省州', + city: '城市', + address: '详细地址', + postalCode: '邮政编码', + status: '状态', + enabled: '可用', + disabled: '不可用', + createTime: '创建时间', + updateTime: '更新时间', + }, + company: { + title: '公司信息', + companyCode: '公司代码', + companyName: '公司全称', + companyShortName: '公司简称', + companyAddress: '公司地址', + status: '状态', + createTime: '创建时间', + updateTime: '更新时间', + createUser: '单据创建人', + updateUser: '单据修改人', + }, + supplierUser: { + title: '供应商用户', + supplierId: '供应商唯一ID', + supplierName: '供应商全称', + supplierRole: '供应商角色', + userEmail: '联络人邮箱', + userName: '联络人', + userPhone: '联络人电话', + status: '状态', + statusValid: '有效', + statusInvalid: '无效', + autoFillNote: '自动带出', + roleQuote: '报价', + createTime: '创建时间', + updateTime: '更新时间', + }, + emailnotice: { + title: '邮件通知记录', + subject: '邮件主题', + bizType: '业务类型', + bizId: '业务标识', + toEmails: '收件人', + ccEmails: '抄送', + bccEmails: '密送', + status: '发送状态', + sentAt: '发送时间', + attachments: '附件', + lastError: '错误信息', + messageId: '消息ID', + retryCount: '重试次数', + statusPending: '待发送', + statusSending: '发送中', + statusSuccess: '已发送', + statusFailed: '发送失败', + resend: '重送', + selectOrSearch: '请选择或搜索', + createTime: '创建时间', + updateTime: '更新时间', + }, + systemNo: { + title: '单据编号规则', + companyCode: '交易厂区', + ruleCode: '生成单据标识号', + resetCycle: '流水码重置类别', + resetCycleYy2: '按年2(YY)', + resetCycleYyyy4: '按年4(YYYY)', + resetCycleYymm4: '按月4(YYMM)', + resetCycleYyyymm6: '按月6(YYYYMM)', + resetCycleYymmdd6: '按日6(YYMMDD)', + resetCycleYyyymmdd8: '按日8(YYYYMMDD)', + ruleCodeMiscQts: 'miscQTS (杂采报价单)', + ruleCodeMiscRfs: 'miscRFS (杂采询价单)', + prefix: '单据头', + factoryCode: '厂区区分码', + seqLength: '流水码长度', + createUser: '单据创建人', + updateUser: '单据修改人', + createTime: '创建时间', + updateTime: '更新时间', + general: '通用', + sequenceDate: '流水日期', + prevSequence: '上一流水码', + currentSequence: '下一流水码', + lastGenerateUser: '单据最后产生人', + lastGenerateTime: '单据最后产生时间', + status: '可用状态', + statusAvailable: '可用', + statusUnavailable: '不可用', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/basicinfo/zh-tw.ts b/web/src/i18n/pages/basicinfo/zh-tw.ts new file mode 100644 index 0000000..cc23e0e --- /dev/null +++ b/web/src/i18n/pages/basicinfo/zh-tw.ts @@ -0,0 +1,142 @@ +// 定義內容 +export default { + message: { + pages: { + basicinfo: { + unit: { + title: '計量單位', + unitname: '計量單位名稱', + unitcode: '計量單位代碼', + unitnameEn: '計量單位英文名', + unitnameZhTw: '計量單位繁體名', + status: '狀態', + enabled: '啟用', + disabled: '停用', + createTime: '創建時間', + updateTime: '更新時間', + }, + currency: { + title: '貨幣', + currencyname: '貨幣名稱', + currencycode: '貨幣代碼', + currencysymbol: '貨幣符號', + factory: '交易廠區', + tax: '稅率', + currencynameEn: '貨幣英文名', + currencynameZhTw: '貨幣繁體名', + status: '狀態', + enabled: '啟用', + disabled: '停用', + createTime: '創建時間', + updateTime: '更新時間', + }, + supplier: { + title: '供應商資訊', + companyCode: '交易廠區', + supplierId: '供應商唯一ID', + supplierName: '供應商全稱', + supplierShortName: '供應商簡稱', + vendorType: '廠商性質', + paymentTerms: '付款條件', + transactionCurrency: '交易貨幣', + incoterms: '國際條款', + supplierLevel: '供應商等級', + contactPerson: '聯絡人', + contactPhone: '聯絡人電話', + contactEmail: '聯絡人郵箱', + country: '國家', + province: '省州', + city: '城市', + address: '詳細地址', + postalCode: '郵遞區號', + status: '狀態', + enabled: '啟用', + disabled: '停用', + createTime: '創建時間', + updateTime: '更新時間', + }, + company: { + title: '公司資訊', + companyCode: '公司代碼', + companyName: '公司全稱', + companyShortName: '公司簡稱', + companyAddress: '公司地址', + status: '狀態', + createTime: '創建時間', + updateTime: '更新時間', + createUser: '單據創建人', + updateUser: '單據修改人', + }, + emailnotice: { + title: '郵件通知記錄', + subject: '郵件主題', + bizType: '業務類型', + bizId: '業務標識', + toEmails: '收件人', + ccEmails: '抄送', + bccEmails: '密送', + status: '發送狀態', + sentAt: '發送時間', + attachments: '附件', + lastError: '錯誤資訊', + messageId: '訊息ID', + retryCount: '重試次數', + statusPending: '待發送', + statusSending: '發送中', + statusSuccess: '已發送', + statusFailed: '發送失敗', + resend: '重送', + selectOrSearch: '請選擇或搜尋', + createTime: '創建時間', + updateTime: '更新時間', + }, + supplierUser: { + title: '供應商用戶', + supplierId: '供應商唯一ID', + supplierName: '供應商全稱', + supplierRole: '供應商角色', + userEmail: '聯絡人郵箱', + userName: '聯絡人', + userPhone: '聯絡人電話', + status: '狀態', + statusValid: '有效', + statusInvalid: '無效', + autoFillNote: '自動帶出', + roleQuote: '報價', + createTime: '創建時間', + updateTime: '更新時間', + }, + systemNo: { + title: '單據編號規則', + companyCode: '交易廠區', + ruleCode: '生成單據識別號', + resetCycle: '流水碼重置類別', + resetCycleYy2: '按年2(YY)', + resetCycleYyyy4: '按年4(YYYY)', + resetCycleYymm4: '按月4(YYMM)', + resetCycleYyyymm6: '按月6(YYYYMM)', + resetCycleYymmdd6: '按日6(YYMMDD)', + resetCycleYyyymmdd8: '按日8(YYYYMMDD)', + ruleCodeMiscQts: 'miscQTS (雜採報價單)', + ruleCodeMiscRfs: 'miscRFS (雜採詢價單)', + prefix: '單據頭', + factoryCode: '廠區區分碼', + seqLength: '流水碼長度', + createUser: '單據創建人', + updateUser: '單據修改人', + createTime: '創建時間', + updateTime: '更新時間', + general: '通用', + sequenceDate: '流水日期', + prevSequence: '上一流水碼', + currentSequence: '下一流水碼', + lastGenerateUser: '單據最後產生人', + lastGenerateTime: '單據最後產生時間', + status: '可用狀態', + statusAvailable: '可用', + statusUnavailable: '不可用', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/columns/en.ts b/web/src/i18n/pages/columns/en.ts new file mode 100644 index 0000000..39e9e36 --- /dev/null +++ b/web/src/i18n/pages/columns/en.ts @@ -0,0 +1,35 @@ +// Define content +export default { + message: { + pages: { + columns: { + table: { + columns: { + index: 'No.', + keyword: 'Keyword', + fieldName: 'Field Name', + columnName: 'Column Name', + status: 'Status', + sort: 'Sort', + type: 'Data Type', + value: 'Value', + color: 'Color', + }, + }, + subTable: { + columns: { + index: 'No.', + keyword: 'Keyword', + fieldName: 'Field Name', + columnName: 'Column Name', + status: 'Status', + sort: 'Sort', + type: 'Data Type', + value: 'Value', + color: 'Color', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/columns/zh-cn.ts b/web/src/i18n/pages/columns/zh-cn.ts new file mode 100644 index 0000000..899382c --- /dev/null +++ b/web/src/i18n/pages/columns/zh-cn.ts @@ -0,0 +1,35 @@ +// 定义内容 +export default { + message: { + pages: { + columns: { + table: { + columns: { + index: '序号', + keyword: '关键词', + fieldName: '字段名', + columnName: '列名', + status: '状态', + sort: '排序', + type: '数据类型', + value: '数据值', + color: '颜色', + }, + }, + subTable: { + columns: { + index: '序号', + keyword: '关键词', + fieldName: '字段名', + columnName: '列名', + status: '状态', + sort: '排序', + type: '数据类型', + value: '数据值', + color: '颜色', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/columns/zh-tw.ts b/web/src/i18n/pages/columns/zh-tw.ts new file mode 100644 index 0000000..502b075 --- /dev/null +++ b/web/src/i18n/pages/columns/zh-tw.ts @@ -0,0 +1,35 @@ +// 定義內容 +export default { + message: { + pages: { + columns: { + table: { + columns: { + index: '序號', + keyword: '關鍵詞', + fieldName: '欄位名', + columnName: '列名', + status: '狀態', + sort: '排序', + type: '資料類型', + value: '資料值', + color: '顏色', + }, + }, + subTable: { + columns: { + index: '序號', + keyword: '關鍵詞', + fieldName: '欄位名', + columnName: '列名', + status: '狀態', + sort: '排序', + type: '資料類型', + value: '資料值', + color: '顏色', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/config/en.ts b/web/src/i18n/pages/config/en.ts new file mode 100644 index 0000000..7f77918 --- /dev/null +++ b/web/src/i18n/pages/config/en.ts @@ -0,0 +1,110 @@ +// Define content +export default { + message: { + pages: { + config: { + header: { + tagText: 'System Config: Customize your website settings here', + }, + table: { + columns: { + configName: 'Config Name', + configCode: 'Config Key', + configValue: 'Config Value', + configType: 'Config Type', + remark: 'Remark', + sort: 'Sort', + status: 'Status', + createTime: 'Create Time', + actions: 'Actions', + }, + }, + form: { + title: 'Title', + key: 'Key', + parent: 'Group', + parentPlaceholder: 'Select group', + titlePlaceholder: 'Enter title', + keyPlaceholder: 'Enter key', + formItemType: 'Form Type', + formItemTypePlaceholder: 'Select', + dictKey: 'Dict Key', + dictKeyPlaceholder: 'Enter dict key in dictionary', + validationRule: 'Validation Rule', + validationRulePlaceholder: 'Select (multiple)', + placeholder: 'Placeholder', + placeholderPlaceholder: 'Enter placeholder', + sort: 'Sort', + remark: 'Remark', + remarkPlaceholder: 'Enter remark', + }, + validation: { + parentRequired: 'Please select a group', + titleRequired: 'Title is required', + keyRequired: 'Key is required', + keyFormat: 'Only letters and numbers allowed', + keyFormat2: 'Only letters, numbers, or underscores allowed', + formItemTypeRequired: 'Form type is required', + dictKeyRequired: 'This field cannot be empty', + }, + dialog: { + addGroup: 'Add Group', + addContent: 'Add Content', + closeConfirm: 'Are you sure you want to close?', + }, + messages: { + addSuccess: 'Added successfully', + saveSuccess: 'Saved successfully', + saveFailed: 'Save failed', + uploadFailed: 'Upload failed', + uploadFailedDetail: 'Upload failed: {msg}', + invalidImage: 'Only image files (jpg/png) are allowed', + exceedFileLimit: 'File count limit exceeded', + }, + buttons: { + addGroup: 'Add Group', + addContent: 'Add Content', + createNow: 'Create Now', + cancel: 'Cancel', + confirm: 'Confirm', + save: 'Save', + submit: 'Submit', + }, + validationRules: { + required: 'Required', + email: 'Email', + emailMessage: 'Please enter a valid email address', + url: 'URL', + urlMessage: 'Please enter a valid URL', + }, + formContent: { + variableTitle: 'Variable Title', + variableName: 'Variable Name', + variableValue: 'Variable Value', + isFrontendConfig: 'Frontend Config', + actions: 'Actions', + titlePlaceholder: 'Enter title', + keyPrefix: 'Enter variable key', + selectImageTip: 'Only jpg/png images allowed', + save: 'Save', + submit: 'Submit', + deleteConfirm: 'Delete this item?', + }, + tabs: { + none: 'No Group', + addTab: 'Add Group', + addContent: 'Add Content', + }, + associationTable: { + tableLabel: 'Associated Table', + displayField: 'Display Field', + storageField: 'Storage Field', + filterCondition: 'Filter Condition', + selectTable: 'Please select', + selectField: 'Please select', + required: 'This field is required', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/config/zh-cn.ts b/web/src/i18n/pages/config/zh-cn.ts new file mode 100644 index 0000000..0d648ca --- /dev/null +++ b/web/src/i18n/pages/config/zh-cn.ts @@ -0,0 +1,110 @@ +// 定义内容 +export default { + message: { + pages: { + config: { + header: { + tagText: '系统配置:您可在此对网站进行自定义配置', + }, + table: { + columns: { + configName: '配置名称', + configCode: '配置键名', + configValue: '配置值', + configType: '配置类型', + remark: '备注', + sort: '排序', + status: '状态', + createTime: '创建时间', + actions: '操作', + }, + }, + form: { + title: '标题', + key: 'Key值', + parent: '所属分组', + parentPlaceholder: '请选择分组', + titlePlaceholder: '请输入标题', + keyPlaceholder: '请输入Key值', + formItemType: '表单类型', + formItemTypePlaceholder: '请选择', + dictKey: '字典Key', + dictKeyPlaceholder: '请输入dictionary中的key值', + validationRule: '校验规则', + validationRulePlaceholder: '请选择(可多选)', + placeholder: '提示信息', + placeholderPlaceholder: '请输入占位提示', + sort: '排序', + remark: '备注', + remarkPlaceholder: '请输入备注', + }, + validation: { + parentRequired: '请选择所属分组', + titleRequired: '请输入标题', + keyRequired: '请输入Key值', + keyFormat: '只能是英文和数字', + keyFormat2: '只能是英文、数字或下划线', + formItemTypeRequired: '请选择表单类型', + dictKeyRequired: '不能为空', + }, + dialog: { + addGroup: '添加分组', + addContent: '添加内容', + closeConfirm: '确定要关闭吗?', + }, + messages: { + addSuccess: '新增成功', + saveSuccess: '保存成功', + saveFailed: '保存失败', + uploadFailed: '上传失败', + uploadFailedDetail: '上传失败:{msg}', + invalidImage: '仅允许上传图片文件(jpg/png)', + exceedFileLimit: '超出文件数量限制', + }, + buttons: { + addGroup: '添加分组', + addContent: '添加内容', + createNow: '立即创建', + cancel: '取消', + confirm: '确定', + save: '保存', + submit: '提交', + }, + validationRules: { + required: '必填项', + email: '邮箱', + emailMessage: '请输入正确的邮箱地址', + url: 'URL地址', + urlMessage: '请输入正确的URL地址', + }, + formContent: { + variableTitle: '变量标题', + variableName: '变量名', + variableValue: '变量值', + isFrontendConfig: '前端配置', + actions: '操作', + titlePlaceholder: '请输入标题', + keyPrefix: '请输入变量Key', + selectImageTip: '只能上传jpg/png图片', + save: '保存', + submit: '提交', + deleteConfirm: '确定删除该条数据吗?', + }, + tabs: { + none: '无分组', + addTab: '添加分组', + addContent: '添加内容', + }, + associationTable: { + tableLabel: '关联表', + displayField: '显示字段', + storageField: '储存字段', + filterCondition: '过滤条件', + selectTable: '请选择', + selectField: '请选择', + required: '必填项不能为空', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/config/zh-tw.ts b/web/src/i18n/pages/config/zh-tw.ts new file mode 100644 index 0000000..73c40aa --- /dev/null +++ b/web/src/i18n/pages/config/zh-tw.ts @@ -0,0 +1,110 @@ +// 定義內容 +export default { + message: { + pages: { + config: { + header: { + tagText: '系統配置:您可在此對網站進行自訂義配置', + }, + table: { + columns: { + configName: '配置名稱', + configCode: '配置鍵名', + configValue: '配置值', + configType: '配置類型', + remark: '備註', + sort: '排序', + status: '狀態', + createTime: '創建時間', + actions: '操作', + }, + }, + form: { + title: '標題', + key: 'Key值', + parent: '所屬分組', + parentPlaceholder: '請選擇分組', + titlePlaceholder: '請輸入標題', + keyPlaceholder: '請輸入Key值', + formItemType: '表單類型', + formItemTypePlaceholder: '請選擇', + dictKey: '字典Key', + dictKeyPlaceholder: '請輸入dictionary中的key值', + validationRule: '校驗規則', + validationRulePlaceholder: '請選擇(可多選)', + placeholder: '提示資訊', + placeholderPlaceholder: '請輸入佔位提示', + sort: '排序', + remark: '備註', + remarkPlaceholder: '請輸入備註', + }, + validation: { + parentRequired: '請選擇所屬分組', + titleRequired: '請輸入標題', + keyRequired: '請輸入Key值', + keyFormat: '只能是英文和數字', + keyFormat2: '只能是英文、數字或底線', + formItemTypeRequired: '請選擇表單類型', + dictKeyRequired: '不能為空', + }, + dialog: { + addGroup: '添加分組', + addContent: '添加內容', + closeConfirm: '確定要關閉嗎?', + }, + messages: { + addSuccess: '新增成功', + saveSuccess: '保存成功', + saveFailed: '保存失敗', + uploadFailed: '上傳失敗', + uploadFailedDetail: '上傳失敗:{msg}', + invalidImage: '僅允許上傳圖片文件(jpg/png)', + exceedFileLimit: '超出文件數量限制', + }, + buttons: { + addGroup: '添加分組', + addContent: '添加內容', + createNow: '立即創建', + cancel: '取消', + confirm: '確定', + save: '保存', + submit: '提交', + }, + validationRules: { + required: '必填項', + email: '郵箱', + emailMessage: '請輸入正確的郵箱地址', + url: 'URL地址', + urlMessage: '請輸入正確的URL地址', + }, + formContent: { + variableTitle: '變量標題', + variableName: '變量名', + variableValue: '變量值', + isFrontendConfig: '前端配置', + actions: '操作', + titlePlaceholder: '請輸入標題', + keyPrefix: '請輸入變量Key', + selectImageTip: '只能上傳jpg/png圖片', + save: '保存', + submit: '提交', + deleteConfirm: '確定刪除該條數據嗎?', + }, + tabs: { + none: '無分組', + addTab: '添加分組', + addContent: '添加內容', + }, + associationTable: { + tableLabel: '關聯表', + displayField: '顯示欄位', + storageField: '儲存欄位', + filterCondition: '過濾條件', + selectTable: '請選擇', + selectField: '請選擇', + required: '必填項不能為空', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/demo/en.ts b/web/src/i18n/pages/demo/en.ts new file mode 100644 index 0000000..b7d6540 --- /dev/null +++ b/web/src/i18n/pages/demo/en.ts @@ -0,0 +1,77 @@ +// Define content +export default { + message: { + pages: { + demo: { + table: { + columns: { + index: 'No.', + keyword: 'Keyword', + testComponent: 'Test Custom Component', + loginIp: 'Login IP', + isp: 'ISP', + continent: 'Continent', + country: 'Country', + province: 'Province', + city: 'City', + district: 'District', + areaCode: 'Area Code', + countryEn: 'English Name', + countryCode: 'Short Name', + longitude: 'Longitude', + latitude: 'Latitude', + loginType: 'Login Type', + os: 'OS', + browser: 'Browser', + agent: 'Agent Info', + normalLogin: 'Normal Login', + wechatLogin: 'WeChat Login', + area_code: '区域代码', + country_english: '英文全称', + country_code: '简称', + longitude: '经度', + latitude: '纬度', + login_type: '登录类型', + os: '操作系统', + browser: '浏览器名', + agent: 'Agent信息', + }, + }, + form: { + keywordPlaceholder: 'Enter keyword', + loginIpPlaceholder: 'Enter login IP', + ispPlaceholder: 'Enter ISP', + continentPlaceholder: 'Enter continent', + countryPlaceholder: 'Enter country', + provincePlaceholder: 'Enter province', + cityPlaceholder: 'Enter city', + districtPlaceholder: 'Enter district', + areaCodePlaceholder: 'Enter area code', + countryEnPlaceholder: 'Enter English name', + countryCodePlaceholder: 'Enter short name', + longitudePlaceholder: 'Enter longitude', + latitudePlaceholder: 'Enter latitude', + loginTypePlaceholder: 'Select login type', + osPlaceholder: 'Enter OS', + browserPlaceholder: 'Enter browser', + agentPlaceholder: 'Enter agent info', + area_codePlaceholder: 'Enter area code', + country_englishPlaceholder: 'Enter English name', + country_codePlaceholder: 'Enter short name', + login_typePlaceholder: 'Select login type', + }, + buttons: { + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + query: 'Search', + refresh: 'Refresh', + showChart: 'Show Chart', + hideChart: 'Hide Chart', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/demo/zh-cn.ts b/web/src/i18n/pages/demo/zh-cn.ts new file mode 100644 index 0000000..2bbe9ca --- /dev/null +++ b/web/src/i18n/pages/demo/zh-cn.ts @@ -0,0 +1,64 @@ +// 定义内容 +export default { + message: { + pages: { + demo: { + table: { + columns: { + index: '序号', + keyword: '关键词', + testComponent: '测试自定义组件', + loginIp: '登录IP', + isp: '运营商', + continent: '大洲', + country: '国家', + province: '省份', + city: '城市', + district: '区县', + areaCode: '区域代码', + countryEn: '英文全称', + countryCode: '简称', + longitude: '经度', + latitude: '纬度', + loginType: '登录类型', + os: '操作系统', + browser: '浏览器名', + agent: 'Agent信息', + normalLogin: '普通登录', + wechatLogin: '微信扫码登录', + }, + }, + form: { + keywordPlaceholder: '请输入关键词', + loginIpPlaceholder: '请输入登录IP', + ispPlaceholder: '请输入运营商', + continentPlaceholder: '请输入大洲', + countryPlaceholder: '请输入国家', + provincePlaceholder: '请输入省份', + cityPlaceholder: '请输入城市', + districtPlaceholder: '请输入区县', + areaCodePlaceholder: '请输入区域代码', + countryEnPlaceholder: '请输入英文全称', + countryCodePlaceholder: '请输入简称', + longitudePlaceholder: '请输入经度', + latitudePlaceholder: '请输入纬度', + loginTypePlaceholder: '请选择登录类型', + osPlaceholder: '请输入操作系统', + browserPlaceholder: '请输入浏览器名', + agentPlaceholder: '请输入Agent信息', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + query: '查询', + refresh: '刷新', + showChart: '显示图表', + hideChart: '隐藏图表', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/demo/zh-tw.ts b/web/src/i18n/pages/demo/zh-tw.ts new file mode 100644 index 0000000..5d85a4f --- /dev/null +++ b/web/src/i18n/pages/demo/zh-tw.ts @@ -0,0 +1,72 @@ +// 定義內容 +export default { + message: { + pages: { + demo: { + table: { + columns: { + index: '序號', + keyword: '關鍵詞', + testComponent: '測試自訂元件', + loginIp: '登入IP', + isp: '運營商', + continent: '大洲', + country: '國家', + province: '省份', + city: '城市', + district: '区县', + areaCode: '區域代碼', + countryEn: '英文全稱', + countryCode: '簡稱', + longitude: '經度', + latitude: '緯度', + loginType: '登入類型', + os: '作業系統', + browser: '瀏覽器名', + agent: 'Agent資訊', + normalLogin: '普通登入', + wechatLogin: '微信掃碼登入', + area_code: '區域代碼', + country_english: '英文全稱', + country_code: '簡稱', + login_type: '登入類型', + }, + }, + form: { + keywordPlaceholder: '請輸入關鍵詞', + loginIpPlaceholder: '請輸入登入IP', + ispPlaceholder: '請輸入運營商', + continentPlaceholder: '請輸入大洲', + countryPlaceholder: '請輸入國家', + provincePlaceholder: '請輸入省份', + cityPlaceholder: '請輸入城市', + districtPlaceholder: '請輸入区县', + areaCodePlaceholder: '請輸入區域代碼', + countryEnPlaceholder: '請輸入英文全稱', + countryCodePlaceholder: '請輸入簡稱', + longitudePlaceholder: '請輸入經度', + latitudePlaceholder: '請輸入緯度', + loginTypePlaceholder: '請選擇登入類型', + osPlaceholder: '請輸入作業系統', + browserPlaceholder: '請輸入瀏覽器名', + agentPlaceholder: '請輸入Agent資訊', + area_codePlaceholder: '請輸入區域代碼', + country_englishPlaceholder: '請輸入英文全稱', + country_codePlaceholder: '請輸入簡稱', + login_typePlaceholder: '請選擇登入類型', + }, + buttons: { + add: '新增', + edit: '編輯', + delete: '刪除', + save: '儲存', + cancel: '取消', + query: '查詢', + refresh: '重新整理', + showChart: '顯示圖表', + hideChart: '隱藏圖表', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/dept/en.ts b/web/src/i18n/pages/dept/en.ts new file mode 100644 index 0000000..286d8e5 --- /dev/null +++ b/web/src/i18n/pages/dept/en.ts @@ -0,0 +1,126 @@ +// Define content +export default { + message: { + pages: { + dept: { + table: { + columns: { + deptName: 'Dept Name', + deptCode: 'Dept Code', + parentDept: 'Parent Dept', + sort: 'Sort', + status: 'Status', + createTime: 'Create Time', + actions: 'Actions', + }, + }, + form: { + parentDept: 'Parent Dept', + deptName: 'Dept Name', + deptCode: 'Dept Code', + owner: 'Leader', + remark: 'Remark', + deptNamePlaceholder: 'Please enter dept name', + deptCodePlaceholder: 'Please enter dept code', + ownerPlaceholder: 'Please enter', + remarkPlaceholder: 'Please enter remark', + }, + validation: { + deptNameRequired: 'Dept name is required', + deptCodeRequired: 'Dept code is required', + }, + dialog: { + deptConfig: 'Dept Configuration', + deleteConfirm: 'Are you sure you want to delete this department?', + deleteWarning: 'Cannot delete: this department has child departments or users', + closeConfirm: 'Are you sure you want to close?', + }, + messages: { + addSuccess: 'Added successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + }, + buttons: { + confirm: 'Confirm', + cancel: 'Cancel', + save: 'Save', + add: 'Add', + edit: 'Edit', + delete: 'Delete', + }, + tree: { + deptStructure: 'Dept Structure', + searchPlaceholder: 'Search dept name', + add: 'Add', + edit: 'Edit', + moveUp: 'Move Up', + moveDown: 'Move Down', + delete: 'Delete', + selectDept: 'Please select a department!', + topDept: 'Top Level', + people: 'people', + }, + user: { + deptHeader: 'Dept Info', + deptLeader: 'Leader: ', + deptCount: 'Headcount: ', + deptDesc: 'Description: ', + showChild: 'Show Sub-Depts: ', + yes: 'Yes', + no: 'No', + none: 'None', + peopleUnit: '', + import: 'Import', + resetPwd: 'Reset Password', + pwdPlaceholder: 'Please enter password', + pwdAgainPlaceholder: 'Please confirm password', + selectUser: 'Please select a user!', + inputPwd: 'Please enter password!', + pwdMismatch: 'Passwords do not match', + pwdComplexity: 'Password is too simple (must contain letters and numbers)', + changeSuccess: 'Changed successfully!', + searchPlaceholder: 'Search username/nickname', + tableColumns: { + index: '#', + keyword: 'Keyword', + keywordPlaceholder: 'Enter keyword', + username: 'Username', + usernamePlaceholder: 'Enter username', + usernameRequired: 'Username is required', + password: 'Password', + passwordPlaceholder: 'Enter password', + passwordRequired: 'Password is required', + name: 'Name', + namePlaceholder: 'Enter name', + nameRequired: 'Name is required', + dept: 'Department', + selectDeptPlaceholder: 'Select', + deptRequired: 'Required', + role: 'Role', + rolePlaceholder: 'Select role', + roleRequired: 'Required', + mobile: 'Mobile', + mobilePlaceholder: 'Enter mobile number', + mobileInvalid: 'Invalid mobile number', + email: 'Email', + emailPlaceholder: 'Enter email', + emailInvalid: 'Invalid email address', + gender: 'Gender', + userType: 'User Type', + locked: 'Locked', + avatar: 'Avatar', + actions: 'Actions', + export: 'Export', + add: 'Add', + edit: 'Edit', + delete: 'Delete', + resetPassword: 'Reset Password', + resetPasswordTooltip: 'Reset Password', + }, + deleteUserConfirm: 'Delete this user?', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/dept/zh-cn.ts b/web/src/i18n/pages/dept/zh-cn.ts new file mode 100644 index 0000000..2177452 --- /dev/null +++ b/web/src/i18n/pages/dept/zh-cn.ts @@ -0,0 +1,126 @@ +// 定义内容 +export default { + message: { + pages: { + dept: { + table: { + columns: { + deptName: '部门名称', + deptCode: '部门编码', + parentDept: '上级部门', + sort: '排序', + status: '状态', + createTime: '创建时间', + actions: '操作', + }, + }, + form: { + parentDept: '父级部门', + deptName: '部门名称', + deptCode: '部门标识', + owner: '负责人', + remark: '备注', + deptNamePlaceholder: '请输入部门名称', + deptCodePlaceholder: '请输入部门标识', + ownerPlaceholder: '请输入', + remarkPlaceholder: '请输入备注', + }, + validation: { + deptNameRequired: '部门名称必填', + deptCodeRequired: '部门标识必填', + }, + dialog: { + deptConfig: '部门配置', + deleteConfirm: '您确认删除该部门吗?', + deleteWarning: '该部门下存在子部门或用户,无法删除', + closeConfirm: '您确定要关闭?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + }, + buttons: { + confirm: '确认', + cancel: '取消', + save: '保存', + add: '新增', + edit: '编辑', + delete: '删除', + }, + tree: { + deptStructure: '部门架构', + searchPlaceholder: '请输入部门名称', + add: '新增', + edit: '编辑', + moveUp: '上移', + moveDown: '下移', + delete: '删除', + selectDept: '请选择部门!', + topDept: '顶级部门', + people: '人', + }, + user: { + deptHeader: '部门信息', + deptLeader: '部门负责人:', + deptCount: '部门人数:', + deptDesc: '部门简介:', + showChild: '显示子级:', + yes: '是', + no: '否', + none: '无', + peopleUnit: '人', + import: '导入', + resetPwd: '重设密码', + pwdPlaceholder: '请输入密码', + pwdAgainPlaceholder: '请再次输入密码', + selectUser: '请选择用户!', + inputPwd: '请输入密码!', + pwdMismatch: '两次输入密码不一致', + pwdComplexity: '您的密码复杂度太低(密码中必须包含字母、数字)', + changeSuccess: '修改成功!', + searchPlaceholder: '搜索用户名/昵称', + tableColumns: { + index: '序号', + keyword: '关键词', + keywordPlaceholder: '请输入关键词', + username: '账号', + usernamePlaceholder: '请输入账号', + usernameRequired: '账号必填项', + password: '密码', + passwordPlaceholder: '请输入密码', + passwordRequired: '密码必填项', + name: '姓名', + namePlaceholder: '请输入姓名', + nameRequired: '姓名必填项', + dept: '部门', + selectDeptPlaceholder: '请选择', + deptRequired: '必填项', + role: '角色', + rolePlaceholder: '请选择角色', + roleRequired: '必填项', + mobile: '手机号码', + mobilePlaceholder: '请输入手机号码', + mobileInvalid: '请输入正确的手机号码', + email: '邮箱', + emailPlaceholder: '请输入邮箱', + emailInvalid: '请输入正确的邮箱地址', + gender: '性别', + userType: '用户类型', + locked: '锁定', + avatar: '头像', + actions: '操作', + export: '导出', + add: '新增', + edit: '编辑', + delete: '删除', + resetPassword: '重设密码', + resetPasswordTooltip: '重设密码', + }, + deleteUserConfirm: '是否删除该用户?', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/dept/zh-tw.ts b/web/src/i18n/pages/dept/zh-tw.ts new file mode 100644 index 0000000..e69de29 diff --git a/web/src/i18n/pages/dictionary/en.ts b/web/src/i18n/pages/dictionary/en.ts new file mode 100644 index 0000000..3ef094f --- /dev/null +++ b/web/src/i18n/pages/dictionary/en.ts @@ -0,0 +1,114 @@ +// Define content +export default { + message: { + pages: { + dictionary: { + table: { + columns: { + index: 'No.', + keyword: 'Keyword', + dictName: 'Dict Name', + dictCode: 'Dict Code', + status: 'Status', + remark: 'Remark', + sort: 'Sort', + createTime: 'Create Time', + actions: 'Actions', + }, + }, + subTable: { + columns: { + index: 'No.', + keyword: 'Keyword', + label: 'Dict Label', + value: 'Dict Value', + type: 'Data Type', + status: 'Status', + sort: 'Sort', + color: 'Color', + isValue: 'Is Value', + remark: 'Remark', + createTime: 'Create Time', + actions: 'Actions', + }, + typeLabels: { + text: 'Text', + number: 'Number', + date: 'Date', + datetime: 'Datetime', + time: 'Time', + file: 'File', + boolean: 'Boolean', + images: 'Images', + }, + form: { + labelPlaceholder: 'Enter dict label', + typePlaceholder: 'Select data type', + valuePlaceholder: 'Enter dict value', + }, + validation: { + labelRequired: 'Please enter dict label', + typeRequired: 'Please select data type', + valueRequired: 'Please enter dict value', + statusRequired: 'Please select status', + sortRequired: 'Please enter sort', + }, + }, + form: { + dictName: 'Dict Name', + dictCode: 'Dict Code', + status: 'Status', + remark: 'Remark', + sort: 'Sort', + keywordPlaceholder: 'Enter keyword', + dictNamePlaceholder: 'Enter dict name', + dictCodePlaceholder: 'Enter dict code', + remarkPlaceholder: 'Enter remark', + dictLabel: 'Dict Label', + dictValue: 'Dict Value', + dictType: 'Dict Type', + dictLabelPlaceholder: 'Enter dict label', + dictValuePlaceholder: 'Enter dict value', + dictCodeHelper: 'Usage: dictionary(\'dictCode\')', + }, + validation: { + dictNameRequired: 'Dict name is required', + dictNameMaxLength: 'Dict name must be 100 characters or less', + dictNameDuplicate: 'Dict name already exists', + dictCodeRequired: 'Dict code is required', + dictCodeMaxLength: 'Dict code must be 100 characters or less', + dictCodeDuplicate: 'Dict code already exists', + dictLabelRequired: 'Dict label is required', + dictValueRequired: 'Dict value is required', + }, + dialog: { + addDict: 'Add Dict', + editDict: 'Edit Dict', + addDictData: 'Add Dict Data', + editDictData: 'Edit Dict Data', + deleteConfirm: 'Delete this dict?', + closeConfirm: 'Are you sure you want to close?', + }, + messages: { + addSuccess: 'Added successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + }, + buttons: { + view: 'View', + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + confirm: 'Confirm', + query: 'Query', + refresh: 'Refresh', + addDictData: 'Add Dict Data', + dictConfig: 'Dict Config', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/dictionary/zh-cn.ts b/web/src/i18n/pages/dictionary/zh-cn.ts new file mode 100644 index 0000000..4e1c58d --- /dev/null +++ b/web/src/i18n/pages/dictionary/zh-cn.ts @@ -0,0 +1,103 @@ +// 定义内容 +export default { + message: { + pages: { + dictionary: { + table: { + columns: { + index: '序号', + keyword: '关键词', + dictName: '字典名称', + dictCode: '字典编码', + status: '状态', + remark: '备注', + sort: '排序', + createTime: '创建时间', + actions: '操作', + }, + }, + subTable: { + columns: { + index: '序号', + keyword: '关键词', + label: '字典标签', + value: '字典键值', + type: '数据类型', + status: '状态', + sort: '排序', + color: '颜色', + isValue: '是否值', + remark: '备注', + createTime: '创建时间', + actions: '操作', + }, + form: { + labelPlaceholder: '请输入字典标签', + typePlaceholder: '请选择数据类型', + valuePlaceholder: '请输入字典键值', + }, + validation: { + labelRequired: '请输入字典标签', + typeRequired: '请选择数据类型', + valueRequired: '请输入字典键值', + statusRequired: '请选择状态', + sortRequired: '请输入排序', + }, + }, + form: { + dictName: '字典名称', + dictCode: '字典编码', + status: '状态', + remark: '备注', + sort: '排序', + keywordPlaceholder: '请输入关键词', + dictNamePlaceholder: '请输入字典名称', + dictCodePlaceholder: '请输入字典编码', + remarkPlaceholder: '请输入备注', + dictLabel: '字典标签', + dictValue: '字典键值', + dictType: '字典类型', + dictLabelPlaceholder: '请输入字典标签', + dictValuePlaceholder: '请输入字典键值', + dictCodeHelper: '使用方法:dictionary(\'字典编号\')', + }, + validation: { + dictNameRequired: '请输入字典名称', + dictNameMaxLength: '字典名称不能超过100个字符', + dictNameDuplicate: '字典名称已存在', + dictCodeRequired: '请输入字典编码', + dictCodeMaxLength: '字典编码不能超过100个字符', + dictCodeDuplicate: '字典编码已存在', + dictLabelRequired: '请输入字典标签', + dictValueRequired: '请输入字典键值', + }, + dialog: { + addDict: '新增字典', + editDict: '编辑字典', + addDictData: '新增字典数据', + editDictData: '编辑字典数据', + deleteConfirm: '确定删除该字典吗?', + closeConfirm: '您确定要关闭吗?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + confirm: '确定', + query: '查询', + refresh: '刷新', + addDictData: '新增字典数据', + dictConfig: '字典配置', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/dictionary/zh-tw.ts b/web/src/i18n/pages/dictionary/zh-tw.ts new file mode 100644 index 0000000..44a6d37 --- /dev/null +++ b/web/src/i18n/pages/dictionary/zh-tw.ts @@ -0,0 +1,104 @@ +// 定義內容 +export default { + message: { + pages: { + dictionary: { + table: { + columns: { + index: '序號', + keyword: '關鍵詞', + dictName: '字典名稱', + dictCode: '字典編碼', + status: '狀態', + remark: '備註', + sort: '排序', + createTime: '創建時間', + actions: '操作', + }, + }, + subTable: { + columns: { + index: '序號', + keyword: '關鍵詞', + label: '字典標籤', + value: '字典鍵值', + type: '資料類型', + status: '狀態', + sort: '排序', + color: '顏色', + isValue: '是否值', + remark: '備註', + createTime: '創建時間', + actions: '操作', + }, + form: { + labelPlaceholder: '請輸入字典標籤', + typePlaceholder: '請選擇資料類型', + valuePlaceholder: '請輸入字典鍵值', + }, + validation: { + labelRequired: '請輸入字典標籤', + typeRequired: '請選擇資料類型', + valueRequired: '請輸入字典鍵值', + statusRequired: '請選擇狀態', + sortRequired: '請輸入排序', + }, + }, + form: { + dictName: '字典名稱', + dictCode: '字典編碼', + status: '狀態', + remark: '備註', + sort: '排序', + keywordPlaceholder: '請輸入關鍵詞', + dictNamePlaceholder: '請輸入字典名稱', + dictCodePlaceholder: '請輸入字典編碼', + remarkPlaceholder: '請輸入備註', + dictLabel: '字典標籤', + dictValue: '字典鍵值', + dictType: '字典類型', + dictLabelPlaceholder: '請輸入字典標籤', + dictValuePlaceholder: '請輸入字典鍵值', + dictCodeHelper: '使用方法:dictionary(\'字典編號\')', + }, + validation: { + dictNameRequired: '請輸入字典名稱', + dictNameMaxLength: '字典名稱不能超過100個字符', + dictNameDuplicate: '字典名稱已存在', + dictCodeRequired: '請輸入字典編碼', + dictCodeMaxLength: '字典編碼不能超過100個字符', + dictCodeDuplicate: '字典編碼已存在', + dictLabelRequired: '請輸入字典標籤', + dictValueRequired: '請輸入字典鍵值', + }, + dialog: { + addDict: '新增字典', + editDict: '編輯字典', + addDictData: '新增字典數據', + editDictData: '編輯字典數據', + deleteConfirm: '確定刪除該字典嗎?', + closeConfirm: '您確定要關閉嗎?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + }, + buttons: { + view: '查看', + add: '新增', + edit: '編輯', + delete: '刪除', + save: '保存', + cancel: '取消', + confirm: '確定', + query: '查詢', + refresh: '刷新', + addDictData: '新增字典數據', + dictConfig: '字典配置', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/downloadCenter/en.ts b/web/src/i18n/pages/downloadCenter/en.ts new file mode 100644 index 0000000..56ffd20 --- /dev/null +++ b/web/src/i18n/pages/downloadCenter/en.ts @@ -0,0 +1,30 @@ +// Define content +export default { + message: { + pages: { + downloadCenter: { + table: { + columns: { + index: 'No.', + taskName: 'Task Name', + fileName: 'File Name', + size: 'Size (b)', + taskStatus: 'Task Status', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + }, + status: { + created: 'Created', + processing: 'Processing', + completed: 'Completed', + failed: 'Failed', + }, + buttons: { + downloadFile: 'Download File', + search: 'Search', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/downloadCenter/zh-cn.ts b/web/src/i18n/pages/downloadCenter/zh-cn.ts new file mode 100644 index 0000000..c4617ca --- /dev/null +++ b/web/src/i18n/pages/downloadCenter/zh-cn.ts @@ -0,0 +1,30 @@ +// 定义内容 +export default { + message: { + pages: { + downloadCenter: { + table: { + columns: { + index: '序号', + taskName: '任务名', + fileName: '文件名', + size: '文件大小(b)', + taskStatus: '任务状态', + createTime: '创建时间', + updateTime: '更新时间', + }, + }, + status: { + created: '任务已创建', + processing: '任务进行中', + completed: '任务完成', + failed: '任务失败', + }, + buttons: { + downloadFile: '下载文件', + search: '查询', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/downloadCenter/zh-tw.ts b/web/src/i18n/pages/downloadCenter/zh-tw.ts new file mode 100644 index 0000000..3ea95b7 --- /dev/null +++ b/web/src/i18n/pages/downloadCenter/zh-tw.ts @@ -0,0 +1,30 @@ +// 定義內容 +export default { + message: { + pages: { + downloadCenter: { + table: { + columns: { + index: '序號', + taskName: '任務名', + fileName: '文件名', + size: '檔案大小(b)', + taskStatus: '任務狀態', + createTime: '創建時間', + updateTime: '更新時間', + }, + }, + status: { + created: '任務已創建', + processing: '任務進行中', + completed: '任務完成', + failed: '任務失敗', + }, + buttons: { + downloadFile: '下載檔案', + search: '查詢', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/fileList/en.ts b/web/src/i18n/pages/fileList/en.ts new file mode 100644 index 0000000..881e2db --- /dev/null +++ b/web/src/i18n/pages/fileList/en.ts @@ -0,0 +1,58 @@ +// Define content +export default { + message: { + pages: { + fileList: { + table: { + columns: { + index: 'No.', + keyword: 'Keyword', + name: 'File Name', + preview: 'Preview', + url: 'File URL', + md5sum: 'MD5', + mimeType: 'MIME Type', + fileType: 'File Type', + size: 'File Size', + uploadMethod: 'Upload Method', + createTime: 'Create Time', + }, + }, + form: { + keywordPlaceholder: 'Enter keyword', + namePlaceholder: 'Enter file name', + fileTypePlaceholder: 'Select file type', + }, + fileType: { + image: 'Image', + video: 'Video', + audio: 'Audio', + document: 'Document', + other: 'Other', + unknown: 'Unknown', + }, + tabs: { + image: 'Image', + video: 'Video', + audio: 'Audio', + other: 'Other', + }, + uploadMethod: { + default: 'Default Upload', + selector: 'File Selector Upload', + }, + buttons: { + upload: 'Upload', + add: 'Add', + edit: 'Edit', + delete: 'Delete', + }, + size: { + bytes: 'B', + kilobytes: 'KB', + megabytes: 'MB', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/fileList/zh-cn.ts b/web/src/i18n/pages/fileList/zh-cn.ts new file mode 100644 index 0000000..97242d6 --- /dev/null +++ b/web/src/i18n/pages/fileList/zh-cn.ts @@ -0,0 +1,58 @@ +// 定义内容 +export default { + message: { + pages: { + fileList: { + table: { + columns: { + index: '序号', + keyword: '关键词', + name: '文件名称', + preview: '预览', + url: '文件地址', + md5sum: '文件MD5', + mimeType: '文件类型(MIME)', + fileType: '文件类型', + size: '文件大小', + uploadMethod: '上传方式', + createTime: '创建时间', + }, + }, + form: { + keywordPlaceholder: '请输入关键词', + namePlaceholder: '请输入文件名称', + fileTypePlaceholder: '请选择文件类型', + }, + fileType: { + image: '图片', + video: '视频', + audio: '音频', + document: '文档', + other: '其他', + unknown: '未知类型', + }, + tabs: { + image: '图片', + video: '视频', + audio: '音频', + other: '其他', + }, + uploadMethod: { + default: '默认上传', + selector: '文件选择器上传', + }, + buttons: { + upload: '上传', + add: '新增', + edit: '编辑', + delete: '删除', + }, + size: { + bytes: 'B', + kilobytes: 'KB', + megabytes: 'MB', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/fileList/zh-tw.ts b/web/src/i18n/pages/fileList/zh-tw.ts new file mode 100644 index 0000000..7eb54b2 --- /dev/null +++ b/web/src/i18n/pages/fileList/zh-tw.ts @@ -0,0 +1,58 @@ +// 定義內容 +export default { + message: { + pages: { + fileList: { + table: { + columns: { + index: '序號', + keyword: '關鍵詞', + name: '文件名稱', + preview: '預覽', + url: '文件地址', + md5sum: '文件MD5', + mimeType: '文件類型(MIME)', + fileType: '文件類型', + size: '文件大小', + uploadMethod: '上傳方式', + createTime: '創建時間', + }, + }, + form: { + keywordPlaceholder: '請輸入關鍵詞', + namePlaceholder: '請輸入文件名稱', + fileTypePlaceholder: '請選擇文件類型', + }, + fileType: { + image: '圖片', + video: '視頻', + audio: '音頻', + document: '文檔', + other: '其他', + unknown: '未知類型', + }, + tabs: { + image: '圖片', + video: '視頻', + audio: '音頻', + other: '其他', + }, + uploadMethod: { + default: '預設上傳', + selector: '檔案選擇器上傳', + }, + buttons: { + upload: '上傳', + add: '新增', + edit: '編輯', + delete: '刪除', + }, + size: { + bytes: 'b', + kilobytes: 'Kb', + megabytes: 'Mb', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/home/en.ts b/web/src/i18n/pages/home/en.ts new file mode 100644 index 0000000..924dc48 --- /dev/null +++ b/web/src/i18n/pages/home/en.ts @@ -0,0 +1,182 @@ +// Define content +export default { + message: { + pages: { + home: { + statCards: { + orderStats: 'Order Statistics', + monthlyPlan: 'Monthly Plan Info', + visitStats: 'Visit Statistics', + }, + chart: { + // Line chart (政策补贴额度) + lineTitle: 'Policy Subsidy Quota', + lineLegendPreOrder: 'Pre-Order Queue', + lineLegendLatestPrice: 'Latest Transaction Price', + lineYAxisName: 'Price', + month: '', + // Pie chart (房屋建筑工程) + pieTitle: 'Building & Structural Engineering', + pieCategory1: 'Buildings & Structures', + pieCategory2: 'Special Equipment', + pieCategory3: 'General Equipment', + pieCategory4: 'Cultural Relics & Exhibits', + pieCategory5: 'Books & Archives', + // Bar chart (地热开发利用) + barTitle: 'Geothermal Development & Utilization', + barLegendSupplyTemp: 'Supply Temperature', + barLegendReturnTemp: 'Return Temperature', + barLegendPressure: 'Pressure (Mpa)', + barYAxisSupplyReturn: 'Supply/Return Temp (℃)', + }, + quickNav: { + quickNavTitle: 'Quick Navigation', + }, + notifications: { + defaultCreator: 'Unknown User', + }, + buyerDashboard: { + roleSwitch: { + buyer: 'Buyer Dashboard', + supplier: 'Supplier Dashboard', + }, + kpi: { + totalInquiries: 'Total Completed Inquiries', + pendingInquiries: 'Pending Inquiries', + quoteTimelyRate: 'Quote Timely Rate', + trendUp: '+12% vs last month', + trendFlat: 'Flat', + }, + task: { + title: 'My Tasks', + empty: 'No pending tasks', + table: { + columns: { + inquiryNo: 'Inquiry No.', + method: 'Procurement Method', + name: 'Inquiry Name', + status: 'Status', + deadline: 'Deadline / Remaining', + action: 'Action', + }, + }, + status: { + bidCompare: 'Bid Comparison', + published: 'Published', + negotiation: 'Negotiation', + urgent: 'Urgent', + default: '', + }, + action: { + goBidCompare: 'Go to Compare', + goNegotiate: 'Go to Negotiate', + viewDetail: 'View Details', + }, + }, + deadline: { + bidTime: 'Bid Time:', + quoteDeadline: 'Quote Deadline:', + remaining: 'Remaining:', + bidInProgress: 'Bid in Progress', + ended: 'Ended', + started: 'Started', + expired: 'Expired', + }, + notification: { + title: 'System Notifications', + empty: 'No notifications', + defaultCreator: 'Unknown User', + }, + quickNav: { + title: 'Quick Navigation', + items: { + role: 'Role Management', + dept: 'Department Management', + config: 'System Config', + dictionary: 'Dictionary Management', + areas: 'Area Management', + message: 'Message Center', + }, + }, + chart: { + title: 'Last 30 Days Trend', + legend: { + publishInquiry: 'Inquiries Published', + negotiationComplete: 'Negotiations Complete', + }, + yAxisName: 'Count', + }, + viewAll: 'View All', + more: 'More', + method: { + inquiry: 'Inquiry', + tender: 'Tender', + }, + }, + supplierDashboard: { + kpi: { + totalQuotes: 'Total Quotes', + pendingQuotes: 'Pending Quotes', + wonQuotes: 'Won Quotes', + conversionRate: 'Win Rate', + trendUp: '+8% vs last month', + waiting: 'Awaiting Quote', + winSuccess: 'Won Successfully', + trendFlat: 'Flat', + }, + quoteList: { + title: 'Pending Quote List', + empty: 'No pending quotes', + columns: { + inquiryNo: 'Inquiry No.', + status: 'Status', + method: 'Procurement Method', + deadline: 'Deadline', + action: 'Action', + }, + productName: 'Product Name', + quantity: 'Quantity', + }, + quoteStatus: { + unquoted: 'Unquoted', + quoting: 'Quoting', + quoted: 'Quoted', + }, + quoteAction: { + goQuote: 'Go to Quote', + }, + notification: { + title: 'System Notifications', + empty: 'No notifications', + defaultCreator: 'Unknown User', + }, + quickNav: { + title: 'Quick Navigation', + items: { + role: 'Role Management', + dept: 'Department Management', + config: 'System Config', + dictionary: 'Dictionary Management', + areas: 'Area Management', + message: 'Message Center', + }, + }, + chart: { + title: 'Quote & Win Trend', + legend: { + quotes: 'Quotes', + won: 'Won', + }, + yAxisName: 'Count', + }, + viewAll: 'View All', + more: 'More', + method: { + inquiry: 'Inquiry', + tender: 'Tender', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/home/zh-cn.ts b/web/src/i18n/pages/home/zh-cn.ts new file mode 100644 index 0000000..8a53562 --- /dev/null +++ b/web/src/i18n/pages/home/zh-cn.ts @@ -0,0 +1,182 @@ +// 定义内容 +export default { + message: { + pages: { + home: { + statCards: { + orderStats: '订单统计信息', + monthlyPlan: '月度计划信息', + visitStats: '访问统计信息', + }, + chart: { + // Line chart (政策补贴额度) + lineTitle: '政策补贴额度', + lineLegendPreOrder: '预购队列', + lineLegendLatestPrice: '最新成交价', + lineYAxisName: '价格', + month: '月', + // Pie chart (房屋建筑工程) + pieTitle: '房屋建筑工程', + pieCategory1: '房屋及结构物', + pieCategory2: '专用设备', + pieCategory3: '通用设备', + pieCategory4: '文物和陈列品', + pieCategory5: '图书、档案', + // Bar chart (地热开发利用) + barTitle: '地热开发利用', + barLegendSupplyTemp: '供温', + barLegendReturnTemp: '回温', + barLegendPressure: '压力值(Mpa)', + barYAxisSupplyReturn: '供回温度(℃)', + }, + quickNav: { + quickNavTitle: '快捷导航工具', + }, + notifications: { + defaultCreator: '未知用户', + }, + buyerDashboard: { + roleSwitch: { + buyer: '采购方仪表盘', + supplier: '供应商仪表盘', + }, + kpi: { + totalInquiries: '已完成询价单总数', + pendingInquiries: '进行中询价单', + quoteTimelyRate: '供应商报价及时率', + trendUp: '较上月 +12%', + trendFlat: '持平', + }, + task: { + title: '我的待办任务', + empty: '暂无待办任务', + table: { + columns: { + inquiryNo: '询价单号', + method: '采购方式', + name: '询价单名称', + status: '当前状态', + deadline: '截止时间 / 剩余时间', + action: '操作', + }, + }, + status: { + bidCompare: '比价', + published: '发布', + negotiation: '议价', + urgent: '紧急', + default: '', + }, + action: { + goBidCompare: '去比价', + goNegotiate: '去议价', + viewDetail: '查看详情', + }, + }, + deadline: { + bidTime: '投标时间:', + quoteDeadline: '报价截止时间:', + remaining: '剩余:', + bidInProgress: '投标进行中', + ended: '已结束', + started: '已开始', + expired: '已到期', + }, + notification: { + title: '系统通知', + empty: '暂无通知', + defaultCreator: '未知用户', + }, + quickNav: { + title: '快捷入口', + items: { + role: '角色管理', + dept: '部门管理', + config: '系统配置', + dictionary: '字典管理', + areas: '区域管理', + message: '消息中心', + }, + }, + chart: { + title: '近30天业务趋势', + legend: { + publishInquiry: '发布询价', + negotiationComplete: '议价完成', + }, + yAxisName: '单据数量', + }, + viewAll: '查看全部', + more: '更多', + method: { + inquiry: '询价', + tender: '招标', + }, + }, + supplierDashboard: { + kpi: { + totalQuotes: '报价单总数', + pendingQuotes: '待报价', + wonQuotes: '已中标', + conversionRate: '中标率', + trendUp: '较上月 +8%', + waiting: '等待报价', + winSuccess: '中标成功', + trendFlat: '持平', + }, + quoteList: { + title: '待报价清单', + empty: '暂无待报价清单', + columns: { + inquiryNo: '询价单号', + status: '状态', + method: '采购方式', + deadline: '截止时间', + action: '操作', + }, + productName: '产品名称', + quantity: '数量', + }, + quoteStatus: { + unquoted: '未报价', + quoting: '报价中', + quoted: '已报价', + }, + quoteAction: { + goQuote: '去报价', + }, + notification: { + title: '系统通知', + empty: '暂无通知', + defaultCreator: '未知用户', + }, + quickNav: { + title: '快捷入口', + items: { + role: '角色管理', + dept: '部门管理', + config: '系统配置', + dictionary: '字典管理', + areas: '区域管理', + message: '消息中心', + }, + }, + chart: { + title: '报价与中标趋势', + legend: { + quotes: '报价数', + won: '中标数', + }, + yAxisName: '单据数量', + }, + viewAll: '查看全部', + more: '更多', + method: { + inquiry: '询价', + tender: '招标', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/home/zh-tw.ts b/web/src/i18n/pages/home/zh-tw.ts new file mode 100644 index 0000000..393d918 --- /dev/null +++ b/web/src/i18n/pages/home/zh-tw.ts @@ -0,0 +1,182 @@ +// Define content +export default { + message: { + pages: { + home: { + statCards: { + orderStats: '訂單統計信息', + monthlyPlan: '月度計劃信息', + visitStats: '訪問統計信息', + }, + chart: { + // Line chart (政策补贴额度) + lineTitle: '政策補貼額度', + lineLegendPreOrder: '預購隊列', + lineLegendLatestPrice: '最新成交價', + lineYAxisName: '價格', + month: '月', + // Pie chart (房屋建筑工程) + pieTitle: '房屋建築工程', + pieCategory1: '房屋及結構物', + pieCategory2: '專用設備', + pieCategory3: '通用設備', + pieCategory4: '文物和陳列品', + pieCategory5: '圖書、檔案', + // Bar chart (地热开发利用) + barTitle: '地熱開發利用', + barLegendSupplyTemp: '供溫', + barLegendReturnTemp: '回溫', + barLegendPressure: '壓力值(Mpa)', + barYAxisSupplyReturn: '供回溫度(℃)', + }, + quickNav: { + quickNavTitle: '快捷導航工具', + }, + notifications: { + defaultCreator: '未知用戶', + }, + buyerDashboard: { + roleSwitch: { + buyer: '採購方儀表盤', + supplier: '供應商儀表盤', + }, + kpi: { + totalInquiries: '已完成詢價單總數', + pendingInquiries: '進行中詢價單', + quoteTimelyRate: '供應商報價及時率', + trendUp: '較上月 +12%', + trendFlat: '持平', + }, + task: { + title: '我的待辦任務', + empty: '暫無待辦任務', + table: { + columns: { + inquiryNo: '詢價單號', + method: '採購方式', + name: '詢價單名稱', + status: '當前狀態', + deadline: '截止時間 / 剩餘時間', + action: '操作', + }, + }, + status: { + bidCompare: '比價', + published: '發布', + negotiation: '議價', + urgent: '緊急', + default: '', + }, + action: { + goBidCompare: '去比價', + goNegotiate: '去議價', + viewDetail: '查看詳情', + }, + }, + deadline: { + bidTime: '投標時間:', + quoteDeadline: '報價截止時間:', + remaining: '剩餘:', + bidInProgress: '投標進行中', + ended: '已結束', + started: '已開始', + expired: '已到期', + }, + notification: { + title: '系統通知', + empty: '暫無通知', + defaultCreator: '未知用戶', + }, + quickNav: { + title: '快捷入口', + items: { + role: '角色管理', + dept: '部門管理', + config: '系統配置', + dictionary: '字典管理', + areas: '區域管理', + message: '消息中心', + }, + }, + chart: { + title: '近30天業務趨勢', + legend: { + publishInquiry: '發布詢價', + negotiationComplete: '議價完成', + }, + yAxisName: '單據數量', + }, + viewAll: '查看全部', + more: '更多', + method: { + inquiry: '詢價', + tender: '招標', + }, + }, + supplierDashboard: { + kpi: { + totalQuotes: '報價單總數', + pendingQuotes: '待報價', + wonQuotes: '已中標', + conversionRate: '中標率', + trendUp: '較上月 +8%', + waiting: '等待報價', + winSuccess: '中標成功', + trendFlat: '持平', + }, + quoteList: { + title: '待報價清單', + empty: '暫無待報價清單', + columns: { + inquiryNo: '詢價單號', + status: '狀態', + method: '採購方式', + deadline: '截止時間', + action: '操作', + }, + productName: '產品名稱', + quantity: '數量', + }, + quoteStatus: { + unquoted: '未報價', + quoting: '報價中', + quoted: '已報價', + }, + quoteAction: { + goQuote: '去報價', + }, + notification: { + title: '系統通知', + empty: '暫無通知', + defaultCreator: '未知用戶', + }, + quickNav: { + title: '快捷入口', + items: { + role: '角色管理', + dept: '部門管理', + config: '系統配置', + dictionary: '字典管理', + areas: '區域管理', + message: '消息中心', + }, + }, + chart: { + title: '報價與中標趨勢', + legend: { + quotes: '報價數', + won: '中標數', + }, + yAxisName: '單據數量', + }, + viewAll: '查看全部', + more: '更多', + method: { + inquiry: '詢價', + tender: '招標', + }, + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/layout/en.ts b/web/src/i18n/pages/layout/en.ts new file mode 100644 index 0000000..05b9889 --- /dev/null +++ b/web/src/i18n/pages/layout/en.ts @@ -0,0 +1,72 @@ +// 定义内容 +export default { + message: { + layout: { + configTitle: 'Interface Settings', + oneTitle: 'Global Theme', + twoTopTitle: 'Top Bar Theme', + twoTopBar: 'Top Bar Background', + twoTopBarColor: 'Top Bar Color', + twoIsTopBarColorGradual: 'Top Bar Gradient', + twoMenuTitle: 'Menu Theme', + twoMenuBar: 'Menu Background', + twoMenuBarColor: 'Menu Background Color', + twoMenuBarActiveColor: 'Menu Active Background', + twoIsMenuBarColorGradual: 'Menu Background Gradient', + twoColumnsTitle: 'Columns Menu', + twoColumnsMenuBar: 'Columns Menu Background', + twoColumnsMenuBarColor: 'Columns Menu Background Color', + twoIsColumnsMenuBarColorGradual: 'Columns Menu Gradient', + twoIsColumnsMenuHoverPreload: 'Columns Menu Hover Preload', + threeTitle: 'Interface Settings', + threeIsCollapse: 'Collapse Menu', + threeIsUniqueOpened: 'Accordion Menu', + threeIsFixedHeader: 'Fixed Header', + threeIsClassicSplitMenu: 'Classic Split Menu', + threeIsLockScreen: 'Enable Lock Screen', + threeLockScreenTime: 'Auto Lock (minutes)', + fourTitle: 'Display Settings', + fourIsDark: 'Dark Theme', + fourIsShowLogo: 'Show Logo', + fourIsBreadcrumb: 'Breadcrumb', + fourIsBreadcrumbIcon: 'Breadcrumb Icon', + fourIsTagsview: 'Tags View', + fourIsTagsviewIcon: 'Tags View Icon', + fourIsCacheTagsView: 'Fixed Tags View', + fourIsSortableTagsView: 'Draggable Tags View', + fourIsShareTagsView: 'Share Tags View', + fourIsFooter: 'Footer', + fourIsGrayscale: 'Grayscale Mode', + fourIsInvert: 'Invert Mode', + fourIsWartermark: 'Enable Watermark', + fourWartermarkText: 'Watermark Text', + fiveTitle: 'Animation', + fiveTagsStyle: 'Tags Style', + fiveAnimation: 'Page Transition', + fiveColumnsAsideStyle: 'Columns Aside Style', + fiveColumnsAsideLayout: 'Columns Aside Layout', + horizontal: 'Horizontal', + vertical: 'Vertical', + card: 'Card', + rounded: 'Rounded', + sixTitle: 'Layout Presets', + sixDefaults: 'Default', + sixClassic: 'Classic', + sixTransverse: 'Transverse', + sixColumns: 'Columns', + tipText: 'Click the button below to configure ↓', + copyText: 'Copy', + resetText: 'Reset', + selectPlaceholder: 'Please select', + style1: 'Style 1', + style4: 'Style 4', + style5: 'Style 5', + animation1: 'Slide Right', + animation2: 'Fade', + animation3: 'Opacity', + animation4: 'Slide Up', + animation5: 'Scale Fade', + animation6: 'Scroll', + }, + }, +}; diff --git a/web/src/i18n/pages/layout/zh-cn.ts b/web/src/i18n/pages/layout/zh-cn.ts new file mode 100644 index 0000000..494826c --- /dev/null +++ b/web/src/i18n/pages/layout/zh-cn.ts @@ -0,0 +1,71 @@ +// 定义内容 +export default { + message: { + layout: { + configTitle: '界面配置', + oneTitle: '整体样式', + twoTopTitle: '顶部主题', + twoTopBar: '顶栏背景色', + twoTopBarColor: '顶栏背景色渐变', + twoMenuTitle: '菜单主题', + twoMenuBar: '菜单背景色', + twoMenuBarColor: '菜单背景色渐变', + twoMenuBarActiveColor: '菜单高亮背景色', + twoIsMenuBarColorGradual: '菜单背景渐变', + twoColumnsTitle: '分栏菜单', + twoColumnsMenuBar: '分栏菜单背景色', + twoColumnsMenuBarColor: '分栏菜单背景渐变', + twoIsColumnsMenuBarColorGradual: '分栏菜单背景渐变', + twoIsColumnsMenuHoverPreload: '分栏菜单hover预加载', + threeTitle: '界面设置', + threeIsCollapse: '菜单水平折叠', + threeIsUniqueOpened: '菜单手风琴', + threeIsFixedHeader: '固定 Header', + threeIsClassicSplitMenu: '经典分割菜单', + threeIsLockScreen: '开启锁屏', + threeLockScreenTime: '自动锁屏(分钟)', + fourTitle: '显示设置', + fourIsDark: '深色主题', + fourIsShowLogo: '侧边栏 Logo', + fourIsBreadcrumb: '面包屑导航', + fourIsBreadcrumbIcon: '面包屑导航图标', + fourIsTagsview: '标签栏', + fourIsTagsviewIcon: '标签栏图标', + fourIsCacheTagsView: '是否固定标签栏', + fourIsSortableTagsView: '标签栏拖拽', + fourIsShareTagsView: '标签栏跨域联动', + fourIsFooter: '页脚', + fourIsGrayscale: '灰色模式', + fourIsInvert: '色弱模式', + fourIsWartermark: '开启水印', + fourWartermarkText: '水印文案', + fiveTitle: '动画配置', + fiveTagsStyle: '标签样式风格', + fiveAnimation: '页面切换动画', + fiveColumnsAsideStyle: '分栏菜单风格', + fiveColumnsAsideLayout: '分栏菜单布局', + horizontal: '横向', + vertical: '纵向', + card: '卡片', + rounded: '圆角', + sixTitle: '预设颜色', + sixDefaults: '默认', + sixClassic: '经典', + sixTransverse: '横向', + sixColumns: '分栏', + tipText: '点击下方按钮进行配置 ↓', + copyText: 'copy', + resetText: '重置', + selectPlaceholder: '请选择', + style1: '风格1', + style4: '风格4', + style5: '风格5', + animation1: '左侧滑入', + animation2: '渐变', + animation3: '淡入淡出', + animation4: '下方滑入', + animation5: '缩放淡入', + animation6: '卷轴', + }, + }, +}; diff --git a/web/src/i18n/pages/layout/zh-tw.ts b/web/src/i18n/pages/layout/zh-tw.ts new file mode 100644 index 0000000..afb11f2 --- /dev/null +++ b/web/src/i18n/pages/layout/zh-tw.ts @@ -0,0 +1,72 @@ +// 定義內容 +export default { + message: { + layout: { + configTitle: '介面設置', + oneTitle: '全域主題', + twoTopTitle: '頂欄主題', + twoTopBar: '頂欄背景色', + twoTopBarColor: '頂欄顏色', + twoIsTopBarColorGradual: '頂欄漸變', + twoMenuTitle: '功能表主題', + twoMenuBar: '功能表背景色', + twoMenuBarColor: '功能表背景顏色', + twoMenuBarActiveColor: '功能表當前背景色', + twoIsMenuBarColorGradual: '功能表背景漸變', + twoColumnsTitle: '分欄功能表', + twoColumnsMenuBar: '分欄功能表背景色', + twoColumnsMenuBarColor: '分欄功能表背景顏色', + twoIsColumnsMenuBarColorGradual: '分欄功能表漸變', + twoIsColumnsMenuHoverPreload: '分欄功能表懸停預載入', + threeTitle: '介面設置', + threeIsCollapse: '功能表折疊', + threeIsUniqueOpened: '功能表手風琴', + threeIsFixedHeader: '固定頂欄', + threeIsClassicSplitMenu: '經典分割功能表', + threeIsLockScreen: '開啟鎖屏', + threeLockScreenTime: '自動鎖屏(分鐘)', + fourTitle: '顯示設置', + fourIsDark: '深色主題', + fourIsShowLogo: '顯示標誌', + fourIsBreadcrumb: '麵包屑導航', + fourIsBreadcrumbIcon: '麵包屑圖標', + fourIsTagsview: '標籤頁', + fourIsTagsviewIcon: '標籤頁圖標', + fourIsCacheTagsView: '固定標籤頁', + fourIsSortableTagsView: '可拖曳標籤頁', + fourIsShareTagsView: '共用標籤頁', + fourIsFooter: '頁腳', + fourIsGrayscale: '灰階模式', + fourIsInvert: '反色模式', + fourIsWartermark: '開啟浮水印', + fourWartermarkText: '浮水印文字', + fiveTitle: '動畫配置', + fiveTagsStyle: '標籤樣式', + fiveAnimation: '頁面切換動畫', + fiveColumnsAsideStyle: '分欄側邊欄樣式', + fiveColumnsAsideLayout: '分欄側邊欄佈局', + horizontal: '橫向', + vertical: '縱向', + card: '卡片', + rounded: '圓角', + sixTitle: '佈局預設', + sixDefaults: '預設', + sixClassic: '經典', + sixTransverse: '橫向', + sixColumns: '分欄', + tipText: '點擊下方按鈕進行配置 ↓', + copyText: '複製', + resetText: '重置', + selectPlaceholder: '請選擇', + style1: '樣式1', + style4: '樣式4', + style5: '樣式5', + animation1: '左側滑入', + animation2: '漸變', + animation3: '淡入淡出', + animation4: '下方滑入', + animation5: '縮放淡入', + animation6: '卷軸', + }, + }, +}; diff --git a/web/src/i18n/pages/login/en.ts b/web/src/i18n/pages/login/en.ts index 4420fc8..054a3df 100644 --- a/web/src/i18n/pages/login/en.ts +++ b/web/src/i18n/pages/login/en.ts @@ -1,31 +1,44 @@ // 定义内容 export default { - label: { - one1: 'User name login', - two2: 'Mobile number', - two3: 'QR code sign-in', - changePwd: 'Change The Password', - }, - link: { - one3: 'Third party login', - two4: 'Links', - }, - account: { - accountPlaceholder1: 'Please enter your login account', - accountPlaceholder2: 'Please enter your login password', - accountPlaceholder3: 'Please enter the verification code', - accountBtnText: 'Sign in', - }, - mobile: { - placeholder1: 'Please input mobile phone number', - placeholder2: 'Please enter the verification code', - codeText: 'Get code', - btnText: 'Sign in', - msgText: - 'Warm tip: it is recommended to use Google, Microsoft edge, version 79.0.1072.62 and above browsers, and 360 browser, please use speed mode', - }, - scan: { - text: 'Open the mobile phone to scan and quickly log in / register', - }, - signInText: 'welcome back!', + message: { + pages: { + login: { + label: { + one1: 'User name login', + two2: 'Mobile number', + two3: 'QR code sign-in', + changePwd: 'Change The Password', + }, + link: { + one3: 'Third party login', + two4: 'Links', + }, + account: { + accountPlaceholder1: 'Please enter your login account', + accountPlaceholder2: 'Please enter your login password', + accountPlaceholder3: 'Please enter the verification code', + accountPlaceholder4: 'Please enter new password', + accountPlaceholder5: 'Please enter new password again', + accountBtnText: 'Sign in', + }, + mobile: { + placeholder1: 'Please input mobile phone number', + placeholder2: 'Please enter the verification code', + codeText: 'Get code', + btnText: 'Sign in', + msgText: + 'Warm tip: it is recommended to use Google, Microsoft edge, version 79.0.1072.62 and above browsers, and 360 browser, please use speed mode', + }, + scan: { + text: 'Open the mobile phone to scan and quickly log in / register', + }, + signInText: 'welcome back!', + loginTitle: 'Procurement Quotation System - Buyer Portal', + supplierTitle: 'Procurement Quotation System - Supplier Portal', + firstLoginTip: 'Please change your password on first login', + welcomeLogin: 'Welcome', + copyright: 'Copyright © AVC All Rights Reserved', + }, + }, + }, }; diff --git a/web/src/i18n/pages/login/zh-cn.ts b/web/src/i18n/pages/login/zh-cn.ts index 225bbb7..bc723a8 100644 --- a/web/src/i18n/pages/login/zh-cn.ts +++ b/web/src/i18n/pages/login/zh-cn.ts @@ -1,32 +1,43 @@ // 定义内容 export default { - label: { - one1: '账号密码登录', - two2: '手机号登录', - two3: '二维码登录', - changePwd: '密码修改', - }, - link: { - one3: '第三方登录', - two4: '友情链接', - }, - account: { - accountPlaceholder1: '请输入登录账号/邮箱/手机号', - accountPlaceholder2: '请输入登录密码', - accountPlaceholder3: '请输入验证码', - accountPlaceholder4:'请输入新密码', - accountPlaceholder5:'请再次输入新密码', - accountBtnText: '登 录', - }, - mobile: { - placeholder1: '请输入手机号', - placeholder2: '请输入验证码', - codeText: '获取验证码', - btnText: '登 录', - msgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式', - }, - scan: { - text: '打开手机扫一扫,快速登录/注册', - }, - signInText: '欢迎回来!', + message: { + pages: { + login: { + label: { + one1: '账号密码登录', + two2: '手机号登录', + two3: '二维码登录', + changePwd: '密码修改', + }, + link: { + one3: '第三方登录', + two4: '友情链接', + }, + account: { + accountPlaceholder1: '请输入登录账号/邮箱/手机号', + accountPlaceholder2: '请输入登录密码', + accountPlaceholder3: '请输入验证码', + accountPlaceholder4: '请输入新密码', + accountPlaceholder5: '请再次输入新密码', + accountBtnText: '登 录', + }, + mobile: { + placeholder1: '请输入手机号', + placeholder2: '请输入验证码', + codeText: '获取验证码', + btnText: '登 录', + msgText: '* 温馨提示:建议使用谷歌、Microsoft Edge,版本 79.0.1072.62 及以上浏览器,360浏览器请使用极速模式', + }, + scan: { + text: '打开手机扫一扫,快速登录/注册', + }, + signInText: '欢迎回来!', + loginTitle: '采购询报价系统 - 采购端', + supplierTitle: '采购询报价系统 - 供应商端', + firstLoginTip: '初次登录请修改密码', + welcomeLogin: '欢迎登录', + copyright: 'Copyright © AVC 版权所有', + }, + }, + }, }; diff --git a/web/src/i18n/pages/login/zh-tw.ts b/web/src/i18n/pages/login/zh-tw.ts index ccdffb9..d9bfe60 100644 --- a/web/src/i18n/pages/login/zh-tw.ts +++ b/web/src/i18n/pages/login/zh-tw.ts @@ -1,30 +1,43 @@ // 定义内容 export default { - label: { - one1: '用戶名登入', - two2: '手機號登入', - two3: '掃碼登錄', - changePwd: '密码修改', - }, - link: { - one3: '協力廠商登入', - two4: '友情連結', - }, - account: { - accountPlaceholder1: '請輸入登入賬號', - accountPlaceholder2: '請輸入登入密碼', - accountPlaceholder3: '請輸入驗證碼', - accountBtnText: '登入', - }, - mobile: { - placeholder1: '請輸入手機號', - placeholder2: '請輸入驗證碼', - codeText: '獲取驗證碼', - btnText: '登入', - msgText: '* 溫馨提示:建議使用穀歌、Microsoft Edge,版本79.0.1072.62及以上瀏覽器,360瀏覽器請使用極速模式', - }, - scan: { - text: '打開手機掃一掃,快速登錄/注册', - }, - signInText: '歡迎回來!', + message: { + pages: { + login: { + label: { + one1: '用戶名登入', + two2: '手機號登入', + two3: '掃碼登錄', + changePwd: '密码修改', + }, + link: { + one3: '協力廠商登入', + two4: '友情連結', + }, + account: { + accountPlaceholder1: '請輸入登入賬號', + accountPlaceholder2: '請輸入登入密碼', + accountPlaceholder3: '請輸入驗證碼', + accountPlaceholder4: '請輸入新密碼', + accountPlaceholder5: '請再次輸入新密碼', + accountBtnText: '登入', + }, + mobile: { + placeholder1: '請輸入手機號', + placeholder2: '請輸入驗證碼', + codeText: '獲取驗證碼', + btnText: '登入', + msgText: '* 溫馨提示:建議使用穀歌、Microsoft Edge,版本79.0.1072.62及以上瀏覽器,360瀏覽器請使用極速模式', + }, + scan: { + text: '打開手機掃一掃,快速登錄/注册', + }, + signInText: '歡迎回來!', + loginTitle: '採購詢報價系統 - 採購端', + supplierTitle: '採購詢報價系統 - 供應商端', + firstLoginTip: '初次登入請修改密碼', + welcomeLogin: '歡迎登入', + copyright: 'Copyright © AVC 版權所有', + }, + }, + }, }; diff --git a/web/src/i18n/pages/loginLog/en.ts b/web/src/i18n/pages/loginLog/en.ts new file mode 100644 index 0000000..9a2c7d6 --- /dev/null +++ b/web/src/i18n/pages/loginLog/en.ts @@ -0,0 +1,72 @@ +// Define content +export default { + message: { + pages: { + loginLog: { + table: { + columns: { + index: 'No.', + keyword: 'Keyword', + username: 'Username', + ip: 'IP Address', + isp: 'ISP', + continent: 'Continent', + country: 'Country', + province: 'Province', + city: 'City', + district: 'District', + areaCode: 'Area Code', + countryEnglish: 'Country (EN)', + countryCode: 'Country Code', + longitude: 'Longitude', + latitude: 'Latitude', + loginType: 'Login Type', + os: 'OS', + browser: 'Browser', + agent: 'User-Agent', + status: 'Status', + createTime: 'Login Time', + msg: 'Message', + }, + }, + status: { + success: 'Success', + failed: 'Failed', + }, + loginType: { + normal: 'Normal Login', + wechat: 'WeChat Login', + }, + form: { + keywordPlaceholder: 'Enter keyword', + usernamePlaceholder: 'Enter username', + ipPlaceholder: 'Enter IP address', + ispPlaceholder: 'Enter ISP', + continentPlaceholder: 'Enter continent', + countryPlaceholder: 'Enter country', + provincePlaceholder: 'Enter province', + cityPlaceholder: 'Enter city', + districtPlaceholder: 'Enter district', + areaCodePlaceholder: 'Enter area code', + countryEnglishPlaceholder: 'Enter country (EN)', + countryCodePlaceholder: 'Enter country code', + longitudePlaceholder: 'Enter longitude', + latitudePlaceholder: 'Enter latitude', + loginTypePlaceholder: 'Select login type', + osPlaceholder: 'Enter OS', + browserPlaceholder: 'Enter browser', + agentPlaceholder: 'Enter User-Agent', + }, + buttons: { + view: 'View', + query: 'Query', + export: 'Export', + refresh: 'Refresh', + reset: 'Reset', + loginTimeRange: 'Login Time Range', + statusFilter: 'Status', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/loginLog/zh-cn.ts b/web/src/i18n/pages/loginLog/zh-cn.ts new file mode 100644 index 0000000..44e9952 --- /dev/null +++ b/web/src/i18n/pages/loginLog/zh-cn.ts @@ -0,0 +1,72 @@ +// 定义内容 +export default { + message: { + pages: { + loginLog: { + table: { + columns: { + index: '序号', + keyword: '关键词', + username: '用户名', + ip: 'IP地址', + isp: '运营商', + continent: '大洲', + country: '国家', + province: '省份', + city: '城市', + district: '区县', + areaCode: '区域代码', + countryEnglish: '国家(英文)', + countryCode: '国家代码', + longitude: '经度', + latitude: '纬度', + loginType: '登录方式', + os: '操作系统', + browser: '浏览器', + agent: 'User-Agent', + status: '状态', + createTime: '登录时间', + msg: '提示消息', + }, + }, + status: { + success: '成功', + failed: '失败', + }, + loginType: { + normal: '普通登录', + wechat: '微信登录', + }, + form: { + keywordPlaceholder: '请输入关键词', + usernamePlaceholder: '请输入用户名', + ipPlaceholder: '请输入IP地址', + ispPlaceholder: '请输入运营商', + continentPlaceholder: '请输入大洲', + countryPlaceholder: '请输入国家', + provincePlaceholder: '请输入省份', + cityPlaceholder: '请输入城市', + districtPlaceholder: '请输入区县', + areaCodePlaceholder: '请输入区域代码', + countryEnglishPlaceholder: '请输入国家(英文)', + countryCodePlaceholder: '请输入国家代码', + longitudePlaceholder: '请输入经度', + latitudePlaceholder: '请输入纬度', + loginTypePlaceholder: '请选择登录方式', + osPlaceholder: '请输入操作系统', + browserPlaceholder: '请输入浏览器', + agentPlaceholder: '请输入User-Agent', + }, + buttons: { + view: '查看', + query: '查询', + export: '导出', + refresh: '刷新', + reset: '重置', + loginTimeRange: '登录时间范围', + statusFilter: '状态', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/loginLog/zh-tw.ts b/web/src/i18n/pages/loginLog/zh-tw.ts new file mode 100644 index 0000000..c6d0cb2 --- /dev/null +++ b/web/src/i18n/pages/loginLog/zh-tw.ts @@ -0,0 +1,72 @@ +// 定義內容 +export default { + message: { + pages: { + loginLog: { + table: { + columns: { + index: '序號', + keyword: '關鍵詞', + username: '用戶名', + ip: 'IP位址', + isp: '運營商', + continent: '大洲', + country: '國家', + province: '省份', + city: '城市', + district: '區縣', + areaCode: '區域代碼', + countryEnglish: '國家(英文)', + countryCode: '國家代碼', + longitude: '經度', + latitude: '緯度', + loginType: '登錄方式', + os: '作業系統', + browser: '瀏覽器', + agent: 'User-Agent', + status: '狀態', + createTime: '登錄時間', + msg: '提示消息', + }, + }, + status: { + success: '成功', + failed: '失敗', + }, + loginType: { + normal: '普通登錄', + wechat: '微信登錄', + }, + form: { + keywordPlaceholder: '請輸入關鍵詞', + usernamePlaceholder: '請輸入用戶名', + ipPlaceholder: '請輸入IP位址', + ispPlaceholder: '請輸入運營商', + continentPlaceholder: '請輸入大洲', + countryPlaceholder: '請輸入國家', + provincePlaceholder: '請輸入省份', + cityPlaceholder: '請輸入城市', + districtPlaceholder: '請輸入區縣', + areaCodePlaceholder: '請輸入區域代碼', + countryEnglishPlaceholder: '請輸入國家(英文)', + countryCodePlaceholder: '請輸入國家代碼', + longitudePlaceholder: '請輸入經度', + latitudePlaceholder: '請輸入緯度', + loginTypePlaceholder: '請選擇登錄方式', + osPlaceholder: '請輸入作業系統', + browserPlaceholder: '請輸入瀏覽器', + agentPlaceholder: '請輸入User-Agent', + }, + buttons: { + view: '查看', + query: '查詢', + export: '導出', + refresh: '刷新', + reset: '重置', + loginTimeRange: '登錄時間範圍', + statusFilter: '狀態', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/menu/en.ts b/web/src/i18n/pages/menu/en.ts new file mode 100644 index 0000000..cf09ba5 --- /dev/null +++ b/web/src/i18n/pages/menu/en.ts @@ -0,0 +1,163 @@ +// Define content +export default { + message: { + pages: { + menu: { + tree: { + menuList: 'Menu List', + deptList: 'Department List', + deptPlaceholder: 'Enter department name', + deptInfo: '1. Department info;', + addTooltip: 'Add', + editTooltip: 'Edit', + moveUpTooltip: 'Move Up', + moveDownTooltip: 'Move Down', + deleteTooltip: 'Delete', + selectMenuWarning: 'Please select a menu!', + menuAlert: '1. Red menu means disabled status; 2. For directory type, component path can be empty; 3. For root node, parent menu can be empty; 4. Drag to reorder is supported;', + }, + table: { + columns: { + fieldName: 'Field Name', + title: 'Column Name', + actions: 'Actions', + menuName: 'Menu Name', + icon: 'Icon', + sort: 'Sort', + status: 'Status', + createTime: 'Created At', + }, + }, + form: { + fieldName: 'Field Name', + title: 'Column Name', + isCreate: 'Show on Create', + isUpdate: 'Show on Edit', + isQuery: 'Show in Search', + confirm: 'Confirm', + cancel: 'Cancel', + menuName: 'Menu Name', + parentMenu: 'Parent Menu', + path: 'Route Path', + icon: 'Icon', + component: 'Component Path', + componentName: 'Component Name', + linkUrl: 'External Link', + cache: 'Cache', + remark: 'Remark', + status: 'Status', + visible: 'Sidebar Visible', + isCatalog: 'Is Directory', + isLink: 'External Link', + isAffix: 'Is Affix', + isIframe: 'Is Iframe', + enabled: 'Enabled', + disabled: 'Disabled', + show: 'Show', + hide: 'Hide', + yes: 'Yes', + no: 'No', + menuNamePlaceholder: 'Please enter menu name', + menuNameZhCn: 'Simplified Chinese', + menuNameEn: 'English Name', + menuNameZhTw: 'Traditional Chinese', + menuNameZhCnPlaceholder: 'Enter menu name in Simplified Chinese (required)', + menuNameEnPlaceholder: 'Enter menu name in English (optional)', + menuNameZhTwPlaceholder: 'Enter menu name in Traditional Chinese (optional)', + parentMenuPlaceholder: 'Please select parent menu', + pathPlaceholder: 'Enter route path, must start with /', + componentPlaceholder: 'Enter component path', + componentNamePlaceholder: 'Please enter component name', + linkUrlPlaceholder: 'Please enter external link URL', + remarkPlaceholder: 'Please enter remark', + tokenTip: 'Enter {{token}} to automatically replace system token', + }, + fieldForm: { + fieldName: 'Field Name', + title: 'Column Name', + fieldLabel: 'Field Label', + fieldType: 'Field Type', + width: 'Width', + isSortable: 'Sortable', + isSearch: 'Searchable', + isFilterable: 'Filterable', + showInList: 'Show in List', + required: 'Required', + fieldNamePlaceholder: 'Please enter field name', + titlePlaceholder: 'Please enter column name', + widthPlaceholder: 'Please enter width', + }, + validation: { + fieldNameRequired: 'Please enter field name!', + titleRequired: 'Please enter column name!', + fieldNameFieldRequired: 'Please enter field name!', + titleFieldRequired: 'Please enter column name!', + pathRequired: 'Please enter a valid route path', + componentRequired: 'Please enter a component path', + componentNameRequired: 'Please enter a component name', + linkUrlRequired: 'Please enter an external link URL', + permissionNameRequired: 'Permission name is required', + permissionValueRequired: 'Permission key is required', + batchGenerate: 'Batch Generate', + alreadyExists: ' already exists and cannot be duplicated', + }, + dialog: { + columnPermission: 'Column Permission', + addColumn: 'Add', + editColumn: 'Edit', + deleteColumn: 'Delete', + deleteConfirm: 'Are you sure you want to delete this field?', + automatch: 'Auto Match', + automatchSuccess: 'Matched successfully', + selectRoleAndModel: 'Please select a role and model table!', + selectModel: 'Select Model', + selected: 'Selected:', + searchPlaceholder: 'Search models...', + menuConfig: 'Menu Config', + buttonPermission: 'Button Permission Config', + columnPermissionTab: 'Column Permission Config', + deleteMenuConfirm: 'Are you sure you want to delete this menu item?', + }, + messages: { + addSuccess: 'Created successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + automatchSuccess: 'Matched successfully', + batchDeleteConfirm: 'Are you sure you want to batch delete {count} records?', + batchDeleteSuccess: 'Deleted successfully', + selectMenu: 'Please select a menu!', + }, + buttons: { + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + reset: 'Reset', + automatch: 'Auto Match', + confirm: 'Confirm', + batchDelete: 'Batch Delete', + expandAll: 'Expand All', + collapseAll: 'Collapse All', + selectMenu: 'Please select a menu', + searchPlaceholder: 'Enter keywords to search', + search: 'Keyword', + select: 'Select', + index: 'No.', + model: 'Model', + chineseName: 'Chinese Name', + fieldName: 'Field Name', + chineseNamePlaceholder: 'Please enter Chinese name', + fieldNamePlaceholder: 'Please enter field name', + permissionName: 'Permission Name', + permissionValue: 'Permission Value', + requestMethod: 'Request Method', + apiEndpoint: 'API Endpoint', + batchGenerate: 'Batch Generate', + selectMenuFirst: 'Please select a menu first', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/menu/zh-cn.ts b/web/src/i18n/pages/menu/zh-cn.ts new file mode 100644 index 0000000..db96b98 --- /dev/null +++ b/web/src/i18n/pages/menu/zh-cn.ts @@ -0,0 +1,163 @@ +// 定义内容 +export default { + message: { + pages: { + menu: { + tree: { + menuList: '菜单列表', + deptList: '部门列表', + deptPlaceholder: '请输入部门名称', + deptInfo: '1.部门信息;', + addTooltip: '新增', + editTooltip: '编辑', + moveUpTooltip: '上移', + moveDownTooltip: '下移', + deleteTooltip: '删除', + selectMenuWarning: '请选择菜单!', + menuAlert: '1.红色菜单代表状态禁用; 2.添加菜单,如果是目录,组件地址为空即可; 3.添加根节点菜单,父级ID为空即可; 4.支持拖拽菜单;', + }, + table: { + columns: { + fieldName: '字段名', + title: '列名', + actions: '操作', + menuName: '菜单名称', + icon: '图标', + sort: '排序', + status: '状态', + createTime: '创建时间', + }, + }, + form: { + fieldName: '字段名', + title: '列名', + isCreate: '创建显示', + isUpdate: '编辑显示', + isQuery: '查询显示', + confirm: '确定', + cancel: '取消', + menuName: '菜单名称', + parentMenu: '上级菜单', + path: '路由地址', + icon: '图标', + component: '组件地址', + componentName: '组件名称', + linkUrl: '外链接', + cache: '缓存', + remark: '备注', + status: '状态', + visible: '侧边显示', + isCatalog: '是否目录', + isLink: '外链接', + isAffix: '是否固定', + isIframe: '是否内嵌', + enabled: '启用', + disabled: '禁用', + show: '显示', + hide: '隐藏', + yes: '是', + no: '否', + menuNamePlaceholder: '请输入菜单名称', + menuNameZhCn: '简体中文', + menuNameEn: '英文名称', + menuNameZhTw: '繁体中文', + menuNameZhCnPlaceholder: '请输入简体中文名称(必填)', + menuNameEnPlaceholder: '请输入英文名称(选填)', + menuNameZhTwPlaceholder: '请输入繁体中文名称(选填)', + parentMenuPlaceholder: '请选择父级菜单', + pathPlaceholder: '请输入路由地址,请以/开头', + componentPlaceholder: '输入组件地址', + componentNamePlaceholder: '请输入组件名称', + linkUrlPlaceholder: '请输入外链接地址', + remarkPlaceholder: '请输入备注', + tokenTip: '输入{{token}}可自动替换系统 token', + }, + fieldForm: { + fieldName: '字段名称', + title: '列名称', + fieldLabel: '字段标签', + fieldType: '字段类型', + width: '宽度', + isSortable: '是否可排', + isSearch: '是否搜索', + isFilterable: '是否筛选', + showInList: '列表显示', + required: '是否必填', + fieldNamePlaceholder: '请输入字段名称', + titlePlaceholder: '请输入列名称', + widthPlaceholder: '请输入宽度', + }, + validation: { + alreadyExists: '已存在,不可重复', + fieldNameRequired: '请输入字段名!', + titleRequired: '请输入列名!', + fieldNameFieldRequired: '请输入字段名称!', + titleFieldRequired: '请输入列名称!', + pathRequired: '请输入正确的地址', + componentRequired: '请输入组件地址', + componentNameRequired: '请输入组件名称', + linkUrlRequired: '请输入外链接地址', + permissionNameRequired: '权限名称必填', + permissionValueRequired: '权限标识必填', + batchGenerate: '批量生成', + }, + dialog: { + columnPermission: '字段权限', + addColumn: '新增', + editColumn: '编辑', + deleteColumn: '删除', + deleteConfirm: '确定删除该字段吗?', + automatch: '自动匹配', + automatchSuccess: '匹配成功', + selectRoleAndModel: '请选择角色和模型表!', + selectModel: '选择model', + selected: '已选择:', + searchPlaceholder: '搜索模型...', + menuConfig: '菜单配置', + buttonPermission: '按钮权限配置', + columnPermissionTab: '列权限配置', + deleteMenuConfirm: '您确认删除该菜单项吗?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + automatchSuccess: '匹配成功', + batchDeleteConfirm: '确定要批量删除这{count}条记录吗', + batchDeleteSuccess: '删除成功', + selectMenu: '请选择菜单!', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + reset: '重置', + automatch: '自动匹配', + confirm: '确定', + batchDelete: '批量删除', + expandAll: '展开所有', + collapseAll: '收起所有', + selectMenu: '请选择菜单', + searchPlaceholder: '输入关键词搜索', + search: '关键词', + select: '选择', + index: '序号', + model: 'model', + chineseName: '中文名', + fieldName: '字段名', + chineseNamePlaceholder: '请输入中文名', + fieldNamePlaceholder: '请输入字段名', + permissionName: '权限名称', + permissionValue: '权限值', + requestMethod: '请求方式', + apiEndpoint: '接口地址', + batchGenerate: '批量生成', + selectMenuFirst: '请选择菜单', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/menu/zh-tw.ts b/web/src/i18n/pages/menu/zh-tw.ts new file mode 100644 index 0000000..7bf8a58 --- /dev/null +++ b/web/src/i18n/pages/menu/zh-tw.ts @@ -0,0 +1,163 @@ +// 定義內容 +export default { + message: { + pages: { + menu: { + tree: { + menuList: '菜單列表', + deptList: '部門列表', + deptPlaceholder: '請輸入部門名稱', + deptInfo: '1.部門信息;', + addTooltip: '新增', + editTooltip: '編輯', + moveUpTooltip: '上移', + moveDownTooltip: '下移', + deleteTooltip: '刪除', + selectMenuWarning: '請選擇菜單!', + menuAlert: '1.紅色菜單代表狀態停用; 2.添加菜單,如果是目錄,組件地址為空即可; 3.添加根節點菜單,父級ID為空即可; 4.支持拖拽菜單;', + }, + table: { + columns: { + fieldName: '字段名', + title: '列名', + actions: '操作', + menuName: '菜單名稱', + icon: '圖標', + sort: '排序', + status: '狀態', + createTime: '創建時間', + }, + }, + form: { + fieldName: '字段名', + title: '列名', + isCreate: '創建顯示', + isUpdate: '編輯顯示', + isQuery: '查詢顯示', + confirm: '確定', + cancel: '取消', + menuName: '菜單名稱', + parentMenu: '上級菜單', + path: '路由地址', + icon: '圖標', + component: '組件地址', + componentName: '組件名稱', + linkUrl: '外鏈接', + cache: '緩存', + remark: '備註', + status: '狀態', + visible: '側邊顯示', + isCatalog: '是否目錄', + isLink: '外鏈接', + isAffix: '是否固定', + isIframe: '是否內嵌', + enabled: '啟用', + disabled: '停用', + show: '顯示', + hide: '隱藏', + yes: '是', + no: '否', + menuNamePlaceholder: '請輸入菜單名稱', + menuNameZhCn: '簡體中文', + menuNameEn: '英文名稱', + menuNameZhTw: '繁體中文', + menuNameZhCnPlaceholder: '請輸入簡體中文名稱(必填)', + menuNameEnPlaceholder: '請輸入英文名稱(選填)', + menuNameZhTwPlaceholder: '請輸入繁體中文名稱(選填)', + parentMenuPlaceholder: '請選擇上級菜單', + pathPlaceholder: '請輸入路由地址,請以/開頭', + componentPlaceholder: '輸入組件地址', + componentNamePlaceholder: '請輸入組件名稱', + linkUrlPlaceholder: '請輸入外鏈接地址', + remarkPlaceholder: '請輸入備註', + tokenTip: '輸入{{token}}可自動替換系統 token', + }, + fieldForm: { + fieldName: '字段名稱', + title: '列名稱', + fieldLabel: '字段標籤', + fieldType: '字段類型', + width: '寬度', + isSortable: '是否可排', + isSearch: '是否搜索', + isFilterable: '是否篩選', + showInList: '列表顯示', + required: '是否必填', + fieldNamePlaceholder: '請輸入字段名稱', + titlePlaceholder: '請輸入列名稱', + widthPlaceholder: '請輸入寬度', + }, + validation: { + fieldNameRequired: '請輸入字段名!', + titleRequired: '請輸入列名!', + fieldNameFieldRequired: '請輸入字段名稱!', + titleFieldRequired: '請輸入列名稱!', + pathRequired: '請輸入正確的地址', + componentRequired: '請輸入組件地址', + componentNameRequired: '請輸入組件名稱', + linkUrlRequired: '請輸入外鏈接地址', + permissionNameRequired: '權限名稱必填', + permissionValueRequired: '權限標識必填', + batchGenerate: '批量生成', + alreadyExists: '已存在,不可重複', + }, + dialog: { + columnPermission: '字段權限', + addColumn: '新增', + editColumn: '編輯', + deleteColumn: '刪除', + deleteConfirm: '確定刪除該字段嗎?', + automatch: '自動匹配', + automatchSuccess: '匹配成功', + selectRoleAndModel: '請選擇角色和模型表!', + selectModel: '選擇model', + selected: '已選擇:', + searchPlaceholder: '搜索模型...', + menuConfig: '菜單配置', + buttonPermission: '按鈕權限配置', + columnPermissionTab: '列權限配置', + deleteMenuConfirm: '您確認刪除該菜單項嗎?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + automatchSuccess: '匹配成功', + batchDeleteConfirm: '確定要批量刪除這{count}條記錄嗎', + batchDeleteSuccess: '刪除成功', + selectMenu: '請選擇菜單!', + }, + buttons: { + add: '新增', + edit: '編輯', + delete: '刪除', + save: '保存', + cancel: '取消', + reset: '重置', + automatch: '自動匹配', + confirm: '確定', + batchDelete: '批量刪除', + expandAll: '展開所有', + collapseAll: '收起所有', + selectMenu: '請選擇菜單', + searchPlaceholder: '輸入關鍵詞搜索', + search: '關鍵詞', + select: '選擇', + index: '序號', + model: 'model', + chineseName: '中文名', + fieldName: '字段名', + chineseNamePlaceholder: '請輸入中文名', + fieldNamePlaceholder: '請輸入字段名', + permissionName: '權限名稱', + permissionValue: '權限值', + requestMethod: '請求方式', + apiEndpoint: '接口地址', + batchGenerate: '批量生成', + selectMenuFirst: '請選擇菜單', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/messageCenter/en.ts b/web/src/i18n/pages/messageCenter/en.ts new file mode 100644 index 0000000..0712efc --- /dev/null +++ b/web/src/i18n/pages/messageCenter/en.ts @@ -0,0 +1,68 @@ +// Define content +export default { + message: { + pages: { + messageCenter: { + tabs: { + myPublish: 'My Published', + myReceive: 'My Received', + unread: 'Unread', + read: 'Read', + all: 'All', + }, + table: { + columns: { + title: 'Title', + type: 'Type', + creatorName: 'Sender', + createTime: 'Send Time', + isRead: 'Status', + actions: 'Actions', + targetType: 'Target Type', + targetUser: 'Target User', + targetRole: 'Target Role', + targetDept: 'Target Dept', + content: 'Content', + }, + }, + status: { + yes: 'Read', + no: 'Unread', + }, + targetType: { + byUser: 'By User', + byRole: 'By Role', + byDept: 'By Dept', + notice: 'Notice', + }, + buttons: { + markAllRead: 'Mark All Read', + markRead: 'Mark as Read', + delete: 'Delete', + refresh: 'Refresh', + view: 'View', + export: 'Export', + add: 'Add', + }, + form: { + titlePlaceholder: 'Enter title', + phone: 'Phone', + roleName: 'Role Name', + roleKey: 'Permission Key', + deptName: 'Dept Name', + status: 'Status', + parentDept: 'Parent Dept', + }, + validation: { + titleRequired: 'Title is required', + targetTypeRequired: 'Please select target type', + required: 'Required', + }, + messages: { + markReadSuccess: 'Marked successfully', + deleteSuccess: 'Deleted successfully', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/messageCenter/zh-cn.ts b/web/src/i18n/pages/messageCenter/zh-cn.ts new file mode 100644 index 0000000..a66651d --- /dev/null +++ b/web/src/i18n/pages/messageCenter/zh-cn.ts @@ -0,0 +1,68 @@ +// 定义内容 +export default { + message: { + pages: { + messageCenter: { + tabs: { + myPublish: '我的发布', + myReceive: '我的接收', + unread: '未读', + read: '已读', + all: '全部', + }, + table: { + columns: { + title: '标题', + type: '类型', + creatorName: '发送人', + createTime: '发送时间', + isRead: '状态', + actions: '操作', + targetType: '目标类型', + targetUser: '目标用户', + targetRole: '目标角色', + targetDept: '目标部门', + content: '内容', + }, + }, + status: { + yes: '已读', + no: '未读', + }, + targetType: { + byUser: '按用户', + byRole: '按角色', + byDept: '按部门', + notice: '通知公告', + }, + buttons: { + markAllRead: '全部已读', + markRead: '标记已读', + delete: '删除', + refresh: '刷新', + view: '查看', + export: '导出', + add: '新增', + }, + form: { + titlePlaceholder: '请输入标题', + phone: '用户电话', + roleName: '角色名称', + roleKey: '权限标识', + deptName: '部门名称', + status: '状态', + parentDept: '父级部门', + }, + validation: { + titleRequired: '标题必填', + targetTypeRequired: '请选择目标类型', + required: '必填项', + }, + messages: { + markReadSuccess: '标记成功', + deleteSuccess: '删除成功', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/messageCenter/zh-tw.ts b/web/src/i18n/pages/messageCenter/zh-tw.ts new file mode 100644 index 0000000..320233d --- /dev/null +++ b/web/src/i18n/pages/messageCenter/zh-tw.ts @@ -0,0 +1,68 @@ +// 定義內容 +export default { + message: { + pages: { + messageCenter: { + tabs: { + myPublish: '我的發布', + myReceive: '我的接收', + unread: '未讀', + read: '已讀', + all: '全部', + }, + table: { + columns: { + title: '標題', + type: '類型', + creatorName: '發送人', + createTime: '發送時間', + isRead: '狀態', + actions: '操作', + targetType: '目標類型', + targetUser: '目標用戶', + targetRole: '目標角色', + targetDept: '目標部門', + content: '內容', + }, + }, + status: { + yes: '已讀', + no: '未讀', + }, + targetType: { + byUser: '按用戶', + byRole: '按角色', + byDept: '按部門', + notice: '通知公告', + }, + buttons: { + markAllRead: '全部已讀', + markRead: '標記已讀', + delete: '刪除', + refresh: '刷新', + view: '查看', + export: '導出', + add: '新增', + }, + form: { + titlePlaceholder: '請輸入標題', + phone: '用戶電話', + roleName: '角色名稱', + roleKey: '權限標識', + deptName: '部門名稱', + status: '狀態', + parentDept: '父級部門', + }, + validation: { + titleRequired: '標題必填', + targetTypeRequired: '請選擇目標類型', + required: '必填項', + }, + messages: { + markReadSuccess: '標記成功', + deleteSuccess: '刪除成功', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/miscprocurement/en.ts b/web/src/i18n/pages/miscprocurement/en.ts new file mode 100644 index 0000000..1eb7242 --- /dev/null +++ b/web/src/i18n/pages/miscprocurement/en.ts @@ -0,0 +1,254 @@ +// Definition +export default { + message: { + pages: { + miscprocurement: { + materialInfo: { + title: 'Misc Procurement Material Info', + factory: 'Factory', + materialtype: 'Material Type', + materialtypeEn: 'Material Type (English)', + materialtypeZhTw: 'Material Type (Traditional Chinese)', + density: 'Density', + price: 'Unit Price', + status: 'Status', + statusEnabled: 'Enabled', + statusDisabled: 'Disabled', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + stationInfo: { + title: 'Misc Procurement Station Info', + companyCode: 'Company Code', + stationname: 'Station Name', + stationnameEn: 'Station Name (English)', + stationnameZhTw: 'Station Name (Traditional Chinese)', + stationcode: 'Station Code', + stationtype: 'Station Type', + unit: 'Unit', + rate: 'Rate', + status: 'Status', + statusEnabled: 'Enabled', + statusDisabled: 'Disabled', + typeTooling: 'Tooling', + typeGraphite: 'Graphite', + createTime: 'Create Time', + updateTime: 'Update Time', + }, + misc_parts: { + title: 'Misc Parts Info', + companyCode: 'Transaction Plant', + partid: 'Part ID', + partidName: 'Part Name', + specification: 'Specification', + unit: 'Unit', + partidCategory: 'Part Category', + categoryTooling: 'Tooling', + categoryGraphite: 'Graphite', + categoryOther: 'Other', + status: 'Status', + statusEnabled: 'Enabled', + statusDisabled: 'Disabled', + createTime: 'Create Time', + updateTime: 'Update Time', + validation: { + fieldNameRequired: 'Field is required', + alreadyExists: 'already exists', + } + }, + inquiry: { + title: 'Inquiry', + inquiryNo: 'Inquiry No', + title_label: 'Inquiry Title', + titleEn: 'Inquiry Title (English)', + titleZhTw: 'Inquiry Title (Traditional Chinese)', + purchaseType: 'Purchase Type', + materialType: 'Material Type', + template: 'Template', + currency: 'Currency', + companyCode: 'Company Code', + purchaseDept: 'Purchase Department', + buyer: 'Buyer', + quoteDeadline: 'Quote Deadline', + targetPrice: 'Target Price', + leadTimeDays: 'Lead Time (Days)', + paymentMethod: 'Payment Method', + status: 'Status', + buyingMethod: 'Buying Method', + }, + costTemplate: { + title: 'Cost Estimate Template', + templateNo: 'Template No', + templateName: 'Template Name', + templateNameEn: 'Template Name (English)', + templateNameZhTw: 'Template Name (Traditional Chinese)', + procurementCategory: 'Procurement Category', + procurementMisc: 'Misc', + procurementStrategic: 'Strategic', + templateDesc: 'Template Description', + status: 'Status', + statusPlaceholder: 'Select status', + statusConfirmed: 'Confirmed', + statusUnconfirmed: 'Unconfirmed', + statusCancelled: 'Cancelled', + selectProcurementCategory: 'Select procurement category', + inputTemplateName: 'Enter template name', + version: 'Version', + newVersion: 'New Version', + newVersionFailed: 'Failed to create new version', + basicInfo: 'Basic Info', + sections: 'Sections', + controls: 'Controls', + fieldKey: 'Field Key', + confirm: 'Confirm', + confirmButtonText: 'Confirm', + confirmSuccess: 'Confirmed successfully', + confirmFailed: 'Confirmation failed', + confirmStatusTip: 'Confirmation status', + cancelButtonText: 'Cancel', + pleaseCompleteAndSave: 'Please complete and save first', + pleaseModifyAndSave: 'Please modify and save first', + loadDetailFailed: 'Failed to load details', + keyNotFilled: 'Required field not filled', + isBom: 'Is BOM', + bomYes: 'Yes', + bomNo: 'No', + acti: 'Action', + actiYes: 'Yes', + actiNo: 'No', + productDetail: 'Product Detail', + materials: 'Materials', + material: 'Material', + length: 'Length', + width: 'Width', + height: 'Height', + specificgravity: 'Specific Gravity', + autoByMaterial: 'Auto calculated by material', + qty: 'Qty', + weight: 'Weight', + weightUsage: 'Material Weight', + unitPrice: 'Unit Price', + materialCost: 'Material Cost', + lengthWidthHeightSpecificgravityQty: 'L*W*H*SG*Qty', + weightTimesUnitPrice: 'Weight x Unit Price', + process: 'Process', + processStation: 'Process Station', + processTime: 'Process Time', + unit: 'Unit', + unitrate: 'Station Rate', + autoByStation: 'Auto calculated by station', + processqty: 'Process Qty', + processprice: 'Process Price', + processCost: 'Process Cost', + unitrateTimesProcessqty: 'Station Rate x Process Qty', + lossRate: 'Loss Rate', + sgna: 'SG&A', + others: 'Others', + profit: 'Profit', + tax: 'Tax', + remark: 'Remark', + updateTime: 'Update Time', + }, + rfqmiscellaneous: { + title: 'Misc RFQ', + inquiryNo: 'RFQ No', + inquiryName: 'RFQ Name', + companyShortName: 'Transaction Plant', + buyingMethod: 'Buying Method', + buyingMethodInquiry: 'Inquiry', + buyingMethodBid: 'Bid', + quoteDeadline: 'Quote Deadline', + bidStartTime: 'Bid Start Time', + bidEndTime: 'Bid End Time', + buyer: 'Buyer', + currency: 'Currency', + leadTimeDays: 'Lead Time (Days)', + paymentMethod: 'Payment Method', + paymentMethod1: 'T/T 30 Days', + paymentMethod2: 'T/T 60 Days', + paymentMethod3: 'T/T 90 Days', + paymentMethod4: 'T/T 120 Days', + paymentMethod5: 'L/C 30 Days', + paymentMethod6: 'L/C 60 Days', + paymentMethod7: 'L/C 90 Days', + paymentMethod8: 'L/C 120 Days', + paymentMethod9: 'Other', + inquiryNoPlaceholder: 'Enter RFQ number', + inquiryNamePlaceholder: 'Enter RFQ name', + buyerPlaceholder: 'Enter buyer name', + selectInquiryFirst: 'Please select an RFQ first', + onlySingleOperation: 'Only single item operation is supported', + confirmBargainPrompt: 'Confirm to change status to [Bargaining]?', + addSupplierFirst: 'Please maintain RFQ supplier list first before confirming', + confirmPrompt: 'After confirmation, the RFQ will be locked and cannot be edited. To modify, you need to [Restore] it.', + prompt: 'Prompt', + confirmFailed: 'Confirmation failed', + restorePrompt: 'Confirm to restore status to [Open]?', + restoreFailed: 'Restore failed', + publishPrompt: 'Confirm to change status to [Published]?', + publishFailed: 'Publish failed', + startBargainFailed: 'Failed to start price comparison', + deleteFailed: 'Delete failed', + cancel: 'Cancel', + inquiryNameRequired: 'Please enter RFQ name', + buyerRequired: 'Please enter buyer name', + status: 'Status', + statusOpen: 'Open', + statusConfirmed: 'Confirmed', + statusPublished: 'Published', + statusQuoting: 'Quoting', + statusQuotingEnd: 'Quote Ended', + statusBargaining: 'Bargaining', + statusPriceAudit: 'Price Audit', + statusPriceApproved: 'Price Approved', + statusLost: 'Lost', + statusCancelled: 'Cancelled', + remark: 'Remark', + opCreate: 'RFQ Created', + opConfirm: 'RFQ Confirmed', + opPublish: 'RFQ Published', + opRestore: 'RFQ Restored', + opQuoteDeadline: 'Quote Deadline', + opSupplierQuote: 'Supplier Quoted', + opBargain: 'Bargain', + opBargainSubmit: 'Bargain Submitted', + opBargainComplete: 'Bargain Completed', + opBargainReject: 'Bargain Rejected', + newInquiry: 'New RFQ', + startBargain: 'Start Comparison', + confirm: 'Confirm', + restore: 'Restore', + publish: 'Publish', + comparePrice: 'Compare Price', + view: 'View', + edit: 'Edit', + delete: 'Delete', + selectOneFirst: 'Please select an RFQ first', + onlySupportSingle: 'Only single item operation is supported', + onlyQuotingCanBargain: 'Only quoting or quote-ended status can start price comparison', + confirmChangeToBargaining: 'Confirm to change status to [Bargaining]?', + maintainSupplierFirst: 'Please maintain RFQ supplier list first before confirming', + confirmLockAfterConfirm: 'After confirmation, the RFQ will be locked and cannot be edited. To modify, you need to [Restore] it.', + confirmRestore: 'Confirm to restore status to [Open]?', + confirmPublish: 'Confirm to change status to [Published]?', + transactionPlant: 'Transaction Plant', + purchaseCategory: 'Purchase Category', + inquiryTemplate: 'RFQ Template', + templateVersion: 'Template Version', + paymentTerm: 'Payment Terms', + totalPriceInclTax: 'Total Price Incl. Tax', + costStructure: 'Cost Structure', + supplierList: 'Supplier List', + attachments: 'Attachments', + basicInfo: 'Basic Info', + operationType: 'Operation Type', + operator: 'Operator', + operationTime: 'Operation Time', + operationDesc: 'Operation Description', + statusChange: 'Status Change', + quotationNo: 'Quotation No', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/miscprocurement/zh-cn.ts b/web/src/i18n/pages/miscprocurement/zh-cn.ts new file mode 100644 index 0000000..fe60c96 --- /dev/null +++ b/web/src/i18n/pages/miscprocurement/zh-cn.ts @@ -0,0 +1,254 @@ +// 定义内容 +export default { + message: { + pages: { + miscprocurement: { + materialInfo: { + title: '杂采材料信息', + factory: '交易厂区', + materialtype: '材质', + materialtypeEn: '材质英文名', + materialtypeZhTw: '材质繁体名', + density: '比重', + price: '单价', + status: '状态', + statusEnabled: '启用', + statusDisabled: '禁用', + createTime: '创建时间', + updateTime: '更新时间', + }, + stationInfo: { + title: '杂采工站信息', + companyCode: '交易厂区', + stationname: '工站名称', + stationnameEn: '工站英文名', + stationnameZhTw: '工站繁体名', + stationcode: '工站代码', + stationtype: '工站类型归属', + unit: '计量单位', + rate: '费率', + status: '状态', + statusEnabled: '启用', + statusDisabled: '禁用', + typeTooling: '模治具', + typeGraphite: '石墨', + createTime: '创建时间', + updateTime: '更新时间', + }, + misc_parts: { + title: '杂采料号信息', + companyCode: '交易厂区', + partid: '料号', + partidName: '物料说明', + specification: '品名规格', + unit: '单位', + partidCategory: '物料分类', + categoryTooling: '模治具', + categoryGraphite: '石墨', + categoryOther: '其他', + status: '启用否', + statusEnabled: '启用', + statusDisabled: '禁用', + createTime: '创建时间', + updateTime: '更新时间', + validation: { + fieldNameRequired: '字段不能为空', + alreadyExists: '已存在', + } + }, + inquiry: { + title: '询价单', + inquiryNo: '询价单号', + title_label: '询价单名称', + titleEn: '询价单英文名', + titleZhTw: '询价单繁体名', + purchaseType: '采购类别', + materialType: '材料类型', + template: '询价模版', + currency: '交易币别', + companyCode: '公司代码', + purchaseDept: '采购部门', + buyer: '采购负责人', + quoteDeadline: '报价截止时间', + targetPrice: '目标价格', + leadTimeDays: '交货周期(天)', + paymentMethod: '付款方式', + status: '状态', + buyingMethod: '采购方式', + }, + costTemplate: { + title: '成本估算模板', + templateNo: '模板编号', + templateName: '模板名称', + templateNameEn: '模板英文名', + templateNameZhTw: '模板繁体名', + procurementCategory: '采购类别', + procurementMisc: '杂采', + procurementStrategic: '策采', + templateDesc: '模板描述', + status: '状态', + statusPlaceholder: '请选择状态', + statusConfirmed: '已确认', + statusUnconfirmed: '未确认', + statusCancelled: '已作废', + selectProcurementCategory: '请选择采购类别', + inputTemplateName: '请输入模板名称', + version: '版本', + newVersion: '新建版本', + newVersionFailed: '新建版本失败', + basicInfo: '基础信息', + sections: '区段信息', + controls: '控件', + fieldKey: '字段标识', + confirm: '确认', + confirmButtonText: '确认', + confirmSuccess: '确认成功', + confirmFailed: '确认失败', + confirmStatusTip: '确认状态提示', + cancelButtonText: '取消', + pleaseCompleteAndSave: '请先完成并保存', + pleaseModifyAndSave: '请先修改并保存', + loadDetailFailed: '加载明细失败', + keyNotFilled: '关键字段未填写', + isBom: '是否BOM', + bomYes: '是', + bomNo: '否', + acti: '操作', + actiYes: '是', + actiNo: '否', + productDetail: '产品明细', + materials: '材料', + material: '材质', + length: '长', + width: '宽', + height: '高', + specificgravity: '比重', + autoByMaterial: '由材质自动计算', + qty: '数量', + weight: '重量', + weightUsage: '用料重量', + unitPrice: '单价', + materialCost: '材料费用', + lengthWidthHeightSpecificgravityQty: '长*宽*高*比重*数量', + weightTimesUnitPrice: '重量*单价', + process: '加工', + processStation: '加工工站', + processTime: '加工时间', + unit: '计量单位', + unitrate: '工站费率', + autoByStation: '由工站自动计算', + processqty: '加工数量', + processprice: '加工单价', + processCost: '加工费', + unitrateTimesProcessqty: '工站费率*加工数量', + lossRate: '损耗率', + sgna: '销管费', + others: '其他', + profit: '利润', + tax: '税金', + remark: '备注', + updateTime: '更新时间', + }, + rfqmiscellaneous: { + title: '杂采询价单', + inquiryNo: '询价单号', + inquiryName: '询价单名称', + companyShortName: '交易厂区', + buyingMethod: '采购方式', + buyingMethodInquiry: '询价', + buyingMethodBid: '招标', + quoteDeadline: '报价截止时间', + bidStartTime: '投标开始时间', + bidEndTime: '投标截止时间', + buyer: '采购负责人', + currency: '币别', + leadTimeDays: '交货周期(天)', + paymentMethod: '付款方式', + paymentMethod1: 'T/T 30天', + paymentMethod2: 'T/T 60天', + paymentMethod3: 'T/T 90天', + paymentMethod4: 'T/T 120天', + paymentMethod5: 'L/C 30天', + paymentMethod6: 'L/C 60天', + paymentMethod7: 'L/C 90天', + paymentMethod8: 'L/C 120天', + paymentMethod9: '其他', + inquiryNoPlaceholder: '请输入询价单号', + inquiryNamePlaceholder: '请输入询价单名称', + buyerPlaceholder: '请输入采购负责人', + selectInquiryFirst: '请先选择询价单', + onlySingleOperation: '仅支持单条操作', + confirmBargainPrompt: '确认将状态改为【比议价中】?', + addSupplierFirst: '请先维护询价单供应商名单后再确认', + confirmPrompt: '确认后,该询价单将锁定并不可再编辑。如需修改,后续需执行【还原】操作', + prompt: '提示', + confirmFailed: '确认失败', + restorePrompt: '确认将状态还原为【开立】?', + restoreFailed: '还原失败', + publishPrompt: '确认将状态改为【发布】?', + publishFailed: '发布失败', + startBargainFailed: '开启比议价失败', + deleteFailed: '删除失败', + cancel: '取消', + inquiryNameRequired: '请输入询价单名称', + buyerRequired: '请输入采购负责人', + status: '状态', + statusOpen: '开立', + statusConfirmed: '确认', + statusPublished: '发布', + statusQuoting: '报价中', + statusQuotingEnd: '报价结束', + statusBargaining: '比议价中', + statusPriceAudit: '价格审核', + statusPriceApproved: '核价通过(结束)', + statusLost: '落标(结束)', + statusCancelled: '作废', + remark: '备注', + opCreate: '询价单创建', + opConfirm: '询价单确认', + opPublish: '询价单发布', + opRestore: '询价单还原', + opQuoteDeadline: '报价截止', + opSupplierQuote: '供应商报价', + opBargain: '比议价', + opBargainSubmit: '议价审核提交', + opBargainComplete: '议价审核完成', + opBargainReject: '议价审核驳回', + newInquiry: '新建询价单', + startBargain: '开启比价', + confirm: '确认', + restore: '还原', + publish: '发布', + comparePrice: '比价', + view: '查看', + edit: '编辑', + delete: '删除', + selectOneFirst: '请先选择询价单', + onlySupportSingle: '仅支持单条操作', + onlyQuotingCanBargain: '仅报价中或报价结束状态可开启比价', + confirmChangeToBargaining: '确认将状态改为【比议价中】?', + maintainSupplierFirst: '请先维护询价单供应商名单后再确认', + confirmLockAfterConfirm: '确认后,该询价单将锁定并不可再编辑。如需修改,后续需执行【还原】操作', + confirmRestore: '确认将状态还原为【开立】?', + confirmPublish: '确认将状态改为【发布】?', + transactionPlant: '交易厂区', + purchaseCategory: '采购类别', + inquiryTemplate: '询价模版', + templateVersion: '模板版本', + paymentTerm: '付款条件', + totalPriceInclTax: '含税总价', + costStructure: '成本结构', + supplierList: '供应商名单', + attachments: '附件', + basicInfo: '基础信息', + operationType: '操作类型', + operator: '操作人', + operationTime: '操作时间', + operationDesc: '操作描述', + statusChange: '状态变更', + quotationNo: '报价单号', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/miscprocurement/zh-tw.ts b/web/src/i18n/pages/miscprocurement/zh-tw.ts new file mode 100644 index 0000000..9c40a98 --- /dev/null +++ b/web/src/i18n/pages/miscprocurement/zh-tw.ts @@ -0,0 +1,254 @@ +// 定義內容 +export default { + message: { + pages: { + miscprocurement: { + materialInfo: { + title: '雜採材料資訊', + factory: '交易廠區', + materialtype: '材質', + materialtypeEn: '材質英文名', + materialtypeZhTw: '材質繁體名', + density: '比重', + price: '單價', + status: '狀態', + statusEnabled: '啟用', + statusDisabled: '禁用', + createTime: '創建時間', + updateTime: '更新時間', + }, + stationInfo: { + title: '雜採工站資訊', + companyCode: '交易廠區', + stationname: '工站名稱', + stationnameEn: '工站英文名', + stationnameZhTw: '工站繁體名', + stationcode: '工站代碼', + stationtype: '工站類型歸屬', + unit: '計量單位', + rate: '費率', + status: '狀態', + statusEnabled: '啟用', + statusDisabled: '禁用', + typeTooling: '模具', + typeGraphite: '石墨', + createTime: '創建時間', + updateTime: '更新時間', + }, + misc_parts: { + title: '雜採料號資訊', + companyCode: '交易廠區', + partid: '料號', + partidName: '物料說明', + specification: '品名規格', + unit: '單位', + partidCategory: '物料分類', + categoryTooling: '模具', + categoryGraphite: '石墨', + categoryOther: '其他', + status: '啟用否', + statusEnabled: '啟用', + statusDisabled: '禁用', + createTime: '創建時間', + updateTime: '更新時間', + validation: { + fieldNameRequired: '字段不能為空', + alreadyExists: '已存在', + } + }, + inquiry: { + title: '詢價單', + inquiryNo: '詢價單號', + title_label: '詢價單名稱', + titleEn: '詢價單英文名', + titleZhTw: '詢價單繁體名', + purchaseType: '採購類別', + materialType: '材料類型', + template: '詢價模版', + currency: '交易幣別', + companyCode: '公司代碼', + purchaseDept: '採購部門', + buyer: '採購負責人', + quoteDeadline: '報價截止時間', + targetPrice: '目標價格', + leadTimeDays: '交貨週期(天)', + paymentMethod: '付款方式', + status: '狀態', + buyingMethod: '採購方式', + }, + costTemplate: { + title: '成本估算模版', + templateNo: '模版編號', + templateName: '模版名稱', + templateNameEn: '模版英文名', + templateNameZhTw: '模版繁體名', + procurementCategory: '採購類別', + procurementMisc: '雜採', + procurementStrategic: '策採', + templateDesc: '模版描述', + status: '狀態', + statusPlaceholder: '請選擇狀態', + statusConfirmed: '已確認', + statusUnconfirmed: '未確認', + statusCancelled: '已作廢', + selectProcurementCategory: '請選擇採購類別', + inputTemplateName: '請輸入模版名稱', + version: '版本', + newVersion: '新建版本', + newVersionFailed: '新建版本失敗', + basicInfo: '基本信息', + sections: '區段資訊', + controls: '控件', + fieldKey: '字段識別', + confirm: '確認', + confirmButtonText: '確認', + confirmSuccess: '確認成功', + confirmFailed: '確認失敗', + confirmStatusTip: '確認狀態提示', + cancelButtonText: '取消', + pleaseCompleteAndSave: '請先完成並儲存', + pleaseModifyAndSave: '請先修改並儲存', + loadDetailFailed: '載入明細失敗', + keyNotFilled: '關鍵字段未填寫', + isBom: '是否BOM', + bomYes: '是', + bomNo: '否', + acti: '操作', + actiYes: '是', + actiNo: '否', + productDetail: '產品明細', + materials: '材料', + material: '材質', + length: '長', + width: '寬', + height: '高', + specificgravity: '比重', + autoByMaterial: '由材質自動計算', + qty: '數量', + weight: '重量', + weightUsage: '用料重量', + unitPrice: '單價', + materialCost: '材料費用', + lengthWidthHeightSpecificgravityQty: '長*寬*高*比重*數量', + weightTimesUnitPrice: '重量*單價', + process: '加工', + processStation: '加工工站', + processTime: '加工時間', + unit: '計量單位', + unitrate: '工站費率', + autoByStation: '由工站自動計算', + processqty: '加工數量', + processprice: '加工單價', + processCost: '加工費', + unitrateTimesProcessqty: '工站費率*加工數量', + lossRate: '損耗率', + sgna: '銷管費', + others: '其他', + profit: '利潤', + tax: '稅金', + remark: '備註', + updateTime: '更新時間', + }, + rfqmiscellaneous: { + title: '雜採詢價單', + inquiryNo: '詢價單號', + inquiryName: '詢價單名稱', + companyShortName: '交易廠區', + buyingMethod: '採購方式', + buyingMethodInquiry: '詢價', + buyingMethodBid: '招標', + quoteDeadline: '報價截止時間', + bidStartTime: '投標開始時間', + bidEndTime: '投標截止時間', + buyer: '採購負責人', + currency: '幣別', + leadTimeDays: '交貨週期(天)', + paymentMethod: '付款方式', + paymentMethod1: 'T/T 30天', + paymentMethod2: 'T/T 60天', + paymentMethod3: 'T/T 90天', + paymentMethod4: 'T/T 120天', + paymentMethod5: 'L/C 30天', + paymentMethod6: 'L/C 60天', + paymentMethod7: 'L/C 90天', + paymentMethod8: 'L/C 120天', + paymentMethod9: '其他', + inquiryNoPlaceholder: '請輸入詢價單號', + inquiryNamePlaceholder: '請輸入詢價單名稱', + buyerPlaceholder: '請輸入採購負責人', + selectInquiryFirst: '請先選擇詢價單', + onlySingleOperation: '僅支援單條操作', + confirmBargainPrompt: '確認將狀態改為【比議價中】?', + addSupplierFirst: '請先維護詢價單供應商名單後再確認', + confirmPrompt: '確認後,該詢價單將鎖定並不可再編輯。如需修改,後續需執行【還原】操作', + prompt: '提示', + confirmFailed: '確認失敗', + restorePrompt: '確認將狀態還原為【開立】?', + restoreFailed: '還原失敗', + publishPrompt: '確認將狀態改為【發布】?', + publishFailed: '發布失敗', + startBargainFailed: '開啟比議價失敗', + deleteFailed: '刪除失敗', + cancel: '取消', + inquiryNameRequired: '請輸入詢價單名稱', + buyerRequired: '請輸入採購負責人', + status: '狀態', + statusOpen: '開立', + statusConfirmed: '確認', + statusPublished: '發布', + statusQuoting: '報價中', + statusQuotingEnd: '報價結束', + statusBargaining: '比議價中', + statusPriceAudit: '價格審核', + statusPriceApproved: '核價通過(結束)', + statusLost: '落標(結束)', + statusCancelled: '作廢', + remark: '備註', + opCreate: '詢價單創建', + opConfirm: '詢價單確認', + opPublish: '詢價單發布', + opRestore: '詢價單還原', + opQuoteDeadline: '報價截止', + opSupplierQuote: '供應商報價', + opBargain: '比議價', + opBargainSubmit: '議價審核提交', + opBargainComplete: '議價審核完成', + opBargainReject: '議價審核駁回', + newInquiry: '新建詢價單', + startBargain: '開啟比價', + confirm: '確認', + restore: '還原', + publish: '發布', + comparePrice: '比價', + view: '查看', + edit: '編輯', + delete: '刪除', + selectOneFirst: '請先選擇詢價單', + onlySupportSingle: '僅支援單條操作', + onlyQuotingCanBargain: '僅報價中或報價結束狀態可開啟比價', + confirmChangeToBargaining: '確認將狀態改為【比議價中】?', + maintainSupplierFirst: '請先維護詢價單供應商名單後再確認', + confirmLockAfterConfirm: '確認後,該詢價單將鎖定並不可再編輯。如需修改,後續需執行【還原】操作', + confirmRestore: '確認將狀態還原為【開立】?', + confirmPublish: '確認將狀態改為【發布】?', + transactionPlant: '交易廠區', + purchaseCategory: '採購類別', + inquiryTemplate: '詢價模版', + templateVersion: '模版版本', + paymentTerm: '付款條件', + totalPriceInclTax: '含稅總價', + costStructure: '成本結構', + supplierList: '供應商名單', + attachments: '附件', + basicInfo: '基本信息', + operationType: '操作類型', + operator: '操作人', + operationTime: '操作時間', + operationDesc: '操作描述', + statusChange: '狀態變更', + quotationNo: '報價單號', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/operationLog/en.ts b/web/src/i18n/pages/operationLog/en.ts new file mode 100644 index 0000000..f5914c6 --- /dev/null +++ b/web/src/i18n/pages/operationLog/en.ts @@ -0,0 +1,65 @@ +// Define content +export default { + message: { + pages: { + operationLog: { + table: { + columns: { + module: 'Module', + method: 'Method', + operationType: 'Operation Type', + requestUrl: 'Request URL', + requestParam: 'Request Params', + responseCode: 'Response Code', + duration: 'Duration (ms)', + status: 'Status', + createTime: 'Operation Time', + creator: 'Operator', + remark: 'Details', + index: 'No.', + keyword: 'Keyword', + requestModule: 'Request Module', + requestPath: 'Request URL', + requestBody: 'Request Params', + requestMethod: 'Request Method', + requestMsg: 'Description', + requestIp: 'IP Address', + requestBrowser: 'Browser', + requestOs: 'OS', + jsonResult: 'Response', + creatorName: 'Operator', + }, + }, + form: { + module: 'Module', + remark: 'Details', + modulePlaceholder: 'Enter module', + remarkPlaceholder: 'Enter details', + keywordPlaceholder: 'Enter keyword', + requestModulePlaceholder: 'Enter request module', + requestPathPlaceholder: 'Enter request URL', + requestBodyPlaceholder: 'Enter request params', + requestMethodPlaceholder: 'Enter request method', + requestIpPlaceholder: 'Enter IP address', + }, + validation: { + moduleMaxLength: 'Module must be 100 characters or less', + remarkMaxLength: 'Details must be 500 characters or less', + }, + buttons: { + view: 'View', + query: 'Query', + export: 'Export', + refresh: 'Refresh', + reset: 'Reset', + timeRange: 'Operation Time Range', + operationType: 'Operation Type', + }, + messages: { + querySuccess: 'Query successful', + exportSuccess: 'Exported successfully', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/operationLog/zh-cn.ts b/web/src/i18n/pages/operationLog/zh-cn.ts new file mode 100644 index 0000000..33f6d81 --- /dev/null +++ b/web/src/i18n/pages/operationLog/zh-cn.ts @@ -0,0 +1,65 @@ +// 定义内容 +export default { + message: { + pages: { + operationLog: { + table: { + columns: { + module: '操作模块', + method: '请求方式', + operationType: '操作类型', + requestUrl: '请求地址', + requestParam: '请求参数', + responseCode: '响应码', + duration: '耗时(ms)', + status: '状态', + createTime: '操作时间', + creator: '操作人', + remark: '操作详情', + index: '序号', + keyword: '关键词', + requestModule: '请求模块', + requestPath: '请求地址', + requestBody: '请求参数', + requestMethod: '请求方法', + requestMsg: '操作说明', + requestIp: 'IP地址', + requestBrowser: '请求浏览器', + requestOs: '操作系统', + jsonResult: '返回信息', + creatorName: '操作人', + }, + }, + form: { + module: '操作模块', + remark: '操作详情', + modulePlaceholder: '请输入操作模块', + remarkPlaceholder: '请输入操作详情', + keywordPlaceholder: '请输入关键词', + requestModulePlaceholder: '请输入请求模块', + requestPathPlaceholder: '请输入请求地址', + requestBodyPlaceholder: '请输入请求参数', + requestMethodPlaceholder: '请输入请求方法', + requestIpPlaceholder: '请输入IP地址', + }, + validation: { + moduleMaxLength: '操作模块不能超过100个字符', + remarkMaxLength: '操作详情不能超过500个字符', + }, + buttons: { + view: '查看', + query: '查询', + export: '导出', + refresh: '刷新', + reset: '重置', + timeRange: '操作时间范围', + operationType: '操作类型', + }, + messages: { + querySuccess: '查询成功', + exportSuccess: '导出成功', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/operationLog/zh-tw.ts b/web/src/i18n/pages/operationLog/zh-tw.ts new file mode 100644 index 0000000..83d2880 --- /dev/null +++ b/web/src/i18n/pages/operationLog/zh-tw.ts @@ -0,0 +1,65 @@ +// 定義內容 +export default { + message: { + pages: { + operationLog: { + table: { + columns: { + module: '操作模組', + method: '請求方式', + operationType: '操作類型', + requestUrl: '請求地址', + requestParam: '請求參數', + responseCode: '響應碼', + duration: '耗時(ms)', + status: '狀態', + createTime: '操作時間', + creator: '操作人', + remark: '操作詳情', + index: '序號', + keyword: '關鍵詞', + requestModule: '請求模組', + requestPath: '請求地址', + requestBody: '請求參數', + requestMethod: '請求方式', + requestMsg: '操作說明', + requestIp: 'IP位址', + requestBrowser: '請求瀏覽器', + requestOs: '作業系統', + jsonResult: '返回資訊', + creatorName: '操作人', + }, + }, + form: { + module: '操作模組', + remark: '操作詳情', + modulePlaceholder: '請輸入操作模組', + remarkPlaceholder: '請輸入操作詳情', + keywordPlaceholder: '請輸入關鍵詞', + requestModulePlaceholder: '請輸入請求模組', + requestPathPlaceholder: '請輸入請求地址', + requestBodyPlaceholder: '請輸入請求參數', + requestMethodPlaceholder: '請輸入請求方式', + requestIpPlaceholder: '請輸入IP位址', + }, + validation: { + moduleMaxLength: '操作模組不能超過100個字符', + remarkMaxLength: '操作詳情不能超過500個字符', + }, + buttons: { + view: '查看', + query: '查詢', + export: '導出', + refresh: '刷新', + reset: '重置', + timeRange: '操作時間範圍', + operationType: '操作類型', + }, + messages: { + querySuccess: '查詢成功', + exportSuccess: '導出成功', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/personal/en.ts b/web/src/i18n/pages/personal/en.ts new file mode 100644 index 0000000..0ef7552 --- /dev/null +++ b/web/src/i18n/pages/personal/en.ts @@ -0,0 +1,64 @@ +// Define content +export default { + message: { + pages: { + personal: { + PersonalInfo1: 'Basic Info', + PersonalInfo2: 'Complete your personal information here', + info: { + myInfoTitle: 'My Information', + updateInfoTitle: 'Update Info', + accountSecurity: 'Account Security', + nickname: 'Nickname:', + department: 'Department:', + roles: 'Roles:', + currentPasswordStrength: 'Current Password Strength: Strong', + changePasswordNow: 'Change Now', + boundMobile: 'Bound Mobile:', + boundEmail: 'Bound Email:', + }, + form: { + nickname: 'Nickname', + nicknamePlaceholder: 'Please enter your nickname', + email: 'Email', + emailPlaceholder: 'Please enter your email', + mobile: 'Mobile', + mobilePlaceholder: 'Please enter your mobile number', + gender: 'Gender', + genderPlaceholder: 'Please select gender', + genderMale: 'Male', + genderFemale: 'Female', + genderSecret: 'Secret', + }, + dialog: { + passwordChange: 'Change Password', + oldPassword: 'Current Password', + newPassword: 'New Password', + confirmPassword: 'Confirm Password', + oldPasswordPlaceholder: 'Please enter your current password', + newPasswordPlaceholder: 'Please enter a new password', + confirmPasswordPlaceholder: 'Please confirm your new password', + submit: 'Submit', + }, + validation: { + nicknameRequired: 'Please enter your nickname', + mobileInvalid: 'Please enter a valid mobile number', + oldPasswordRequired: 'Please enter your current password', + sameAsOldPassword: 'New password cannot be the same as current password', + passwordComplexity: 'Password complexity too low (must contain letters and numbers)', + confirmPasswordRequired: 'Please confirm your password', + passwordMismatch: 'Passwords do not match', + formValidationFailed: 'Form validation failed, please check', + }, + messages: { + updateSuccess: 'Update successful', + passwordChangeSuccess: 'Password changed successfully', + formValidationFailed: 'Form validation failed, please check', + }, + button: { + submit: 'Submit', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/personal/zh-cn.ts b/web/src/i18n/pages/personal/zh-cn.ts new file mode 100644 index 0000000..31c8e53 --- /dev/null +++ b/web/src/i18n/pages/personal/zh-cn.ts @@ -0,0 +1,64 @@ +// 定义内容 +export default { + message: { + pages: { + personal: { + PersonalInfo1: '基本信息', + PersonalInfo2: '在这里完善你的个人信息', + info: { + myInfoTitle: '个人信息', + updateInfoTitle: '更新信息', + accountSecurity: '账号安全', + nickname: '昵称:', + department: '部门:', + roles: '角色:', + currentPasswordStrength: '当前密码强度:强', + changePasswordNow: '立即修改', + boundMobile: '已绑定手机:', + boundEmail: '已绑定邮箱:', + }, + form: { + nickname: '昵称', + nicknamePlaceholder: '请输入昵称', + email: '邮箱', + emailPlaceholder: '请输入邮箱', + mobile: '手机', + mobilePlaceholder: '请输入手机', + gender: '性别', + genderPlaceholder: '请选择性别', + genderMale: '男', + genderFemale: '女', + genderSecret: '保密', + }, + dialog: { + passwordChange: '密码修改', + oldPassword: '原密码', + newPassword: '新密码', + confirmPassword: '确认密码', + oldPasswordPlaceholder: '请输入原始密码', + newPasswordPlaceholder: '请输入新密码', + confirmPasswordPlaceholder: '请再次输入新密码', + submit: '提交', + }, + validation: { + nicknameRequired: '请输入昵称', + mobileInvalid: '请输入正确手机号', + oldPasswordRequired: '请输入原密码', + sameAsOldPassword: '原密码与新密码一致', + passwordComplexity: '您的密码复杂度太低(密码中必须包含字母、数字)', + confirmPasswordRequired: '请再次输入密码', + passwordMismatch: '两次输入密码不一致!', + formValidationFailed: '表单验证失败,请检查~', + }, + messages: { + updateSuccess: '更新成功', + passwordChangeSuccess: '密码修改成功', + formValidationFailed: '表单校验失败,请检查', + }, + button: { + submit: '提交', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/personal/zh-tw.ts b/web/src/i18n/pages/personal/zh-tw.ts new file mode 100644 index 0000000..b934480 --- /dev/null +++ b/web/src/i18n/pages/personal/zh-tw.ts @@ -0,0 +1,64 @@ +// 定義內容 +export default { + message: { + pages: { + personal: { + PersonalInfo1: '基本資訊', + PersonalInfo2: '在這裡完善您的個人資訊', + info: { + myInfoTitle: '個人資訊', + updateInfoTitle: '更新資訊', + accountSecurity: '帳號安全', + nickname: '暱稱:', + department: '部門:', + roles: '角色:', + currentPasswordStrength: '當前密碼強度:強', + changePasswordNow: '立即修改', + boundMobile: '已綁定手機:', + boundEmail: '已綁定郵箱:', + }, + form: { + nickname: '暱稱', + nicknamePlaceholder: '請輸入暱稱', + email: '郵箱', + emailPlaceholder: '請輸入郵箱', + mobile: '手機', + mobilePlaceholder: '請輸入手機', + gender: '性別', + genderPlaceholder: '請選擇性別', + genderMale: '男', + genderFemale: '女', + genderSecret: '保密', + }, + dialog: { + passwordChange: '密碼修改', + oldPassword: '原始密碼', + newPassword: '新密碼', + confirmPassword: '確認密碼', + oldPasswordPlaceholder: '請輸入原始密碼', + newPasswordPlaceholder: '請輸入新密碼', + confirmPasswordPlaceholder: '請再次輸入新密碼', + submit: '提交', + }, + validation: { + nicknameRequired: '請輸入暱稱', + mobileInvalid: '請輸入正確手機號', + oldPasswordRequired: '請輸入原始密碼', + sameAsOldPassword: '原始密碼與新密碼一致', + passwordComplexity: '您的密碼複雜度太低(密碼中必須包含字母、數字)', + confirmPasswordRequired: '請再次輸入密碼', + passwordMismatch: '兩次輸入密碼不一致!', + formValidationFailed: '表單驗證失敗,請檢查~', + }, + messages: { + updateSuccess: '更新成功', + passwordChangeSuccess: '密碼修改成功', + formValidationFailed: '表單校驗失敗,請檢查', + }, + button: { + submit: '提交', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/pissupplier/en.ts b/web/src/i18n/pages/pissupplier/en.ts new file mode 100644 index 0000000..800a96f --- /dev/null +++ b/web/src/i18n/pages/pissupplier/en.ts @@ -0,0 +1,143 @@ +// Definition +export default { + message: { + pages: { + pissupplier: { + quotation: { + title: 'Supplier Quotation', + quotationNo: 'Quotation No', + inquiryNo: 'Inquiry No', + supplierCode: 'Supplier Code', + supplierName: 'Supplier Name', + supplierNameEn: 'Supplier Name (English)', + supplierNameZhTw: 'Supplier Name (Traditional Chinese)', + contactPerson: 'Contact Person', + contactPhone: 'Contact Phone', + contactEmail: 'Contact Email', + quoteDeadline: 'Quote Deadline', + paymentMethod: 'Payment Method', + status: 'Status', + isAwarded: 'Award Status', + buyingMethod: 'Buying Method', + remark: 'Remark', + buyingMethodInquiry: 'Inquiry', + buyingMethodBid: 'Bid', + bidStartTime: 'Bid Start Time', + bidEndTime: 'Bid End Time', + leadTimeDays: 'Lead Time (Days)', + statusPending: 'Pending', + statusQuoting: 'Quoting', + statusCompleted: 'Completed', + statusExpired: 'Expired', + newQuote: 'New Quote', + viewQuote: 'View Quote', + editQuote: 'Edit Quote', + submitQuote: 'Submit Quote', + saveQuote: 'Save Quote', + bidWindowExpired: 'Bid deadline has passed, cannot quote or submit', + bidWindowMissing: 'Bid project is missing bid start or end time, cannot quote or submit', + fillBasicInfoFirst: 'Please complete [Quote Basic Info] before saving.', + onlyPendingCanSave: 'Only pending/quoting status can be saved', + onlyQuotingCanSubmit: 'Only quoting status can submit quote', + fillBasicInfoBeforeSubmit: 'Please complete [Quote Basic Info] in the quotation before submitting.', + cannotSubmitNoId: 'Cannot submit: missing quotation ID', + materialCost: 'Material Cost', + processCost: 'Process Cost', + otherCost: 'Other Cost', + profit: 'Profit', + tax: 'Tax', + profitRate: 'Profit Rate', + taxRate: 'Tax Rate', + weight: 'Weight', + unitPrice: 'Unit Price', + materialFee: 'Material Fee', + processFee: 'Process Fee', + packagingFee: 'Packaging Fee', + transportFee: 'Transport Fee', + contact: 'Contact', + phone: 'Phone', + email: 'Email', + validityDays: 'Validity (Days)', + awarded: 'Awarded', + notAwarded: 'Not Awarded', + evaluating: 'Evaluating', + quoteAmount: 'Quote Amount', + quoteTime: 'Quote Time', + uploadAttachment: 'Upload Attachment', + comparePrice: 'Compare Price', + lowestPrice: 'Lowest Price', + averagePrice: 'Average Price', + inquiryTitle: 'Inquiry Title', + fileTypeDrawing: 'Drawing', + fileTypeBidDoc: 'Bid Document', + fileTypeOther: 'Other', + paymentTt30_70: 'T/T 30% Prepay, 70% Before Shipment', + paymentNet30: 'Net 30 Days', + paymentNet45: 'Net 45 Days', + paymentPrepaid: 'Full Prepayment', + partNo: 'Part No', + specDesc: 'Spec Description', + processStation: 'Process Station', + processUnit: 'Process Unit', + processRate: 'Station Rate', + processMeasure: 'Process Qty', + specificGravity: 'Specific Gravity', + totalPrice: 'Total Amount', + taxAmount: 'Tax Amount', + taxRatePct: 'Tax Rate (%)', + profitAmount: 'Profit Amount', + profitRatePct: 'Profit Rate (%)', + saved: 'Saved', + submitted: 'Submitted', + submittedInquiryClosed: 'Submitted, Inquiry Closed', + saveFailed: 'Save Failed', + submitFailed: 'Submit Failed', + cannotAddRowNoFields: 'Please configure fields in the template before adding rows', + attachmentUploadFailed: 'Attachment upload failed: {{name}}', + attachmentMissingPath: 'Attachment path missing: {{name}}', + unnamed: 'Unnamed', + unnamedFile: 'Unnamed File', + statusEvaluating: 'Evaluating', + statusLost: 'Lost', + statusOpen: 'Open', + statusConfirmed: 'Confirmed', + statusPublished: 'Published', + statusQuotingEnd: 'Quote Ended', + statusBargaining: 'Bargaining', + statusPriceAudit: 'Price Audit', + statusPriceApproved: 'Price Approved', + statusCancelled: 'Cancelled', + length: 'Length', + width: 'Width', + height: 'Height', + qty: 'Qty', + material: 'Material', + companyShortName: 'Transaction Plant', + inquiryTemplate: 'Inquiry Template', + quoteTime: 'Quote Time', + currency: 'Currency', + quoteStatus: 'Quote Status', + createTime: 'Create Time', + quoteNow: 'Quote Now', + submitQuote: 'Submit', + view: 'View', + companyCodeOrName: 'Company code or name', + }, + vendorType: { + stateOwned: 'State-owned', + collective: 'Collective', + private: 'Private', + joint: 'Joint Venture', + whollyOwned: 'Wholly Foreign-owned', + other: 'Other', + }, + paymentTerms: { + tt30_70: 'T/T 30% Prepay, 70% Before Shipment', + net30: 'Net 30 Days', + net45: 'Net 45 Days', + prepaid: 'Full Prepayment', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/pissupplier/zh-cn.ts b/web/src/i18n/pages/pissupplier/zh-cn.ts new file mode 100644 index 0000000..3a19584 --- /dev/null +++ b/web/src/i18n/pages/pissupplier/zh-cn.ts @@ -0,0 +1,143 @@ +// 定义内容 +export default { + message: { + pages: { + pissupplier: { + quotation: { + title: '供应商报价', + quotationNo: '报价单单号', + inquiryNo: '询价单单号', + supplierCode: '供应商代码', + supplierName: '供应商名称', + supplierNameEn: '供应商英文名', + supplierNameZhTw: '供应商繁体名', + contactPerson: '联系人', + contactPhone: '联系人电话', + contactEmail: '联系人邮件', + quoteDeadline: '报价截止时间', + paymentMethod: '付款方式', + status: '状态', + isAwarded: '报价中标否', + buyingMethod: '采购方式', + remark: '报价说明及备注', + buyingMethodInquiry: '询价', + buyingMethodBid: '招标', + bidStartTime: '投标开始时间', + bidEndTime: '投标截止时间', + leadTimeDays: '交货周期(天)', + statusPending: '待报价', + statusQuoting: '报价中', + statusCompleted: '已报价', + statusExpired: '已过期', + newQuote: '新建报价单', + viewQuote: '查看报价', + editQuote: '编辑报价', + submitQuote: '提交报价', + saveQuote: '保存报价', + bidWindowExpired: '已超过投标截止时间,无法报价或提交', + bidWindowMissing: '招标项目缺少投标开始或截止时间,无法报价或提交', + fillBasicInfoFirst: '请先填写完整【报价基础信息】后再保存。', + onlyPendingCanSave: '仅未报价/报价中状态可保存', + onlyQuotingCanSubmit: '仅报价中状态可提交报价', + fillBasicInfoBeforeSubmit: '请先将报价单中的【报价基础信息】填写完整后再提交报价。', + cannotSubmitNoId: '无法提交:缺少报价单标识', + materialCost: '材料成本', + processCost: '加工成本', + otherCost: '其它成本', + profit: '利润', + tax: '税金', + profitRate: '利润率', + taxRate: '税率', + weight: '重量', + unitPrice: '单价', + materialFee: '材料费用', + processFee: '加工费', + packagingFee: '包装费', + transportFee: '运输费', + contact: '联络人', + phone: '电话', + email: '邮箱', + validityDays: '有效期(天)', + awarded: '中标', + notAwarded: '未中标', + evaluating: '评标中', + quoteAmount: '报价金额', + quoteTime: '报价时间', + uploadAttachment: '上传附件', + comparePrice: '比价', + lowestPrice: '制程最低价', + averagePrice: '平均价', + inquiryTitle: '询价单名称', + fileTypeDrawing: '图纸', + fileTypeBidDoc: '招标文件', + fileTypeOther: '其他', + paymentTt30_70: 'T/T 30%预付,70%出货前', + paymentNet30: '月结30天', + paymentNet45: '月结45天', + paymentPrepaid: '全额预付', + partNo: '料号', + specDesc: '规格描述', + processStation: '加工工站', + processUnit: '加工单位', + processRate: '工站费率', + processMeasure: '加工数量', + specificGravity: '比重', + totalPrice: '合计金额', + taxAmount: '税额', + taxRatePct: '税率(%)', + profitAmount: '利润金额', + profitRatePct: '利润率(%)', + saved: '已保存', + submitted: '已提交', + submittedInquiryClosed: '已提交,询价单已关闭', + saveFailed: '保存失败', + submitFailed: '提交失败', + cannotAddRowNoFields: '请先在模板中配置要填写的字段后再新增行', + attachmentUploadFailed: '附件上传失败:{{name}}', + attachmentMissingPath: '附件路径缺失:{{name}}', + unnamed: '未命名', + unnamedFile: '未命名文件', + statusEvaluating: '评标中', + statusLost: '落标', + statusOpen: '开立', + statusConfirmed: '确认', + statusPublished: '发布', + statusQuotingEnd: '报价结束', + statusBargaining: '比议价中', + statusPriceAudit: '价格审核', + statusPriceApproved: '核价通过(结束)', + statusCancelled: '作废', + length: '长', + width: '宽', + height: '高', + qty: '数量', + material: '材质', + companyShortName: '交易厂区', + inquiryTemplate: '询价模板', + quoteTime: '报价时间', + currency: '币别', + quoteStatus: '报价状态', + createTime: '创建时间', + quoteNow: '报价', + submitQuote: '提交', + view: '查看', + companyCodeOrName: '公司代码或简称', + }, + vendorType: { + stateOwned: '国有', + collective: '集体', + private: '私营', + joint: '合资', + whollyOwned: '独资', + other: '其他', + }, + paymentTerms: { + tt30_70: 'T/T 30%预付,70%出货前', + net30: '月结30天', + net45: '月结45天', + prepaid: '全额预付', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/pissupplier/zh-tw.ts b/web/src/i18n/pages/pissupplier/zh-tw.ts new file mode 100644 index 0000000..a7cc0f1 --- /dev/null +++ b/web/src/i18n/pages/pissupplier/zh-tw.ts @@ -0,0 +1,143 @@ +// 定義內容 +export default { + message: { + pages: { + pissupplier: { + quotation: { + title: '供應商報價', + quotationNo: '報價單號', + inquiryNo: '詢價單號', + supplierCode: '供應商代碼', + supplierName: '供應商名稱', + supplierNameEn: '供應商英文名', + supplierNameZhTw: '供應商繁體名', + contactPerson: '聯絡人', + contactPhone: '聯絡人電話', + contactEmail: '聯絡人郵箱', + quoteDeadline: '報價截止時間', + paymentMethod: '付款方式', + status: '狀態', + isAwarded: '報價中標否', + buyingMethod: '採購方式', + remark: '報價說明及備註', + buyingMethodInquiry: '詢價', + buyingMethodBid: '招標', + bidStartTime: '投標開始時間', + bidEndTime: '投標截止時間', + leadTimeDays: '交貨週期(天)', + statusPending: '待報價', + statusQuoting: '報價中', + statusCompleted: '已報價', + statusExpired: '已過期', + newQuote: '新建報價單', + viewQuote: '查看報價', + editQuote: '編輯報價', + submitQuote: '提交報價', + saveQuote: '儲存報價', + bidWindowExpired: '已超過投標截止時間,無法報價或提交', + bidWindowMissing: '招標項目缺少投標開始或截止時間,無法報價或提交', + fillBasicInfoFirst: '請先填寫完整【報價基本信息】後再儲存。', + onlyPendingCanSave: '僅未報價/報價中狀態可儲存', + onlyQuotingCanSubmit: '僅報價中狀態可提交報價', + fillBasicInfoBeforeSubmit: '請先將報價單中的【報價基本信息】填寫完整後再提交報價。', + cannotSubmitNoId: '無法提交:缺少報價單標識', + materialCost: '材料成本', + processCost: '加工成本', + otherCost: '其它成本', + profit: '利潤', + tax: '税金', + profitRate: '利潤率', + taxRate: '税率', + weight: '重量', + unitPrice: '單價', + materialFee: '材料費用', + processFee: '加工費', + packagingFee: '包裝費', + transportFee: '運輸費', + contact: '聯絡人', + phone: '電話', + email: '郵箱', + validityDays: '有效期(天)', + awarded: '中標', + notAwarded: '未中標', + evaluating: '評標中', + quoteAmount: '報價金額', + quoteTime: '報價時間', + uploadAttachment: '上傳附件', + comparePrice: '比價', + lowestPrice: '製程最低價', + averagePrice: '平均價', + inquiryTitle: '詢價單名稱', + fileTypeDrawing: '圖紙', + fileTypeBidDoc: '招標文件', + fileTypeOther: '其他', + paymentTt30_70: 'T/T 30%預付,70%出貨前', + paymentNet30: '月結30天', + paymentNet45: '月結45天', + paymentPrepaid: '全額預付', + partNo: '料號', + specDesc: '規格描述', + processStation: '加工工站', + processUnit: '加工單位', + processRate: '工站費率', + processMeasure: '加工數量', + specificGravity: '比重', + totalPrice: '合計金額', + taxAmount: '稅額', + taxRatePct: '稅率(%)', + profitAmount: '利潤金額', + profitRatePct: '利潤率(%)', + saved: '已儲存', + submitted: '已提交', + submittedInquiryClosed: '已提交,詢價單已關閉', + saveFailed: '儲存失敗', + submitFailed: '提交失敗', + cannotAddRowNoFields: '請先在模板中配置要填寫的欄位後再新增行', + attachmentUploadFailed: '附件上傳失敗:{{name}}', + attachmentMissingPath: '附件路徑缺失:{{name}}', + unnamed: '未命名', + unnamedFile: '未命名檔案', + statusEvaluating: '評標中', + statusLost: '落標', + statusOpen: '開立', + statusConfirmed: '確認', + statusPublished: '發布', + statusQuotingEnd: '報價結束', + statusBargaining: '比議價中', + statusPriceAudit: '價格審核', + statusPriceApproved: '核價通過(結束)', + statusCancelled: '作廢', + length: '長', + width: '寬', + height: '高', + qty: '數量', + material: '材質', + companyShortName: '交易廠區', + inquiryTemplate: '詢價模版', + quoteTime: '報價時間', + currency: '幣別', + quoteStatus: '報價狀態', + createTime: '創建時間', + quoteNow: '報價', + submitQuote: '提交', + view: '查看', + companyCodeOrName: '公司代碼或簡稱', + }, + vendorType: { + stateOwned: '國有', + collective: '集體', + private: '私營', + joint: '合資', + whollyOwned: '獨資', + other: '其他', + }, + paymentTerms: { + tt30_70: 'T/T 30%預付,70%出貨前', + net30: '月結30天', + net45: '月結45天', + prepaid: '全額預付', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/role/en.ts b/web/src/i18n/pages/role/en.ts new file mode 100644 index 0000000..3ee8bc8 --- /dev/null +++ b/web/src/i18n/pages/role/en.ts @@ -0,0 +1,91 @@ +// Define content +export default { + message: { + pages: { + role: { + table: { + columns: { + index: 'No.', + name: 'Role Name', + key: 'Permission Key', + sort: 'Sort', + status: 'Status', + actions: 'Actions', + }, + }, + form: { + name: 'Role Name', + key: 'Permission Key', + sort: 'Sort', + status: 'Status', + remark: 'Remark', + namePlaceholder: 'Please enter role name', + keyPlaceholder: 'Enter permission key', + sortPlaceholder: 'Please enter sort order', + remarkPlaceholder: 'Please enter remark', + }, + validation: { + nameRequired: 'Role name is required', + keyRequired: 'Permission key is required', + sortRequired: 'Sort order is required', + }, + dialog: { + addRole: 'Add Role', + editRole: 'Edit Role', + assignPermissions: 'Permission Config', + assignUsers: 'Assign Users', + deleteConfirm: 'Are you sure you want to delete this role?', + menuPermission: 'Menu Permission', + buttonPermission: 'Button Permission', + columnPermission: 'Column Field Permission', + interfacePermission: 'Interface Permission', + currentRole: 'Current authorized role:', + authorizedUsers: 'Authorized users:', + selectDataPermission: 'Please select', + customDeptPlaceholder: 'Select custom departments', + dataPermissionConfig: 'Data Permission Config', + defaultInterfacePermission: 'Default interface permission:', + configureOperationPermission: 'Configure operation interface permissions. Click the gear icon to configure data permissions.', + }, + messages: { + addSuccess: 'Created successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + assignSuccess: 'Assigned successfully', + saveSuccess: 'Saved successfully', + checkUsersFirst: 'Please select users first', + batchDeleteConfirm: 'Are you sure you want to delete permissions for {count} users?', + deleteUserConfirm: 'Are you sure you want to delete permissions for "{count}" users?', + }, + buttons: { + add: 'Add', + view: 'View', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + reset: 'Reset', + export: 'Export', + query: 'Search', + refresh: 'Refresh', + assignPermission: 'Permission Config', + assignUsers: 'Assign Users', + batchDelete: 'Batch Delete', + confirm: 'Confirm', + }, + transfer: { + unassignedUsers: 'Unassigned Users', + assignedUsers: 'Assigned Users', + }, + dataPermission: { + ownDataOnly: 'Own data only', + deptAndBelow: 'Department and below', + deptOnly: 'Department only', + allData: 'All data', + customData: 'Custom data', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/role/zh-cn.ts b/web/src/i18n/pages/role/zh-cn.ts new file mode 100644 index 0000000..24b8abf --- /dev/null +++ b/web/src/i18n/pages/role/zh-cn.ts @@ -0,0 +1,91 @@ +// 定义内容 +export default { + message: { + pages: { + role: { + table: { + columns: { + index: '序号', + name: '角色名称', + key: '权限标识', + sort: '排序', + status: '状态', + actions: '操作', + }, + }, + form: { + name: '角色名称', + key: '权限标识', + sort: '排序', + status: '状态', + remark: '备注', + namePlaceholder: '请输入角色名称', + keyPlaceholder: '输入权限标识', + sortPlaceholder: '请输入排序', + remarkPlaceholder: '请输入备注', + }, + validation: { + nameRequired: '角色名称必填', + keyRequired: '权限标识必填', + sortRequired: '排序必填', + }, + dialog: { + addRole: '新增角色', + editRole: '编辑角色', + assignPermissions: '权限配置', + assignUsers: '授权用户', + deleteConfirm: '确定删除该角色吗?', + menuPermission: '菜单权限', + buttonPermission: '按钮权限', + columnPermission: '列字段权限', + interfacePermission: '接口权限', + currentRole: '当前授权角色:', + authorizedUsers: '授权人员:', + selectDataPermission: '请选择', + customDeptPlaceholder: '请选择自定义部门', + dataPermissionConfig: '数据权限配置', + defaultInterfacePermission: '默认接口权限:', + configureOperationPermission: '配置操作功能接口权限,配置数据权限点击小齿轮', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + assignSuccess: '分配成功', + saveSuccess: '保存成功', + checkUsersFirst: '请先勾选用户', + batchDeleteConfirm: '确定要删除这{count}位用户的权限吗', + deleteUserConfirm: '确定要删除这 "{count}" 位用户的权限吗', + }, + buttons: { + add: '新增', + view: '查看', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + reset: '重置', + export: '导出', + query: '查询', + refresh: '刷新', + assignPermission: '权限配置', + assignUsers: '授权用户', + batchDelete: '批量删除', + confirm: '确定', + }, + transfer: { + unassignedUsers: '未授权用户', + assignedUsers: '已授权用户', + }, + dataPermission: { + ownDataOnly: '仅本人数据权限', + deptAndBelow: '本部门及以下数据权限', + deptOnly: '本部门数据权限', + allData: '全部数据权限', + customData: '自定数据权限', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/role/zh-tw.ts b/web/src/i18n/pages/role/zh-tw.ts new file mode 100644 index 0000000..e69de29 diff --git a/web/src/i18n/pages/taskLog/en.ts b/web/src/i18n/pages/taskLog/en.ts new file mode 100644 index 0000000..5e581f5 --- /dev/null +++ b/web/src/i18n/pages/taskLog/en.ts @@ -0,0 +1,34 @@ +// Define content +export default { + message: { + pages: { + taskLog: { + table: { + columns: { + index: 'No.', + taskId: 'Task ID', + taskName: 'Task Name', + periodicTaskName: 'Periodic Task Name', + taskKwargs: 'Parameters', + status: 'Status', + result: 'Result', + dateDone: 'Completed At', + dateCreated: 'Created At', + }, + }, + status: { + SUCCESS: 'Success', + STARTED: 'Started', + REVOKED: 'Revoked', + RETRY: 'Retrying', + RECEIVED: 'Received', + PENDING: 'Pending', + FAILURE: 'Failure', + }, + buttons: { + view: 'View', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/taskLog/zh-cn.ts b/web/src/i18n/pages/taskLog/zh-cn.ts new file mode 100644 index 0000000..cb026a8 --- /dev/null +++ b/web/src/i18n/pages/taskLog/zh-cn.ts @@ -0,0 +1,34 @@ +// 定义内容 +export default { + message: { + pages: { + taskLog: { + table: { + columns: { + index: '序号', + taskId: '任务ID', + taskName: '任务名称', + periodicTaskName: '周期任务名称', + taskKwargs: '请求参数', + status: '执行状态', + result: '执行结果', + dateDone: '执行完成时间', + dateCreated: '创建时间', + }, + }, + status: { + SUCCESS: '执行成功', + STARTED: '已开始', + REVOKED: '已取消', + RETRY: '重试中', + RECEIVED: '已收到', + PENDING: '待定中', + FAILURE: '执行失败', + }, + buttons: { + view: '查看', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/taskLog/zh-tw.ts b/web/src/i18n/pages/taskLog/zh-tw.ts new file mode 100644 index 0000000..1bdeb5a --- /dev/null +++ b/web/src/i18n/pages/taskLog/zh-tw.ts @@ -0,0 +1,34 @@ +// 定義內容 +export default { + message: { + pages: { + taskLog: { + table: { + columns: { + index: '序號', + taskId: '任務ID', + taskName: '任務名稱', + periodicTaskName: '週期任務名稱', + taskKwargs: '請求參數', + status: '執行狀態', + result: '執行結果', + dateDone: '執行完成時間', + dateCreated: '創建時間', + }, + }, + status: { + SUCCESS: '執行成功', + STARTED: '已開始', + REVOKED: '已取消', + RETRY: '重試中', + RECEIVED: '已收到', + PENDING: '待定中', + FAILURE: '執行失敗', + }, + buttons: { + view: '查看', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/taskManage/en.ts b/web/src/i18n/pages/taskManage/en.ts new file mode 100644 index 0000000..4db7c69 --- /dev/null +++ b/web/src/i18n/pages/taskManage/en.ts @@ -0,0 +1,73 @@ +// Define content +export default { + message: { + pages: { + taskManage: { + table: { + columns: { + index: 'No.', + name: 'Task Name', + task: 'Task', + lastRunAt: 'Last Run', + description: 'Description', + cron: 'Cron Expression', + kwargs: 'Parameters', + status: 'Status', + enabled: 'Enabled', + disabled: 'Disabled', + }, + }, + form: { + name: 'Task Name', + namePlaceholder: 'Please enter task name', + task: 'Task', + taskPlaceholder: 'Input task', + cron: 'Cron Expression Settings', + cronExpression: 'Cron Expression', + lastRunAt: 'Last Run', + description: 'Description', + kwargs: 'Parameters', + enabled: 'Status', + validation: { + nameRequired: 'Task name is required', + taskRequired: 'Task is required', + cronRequired: 'Expression is required', + statusRequired: 'Status is required', + }, + }, + dialog: { + taskLogs: 'Task Execution Logs', + cronSelector: 'Cron Expression Selector', + confirmStop: 'Confirm to disable this task?', + confirmEnable: 'Confirm to enable this task?', + confirmRun: 'Run this task immediately?', + confirmDelete: 'Confirm to delete this task?', + }, + messages: { + enableSuccess: 'Task enabled', + disableSuccess: 'Task disabled', + runSuccess: 'Task triggered', + deleteSuccess: 'Task deleted', + }, + buttons: { + view: 'View', + edit: 'Edit', + delete: 'Delete', + add: 'Add', + confirm: 'Confirm', + cancel: 'Cancel', + enable: 'Enabled', + disabled: 'Disabled', + runNow: 'Run Now', + taskLogs: 'Task Logs', + }, + card: { + executeTask: 'Execute Task', + cronRule: 'Cron Rule', + lastRunTime: 'Last Run Time', + }, + empty: 'No data, please add', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/taskManage/zh-cn.ts b/web/src/i18n/pages/taskManage/zh-cn.ts new file mode 100644 index 0000000..3c7b93e --- /dev/null +++ b/web/src/i18n/pages/taskManage/zh-cn.ts @@ -0,0 +1,73 @@ +// 定义内容 +export default { + message: { + pages: { + taskManage: { + table: { + columns: { + index: '序号', + name: '任务名称', + task: '执行任务', + lastRunAt: '最后运行时间', + description: '备注', + cron: '表达式', + kwargs: '请求参数', + status: '状态', + enabled: '启用', + disabled: '禁用', + }, + }, + form: { + name: '任务名称', + namePlaceholder: '请输入任务名称', + task: '执行任务', + taskPlaceholder: '输入执行任务', + cron: 'Cron表达式设置', + cronExpression: 'Cron表达式', + lastRunAt: '最后运行时间', + description: '备注', + kwargs: '请求参数', + enabled: '状态', + validation: { + nameRequired: '任务名称必填', + taskRequired: '执行任务必填', + cronRequired: '表达式必填', + statusRequired: '排序必填', + }, + }, + dialog: { + taskLogs: '任务运行日志', + cronSelector: 'Cron表达式选择器', + confirmStop: '确认停用该任务?', + confirmEnable: '确认启用该任务?', + confirmRun: '立即运行该任务?', + confirmDelete: '确定删除该任务?', + }, + messages: { + enableSuccess: '任务已启用', + disableSuccess: '任务已停用', + runSuccess: '任务已触发执行', + deleteSuccess: '任务已删除', + }, + buttons: { + view: '查看', + edit: '编辑', + delete: '删除', + add: '新增', + confirm: '确定', + cancel: '取消', + enable: '已启用', + disabled: '已停用', + runNow: '立即运行', + taskLogs: '任务日志', + }, + card: { + executeTask: '执行任务', + cronRule: '定时规则', + lastRunTime: '最后运行时间', + }, + empty: '暂无数据,请添加', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/taskManage/zh-tw.ts b/web/src/i18n/pages/taskManage/zh-tw.ts new file mode 100644 index 0000000..76134be --- /dev/null +++ b/web/src/i18n/pages/taskManage/zh-tw.ts @@ -0,0 +1,73 @@ +// 定義內容 +export default { + message: { + pages: { + taskManage: { + table: { + columns: { + index: '序號', + name: '任務名稱', + task: '執行任務', + lastRunAt: '最後運行時間', + description: '備註', + cron: '表達式', + kwargs: '請求參數', + status: '狀態', + enabled: '啟用', + disabled: '禁用', + }, + }, + form: { + name: '任務名稱', + namePlaceholder: '請輸入任務名稱', + task: '執行任務', + taskPlaceholder: '輸入執行任務', + cron: 'Cron表達式設置', + cronExpression: 'Cron表達式', + lastRunAt: '最後運行時間', + description: '備註', + kwargs: '請求參數', + enabled: '狀態', + validation: { + nameRequired: '任務名稱必填', + taskRequired: '執行任務必填', + cronRequired: '表達式必填', + statusRequired: '排序必填', + }, + }, + dialog: { + taskLogs: '任務運行日誌', + cronSelector: 'Cron表達式選擇器', + confirmStop: '確認停用該任務?', + confirmEnable: '確認啟用該任務?', + confirmRun: '立即運行該任務?', + confirmDelete: '確定刪除該任務?', + }, + messages: { + enableSuccess: '任務已啟用', + disableSuccess: '任務已停用', + runSuccess: '任務已觸發執行', + deleteSuccess: '任務已刪除', + }, + buttons: { + view: '查看', + edit: '編輯', + delete: '刪除', + add: '新增', + confirm: '確定', + cancel: '取消', + enable: '已啟用', + disabled: '已停用', + runNow: '立即運行', + taskLogs: '任務日誌', + }, + card: { + executeTask: '執行任務', + cronRule: '定時規則', + lastRunTime: '最後運行時間', + }, + empty: '暫無數據,請添加', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/user/en.ts b/web/src/i18n/pages/user/en.ts new file mode 100644 index 0000000..cf77e78 --- /dev/null +++ b/web/src/i18n/pages/user/en.ts @@ -0,0 +1,129 @@ +// Define content +export default { + message: { + pages: { + user: { + table: { + columns: { + select: 'Select', + index: 'No.', + username: 'Username', + name: 'Full Name', + dept: 'Department', + manageDept: 'Managed Dept.', + role: 'Roles', + mobile: 'Mobile', + email: 'Email', + gender: 'Gender', + userType: 'User Type', + status: 'Status', + avatar: 'Avatar', + actions: 'Actions', + }, + }, + form: { + username: 'Username', + password: 'Password', + name: 'Full Name', + dept: 'Department', + manageDept: 'Managed Dept.', + role: 'Roles', + mobile: 'Mobile', + email: 'Email', + gender: 'Gender', + userType: 'User Type', + status: 'Status', + avatar: 'Avatar', + usernamePlaceholder: 'Please enter username', + passwordPlaceholder: 'Please enter password', + namePlaceholder: 'Please enter full name', + deptPlaceholder: 'Please select', + manageDeptPlaceholder: 'Please select', + rolePlaceholder: 'Please select roles', + mobilePlaceholder: 'Please enter mobile number', + emailPlaceholder: 'Please enter email', + genderPlaceholder: 'Please select gender', + userTypePlaceholder: 'Please select user type', + }, + validation: { + usernameRequired: 'Username is required', + passwordRequired: 'Password is required', + nameRequired: 'Full name is required', + deptRequired: 'Required', + roleRequired: 'Required', + mobileInvalid: 'Please enter a valid mobile number', + emailInvalid: 'Please enter a valid email address', + manageDeptHelper: 'Defaults to department if not selected', + }, + dialog: { + addUser: 'Add User', + editUser: 'Edit User', + assignRoles: 'Assign Roles', + deleteConfirm: 'Are you sure you want to delete this user?', + resetPassword: 'Reset Password', + resetPasswordConfirm: 'Are you sure you want to reset to the system default password?', + resetPasswordSuccess: 'Password reset successfully', + exportTitle: 'Prompt', + exportConfirm: 'Are you sure you want to export data?', + }, + messages: { + addSuccess: 'Created successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + importSuccess: 'Imported successfully', + exportSuccess: 'Exported successfully', + exportFailed: 'Export failed', + }, + buttons: { + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + reset: 'Reset', + import: 'Import', + export: 'Export', + query: 'Search', + batchAdd: 'Batch Add', + refresh: 'Refresh', + columnSetting: 'Columns', + resetPassword: 'Reset Password', + confirm: 'Confirm', + selectedCount: '{count} selected', + }, + tree: { + deptList: 'Department List', + deptPlaceholder: 'Enter department name', + deptInfo: '1. Department info;', + }, + title0: 'Switch Component Size', + title1: 'Switch Language', + title2: 'Search', + title3: 'Layout Settings', + title4: 'Message Center', + title5: 'Fullscreen', + title6: 'Exit Fullscreen', + dropdown1: 'Home', + dropdown2: 'Personal Center', + versionLog: 'Version Upgrade Log', + dropdownLarge: 'Large', + dropdownDefault: 'Default', + dropdownSmall: 'Small', + langZhCn: '简体中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: 'Log Out', + fullscreenNotSupported: 'Your browser does not support fullscreen!', + logOutTitle: 'Notice', + logOutMessage: 'You are about to log out. Continue?', + logOutConfirm: 'Confirm', + logOutCancel: 'Cancel', + logOutExit: 'Exiting...', + retry: 'Retry', + onlinePrompt: 'Reconnecting to server...', + defaultUsername: 'User', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/user/zh-cn.ts b/web/src/i18n/pages/user/zh-cn.ts new file mode 100644 index 0000000..f0fe121 --- /dev/null +++ b/web/src/i18n/pages/user/zh-cn.ts @@ -0,0 +1,129 @@ +// 定义内容 +export default { + message: { + pages: { + user: { + table: { + columns: { + select: '选择', + index: '序号', + username: '账号', + name: '姓名', + dept: '所属部门', + manageDept: '管理部门', + role: '角色', + mobile: '手机号码', + email: '邮箱', + gender: '性别', + userType: '用户类型', + status: '状态', + avatar: '头像', + actions: '操作', + }, + }, + form: { + username: '账号', + password: '密码', + name: '姓名', + dept: '所属部门', + manageDept: '管理部门', + role: '角色', + mobile: '手机号码', + email: '邮箱', + gender: '性别', + userType: '用户类型', + status: '状态', + avatar: '头像', + usernamePlaceholder: '请输入账号', + passwordPlaceholder: '请输入密码', + namePlaceholder: '请输入姓名', + deptPlaceholder: '请选择', + manageDeptPlaceholder: '请选择', + rolePlaceholder: '请选择角色', + mobilePlaceholder: '请输入手机号码', + emailPlaceholder: '请输入邮箱', + genderPlaceholder: '请选择性别', + userTypePlaceholder: '请选择用户类型', + }, + validation: { + usernameRequired: '账号必填项', + passwordRequired: '密码必填项', + nameRequired: '姓名必填项', + deptRequired: '必填项', + roleRequired: '必填项', + mobileInvalid: '请输入正确的手机号码', + emailInvalid: '请输入正确的邮箱地址', + manageDeptHelper: '不选则默认为所属部门', + }, + dialog: { + addUser: '新增用户', + editUser: '编辑用户', + assignRoles: '分配角色', + deleteConfirm: '是否删除该用户?', + resetPassword: '重置密码', + resetPasswordConfirm: '确定重置为系统默认密码吗?', + resetPasswordSuccess: '重置密码成功', + exportTitle: '提示', + exportConfirm: '确定导出数据吗?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + importSuccess: '导入成功', + exportSuccess: '导出成功', + exportFailed: '导出失败', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + reset: '重置', + import: '导入', + export: '导出', + query: '查询', + batchAdd: '批量新增', + refresh: '刷新', + columnSetting: '列设置', + resetPassword: '重置密码', + confirm: '确定', + selectedCount: '已选中{count}条数据', + }, + tree: { + deptList: '部门列表', + deptPlaceholder: '请输入部门名称', + deptInfo: '1.部门信息;', + }, + title0: '切换组件大小', + title1: '切换语言', + title2: '搜索', + title3: '布局配置', + title4: '消息中心', + title5: '全屏', + title6: '退出全屏', + dropdown1: '首页', + dropdown2: '个人中心', + versionLog: '版本升级日志', + dropdownLarge: '大号', + dropdownDefault: '默认', + dropdownSmall: '小号', + langZhCn: '简体中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: '退出登录', + fullscreenNotSupported: '您的浏览器不支持全屏!', + logOutTitle: '提示', + logOutMessage: '即将退出系统,是否继续?', + logOutConfirm: '确定', + logOutCancel: '取消', + logOutExit: '正在退出...', + retry: '重试', + onlinePrompt: '正在重新连接服务器...', + defaultUsername: '用户', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/user/zh-tw.ts b/web/src/i18n/pages/user/zh-tw.ts new file mode 100644 index 0000000..ecd8e8f --- /dev/null +++ b/web/src/i18n/pages/user/zh-tw.ts @@ -0,0 +1,129 @@ +// 定義內容 +export default { + message: { + pages: { + user: { + table: { + columns: { + select: '選取', + index: '序號', + username: '帳號', + name: '姓名', + dept: '所屬部門', + manageDept: '管理部門', + role: '角色', + mobile: '手機號碼', + email: '信箱', + gender: '性別', + userType: '使用者類型', + status: '狀態', + avatar: '頭像', + actions: '操作', + }, + }, + form: { + username: '帳號', + password: '密碼', + name: '姓名', + dept: '所屬部門', + manageDept: '管理部門', + role: '角色', + mobile: '手機號碼', + email: '信箱', + gender: '性別', + userType: '使用者類型', + status: '狀態', + avatar: '頭像', + usernamePlaceholder: '請輸入帳號', + passwordPlaceholder: '請輸入密碼', + namePlaceholder: '請輸入姓名', + deptPlaceholder: '請選擇', + manageDeptPlaceholder: '請選擇', + rolePlaceholder: '請選擇角色', + mobilePlaceholder: '請輸入手機號碼', + emailPlaceholder: '請輸入信箱', + genderPlaceholder: '請選擇性別', + userTypePlaceholder: '請選擇使用者類型', + }, + validation: { + usernameRequired: '帳號必填項', + passwordRequired: '密碼必填項', + nameRequired: '姓名必填項', + deptRequired: '必填項', + roleRequired: '必填項', + mobileInvalid: '請輸入正確的手機號碼', + emailInvalid: '請輸入正確的信箱地址', + manageDeptHelper: '不選則預設為所屬部門', + }, + dialog: { + addUser: '新增使用者', + editUser: '編輯使用者', + assignRoles: '分配角色', + deleteConfirm: '是否刪除該使用者?', + resetPassword: '重置密碼', + resetPasswordConfirm: '確定重置為系統預設密碼嗎?', + resetPasswordSuccess: '重置密碼成功', + exportTitle: '提示', + exportConfirm: '確定匯出資料嗎?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + importSuccess: '匯入成功', + exportSuccess: '匯出成功', + exportFailed: '匯出失敗', + }, + buttons: { + add: '新增', + edit: '編輯', + delete: '刪除', + save: '儲存', + cancel: '取消', + reset: '重置', + import: '匯入', + export: '匯出', + query: '查詢', + batchAdd: '批次新增', + refresh: '重新整理', + columnSetting: '欄位設定', + resetPassword: '重置密碼', + confirm: '確定', + selectedCount: '已選取{count}筆資料', + }, + tree: { + deptList: '部門列表', + deptPlaceholder: '請輸入部門名稱', + deptInfo: '1.部門資訊;', + }, + title0: '切換元件大小', + title1: '切換語言', + title2: '搜尋', + title3: '版面設定', + title4: '訊息中心', + title5: '全螢幕', + title6: '退出全螢幕', + dropdown1: '首頁', + dropdown2: '個人中心', + versionLog: '版本升級日誌', + dropdownLarge: '大', + dropdownDefault: '預設', + dropdownSmall: '小', + langZhCn: '簡體中文', + langEn: 'English', + langZhTw: '繁體中文', + dropdown5: '退出登入', + fullscreenNotSupported: '您的瀏覽器不支援全螢幕!', + logOutTitle: '提示', + logOutMessage: '即將退出系統,是否繼續?', + logOutConfirm: '確定', + logOutCancel: '取消', + logOutExit: '正在退出...', + retry: '重試', + onlinePrompt: '正在重新連線伺服器...', + defaultUsername: '使用者', + }, + }, + }, +}; diff --git a/web/src/i18n/pages/whitelist/en.ts b/web/src/i18n/pages/whitelist/en.ts new file mode 100644 index 0000000..027c647 --- /dev/null +++ b/web/src/i18n/pages/whitelist/en.ts @@ -0,0 +1,60 @@ +// Define content +export default { + message: { + pages: { + whitelist: { + table: { + columns: { + url: 'URL', + description: 'Description', + status: 'Status', + createTime: 'Create Time', + creator: 'Created By', + actions: 'Actions', + index: 'No.', + keyword: 'Keyword', + method: 'Method', + dataPermission: 'Data Permission', + }, + }, + form: { + url: 'URL', + description: 'Description', + status: 'Status', + urlPlaceholder: 'Enter URL', + descriptionPlaceholder: 'Enter description', + keywordPlaceholder: 'Enter keyword', + urlHelper: 'Supports fuzzy matching, e.g. /api/user/* matches /api/user/1, /api/user/2', + }, + validation: { + urlRequired: 'URL is required', + urlMaxLength: 'URL must be 200 characters or less', + urlFormat: 'Invalid URL format', + urlDuplicate: 'URL already exists', + methodRequired: 'Please select a request method', + }, + dialog: { + addWhiteList: 'Add Whitelist', + editWhiteList: 'Edit Whitelist', + deleteConfirm: 'Delete this whitelist entry?', + }, + messages: { + addSuccess: 'Added successfully', + updateSuccess: 'Updated successfully', + deleteSuccess: 'Deleted successfully', + deleteFailed: 'Delete failed', + }, + buttons: { + add: 'Add', + edit: 'Edit', + delete: 'Delete', + save: 'Save', + cancel: 'Cancel', + query: 'Query', + refresh: 'Refresh', + export: 'Export', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/whitelist/zh-cn.ts b/web/src/i18n/pages/whitelist/zh-cn.ts new file mode 100644 index 0000000..2815b22 --- /dev/null +++ b/web/src/i18n/pages/whitelist/zh-cn.ts @@ -0,0 +1,60 @@ +// 定义内容 +export default { + message: { + pages: { + whitelist: { + table: { + columns: { + url: 'URL', + description: '描述', + status: '状态', + createTime: '创建时间', + creator: '创建人', + actions: '操作', + index: '序号', + keyword: '关键词', + method: '请求方法', + dataPermission: '数据权限', + }, + }, + form: { + url: 'URL', + description: '描述', + status: '状态', + urlPlaceholder: '请输入URL', + descriptionPlaceholder: '请输入描述', + keywordPlaceholder: '请输入关键词', + urlHelper: '支持模糊匹配,如 /api/user/* 可匹配 /api/user/1、/api/user/2', + }, + validation: { + urlRequired: '请输入URL', + urlMaxLength: 'URL不能超过200个字符', + urlFormat: 'URL格式不正确', + urlDuplicate: 'URL已存在', + methodRequired: '请选择请求方法', + }, + dialog: { + addWhiteList: '新增白名单', + editWhiteList: '编辑白名单', + deleteConfirm: '确定删除该白名单吗?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '删除成功', + deleteFailed: '删除失败', + }, + buttons: { + add: '新增', + edit: '编辑', + delete: '删除', + save: '保存', + cancel: '取消', + query: '查询', + refresh: '刷新', + export: '导出', + }, + }, + }, + }, +}; diff --git a/web/src/i18n/pages/whitelist/zh-tw.ts b/web/src/i18n/pages/whitelist/zh-tw.ts new file mode 100644 index 0000000..15affa7 --- /dev/null +++ b/web/src/i18n/pages/whitelist/zh-tw.ts @@ -0,0 +1,60 @@ +// 定義內容 +export default { + message: { + pages: { + whitelist: { + table: { + columns: { + url: 'URL', + description: '描述', + status: '狀態', + createTime: '創建時間', + creator: '創建人', + actions: '操作', + index: '序號', + keyword: '關鍵詞', + method: '請求方式', + dataPermission: '資料權限', + }, + }, + form: { + url: 'URL', + description: '描述', + status: '狀態', + urlPlaceholder: '請輸入URL', + descriptionPlaceholder: '請輸入描述', + keywordPlaceholder: '請輸入關鍵詞', + urlHelper: '支援模糊匹配,如 /api/user/* 可匹配 /api/user/1、/api/user/2', + }, + validation: { + urlRequired: '請輸入URL', + urlMaxLength: 'URL不能超過200個字符', + urlFormat: 'URL格式不正確', + urlDuplicate: 'URL已存在', + methodRequired: '請選擇請求方式', + }, + dialog: { + addWhiteList: '新增白名單', + editWhiteList: '編輯白名單', + deleteConfirm: '確定刪除該白名單嗎?', + }, + messages: { + addSuccess: '新增成功', + updateSuccess: '更新成功', + deleteSuccess: '刪除成功', + deleteFailed: '刪除失敗', + }, + buttons: { + add: '新增', + edit: '編輯', + delete: '刪除', + save: '保存', + cancel: '取消', + query: '查詢', + refresh: '刷新', + export: '導出', + }, + }, + }, + }, +}; diff --git a/web/src/layout/navBars/breadcrumb/user.vue b/web/src/layout/navBars/breadcrumb/user.vue index 24e4d19..d6cc3e5 100644 --- a/web/src/layout/navBars/breadcrumb/user.vue +++ b/web/src/layout/navBars/breadcrumb/user.vue @@ -112,6 +112,8 @@ import { useUserInfo } from '/@/stores/userInfo'; import { useThemeConfig } from '/@/stores/themeConfig'; import other from '/@/utils/other'; import mittBus from '/@/utils/mitt'; +import { refreshRoutesForI18n } from '/@/router/backEnd'; +import { request } from '/@/utils/service'; import { Session, Local } from '/@/utils/storage'; import headerImage from '/@/assets/img/headerImage.png'; import { InfoFilled } from '@element-plus/icons-vue'; @@ -228,13 +230,21 @@ const onComponentSizeChange = (size: string) => { window.location.reload(); }; // 语言切换 -const onLanguageChange = (lang: string) => { +const onLanguageChange = async (lang: string) => { Local.remove('themeConfig'); themeConfig.value.globalI18n = lang; Local.set('themeConfig', themeConfig.value); locale.value = lang; other.useTitle(); initI18nOrSize('globalI18n', 'disabledI18n'); + // 重新请求菜单(带上新语言,让后端返回对应翻译) + await refreshRoutesForI18n(); + // 持久化到后端 + try { + await request({ url: '/api/system/user/update_language/', method: 'put', data: { language: lang } }); + } catch (e) { + console.warn('Failed to persist language preference:', e); + } }; // 初始化组件大小/i18n const initI18nOrSize = (value: string, attr: keyof typeof state) => { diff --git a/web/src/router/backEnd.ts b/web/src/router/backEnd.ts index e159dea..ccb57bc 100644 --- a/web/src/router/backEnd.ts +++ b/web/src/router/backEnd.ts @@ -101,7 +101,9 @@ import {SystemConfigStore} from "/@/stores/systemConfig"; import {useDeptInfoStore} from "/@/stores/modules/dept"; import {DictionaryStore} from "/@/stores/dictionary"; import {useFrontendMenuStore} from "/@/stores/frontendMenu"; +import {useThemeConfig} from "/@/stores/themeConfig"; import {toRaw} from "vue"; +import mitt from "/@/utils/mitt"; const menuApi = useMenuApi(); const layouModules: any = import.meta.glob('../layout/routerView/*.{vue,tsx}'); @@ -240,7 +242,33 @@ export function getBackEndControlRoutes() { useDeptInfoStore().requestDeptInfo() // 获取字典信息 DictionaryStore().getSystemDictionarys() - return menuApi.getSystemMenu(); + const { themeConfig } = storeToRefs(useThemeConfig(pinia)) + return menuApi.getSystemMenu({ language: themeConfig.value.globalI18n }); +} + +/** + * 根据语言重新请求后端路由菜单 + * @description 用于语言切换后刷新路由 + */ +export async function refreshRoutesForI18n() { + const { themeConfig } = storeToRefs(useThemeConfig(pinia)); + const res = await menuApi.getSystemMenu({ language: themeConfig.value.globalI18n }); + const { frameIn, frameOut } = handleMenu(res.data); + const frameInProcessed = await backEndComponent(frameIn); + dynamicRoutes[0].children = [ + ...(frameInProcessed || []), + pissupplierQuotationDetailRoute, + pisadminRfqMiscInquiryDetailRoute, + pisadminRfqMiscComparePriceRoute, + pisadminMiscMaterialsIndexRoute, + pisadminRfsOperationLogsRoute + ]; + const storesRoutesList = useRoutesList(pinia); + storesRoutesList.setRoutesList([...(dynamicRoutes[0].children || []), ...frameOut]); + // 通知侧边栏刷新菜单 + mitt.emit('getBreadcrumbIndexSetFilterRoutes'); + // 清除 tagsView 缓存,重新加载时会用新语言读取标题 + Session.remove('tagsViewList'); } /** diff --git a/web/src/settings.ts b/web/src/settings.ts index cecbf2d..6f1d718 100644 --- a/web/src/settings.ts +++ b/web/src/settings.ts @@ -1,5 +1,6 @@ // 引入fast-crud import {FastCrud, useTypes} from '@fast-crud/fast-crud'; +import { i18n } from '/@/i18n'; const {getType} = useTypes(); import '@fast-crud/fast-crud/dist/style.css'; @@ -19,7 +20,7 @@ export default { app.use(ui); // 然后安装FastCrud app.use(FastCrud, { - //i18n, //i18n配置,可选,默认使用中文,具体用法请看demo里的 src/i18n/index.js 文件 + i18n, // fast-crud 国际化,支持 search/reset 按钮、操作列等界面文字 // 此处配置公共的dictRequest(字典请求) async dictRequest({dict,url}: any) { const {isTree} = dict diff --git a/web/src/utils/formatTime.ts b/web/src/utils/formatTime.ts index 441e30c..b9aff43 100644 --- a/web/src/utils/formatTime.ts +++ b/web/src/utils/formatTime.ts @@ -122,16 +122,16 @@ export function formatPast(param: string | Date, format: string = 'YYYY-mm-dd'): * 时间问候语 * @param param 当前时间,new Date() 格式 * @description param 调用 `formatAxis(new Date())` 输出 `上午好` - * @returns 返回拼接后的时间字符串 + * @returns 返回 i18n key 路径 */ export function formatAxis(param: Date): string { let hour: number = new Date(param).getHours(); - if (hour < 6) return '凌晨好'; - else if (hour < 9) return '早上好'; - else if (hour < 12) return '上午好'; - else if (hour < 14) return '中午好'; - else if (hour < 17) return '下午好'; - else if (hour < 19) return '傍晚好'; - else if (hour < 22) return '晚上好'; - else return '夜里好'; + if (hour < 6) return 'message.common.greeting.dawn'; + else if (hour < 9) return 'message.common.greeting.morning'; + else if (hour < 12) return 'message.common.greeting.lateMorning'; + else if (hour < 14) return 'message.common.greeting.noon'; + else if (hour < 17) return 'message.common.greeting.afternoon'; + else if (hour < 19) return 'message.common.greeting.evening'; + else if (hour < 22) return 'message.common.greeting.night'; + else return 'message.common.greeting.lateNight'; } diff --git a/web/src/views/pisadmin/basicinfo/company/crud.tsx b/web/src/views/pisadmin/basicinfo/company/crud.tsx index cb084eb..46f549e 100644 --- a/web/src/views/pisadmin/basicinfo/company/crud.tsx +++ b/web/src/views/pisadmin/basicinfo/company/crud.tsx @@ -2,14 +2,11 @@ import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/f import * as api from './api' import { useUserInfo } from '/@/stores/userInfo' import { ElMessage } from 'element-plus' - -const statusDict = [ - { value: 1, label: '可用' }, - { value: 0, label: '不可用' } -] +import { useI18n } from 'vue-i18n' export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { void crudExpose + const { t } = useI18n() const userStore = useUserInfo() const currentUser = userStore.userInfos?.name || @@ -30,7 +27,7 @@ export const createCrudOptions = function ({ crudExpose }: Partial item.company_code === code) : null if (exists && (!currentId || exists.id !== currentId)) { - throw new Error('公司代码已存在,不可重复') + throw new Error(t('message.pages.basicinfo.company.companyCode') + t('message.pages.menu.validation.alreadyExists')) } } return { @@ -84,58 +81,58 @@ export const createCrudOptions = function ({ crudExpose }: Partial { - try { - const res = await api.GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 }) - const list = - res?.data?.data?.results || - res?.data?.results || - res?.data?.list || - res?.data || - res?.results || - res?.list || - [] - return (Array.isArray(list) ? list : []).map((c: any) => ({ - company_code: c.company_code, - company_short_name: c.company_short_name || c.company_code || c.company_name - })) - } catch (e) { - console.warn('加载公司列表失败', e) - return [] - } -} - -// 预取一次,确保进入页面时就触发请求 -void loadCompanyOptions() - -export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { void crudExpose + const { t } = useI18n() + return { crudOptions: { form: { @@ -56,64 +30,80 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, columns: { currencyname: { - title: '货币名称', + title: t('message.pages.basicinfo.currency.currencyname'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入货币名称', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入货币名称' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.currency.currencyname'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.currency.currencyname') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 160, showOverflowTooltip: true } }, currencycode: { - title: '货币代码', + title: t('message.pages.basicinfo.currency.currencycode'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入货币代码', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入货币代码' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.currency.currencycode'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.currency.currencycode') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, editForm: { component: { props: { disabled: true } } }, column: { minWidth: 140, showOverflowTooltip: true } }, currencysymbol: { - title: '货币符号', + title: t('message.pages.basicinfo.currency.currencysymbol'), type: 'input', - form: { rules: [{ required: true, message: '请输入货币符号' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.currency.currencysymbol') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { width: 120, showOverflowTooltip: true } }, factory: { - title: '交易厂区', + title: t('message.pages.basicinfo.currency.factory'), type: 'dict-select', dict: dict({ cache: false, value: 'company_code', label: 'company_short_name', getData: async () => { - return loadCompanyOptions() + try { + const res = await api.GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 }) + const list = + res?.data?.data?.results || + res?.data?.results || + res?.data?.list || + res?.data || + res?.results || + res?.list || + [] + return (Array.isArray(list) ? list : []).map((c: any) => ({ + company_code: c.company_code, + company_short_name: c.company_short_name || c.company_code || c.company_name + })) + } catch (e) { + return [] + } } }), search: { show: true }, - form: { rules: [{ required: true, message: '请选择交易厂区' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.currency.factory') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { width: 160, showOverflowTooltip: true } }, tax: { - title: '税率(%)', + title: t('message.pages.basicinfo.currency.tax') + '(%)', type: 'number', - form: { rules: [{ required: true, message: '请输入税率' }], component: { props: { precision: 2 } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.currency.tax') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }], component: { props: { precision: 2 } } }, column: { width: 120 } }, status: { - title: '可用状态', + title: t('message.pages.basicinfo.currency.status'), type: 'dict-switch', - dict: dict({ data: statusDict }), + dict: dict({ data: [{ value: 1, label: t('message.pages.basicinfo.currency.enabled') }, { value: 0, label: t('message.pages.basicinfo.currency.disabled') }] }), form: { value: 1 }, column: { width: 120 } }, create_datetime: { - title: '创建时间', + title: t('message.pages.basicinfo.currency.createTime'), type: 'datetime', form: { show: false }, column: { width: 180 } }, update_datetime: { - title: '更新时间', + title: t('message.pages.basicinfo.currency.updateTime'), type: 'datetime', form: { show: false }, column: { width: 180 } diff --git a/web/src/views/pisadmin/basicinfo/emailnotice/crud.tsx b/web/src/views/pisadmin/basicinfo/emailnotice/crud.tsx index 7f929fd..c080809 100644 --- a/web/src/views/pisadmin/basicinfo/emailnotice/crud.tsx +++ b/web/src/views/pisadmin/basicinfo/emailnotice/crud.tsx @@ -1,29 +1,32 @@ import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/fast-crud' import { ElMessage } from 'element-plus' +import { useI18n } from 'vue-i18n' import * as api from './api' -const statusDict = [ - { value: 'pending', label: '待发送' }, - { value: 'sending', label: '发送中' }, - { value: 'success', label: '已发送' }, - { value: 'failed', label: '发送失败' } -] - const joinEmails = (value: unknown) => { if (!Array.isArray(value)) return '' return value.filter((v) => !!v).join('; ') } -const formatAttachments = (value: unknown) => { - if (!Array.isArray(value)) return '' - const names = value - .map((v: any) => v?.name || v?.file_name || v?.filename || v?.key || '') - .filter((v: any) => !!v) - if (names.length === 0) return value.length ? `${value.length} 个附件` : '' - return names.join('; ') -} - export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { + const { t } = useI18n() + + const statusDict = [ + { value: 'pending', label: t('message.pages.basicinfo.emailnotice.statusPending') }, + { value: 'sending', label: t('message.pages.basicinfo.emailnotice.statusSending') }, + { value: 'success', label: t('message.pages.basicinfo.emailnotice.statusSuccess') }, + { value: 'failed', label: t('message.pages.basicinfo.emailnotice.statusFailed') } + ] + + const formatAttachments = (value: unknown) => { + if (!Array.isArray(value)) return '' + const names = value + .map((v: any) => v?.name || v?.file_name || v?.filename || v?.key || '') + .filter((v: any) => !!v) + if (names.length === 0) return value.length ? `${value.length} ${t('message.pages.basicinfo.emailnotice.attachments')}` : '' + return names.join('; ') + } + return { crudOptions: { request: { @@ -42,7 +45,7 @@ export const createCrudOptions = function ({ crudExpose }: Partial row.status !== 'sending', @@ -53,9 +56,9 @@ export const createCrudOptions = function ({ crudExpose }: Partial joinEmails(value) } }, cc_emails: { - title: '抄送', + title: t('message.pages.basicinfo.emailnotice.ccEmails'), type: 'text', column: { minWidth: 180, showOverflowTooltip: true, formatter: ({ value }) => joinEmails(value) } }, bcc_emails: { - title: '密送', + title: t('message.pages.basicinfo.emailnotice.bccEmails'), type: 'text', column: { minWidth: 180, showOverflowTooltip: true, formatter: ({ value }) => joinEmails(value) } }, status: { - title: '发送状态', + title: t('message.pages.basicinfo.emailnotice.status'), type: 'dict-select', dict: dict({ data: statusDict }), - search: { show: true, component: { props: { clearable: true, placeholder: '请选择状态' } } }, + search: { show: true, component: { props: { clearable: true, placeholder: t('message.pages.basicinfo.emailnotice.status') } } }, column: { width: 120 } }, sent_at: { - title: '发送时间', + title: t('message.pages.basicinfo.emailnotice.sentAt'), type: 'datetime', search: { show: true, @@ -121,35 +124,35 @@ export const createCrudOptions = function ({ crudExpose }: Partial formatAttachments(value) } }, last_error: { - title: '错误信息', + title: t('message.pages.basicinfo.emailnotice.lastError'), type: 'text', column: { minWidth: 240, showOverflowTooltip: true } }, message_id: { - title: '消息ID', + title: t('message.pages.basicinfo.emailnotice.messageId'), type: 'text', column: { minWidth: 180, showOverflowTooltip: true } }, retry_count: { - title: '重试次数', + title: t('message.pages.basicinfo.emailnotice.retryCount'), type: 'number', column: { width: 100 } }, create_datetime: { - title: '创建时间', + title: t('message.pages.basicinfo.emailnotice.createTime'), type: 'datetime', form: { show: false }, column: { width: 180 } diff --git a/web/src/views/pisadmin/basicinfo/supplier/crud.tsx b/web/src/views/pisadmin/basicinfo/supplier/crud.tsx index 9462be0..8c46ecf 100644 --- a/web/src/views/pisadmin/basicinfo/supplier/crud.tsx +++ b/web/src/views/pisadmin/basicinfo/supplier/crud.tsx @@ -3,91 +3,55 @@ import * as api from './api' import { GetCompanies } from '../currency/api' import { GetList as GetCurrencies } from '../currency/api' import { ElMessage } from 'element-plus' +import { useI18n } from 'vue-i18n' -const statusDict = [ - { value: 1, label: '可用' }, - { value: 0, label: '不可用' } -] - -const vendorTypeDict = [ - { value: '国有', label: '国有' }, - { value: '集体', label: '集体' }, - { value: '私营', label: '私营' }, - { value: '合资', label: '合资' }, - { value: '独资', label: '独资' }, - { value: '其他', label: '其他' } -] - -const paymentTermDict = [ - { value: 'tt_30_70', label: 'T/T 30%预付,70%出货前' }, - { value: 'net30', label: '月结30天' }, - { value: 'net45', label: '月结45天' }, - { value: 'prepaid', label: '全额预付' } -] - -const incotermDict = [ - { value: 'EXW', label: 'EXW(工厂交货)' }, - { value: 'FCA', label: 'FCA(货交承运人)' }, - { value: 'CPT', label: 'CPT(运费付至)' }, - { value: 'CIP', label: 'CIP(运费及保险费付至)' }, - { value: 'DAP', label: 'DAP(目的地交货)' }, - { value: 'DPU', label: 'DPU(卸货地交货)' }, - { value: 'DDP', label: 'DDP(完税后交货)' }, - { value: 'FAS', label: 'FAS(船边交货)' }, - { value: 'FOB', label: 'FOB(船上交货)' }, - { value: 'CFR', label: 'CFR(成本加运费)' }, - { value: 'CIF', label: 'CIF(成本、保险费加运费)' } -] - -const loadCompanyOptions = async () => { - try { - const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 }) - const list = - res?.data?.data?.results || - res?.data?.results || - res?.data?.list || - res?.data || - res?.results || - res?.list || - [] - return (Array.isArray(list) ? list : []).map((c: any) => ({ - company_code: c.company_code, - company_short_name: c.company_short_name || c.company_code || c.company_name - })) - } catch (e) { - console.warn('加载公司列表失败', e) - return [] - } -} - -const loadCurrencyOptions = async (companyCode?: string) => { - try { - const params: any = { page: 1, page_size: 500, pageSize: 500 } - if (companyCode) params.factory = companyCode - const res = await GetCurrencies(params) - const list = - res?.data?.data?.results || - res?.data?.results || - res?.data?.list || - res?.data || - res?.results || - res?.list || - [] - return (Array.isArray(list) ? list : []).map((c: any) => ({ - value: c.currencycode || c.currency_code, - label: c.currencyname || c.currency_code || c.currencycode || c.currency_name - })) - } catch (e) { - console.warn('加载币别列表失败', e) - return [] - } -} - -// 预取一次公司列表 -void loadCompanyOptions() - -export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { +export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { void crudExpose + const { t } = useI18n() + + const loadCompanyOptions = async () => { + try { + const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 }) + const list = + res?.data?.data?.results || + res?.data?.results || + res?.data?.list || + res?.data || + res?.results || + res?.list || + [] + return (Array.isArray(list) ? list : []).map((c: any) => ({ + company_code: c.company_code, + company_short_name: c.company_short_name || c.company_code || c.company_name + })) + } catch (e) { + console.warn('Failed to load company list', e) + return [] + } + } + + const loadCurrencyOptions = async (companyCode?: string) => { + try { + const params: any = { page: 1, page_size: 500, pageSize: 500 } + if (companyCode) params.factory = companyCode + const res = await GetCurrencies(params) + const list = + res?.data?.data?.results || + res?.data?.results || + res?.data?.list || + res?.data || + res?.results || + res?.list || + [] + return (Array.isArray(list) ? list : []).map((c: any) => ({ + value: c.currencycode || c.currency_code, + label: c.currencyname || c.currency_code || c.currencycode || c.currency_name + })) + } catch (e) { + console.warn('Failed to load currency list', e) + return [] + } + } const ensureSupplierUnique = async (companyCode: string, supplierId: string, currentId?: number) => { if (!companyCode || !supplierId) return @@ -104,9 +68,13 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp ? list.find((item: any) => item.company_code === companyCode && item.supplier_id === supplierId) : null if (exists && (!currentId || exists.id !== currentId)) { - throw new Error('同一交易厂区下供应商代码已存在,不可重复') + throw new Error(t('message.pages.basicinfo.supplier.supplierId') + t('message.pages.menu.validation.alreadyExists')) } } + + // Pre-load company options + void loadCompanyOptions() + return { crudOptions: { form: { @@ -147,7 +115,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, columns: { company_code: { - title: '交易厂区', + title: t('message.pages.basicinfo.supplier.companyCode'), type: 'dict-select', dict: dict({ cache: false, @@ -157,11 +125,10 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }), search: { show: true }, form: { - rules: [{ required: true, message: '请选择交易厂区' }], + rules: [{ required: true, message: t('message.pages.basicinfo.supplier.companyCode') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }], component: { on: { change({ form, value }: any) { - // 切换厂区时清空币别,触发重新加载 form.transaction_currency = undefined form.company_code = value } @@ -171,39 +138,51 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp column: { minWidth: 160, showOverflowTooltip: true } }, supplier_id: { - title: '供应商代码/ID', + title: t('message.pages.basicinfo.supplier.supplierId'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入供应商代码/ID', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入供应商代码/ID' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplier.supplierId'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.supplierId') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 140, showOverflowTooltip: true } }, supplier_name: { - title: '供应商全称', + title: t('message.pages.basicinfo.supplier.supplierName'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入供应商全称', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入供应商全称' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplier.supplierName'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.supplierName') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 180, showOverflowTooltip: true } }, supplier_short_name: { - title: '供应商简称', + title: t('message.pages.basicinfo.supplier.supplierShortName'), type: 'input', - form: { rules: [{ required: true, message: '请输入供应商简称' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.supplierShortName') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 160, showOverflowTooltip: true } }, vendor_type: { - title: '厂商性质', + title: t('message.pages.basicinfo.supplier.vendorType'), type: 'dict-select', - dict: dict({ data: vendorTypeDict }), + dict: dict({ data: [ + { value: '国有', label: t('message.pages.pissupplier.vendorType.stateOwned') }, + { value: '集体', label: t('message.pages.pissupplier.vendorType.collective') }, + { value: '私营', label: t('message.pages.pissupplier.vendorType.private') }, + { value: '合资', label: t('message.pages.pissupplier.vendorType.joint') }, + { value: '独资', label: t('message.pages.pissupplier.vendorType.whollyOwned') }, + { value: '其他', label: t('message.pages.pissupplier.vendorType.other') }, + ] }), column: { minWidth: 140, showOverflowTooltip: true } }, payment_terms: { - title: '付款条件', + title: t('message.pages.basicinfo.supplier.paymentTerms'), type: 'dict-select', - dict: dict({ data: paymentTermDict }), + dict: dict({ data: [ + { value: 'tt_30_70', label: t('message.pages.pissupplier.paymentTerms.tt30_70') }, + { value: 'net30', label: t('message.pages.pissupplier.paymentTerms.net30') }, + { value: 'net45', label: t('message.pages.pissupplier.paymentTerms.net45') }, + { value: 'prepaid', label: t('message.pages.pissupplier.paymentTerms.prepaid') }, + ] }), column: { minWidth: 160, showOverflowTooltip: true } }, transaction_currency: { - title: '交易货币', + title: t('message.pages.basicinfo.supplier.transactionCurrency'), type: 'dict-select', dict: dict({ cache: false, @@ -215,77 +194,89 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp column: { minWidth: 140, showOverflowTooltip: true } }, incoterms: { - title: '国际条款', + title: t('message.pages.basicinfo.supplier.incoterms'), type: 'dict-select', - dict: dict({ data: incotermDict }), + dict: dict({ data: [ + { value: 'EXW', label: 'EXW' }, + { value: 'FCA', label: 'FCA' }, + { value: 'CPT', label: 'CPT' }, + { value: 'CIP', label: 'CIP' }, + { value: 'DAP', label: 'DAP' }, + { value: 'DPU', label: 'DPU' }, + { value: 'DDP', label: 'DDP' }, + { value: 'FAS', label: 'FAS' }, + { value: 'FOB', label: 'FOB' }, + { value: 'CFR', label: 'CFR' }, + { value: 'CIF', label: 'CIF' }, + ] }), column: { minWidth: 160, showOverflowTooltip: true } }, supplier_level: { - title: '供应商等级', + title: t('message.pages.basicinfo.supplier.supplierLevel'), type: 'input', column: { minWidth: 120, showOverflowTooltip: true } }, contact_person: { - title: '联络人', + title: t('message.pages.basicinfo.supplier.contactPerson'), type: 'input', - form: { rules: [{ required: true, message: '请输入联络人' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.contactPerson') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 120, showOverflowTooltip: true } }, contact_phone: { - title: '联络人电话', + title: t('message.pages.basicinfo.supplier.contactPhone'), type: 'input', - form: { rules: [{ required: true, message: '请输入联络人电话' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.contactPhone') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 140, showOverflowTooltip: true } }, contact_email: { - title: '联络人邮箱', + title: t('message.pages.basicinfo.supplier.contactEmail'), type: 'input', - form: { rules: [{ required: true, message: '请输入联络人邮箱' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.contactEmail') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 180, showOverflowTooltip: true } }, country: { - title: '国家', + title: t('message.pages.basicinfo.supplier.country'), type: 'input', - form: { rules: [{ required: true, message: '请输入国家' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.country') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 120, showOverflowTooltip: true } }, province: { - title: '省州', + title: t('message.pages.basicinfo.supplier.province'), type: 'input', - form: { rules: [{ required: true, message: '请输入省州' }] }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplier.province') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 120, showOverflowTooltip: true } }, city: { - title: '城市', + title: t('message.pages.basicinfo.supplier.city'), type: 'input', column: { minWidth: 120, showOverflowTooltip: true } }, address: { - title: '详细地址', + title: t('message.pages.basicinfo.supplier.address'), type: 'textarea', column: { minWidth: 200, showOverflowTooltip: true }, form: { component: { props: { rows: 2 } } } }, postal_code: { - title: '邮递区号', + title: t('message.pages.basicinfo.supplier.postalCode'), type: 'input', column: { minWidth: 120, showOverflowTooltip: true } }, status: { - title: '可用状态', + title: t('message.pages.basicinfo.supplier.status'), type: 'dict-switch', - dict: dict({ data: statusDict }), + dict: dict({ data: [{ value: 1, label: t('message.pages.basicinfo.supplier.enabled') }, { value: 0, label: t('message.pages.basicinfo.supplier.disabled') }] }), form: { value: 1 }, column: { width: 120 } }, create_datetime: { - title: '创建时间', + title: t('message.pages.basicinfo.supplier.createTime'), type: 'datetime', form: { show: false }, column: { width: 180 } }, update_datetime: { - title: '更新时间', + title: t('message.pages.basicinfo.supplier.updateTime'), type: 'datetime', form: { show: false }, column: { width: 180 } diff --git a/web/src/views/pisadmin/basicinfo/supplier_user/crud.tsx b/web/src/views/pisadmin/basicinfo/supplier_user/crud.tsx index d985bb4..c1e5bf3 100644 --- a/web/src/views/pisadmin/basicinfo/supplier_user/crud.tsx +++ b/web/src/views/pisadmin/basicinfo/supplier_user/crud.tsx @@ -2,13 +2,7 @@ import { dict, CreateCrudOptionsProps, CreateCrudOptionsRet } from '@fast-crud/f import * as api from './api' import { GetList as GetSupplierList } from '../supplier/api' import { ElMessage } from 'element-plus' - -const statusDict = [ - { value: 1, label: '有效' }, - { value: 0, label: '无效' } -] - -const supplierRoleDict = [{ value: 1, label: '报价' }] +import { useI18n } from 'vue-i18n' let supplierById: Record = {} @@ -66,6 +60,7 @@ void loadSupplierOptions() export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { void crudExpose + const { t } = useI18n() const ensureUserEmailUnique = async (supplierId: string, userEmail: string, currentId?: number) => { if (!supplierId || !userEmail) return @@ -85,7 +80,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp ) : null if (exists && (!currentId || exists.id !== currentId)) { - throw new Error('同一供应商下该联络邮箱已存在') + throw new Error(t('message.pages.basicinfo.supplierUser.userEmail') + t('message.pages.menu.validation.alreadyExists')) } } @@ -101,7 +96,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp await ensureUserEmailUnique(form.supplier_id, form.user_email) const res = await api.AddObj(form) ElMessage.success( - '保存成功;已同步创建系统用户(登录账号为联络人邮箱,初始密码为系统默认密码,部门:供应商)' + '保存成功,已同步创建系统用户(登录账号为联络人邮箱,初始密码为系统默认密码,部门:供应商)' ) return res } catch (err: any) { @@ -133,7 +128,7 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, columns: { supplier_id: { - title: '供应商唯一ID', + title: t('message.pages.basicinfo.supplierUser.supplierId'), type: 'dict-select', dict: dict({ cache: false, @@ -147,9 +142,9 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp })) } }), - search: { show: true, component: { props: { placeholder: '请选择或搜索', filterable: true, clearable: true } } }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.emailnotice.selectOrSearch'), filterable: true, clearable: true } } }, form: { - rules: [{ required: true, message: '请选择供应商' }], + rules: [{ required: true, message: t('message.pages.basicinfo.supplierUser.supplierId') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }], /** dict-select 需用 fast-crud 的 valueChange;component.on.change 往往不会触发 */ valueChange: async ({ value, form }: any) => { const v = value @@ -181,67 +176,67 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp column: { minWidth: 200, showOverflowTooltip: true } }, supplier_name: { - title: '供应商全称', + title: t('message.pages.basicinfo.supplierUser.supplierName'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入供应商全称', clearable: true } } }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplierUser.supplierName'), clearable: true } } }, form: { rules: [{ required: true, message: '请先选择供应商唯一ID,将自动带出供应商全称' }], component: { props: { disabled: true, - placeholder: '选择供应商唯一ID后自动带出' + placeholder: t('message.pages.basicinfo.supplierUser.autoFillNote') } } }, column: { minWidth: 180, showOverflowTooltip: true } }, supplier_role: { - title: '供应商角色', + title: t('message.pages.basicinfo.supplierUser.supplierRole'), type: 'dict-select', - dict: dict({ data: supplierRoleDict }), + dict: dict({ data: [{ value: 1, label: t('message.pages.basicinfo.supplierUser.roleQuote') }] }), search: { show: true }, form: { - rules: [{ required: true, message: '请选择供应商角色' }], + rules: [{ required: true, message: t('message.pages.basicinfo.supplierUser.supplierRole') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }], value: 1 }, column: { minWidth: 120, showOverflowTooltip: true } }, user_email: { - title: '联络人邮箱', + title: t('message.pages.basicinfo.supplierUser.userEmail'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入邮箱', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入联络人邮箱' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplierUser.userEmail'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplierUser.userEmail') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 200, showOverflowTooltip: true } }, user_name: { - title: '联络人', + title: t('message.pages.basicinfo.supplierUser.userName'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入联络人', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入联络人' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplierUser.userName'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplierUser.userName') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 120, showOverflowTooltip: true } }, user_phone: { - title: '联络人电话', + title: t('message.pages.basicinfo.supplierUser.userPhone'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入电话', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入联络人电话' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.supplierUser.userPhone'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.supplierUser.userPhone') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 140, showOverflowTooltip: true } }, status: { - title: '有效否', + title: t('message.pages.basicinfo.supplierUser.status'), type: 'dict-switch', - dict: dict({ data: statusDict }), + dict: dict({ data: [{ value: 1, label: t('message.pages.basicinfo.supplierUser.statusValid') }, { value: 0, label: t('message.pages.basicinfo.supplierUser.statusInvalid') }] }), form: { value: 1 }, column: { width: 120 } }, create_datetime: { - title: '创建时间', + title: t('message.pages.basicinfo.supplierUser.createTime'), type: 'datetime', form: { show: false }, column: { width: 180 } }, update_datetime: { - title: '更新时间', + title: t('message.pages.basicinfo.supplierUser.updateTime'), type: 'datetime', form: { show: false }, column: { width: 180 } diff --git a/web/src/views/pisadmin/basicinfo/systemno/crud.tsx b/web/src/views/pisadmin/basicinfo/systemno/crud.tsx index a5198bf..dfc19d5 100644 --- a/web/src/views/pisadmin/basicinfo/systemno/crud.tsx +++ b/web/src/views/pisadmin/basicinfo/systemno/crud.tsx @@ -3,21 +3,7 @@ import * as api from './api' import { GetCompanies } from '../currency/api' import { useUserInfo } from '/@/stores/userInfo' import { ElMessage } from 'element-plus' - -const resetCycleDict = [ - { value: 'yy', label: '按年2(YY)' }, - { value: 'yyyy', label: '按年4(YYYY)' }, - { value: 'yymm', label: '按月4(YYMM)' }, - { value: 'yyyymm', label: '按月6(YYYYMM)' }, - { value: 'yymmdd', label: '按日6(YYMMDD)' }, - { value: 'yyyymmdd', label: '按日8(YYYYMMDD)' } -] - -/** 与 `SystemNoRule.RULE_CODE_CHOICES` 一致;表单/搜索下拉展示「代码 - 名称」,列表列仅显示代码(见 column.formatter) */ -const ruleCodeDict = [ - { value: 'miscQTS', label: 'miscQTS (杂采报价单)' }, - { value: 'miscRFS', label: 'miscRFS (杂采询价单)' } -] +import { useI18n } from 'vue-i18n' /** * 交易厂区「通用」:非公司主数据,仅存于编号规则下拉;与 unique(company_code, rule_code) 兼容。 @@ -25,12 +11,7 @@ const ruleCodeDict = [ */ export const SYSTEMNO_GENERAL_COMPANY_CODE = 'GENERAL' -const generalCompanyOption = () => ({ - company_code: SYSTEMNO_GENERAL_COMPANY_CODE, - company_short_name: '通用' -}) - -const loadCompanyOptions = async () => { +const loadCompanyOptions = async (generalLabel: string) => { try { const res = await GetCompanies({ page: 1, page_size: 1000, pageSize: 1000 }) const list = @@ -47,14 +28,15 @@ const loadCompanyOptions = async () => { company_short_name: c.company_short_name || c.company_code || c.company_name })) .filter((c: { company_code: string }) => c.company_code !== SYSTEMNO_GENERAL_COMPANY_CODE) - return [generalCompanyOption(), ...fromApi] + return [{ company_code: SYSTEMNO_GENERAL_COMPANY_CODE, company_short_name: generalLabel }, ...fromApi] } catch (e) { console.warn('加载公司列表失败', e) - return [generalCompanyOption()] + return [{ company_code: SYSTEMNO_GENERAL_COMPANY_CODE, company_short_name: generalLabel }] } } export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { + const { t } = useI18n() void crudExpose const userStore = useUserInfo() const currentUser = @@ -63,6 +45,21 @@ export const createCrudOptions = function ({ crudExpose }: Partial { if (!companyCode || !ruleCode) return const res = await api.GetList({ company_code: companyCode, rule_code: ruleCode, page: 1, page_size: 1, pageSize: 1 }) @@ -78,7 +75,7 @@ export const createCrudOptions = function ({ crudExpose }: Partial item.company_code === companyCode && item.rule_code === ruleCode) : null if (exists && (!currentId || exists.id !== currentId)) { - throw new Error('同一交易厂区下的生成单据标识号不可重复') + throw new Error(t('message.pages.basicinfo.systemNo.companyCode') + t('message.pages.basicinfo.systemNo.ruleCode') + t('message.pages.menu.validation.alreadyExists')) } } @@ -130,32 +127,32 @@ export const createCrudOptions = function ({ crudExpose }: Partial loadCompanyOptions() + getData: async () => loadCompanyOptions(t('message.pages.basicinfo.systemNo.general')) }), search: { show: true }, form: { value: SYSTEMNO_GENERAL_COMPANY_CODE, - rules: [{ required: true, message: '请选择交易厂区' }] + rules: [{ required: true, message: t('message.pages.basicinfo.systemNo.companyCode') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 160, showOverflowTooltip: true } }, rule_code: { - title: '生成单据标识号', + title: t('message.pages.basicinfo.systemNo.ruleCode'), type: 'dict-select', dict: dict({ data: ruleCodeDict }), search: { show: true, - component: { props: { placeholder: '请选择', clearable: true } } + component: { props: { placeholder: t('message.pages.menu.buttons.select'), clearable: true } } }, form: { - rules: [{ required: true, message: '请选择生成单据标识号' }], - component: { props: { placeholder: '请选择', filterable: true } } + rules: [{ required: true, message: t('message.pages.basicinfo.systemNo.ruleCode') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }], + component: { props: { placeholder: t('message.pages.menu.buttons.select'), filterable: true } } }, column: { minWidth: 140, @@ -167,78 +164,78 @@ export const createCrudOptions = function ({ crudExpose }: Partial): CreateCrudOptionsRet { void crudExpose - - const ensureUnitCodeUnique = async (code: string, currentId?: number) => { - if (!code) return - const res = await api.GetList({ unitcode: code, page: 1, page_size: 1, pageSize: 1 }) - const list = - res?.data?.data?.results || - res?.data?.results || - res?.data?.list || - res?.data || - res?.results || - res?.list || - [] - const exists = Array.isArray(list) ? list.find((item: any) => item.unitcode === code) : null - if (exists && (!currentId || exists.id !== currentId)) { - throw new Error('计量单位代码已存在,不可重复') - } - } + const { t } = useI18n() return { crudOptions: { @@ -34,24 +13,8 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, request: { pageRequest: async (query) => api.GetList(query), - addRequest: async ({ form }) => { - try { - await ensureUnitCodeUnique(form.unitcode) - return await api.AddObj(form) - } catch (err: any) { - ElMessage.error(err?.message || '保存失败') - throw err - } - }, - editRequest: async ({ form, row }) => { - try { - await ensureUnitCodeUnique(form.unitcode, row.id) - return await api.UpdateObj({ ...form, id: row.id }) - } catch (err: any) { - ElMessage.error(err?.message || '保存失败') - throw err - } - }, + addRequest: async ({ form }) => api.AddObj(form), + editRequest: async ({ form, row }) => api.UpdateObj({ ...form, id: row.id }), delRequest: async ({ row }) => api.DelObj(row.id) }, table: { @@ -67,35 +30,34 @@ export const createCrudOptions = function ({ crudExpose }: CreateCrudOptionsProp }, columns: { unitcode: { - title: '计量单位代码', + title: t('message.pages.basicinfo.unit.unitcode'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入计量单位代码', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入计量单位代码' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.unit.unitcode'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.unit.unitcode') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 140, showOverflowTooltip: true } }, unitname: { - title: '计量单位名称', + title: t('message.pages.basicinfo.unit.unitname'), type: 'input', - search: { show: true, component: { props: { placeholder: '请输入计量单位名称', clearable: true } } }, - form: { rules: [{ required: true, message: '请输入计量单位名称' }] }, + search: { show: true, component: { props: { placeholder: t('message.pages.basicinfo.unit.unitname'), clearable: true } } }, + form: { rules: [{ required: true, message: t('message.pages.basicinfo.unit.unitname') + ' ' + t('message.pages.menu.validation.fieldNameRequired') }] }, column: { minWidth: 160, showOverflowTooltip: true } }, - status: { - title: '可用状态', + title: t('message.pages.basicinfo.unit.status'), type: 'dict-switch', - dict: dict({ data: statusDict }), + dict: dict({ data: [{ value: 1, label: t('message.pages.basicinfo.unit.enabled') }, { value: 0, label: t('message.pages.basicinfo.unit.disabled') }] }), form: { value: 1 }, column: { width: 120 } }, create_datetime: { - title: '创建时间', + title: t('message.pages.basicinfo.unit.createTime'), type: 'datetime', form: { show: false }, column: { width: 180 } }, update_datetime: { - title: '更新时间', + title: t('message.pages.basicinfo.unit.updateTime'), type: 'datetime', form: { show: false }, column: { width: 180 } diff --git a/web/src/views/pisadmin/dashboard/BuyerDashboard.vue b/web/src/views/pisadmin/dashboard/BuyerDashboard.vue index 5dfe6a5..585c128 100644 --- a/web/src/views/pisadmin/dashboard/BuyerDashboard.vue +++ b/web/src/views/pisadmin/dashboard/BuyerDashboard.vue @@ -10,20 +10,20 @@
-
已完成询价单总数
+
{{ $t('message.pages.home.buyerDashboard.kpi.totalInquiries') }}
{{ kpi.total_inquiries.toLocaleString() }}
-
较上月 +12%
+
{{ $t('message.pages.home.buyerDashboard.kpi.trendUp') }}
-
进行中询价单
+
{{ $t('message.pages.home.buyerDashboard.kpi.pendingInquiries') }}
{{ kpi.pending_inquiries }}
-
供应商报价及时率
+
{{ $t('message.pages.home.buyerDashboard.kpi.quoteTimelyRate') }}
{{ kpi.quote_timely_rate }}%
-
持平
+
{{ $t('message.pages.home.buyerDashboard.kpi.trendFlat') }}
@@ -33,21 +33,21 @@
- 我的待办任务({{ tasks.length }} {{ $t('message.pages.home.buyerDashboard.task.title') }}({{ tasks.length }})
- 查看全部 + {{ $t('message.pages.home.buyerDashboard.viewAll') }}
- - - - - - + + + + + + @@ -72,7 +72,7 @@ @@ -86,7 +86,7 @@ - +
询价单号采购方式询价单名称当前状态截止时间 / 剩余时间操作{{ $t('message.pages.home.buyerDashboard.task.table.columns.inquiryNo') }}{{ $t('message.pages.home.buyerDashboard.task.table.columns.method') }}{{ $t('message.pages.home.buyerDashboard.task.table.columns.name') }}{{ $t('message.pages.home.buyerDashboard.task.table.columns.status') }}{{ $t('message.pages.home.buyerDashboard.task.table.columns.deadline') }}{{ $t('message.pages.home.buyerDashboard.task.table.columns.action') }}
- 剩余: + {{ $t('message.pages.home.buyerDashboard.deadline.remaining') }} {{ getDeadlineRemainingValue(task) }}
暂无待办任务{{ $t('message.pages.home.buyerDashboard.task.empty') }}
@@ -102,8 +102,8 @@
-
系统通知
- 更多 +
{{ $t('message.pages.home.buyerDashboard.notification.title') }}
+ {{ $t('message.pages.home.buyerDashboard.more') }}
@@ -117,14 +117,14 @@
{{ v.title }}
-
暂无通知
+
{{ $t('message.pages.home.buyerDashboard.notification.empty') }}
-
快捷入口
+
{{ $t('message.pages.home.buyerDashboard.quickNav.title') }}
@@ -141,10 +141,10 @@
-
近30天业务趋势
+
{{ $t('message.pages.home.buyerDashboard.chart.title') }}
- 发布询价 - 议价完成 + {{ $t('message.pages.home.buyerDashboard.chart.legend.publishInquiry') }} + {{ $t('message.pages.home.buyerDashboard.chart.legend.negotiationComplete') }}
@@ -156,6 +156,7 @@ diff --git a/web/src/views/system/config/components/formContent.vue b/web/src/views/system/config/components/formContent.vue index 16faf51..616ee70 100644 --- a/web/src/views/system/config/components/formContent.vue +++ b/web/src/views/system/config/components/formContent.vue @@ -1,11 +1,11 @@