From fc1084ce33e3d070f7164e2ae58cfec7ff15bf15 Mon Sep 17 00:00:00 2001 From: Lorenzo Date: Fri, 27 Jun 2025 01:31:31 +0200 Subject: [PATCH] More translation --- .../src/locales/langs/en-US/certd.ts | 233 ++++ .../src/locales/langs/zh-CN/certd.ts | 234 ++++ .../src/views/certd/monitor/cert/crud.tsx | 27 +- .../src/views/certd/monitor/site/ip/crud.tsx | 693 +++++------ .../views/sys/authority/permission/crud.tsx | 284 ++--- .../permission/fs-permission-tree.vue | 345 +++--- .../views/sys/authority/permission/index.vue | 111 +- .../src/views/sys/authority/role/crud.tsx | 158 +-- .../src/views/sys/authority/role/index.vue | 190 +-- .../src/views/sys/authority/user/crud.tsx | 49 +- .../src/views/sys/cname/provider/crud.tsx | 472 ++++---- .../src/views/sys/cname/provider/index.vue | 77 +- .../src/views/sys/plugin/crud.tsx | 1070 ++++++++--------- .../src/views/sys/plugin/index.vue | 69 +- .../src/views/sys/settings/email/index.vue | 255 ++-- .../src/views/sys/settings/tabs/base.vue | 205 ++-- .../src/views/sys/settings/tabs/register.vue | 311 ++--- .../src/views/sys/settings/tabs/safe.vue | 242 ++-- 18 files changed, 2772 insertions(+), 2253 deletions(-) diff --git a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts index 1e2705f1..6c5beb8e 100644 --- a/packages/ui/certd-client/src/locales/langs/en-US/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/en-US/certd.ts @@ -447,4 +447,237 @@ export default { subdomainManagement: "Subdomain Management", isDisabled: "Is Disabled", enabled: "Enabled", + uploadCustomCert: "Upload Custom Certificate", + sourcee: "Source", + sourcePipeline: "Pipeline", + sourceManualUpload: "Manual Upload", + domains: "Domains", + enterDomain: "Please enter domain", + validDays: "Valid Days", + expires: " expires", + days: " days", + expireTime: "Expiration Time", + certIssuer: "Certificate Issuer", + applyTime: "Application Time", + relatedPipeline: "Related Pipeline", + statusSuccess: "Success", + statusChecking: "Checking", + statusError: "Error", + actionImportBatch: "Batch Import", + actionSyncIp: "Sync IP", + modalTitleSyncIp: "Sync IP", + modalContentSyncIp: "Are you sure to sync IP?", + notificationSyncComplete: "Sync Complete", + actionCheckAll: "Check All", + modalTitleConfirm: "Confirm", + modalContentCheckAll: "Confirm to trigger checking all IP site's certificates?", + notificationCheckSubmitted: "Check task submitted", + notificationCheckDescription: "Please refresh later to see results", + tooltipCheckNow: "Check Now", + notificationCheckSubmittedPleaseRefresh: "Check task submitted, please refresh later", + columnId: "ID", + columnIp: "IP", + helperIpCname: "Supports entering CNAME domain name", + ruleIpRequired: "Please enter IP", + columnCertDomains: "Certificate Domains", + columnCertProvider: "Issuer", + columnCertStatus: "Certificate Status", + statusNormal: "Normal", + statusExpired: "Expired", + columnCertExpiresTime: "Certificate Expiration Time", + expired: "expired", + columnCheckStatus: "Check Status", + columnLastCheckTime: "Last Check Time", + columnSource: "Source", + sourceSync: "Sync", + sourceManual: "Manual", + sourceImport: "Import", + columnDisabled: "Enabled/Disabled", + columnRemark: "Remark", + pluginFile: "Plugin File", + selectPluginFile: "Select plugin file", + overrideSameName: "Override same name", + override: "Override", + noOverride: "No override", + overrideHelper: "If a plugin with the same name exists, override it directly", + importPlugin: "Import Plugin", + operationSuccess: "Operation successful", + customPlugin: "Custom Plugin", + import: "Import", + export: "Export", + pluginType: "Plugin Type", + auth: "Authorization", + dns: "DNS", + deployPlugin: "Deploy Plugin", + icon: "Icon", + pluginName: "Plugin Name", + pluginNameHelper: "Must be English letters or digits, camelCase with type prefix\nExample: AliyunDeployToCDN\nDo not modify name once plugin is used", + pluginNameRuleMsg: "Must be English letters or digits, camelCase with type prefix", + author: "Author", + authorHelper: "Used as prefix when uploading to plugin store, e.g., greper/pluginName", + authorRuleMsg: "Must be English letters or digits", + titleHelper: "Plugin name in Chinese", + descriptionHelper: "Description of the plugin", + builtIn: "Built-in", + custom: "Custom", + store: "Store", + version: "Version", + pluginDependencies: "Plugin Dependencies", + pluginDependenciesHelper: "Dependencies to install first in format: [author/]pluginName[:version]", + editableRunStrategy: "Editable Run Strategy", + editable: "Editable", + notEditable: "Not Editable", + runStrategy: "Run Strategy", + normalRun: "Normal Run", + skipOnSuccess: "Skip on success (Deploy task)", + defaultRunStrategyHelper: "Default run strategy", + enableDisable: "Enable/Disable", + clickToToggle: "Click to toggle enable/disable", + confirmToggle: "Are you sure to", + disable: "disable", + enable: "enable", + pluginGroup: "Plugin Group", + icpRegistrationNumber: "ICP Registration Number", + icpPlaceholder: "Guangdong ICP xxxxxxx Number", + publicSecurityRegistrationNumber: "Public Security Registration Number", + publicSecurityPlaceholder: "Beijing Public Security xxxxxxx Number", + enableAssistant: "Enable Assistant", + allowCrawlers: "Allow Crawlers", + httpProxy: "HTTP Proxy", + httpProxyPlaceholder: "http://192.168.1.2:18010/", + httpProxyHelper: "Configure when some websites are blocked", + httpsProxy: "HTTPS Proxy", + httpsProxyPlaceholder: "http://192.168.1.2:18010/", + saveThenTestTitle: "Save first, then click test", + testButton: "Test", + httpsProxyHelper: "Usually both proxies are the same, save first then test", + dualStackNetwork: "Dual Stack Network", + default: "Default", + ipv4Priority: "IPv4 Priority", + ipv6Priority: "IPv6 Priority", + dualStackNetworkHelper: "If IPv6 priority is selected, enable IPv6 in docker-compose.yaml", + enableCommonCnameService: "Enable Public CNAME Service", + commonCnameHelper: "Allow use of public CNAME service. If disabled and no custom CNAME service is set, CNAME proxy certificate application will not work.", + saveButton: "Save", + stopSuccess: "Stopped successfully", + google: "Google", + baidu: "Baidu", + success: "Success", + testFailed: "Test Failed", + testCompleted: "Test Completed", + manageOtherUserPipeline: "Manage other users' pipelines", + limitUserPipelineCount: "Limit user pipeline count", + limitUserPipelineCountHelper: "0 means no limit", + enableSelfRegistration: "Enable self-registration", + enableUserValidityPeriod: "Enable user validity period", + userValidityPeriodHelper: "Users can use normally within validity; pipelines disabled after expiry", + enableUsernameRegistration: "Enable username registration", + enableEmailRegistration: "Enable email registration", + proFeature: "Pro feature", + emailServerSetup: "Set up email server", + enableSmsLoginRegister: "Enable SMS login and registration", + commFeature: "Commercial feature", + smsProvider: "SMS provider", + aliyunSms: "Aliyun SMS", + yfySms: "YFY SMS", + smsTest: "SMS test", + testMobilePlaceholder: "Enter test mobile number", + saveThenTest: "Save first then test", + enterTestMobile: "Please enter test mobile number", + sendSuccess: "Sent successfully", + atLeastOneLoginRequired: "At least one of password login or SMS login must be enabled", + fieldRequired: "This field is required", + siteHide: "Site Hide", + enableSiteHide: "Enable Site Hide", + siteHideDescription: "You can disable site accessibility normally and enable it when needed to enhance site security", + helpDoc: "Help Document", + randomAddress: "Random Address", + siteHideUrlHelper: "After the site is hidden, you need to visit this URL to unlock to access normally", + fullUnlockUrl: "Full Unlock URL", + saveThisUrl: "Please save this URL carefully", + unlockPassword: "Unlock Password", + unlockPasswordHelper: "Password needed to unlock the hide; set on first time or reset when filled", + autoHideTime: "Auto Hide Time", + autoHideTimeHelper: "Minutes without requests before auto hiding", + hideOpenApi: "Hide Open API", + hideOpenApiHelper: "Whether to hide open APIs; whether to expose /api/v1 prefixed endpoints", + hideSiteImmediately: "Hide Site Immediately", + hideImmediately: "Hide Immediately", + confirmHideSiteTitle: "Are you sure to hide the site immediately?", + confirmHideSiteContent: "After hiding, the site will be inaccessible. Please operate cautiously.", + siteHiddenSuccess: "Site has been hidden", + emailServerSettings: "Email Server Settings", + setEmailSendingServer: "Set the email sending server", + useCustomEmailServer: "Use Custom Email Server", + smtpDomain: "SMTP Domain", + pleaseEnterSmtpDomain: "Please enter SMTP domain or IP", + smtpPort: "SMTP Port", + pleaseEnterSmtpPort: "Please enter SMTP port", + username: "Username", + pleaseEnterUsername: "Please enter username", + password: "Password", + pleaseEnterPassword: "Please enter password", + qqEmailAuthCodeHelper: "If using QQ email, get an authorization code in QQ email settings as the password", + senderEmail: "Sender Email", + pleaseEnterSenderEmail: "Please enter sender email", + useSsl: "Use SSL", + sslPortNote: "SSL and non-SSL SMTP ports are different, please adjust port accordingly", + ignoreCertValidation: "Ignore Certificate Validation", + useOfficialEmailServer: "Use Official Email Server", + useOfficialEmailServerHelper: "Send emails directly using the official server to avoid complicated setup", + testReceiverEmail: "Test Receiver Email", + pleaseEnterTestReceiverEmail: "Please enter test receiver email", + saveBeforeTest: "Save before testing", + sendFailHelpDoc: "Failed to send??? ", + emailConfigHelpDoc: "Email configuration help document", + tryOfficialEmailServer: "You can also try using the official email server ↗↗↗↗↗↗↗↗", + pluginManagement: "Plugin Management", + pluginBetaWarning: "Custom plugins are in BETA and may have breaking changes in future", + pleaseSelectRecord: "Please select records first", + permissionManagement: "Permission Management", + adda: "Add", + rootNode: "Root Node", + permissionName: "Permission Name", + enterPermissionName: "Please enter permission name", + permissionCode: "Permission Code", + enterPermissionCode: "Please enter permission code", + max100Chars: "Maximum 100 characters", + examplePermissionCode: "e.g.: sys:user:view", + sortOrder: "Sort Order", + sortRequired: "Sort order is required", + parentNode: "Parent Node", + roleManagement: "Role Management", + assignPermissions: "Assign Permissions", + roleName: "Role Name", + enterRoleName: "Please enter role name", + unlockLogin: "Unlock Login", + notice: "Notice", + confirmUnlock: "Are you sure you want to unlock this user's login?", + unlockSuccess: "Unlock successful", + enterUsername: "Please enter username", + modifyPasswordIfFilled: "Fill in to change the password", + emaila: "Email", + mobile: "Mobile", + avatar: "Avatar", + validTime: "Valid Time", + remark: "Remark", + roles: "Roles", + cnameTitle: "CNAME Service Configuration", + cnameDescription: + "The domain name configured here serves as a proxy for verifying other domains. When other domains apply for certificates, they map to this domain via CNAME for ownership verification. The advantage is that any domain can apply for a certificate this way without providing an AccessSecret.", + cnameLinkText: "CNAME principle and usage instructions", + confirmTitle: "Confirm", + confirmDeleteBatch: "Are you sure you want to delete these {count} records?", + selectRecordsFirst: "Please select records first", + cnameDomain: "CNAME Domain", + cnameDomainPlaceholder: "cname.handsfree.work", + cnameDomainHelper: + "Requires a domain registered with a DNS provider on the right (or you can transfer other domain DNS servers here).\nOnce the CNAME domain is set, it cannot be changed. It is recommended to use a first-level subdomain.", + dnsProvider: "DNS Provider", + dnsProviderAuthorization: "DNS Provider Authorization", + setDefault: "Set Default", + confirmSetDefault: "Are you sure to set as default?", + setAsDefault: "Set as Default", + disabledLabel: "Disabled", + confirmToggleStatus: "Are you sure to {action}?", }; diff --git a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts index 4d545901..23225da0 100644 --- a/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts +++ b/packages/ui/certd-client/src/locales/langs/zh-CN/certd.ts @@ -453,4 +453,238 @@ export default { subdomainManagement: "子域管理", isDisabled: "是否禁用", enabled: "启用", + uploadCustomCert: "上传自定义证书", + sourcee: "来源", + sourcePipeline: "流水线", + sourceManualUpload: "手动上传", + domains: "域名", + enterDomain: "请输入域名", + validDays: "有效天数", + expires: "过期", + days: "天", + expireTime: "过期时间", + certIssuer: "证书颁发机构", + applyTime: "申请时间", + relatedPipeline: "关联流水线", + statusSuccess: "成功", + statusChecking: "检查中", + statusError: "异常", + actionImportBatch: "批量导入", + actionSyncIp: "同步IP", + modalTitleSyncIp: "同步IP", + modalContentSyncIp: "确定要同步IP吗?", + notificationSyncComplete: "同步完成", + actionCheckAll: "检查全部", + modalTitleConfirm: "确认", + modalContentCheckAll: "确认触发检查全部IP站点的证书吗?", + notificationCheckSubmitted: "检查任务已提交", + notificationCheckDescription: "请稍后刷新页面查看结果", + tooltipCheckNow: "立即检查", + notificationCheckSubmittedPleaseRefresh: "检查任务已提交,请稍后刷新查看结果", + columnId: "ID", + columnIp: "IP", + helperIpCname: "也支持填写CNAME域名", + ruleIpRequired: "请输入IP", + columnCertDomains: "证书域名", + columnCertProvider: "颁发机构", + columnCertStatus: "证书状态", + statusNormal: "正常", + statusExpired: "过期", + columnCertExpiresTime: "证书到期时间", + expired: "过期", + columnCheckStatus: "检查状态", + columnLastCheckTime: "上次检查时间", + columnSource: "来源", + sourceSync: "同步", + sourceManual: "手动", + sourceImport: "导入", + columnDisabled: "禁用启用", + columnRemark: "备注", + pluginFile: "插件文件", + selectPluginFile: "选择插件文件", + overrideSameName: "同名覆盖", + override: "覆盖", + noOverride: "不覆盖", + overrideHelper: "如果已有相同名称插件,直接覆盖", + importPlugin: "导入插件", + operationSuccess: "操作成功", + customPlugin: "自定义插件", + import: "导入", + export: "导出", + pluginType: "插件类型", + auth: "授权", + dns: "DNS", + deployPlugin: "部署插件", + icon: "图标", + pluginName: "插件名称", + pluginNameHelper: "必须为英文或数字,驼峰命名,类型作为前缀\n示例:AliyunDeployToCDN\n插件使用后,名称不可修改", + pluginNameRuleMsg: "必须为英文或数字,驼峰命名,类型作为前缀", + author: "作者", + authorHelper: "上传插件市场时作为前缀,如 greper/pluginName", + authorRuleMsg: "必须为英文或数字", + titleHelper: "插件中文名称", + descriptionHelper: "插件描述", + builtIn: "内置", + custom: "自定义", + store: "市场", + version: "版本", + pluginDependencies: "插件依赖", + pluginDependenciesHelper: "格式: [作者/]插件名[:版本],需先安装依赖插件", + editableRunStrategy: "可编辑运行策略", + editable: "可编辑", + notEditable: "不可编辑", + runStrategy: "运行策略", + normalRun: "正常运行", + skipOnSuccess: "成功跳过(部署任务)", + defaultRunStrategyHelper: "默认运行策略", + enableDisable: "启用/禁用", + clickToToggle: "点击切换启用/禁用", + confirmToggle: "确认要", + disable: "禁用", + enable: "启用", + pluginGroup: "插件分组", + icpRegistrationNumber: "ICP备案号", + icpPlaceholder: "粤ICP备xxxxxxx号", + publicSecurityRegistrationNumber: "网安备案号", + publicSecurityPlaceholder: "京公网安备xxxxxxx号", + enableAssistant: "开启小助手", + allowCrawlers: "允许爬虫", + httpProxy: "HTTP代理", + httpProxyPlaceholder: "http://192.168.1.2:18010/", + httpProxyHelper: "当某些网站被墙时可以配置", + httpsProxy: "HTTPS代理", + httpsProxyPlaceholder: "http://192.168.1.2:18010/", + saveThenTestTitle: "保存后,再点击测试", + testButton: "测试", + httpsProxyHelper: "一般这两个代理填一样的,保存后再测试", + dualStackNetwork: "双栈网络", + default: "默认", + ipv4Priority: "IPV4优先", + ipv6Priority: "IPV6优先", + dualStackNetworkHelper: "如果选择IPv6优先,需要在docker-compose.yaml中启用ipv6", + enableCommonCnameService: "启用公共CNAME服务", + commonCnameHelper: "是否可以使用公共CNAME服务,如果禁用,且没有设置自定义CNAME服务,则无法使用CNAME代理方式申请证书", + saveButton: "保存", + stopSuccess: "停止成功", + google: "Google", + baidu: "百度", + success: "成功", + testFailed: "测试失败", + testCompleted: "测试完成", + manageOtherUserPipeline: "管理其他用户流水线", + limitUserPipelineCount: "限制用户流水线数量", + limitUserPipelineCountHelper: "0为不限制", + enableSelfRegistration: "开启自助注册", + enableUserValidityPeriod: "开启用户有效期", + userValidityPeriodHelper: "有效期内用户可正常使用,失效后流水线将被停用", + enableUsernameRegistration: "开启用户名注册", + enableEmailRegistration: "开启邮箱注册", + proFeature: "专业版功能", + emailServerSetup: "设置邮箱服务器", + enableSmsLoginRegister: "开启手机号登录、注册", + commFeature: "商业版功能", + smsProvider: "短信提供商", + aliyunSms: "阿里云短信", + yfySms: "易发云短信", + smsTest: "短信测试", + testMobilePlaceholder: "输入测试手机号", + saveThenTest: "保存后再点击测试", + enterTestMobile: "请输入测试手机号", + sendSuccess: "发送成功", + atLeastOneLoginRequired: "密码登录和手机号登录至少开启一个", + fieldRequired: "此项必填", + siteHide: "站点隐藏", + enableSiteHide: "启用站点隐藏", + siteHideDescription: "可以在平时关闭站点的可访问性,需要时再打开,增强站点安全性", + helpDoc: "帮助说明", + randomAddress: "随机地址", + siteHideUrlHelper: "站点被隐藏后,需要访问此URL解锁,才能正常访问", + fullUnlockUrl: "完整解除隐藏地址", + saveThisUrl: "请保存好此地址", + unlockPassword: "解除密码", + unlockPasswordHelper: "解除隐藏时需要输入密码,第一次需要设置密码,填写则重置密码", + autoHideTime: "自动隐藏时间", + autoHideTimeHelper: "多少分钟内无请求自动隐藏", + hideOpenApi: "隐藏开放接口", + hideOpenApiHelper: "是否隐藏开放接口,是否放开/api/v1开头的接口", + hideSiteImmediately: "立即隐藏站点", + hideImmediately: "立即隐藏", + confirmHideSiteTitle: "确定要立即隐藏站点吗?", + confirmHideSiteContent: "隐藏后,将无法访问站点,请谨慎操作", + siteHiddenSuccess: "站点已隐藏", + emailServerSettings: "邮件服务器设置", + setEmailSendingServer: "设置邮件发送服务器", + useCustomEmailServer: "使用自定义邮件服务器", + smtpDomain: "SMTP域名", + pleaseEnterSmtpDomain: "请输入smtp域名或ip", + smtpPort: "SMTP端口", + pleaseEnterSmtpPort: "请输入smtp端口号", + username: "用户名", + pleaseEnterUsername: "请输入用户名", + password: "密码", + pleaseEnterPassword: "请输入密码", + qqEmailAuthCodeHelper: "如果是qq邮箱,需要到qq邮箱的设置里面申请授权码作为密码", + senderEmail: "发件邮箱", + pleaseEnterSenderEmail: "请输入发件邮箱", + useSsl: "是否ssl", + sslPortNote: "ssl和非ssl的smtp端口是不一样的,注意修改端口", + ignoreCertValidation: "忽略证书校验", + useOfficialEmailServer: "使用官方邮件服务器", + useOfficialEmailServerHelper: "使用官方邮箱服务器直接发邮件,免除繁琐的配置", + testReceiverEmail: "测试收件邮箱", + pleaseEnterTestReceiverEmail: "请输入测试收件邮箱", + saveBeforeTest: "保存后再点击测试", + sendFailHelpDoc: "发送失败???", + emailConfigHelpDoc: "邮件配置帮助文档", + tryOfficialEmailServer: "您还可以试试使用官方邮件服务器↗↗↗↗↗↗↗↗", + pluginManagement: "插件管理", + pluginBetaWarning: "自定义插件处于BETA测试版,后续可能会有破坏性变更", + pleaseSelectRecord: "请先勾选记录", + permissionManagement: "权限管理", + adda: "添加", + rootNode: "根节点", + permissionName: "权限名称", + enterPermissionName: "请输入权限名称", + permissionCode: "权限代码", + enterPermissionCode: "请输入权限代码", + max100Chars: "最大100个字符", + examplePermissionCode: "例如:sys:user:view", + sortOrder: "排序", + sortRequired: "排序号必填", + parentNode: "父节点", + roleManagement: "角色管理", + assignPermissions: "分配权限", + roleName: "角色名称", + enterRoleName: "请输入角色名称", + unlockLogin: "解除登录锁定", + notice: "提示", + confirmUnlock: "确定要解除该用户的登录锁定吗?", + unlockSuccess: "解除成功", + enterUsername: "请输入用户名", + modifyPasswordIfFilled: "填写则修改密码", + emaila: "邮箱", + mobile: "手机号", + avatar: "头像", + validTime: "有效期", + remark: "备注", + roles: "角色", + cnameTitle: "CNAME服务配置", + cnameDescription: + "此处配置的域名作为其他域名校验的代理,当别的域名需要申请证书时,通过CNAME映射到此域名上来验证所有权。好处是任何域名都可以通过此方式申请证书,也无需填写AccessSecret。", + cnameLinkText: "CNAME功能原理及使用说明", + confirmTitle: "确认", + confirmDeleteBatch: "确定要批量删除这{count}条记录吗", + selectRecordsFirst: "请先勾选记录", + cnameDomain: "CNAME域名", + cnameDomainPlaceholder: "cname.handsfree.work", + cnameDomainHelper: + "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名", + dnsProvider: "DNS提供商", + dnsProviderAuthorization: "DNS提供商授权", + setDefault: "设置默认", + confirmSetDefault: "确定要设置为默认吗?", + setAsDefault: "设为默认", + disabledLabel: "禁用", + confirmToggleStatus: "确定要{action}吗?", + }; diff --git a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx index 8e254b73..88f3bce9 100644 --- a/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/monitor/cert/crud.tsx @@ -82,7 +82,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat show: true, buttons: { add: { - text: "上传自定义证书", + text: t('certd.uploadCustomCert'), type: "primary", show: false, async click() { @@ -150,15 +150,15 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, fromType: { - title: "来源", + title: t('certd.sourcee'), search: { show: true, }, type: "dict-select", dict: dict({ data: [ - { label: "流水线", value: "pipeline" }, - { label: "手动上传", value: "upload" }, + { label: t('certd.sourcePipeline'), value: "pipeline" }, + { label: t('certd.sourceManualUpload'), value: "upload" }, ], }), form: { @@ -179,13 +179,13 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, domains: { - title: "域名", + title: t('certd.domains'), search: { show: true, }, type: "text", form: { - rules: [{ required: true, message: "请输入域名" }], + rules: [{ required: true, message: t('certd.enterDomain') }], }, column: { width: 450, @@ -197,7 +197,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, domainCount: { - title: "域名数量", + title: t('certd.domainCount'), type: "number", form: { show: false, @@ -209,7 +209,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, expiresLeft: { - title: "有效天数", + title: t('certd.validDays'), search: { show: false, }, @@ -229,12 +229,12 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat const leftDays = dayjs(value).diff(dayjs(), "day"); const color = leftDays < 20 ? "red" : "#389e0d"; const percent = (leftDays / 90) * 100; - return `${leftDays}天`} />; + return `${leftDays}${t('certd.days')}`} />; }, }, }, expiresTime: { - title: "过期时间", + title: t('certd.expireTime'), search: { show: false, }, @@ -247,7 +247,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, certProvider: { - title: "证书颁发机构", + title: t('certd.certIssuer'), search: { show: false, }, @@ -260,7 +260,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, applyTime: { - title: "申请时间", + title: t('certd.applyTime'), search: { show: false, }, @@ -273,7 +273,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, "pipeline.title": { - title: "关联流水线", + title: t('certd.relatedPipeline'), search: { show: false }, type: "link", form: { @@ -291,6 +291,7 @@ export default function ({ crudExpose, context }: CreateCrudOptionsProps): Creat }, }, }, + }, }, }; diff --git a/packages/ui/certd-client/src/views/certd/monitor/site/ip/crud.tsx b/packages/ui/certd-client/src/views/certd/monitor/site/ip/crud.tsx index 1fb77a2a..f600adb4 100644 --- a/packages/ui/certd-client/src/views/certd/monitor/site/ip/crud.tsx +++ b/packages/ui/certd-client/src/views/certd/monitor/site/ip/crud.tsx @@ -7,353 +7,354 @@ import { Modal, notification } from "ant-design-vue"; import { useSiteIpMonitor } from "/@/views/certd/monitor/site/ip/use"; export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { - const api = siteIpApi; + const { t } = useI18n(); + const api = siteIpApi; - const pageRequest = async (query: UserPageQuery): Promise => { - if (!query.query) { - query.query = {}; - } - query.query.siteId = context.props.siteId; - return await api.GetList(query); - }; - const editRequest = async (req: EditReq) => { - const { form, row } = req; - form.id = row.id; - const res = await api.UpdateObj(form); - return res; - }; - const delRequest = async (req: DelReq) => { - const { row } = req; - return await api.DelObj(row.id); - }; + const pageRequest = async (query: UserPageQuery): Promise => { + if (!query.query) { + query.query = {}; + } + query.query.siteId = context.props.siteId; + return await api.GetList(query); + }; + const editRequest = async (req: EditReq) => { + const { form, row } = req; + form.id = row.id; + const res = await api.UpdateObj(form); + return res; + }; + const delRequest = async (req: DelReq) => { + const { row } = req; + return await api.DelObj(row.id); + }; - const addRequest = async (req: AddReq) => { - const { form } = req; - form.siteId = context.props.siteId; - const res = await api.AddObj(form); - return res; - }; + const addRequest = async (req: AddReq) => { + const { form } = req; + form.siteId = context.props.siteId; + const res = await api.AddObj(form); + return res; + }; - const checkStatusDict = dict({ - data: [ - { label: "成功", value: "ok", color: "green" }, - { label: "检查中", value: "checking", color: "blue" }, - { label: "异常", value: "error", color: "red" }, - ], - }); - const { openSiteIpImportDialog } = useSiteIpMonitor(); - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest, - }, - form: { - labelCol: { - //固定label宽度 - span: null, - style: { - width: "100px", - }, - }, - col: { - span: 22, - }, - wrapper: { - width: 600, - }, - }, - actionbar: { - buttons: { - add: { - async click() { - await crudExpose.openAdd({}); - }, - }, - import: { - show: true, - text: "批量导入", - type: "primary", - async click() { - openSiteIpImportDialog({ - siteId: context.props.siteId, - afterSubmit() { - crudExpose.doRefresh(); - }, - }); - }, - }, - load: { - text: "同步IP", - type: "primary", - async click() { - Modal.confirm({ - title: "同步IP", - content: "确定要同步IP吗?", - onOk: async () => { - await api.DoSync(context.props.siteId); - await crudExpose.doRefresh(); - notification.success({ - message: "同步完成", - }); - }, - }); - }, - }, - checkAll: { - text: "检查全部", - type: "primary", - click: () => { - Modal.confirm({ - title: "确认", - content: "确认触发检查全部IP站点的证书吗?", - onOk: async () => { - await siteIpApi.CheckAll(context.props.siteId); - notification.success({ - message: "检查任务已提交", - description: "请稍后刷新页面查看结果", - }); - }, - }); - }, - }, - }, - }, - rowHandle: { - fixed: "right", - width: 240, - buttons: { - check: { - order: 0, - type: "link", - text: null, - tooltip: { - title: "立即检查", - }, - icon: "ion:play-sharp", - click: async ({ row }) => { - await api.DoCheck(row.id); - await crudExpose.doRefresh(); - notification.success({ - message: "检查任务已提交,请稍后刷新查看结果", - }); - }, - }, - }, - }, - columns: { - id: { - title: "ID", - key: "id", - type: "number", - search: { - show: false, - }, - column: { - width: 80, - align: "center", - }, - form: { - show: false, - }, - }, - ipAddress: { - title: "IP", - search: { - show: true, - }, - type: "text", - helper: "也支持填写CNAME域名", - form: { - rules: [{ required: true, message: "请输入IP" }], - }, - column: { - width: 160, - }, - }, - certDomains: { - title: "证书域名", - search: { - show: false, - }, - type: "text", - form: { - show: false, - }, - column: { - width: 200, - sorter: true, - show: false, - cellRender({ value }) { - return ( - - {value} - - ); - }, - }, - }, - certProvider: { - title: "颁发机构", - search: { - show: false, - }, - type: "text", - form: { - show: false, - }, - column: { - width: 200, - show: false, - sorter: true, - cellRender({ value }) { - return {value}; - }, - }, - }, - certStatus: { - title: "证书状态", - search: { - show: true, - }, - type: "dict-select", - dict: dict({ - data: [ - { label: "正常", value: "ok", color: "green" }, - { label: "过期", value: "expired", color: "red" }, - ], - }), - form: { - show: false, - }, - column: { - width: 100, - sorter: true, - show: true, - align: "center", - }, - }, - certExpiresTime: { - title: "证书到期时间", - search: { - show: false, - }, - type: "date", - form: { - show: false, - }, - column: { - sorter: true, - cellRender({ value }) { - if (!value) { - return "-"; - } - const expireDate = dayjs(value).format("YYYY-MM-DD"); - const leftDays = dayjs(value).diff(dayjs(), "day"); - const color = leftDays < 20 ? "red" : "#389e0d"; - const percent = (leftDays / 90) * 100; - return `${leftDays}天`} />; - }, - }, - }, - checkStatus: { - title: "检查状态", - search: { - show: false, - }, - type: "dict-select", - dict: checkStatusDict, - form: { - show: false, - }, - column: { - width: 100, - align: "center", - sorter: true, - cellRender({ value, row, key }) { - return ( - - - - ); - }, - }, - }, - lastCheckTime: { - title: "上次检查时间", - search: { - show: false, - }, - type: "datetime", - form: { - show: false, - }, - column: { - sorter: true, - width: 155, - }, - }, - from: { - title: "来源", - search: { - show: false, - }, - type: "dict-switch", - dict: dict({ - data: [ - { label: "同步", value: "sync", color: "green" }, - { label: "手动", value: "manual", color: "blue" }, - { label: "导入", value: "import", color: "blue" }, - ], - }), - form: { - value: false, - }, - column: { - width: 100, - sorter: true, - align: "center", - }, - }, - disabled: { - title: "禁用启用", - search: { - show: false, - }, - type: "dict-switch", - dict: dict({ - data: [ - { label: "启用", value: false, color: "green" }, - { label: "禁用", value: true, color: "red" }, - ], - }), - form: { - value: false, - }, - column: { - width: 100, - sorter: true, - align: "center", - }, - }, - remark: { - title: "备注", - search: { - show: false, - }, - type: "text", - form: { - show: false, - }, - column: { - width: 200, - sorter: true, - tooltip: true, - }, - }, - }, - }, - }; + const checkStatusDict = dict({ + data: [ + { label: t("certd.statusSuccess"), value: "ok", color: "green" }, + { label: t("certd.statusChecking"), value: "checking", color: "blue" }, + { label: t("certd.statusError"), value: "error", color: "red" }, + ], + }); + const { openSiteIpImportDialog } = useSiteIpMonitor(); + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + form: { + labelCol: { + //固定label宽度 + span: null, + style: { + width: "100px", + }, + }, + col: { + span: 22, + }, + wrapper: { + width: 600, + }, + }, + actionbar: { + buttons: { + add: { + async click() { + await crudExpose.openAdd({}); + }, + }, + import: { + show: true, + text: t("certd.actionImportBatch"), + type: "primary", + async click() { + openSiteIpImportDialog({ + siteId: context.props.siteId, + afterSubmit() { + crudExpose.doRefresh(); + }, + }); + }, + }, + load: { + text: t("certd.actionSyncIp"), + type: "primary", + async click() { + Modal.confirm({ + title: t("certd.modalTitleSyncIp"), + content: t("certd.modalContentSyncIp"), + onOk: async () => { + await api.DoSync(context.props.siteId); + await crudExpose.doRefresh(); + notification.success({ + message: t("certd.notificationSyncComplete"), + }); + }, + }); + }, + }, + checkAll: { + text: t("certd.actionCheckAll"), + type: "primary", + click: () => { + Modal.confirm({ + title: t("certd.modalTitleConfirm"), + content: t("certd.modalContentCheckAll"), + onOk: async () => { + await siteIpApi.CheckAll(context.props.siteId); + notification.success({ + message: t("certd.notificationCheckSubmitted"), + description: t("certd.notificationCheckDescription"), + }); + }, + }); + }, + }, + }, + }, + rowHandle: { + fixed: "right", + width: 240, + buttons: { + check: { + order: 0, + type: "link", + text: null, + tooltip: { + title: t("certd.tooltipCheckNow"), + }, + icon: "ion:play-sharp", + click: async ({ row }) => { + await api.DoCheck(row.id); + await crudExpose.doRefresh(); + notification.success({ + message: t("certd.notificationCheckSubmittedPleaseRefresh"), + }); + }, + }, + }, + }, + columns: { + id: { + title: t("certd.columnId"), + key: "id", + type: "number", + search: { + show: false, + }, + column: { + width: 80, + align: "center", + }, + form: { + show: false, + }, + }, + ipAddress: { + title: t("certd.columnIp"), + search: { + show: true, + }, + type: "text", + helper: t("certd.helperIpCname"), + form: { + rules: [{ required: true, message: t("certd.ruleIpRequired") }], + }, + column: { + width: 160, + }, + }, + certDomains: { + title: t("certd.columnCertDomains"), + search: { + show: false, + }, + type: "text", + form: { + show: false, + }, + column: { + width: 200, + sorter: true, + show: false, + cellRender({ value }) { + return ( + + {value} + + ); + }, + }, + }, + certProvider: { + title: t("certd.columnCertProvider"), + search: { + show: false, + }, + type: "text", + form: { + show: false, + }, + column: { + width: 200, + show: false, + sorter: true, + cellRender({ value }) { + return {value}; + }, + }, + }, + certStatus: { + title: t("certd.columnCertStatus"), + search: { + show: true, + }, + type: "dict-select", + dict: dict({ + data: [ + { label: t("certd.statusNormal"), value: "ok", color: "green" }, + { label: t("certd.statusExpired"), value: "expired", color: "red" }, + ], + }), + form: { + show: false, + }, + column: { + width: 100, + sorter: true, + show: true, + align: "center", + }, + }, + certExpiresTime: { + title: t("certd.columnCertExpiresTime"), + search: { + show: false, + }, + type: "date", + form: { + show: false, + }, + column: { + sorter: true, + cellRender({ value }) { + if (!value) { + return "-"; + } + const expireDate = dayjs(value).format("YYYY-MM-DD"); + const leftDays = dayjs(value).diff(dayjs(), "day"); + const color = leftDays < 20 ? "red" : "#389e0d"; + const percent = (leftDays / 90) * 100; + return `${leftDays} ${t("certd.days")}`} />; + }, + }, + }, + checkStatus: { + title: t("certd.columnCheckStatus"), + search: { + show: false, + }, + type: "dict-select", + dict: checkStatusDict, + form: { + show: false, + }, + column: { + width: 100, + align: "center", + sorter: true, + cellRender({ value, row, key }) { + return ( + + + + ); + }, + }, + }, + lastCheckTime: { + title: t("certd.columnLastCheckTime"), + search: { + show: false, + }, + type: "datetime", + form: { + show: false, + }, + column: { + sorter: true, + width: 155, + }, + }, + from: { + title: t("certd.columnSource"), + search: { + show: false, + }, + type: "dict-switch", + dict: dict({ + data: [ + { label: t("certd.sourceSync"), value: "sync", color: "green" }, + { label: t("certd.sourceManual"), value: "manual", color: "blue" }, + { label: t("certd.sourceImport"), value: "import", color: "blue" }, + ], + }), + form: { + value: false, + }, + column: { + width: 100, + sorter: true, + align: "center", + }, + }, + disabled: { + title: t("certd.columnDisabled"), + search: { + show: false, + }, + type: "dict-switch", + dict: dict({ + data: [ + { label: t("certd.enabled"), value: false, color: "green" }, + { label: t("certd.disabled"), value: true, color: "red" }, + ], + }), + form: { + value: false, + }, + column: { + width: 100, + sorter: true, + align: "center", + }, + }, + remark: { + title: t("certd.columnRemark"), + search: { + show: false, + }, + type: "text", + form: { + show: false, + }, + column: { + width: 200, + sorter: true, + tooltip: true, + }, + }, + }, + }, + }; } diff --git a/packages/ui/certd-client/src/views/sys/authority/permission/crud.tsx b/packages/ui/certd-client/src/views/sys/authority/permission/crud.tsx index 58cebc70..e6ae5127 100644 --- a/packages/ui/certd-client/src/views/sys/authority/permission/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/authority/permission/crud.tsx @@ -1,150 +1,152 @@ import * as api from "./api.js"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, dict, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { useI18n } from "vue-i18n"; export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOptionsRet { - const pageRequest = async (query: UserPageQuery): Promise => { - const list = await api.GetTree(); + const { t } = useI18n(); + const pageRequest = async (query: UserPageQuery): Promise => { + const list = await api.GetTree(); - return { - offset: 0, - records: list, - total: 10000, - limit: 10000 - }; - }; + return { + offset: 0, + records: list, + total: 10000, + limit: 10000 + }; + }; - async function afterChange() { - await permissionTreeDict.reloadDict(); - } - const editRequest = async ({ form, row }: EditReq) => { - form.id = row.id; - const ret = await api.UpdateObj(form); - await afterChange(); - return ret; - }; - const delRequest = async ({ row }: DelReq) => { - const ret = await api.DelObj(row.id); - await afterChange(); - return ret; - }; + async function afterChange() { + await permissionTreeDict.reloadDict(); + } + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + const ret = await api.UpdateObj(form); + await afterChange(); + return ret; + }; + const delRequest = async ({ row }: DelReq) => { + const ret = await api.DelObj(row.id); + await afterChange(); + return ret; + }; - const addRequest = async ({ form }: AddReq) => { - const ret = await api.AddObj(form); - await afterChange(); - return ret; - }; - const permissionTreeDict = dict({ - url: "/sys/authority/permission/tree", - isTree: true, - value: "id", - label: "title", - async onReady({ dict }: any) { - dict.setData([{ id: -1, title: "根节点", children: dict.data }]); - } - }); - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest - }, - actionbar: { - show: false - }, - toolbar: { - show: false - }, - table: { - show: false - // scroll: { fixed: true } - }, - rowHandle: { - fixed: "right" - }, - search: { - show: false - }, - pagination: { - show: false, - pageSize: 100000 - }, - columns: { - id: { - title: "id", - type: "number", - form: { show: false }, // 表单配置 - column: { - width: 120, - sortable: "custom" - } - }, - title: { - title: "权限名称", - type: "text", - form: { - rules: [ - { required: true, message: "请输入权限名称" }, - { max: 50, message: "最大50个字符" } - ], - component: { - placeholder: "权限名称" - } - }, - column: { - width: 200 - } - }, + const addRequest = async ({ form }: AddReq) => { + const ret = await api.AddObj(form); + await afterChange(); + return ret; + }; + const permissionTreeDict = dict({ + url: "/sys/authority/permission/tree", + isTree: true, + value: "id", + label: "title", + async onReady({ dict }: any) { + dict.setData([{ id: -1, title: t("certd.rootNode"), children: dict.data }]); + } + }); + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + actionbar: { + show: false + }, + toolbar: { + show: false + }, + table: { + show: false + // scroll: { fixed: true } + }, + rowHandle: { + fixed: "right" + }, + search: { + show: false + }, + pagination: { + show: false, + pageSize: 100000 + }, + columns: { + id: { + title: "id", + type: "number", + form: { show: false }, // 表单配置 + column: { + width: 120, + sortable: "custom" + } + }, + title: { + title: t("certd.permissionName"), + type: "text", + form: { + rules: [ + { required: true, message: t("certd.enterPermissionName") }, + { max: 50, message: t("certd.max50Chars") } + ], + component: { + placeholder: t("certd.permissionName") + } + }, + column: { + width: 200 + } + }, + permission: { + title: t("certd.permissionCode"), + type: "text", + column: { + width: 170 + }, + form: { + rules: [ + { required: true, message: t("certd.enterPermissionCode") }, + { max: 100, message: t("certd.max100Chars") } + ], + component: { + placeholder: t("certd.examplePermissionCode") + } + } + }, + sort: { + title: t("certd.sortOrder"), + type: "number", + column: { + width: 100 + }, + form: { + value: 100, + rules: [{ required: true, type: "number", message: t("certd.sortRequired") }] + } + }, + parentId: { + title: t("certd.parentNode"), + type: "dict-tree", + column: { + width: 100 + }, + dict: permissionTreeDict, + form: { + value: -1, + component: { + multiple: false, + defaultExpandAll: true, + dict: { cache: false }, + fieldNames: { + value: "id", + label: "title" + } + } + } + } - permission: { - title: "权限代码", - type: "text", - column: { - width: 170 - }, - form: { - rules: [ - { required: true, message: "请输入权限代码" }, - { max: 100, message: "最大100个字符" } - ], - component: { - placeholder: "例如:sys:user:view" - } - } - }, - sort: { - title: "排序", - type: "number", - column: { - width: 100 - }, - form: { - value: 100, - rules: [{ required: true, type: "number", message: "排序号必填" }] - } - }, - parentId: { - title: "父节点", - type: "dict-tree", - column: { - width: 100 - }, - dict: permissionTreeDict, - form: { - value: -1, - component: { - multiple: false, - defaultExpandAll: true, - dict: { cache: false }, - fieldNames: { - value: "id", - label: "title" - } - } - } - } - } - } - }; + } + } + }; } diff --git a/packages/ui/certd-client/src/views/sys/authority/permission/fs-permission-tree.vue b/packages/ui/certd-client/src/views/sys/authority/permission/fs-permission-tree.vue index d7c34d8d..207319bf 100644 --- a/packages/ui/certd-client/src/views/sys/authority/permission/fs-permission-tree.vue +++ b/packages/ui/certd-client/src/views/sys/authority/permission/fs-permission-tree.vue @@ -1,193 +1,194 @@ diff --git a/packages/ui/certd-client/src/views/sys/authority/permission/index.vue b/packages/ui/certd-client/src/views/sys/authority/permission/index.vue index 9e07ade2..1d5be571 100644 --- a/packages/ui/certd-client/src/views/sys/authority/permission/index.vue +++ b/packages/ui/certd-client/src/views/sys/authority/permission/index.vue @@ -1,76 +1,81 @@ + diff --git a/packages/ui/certd-client/src/views/sys/authority/role/crud.tsx b/packages/ui/certd-client/src/views/sys/authority/role/crud.tsx index 026746c6..22535080 100644 --- a/packages/ui/certd-client/src/views/sys/authority/role/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/authority/role/crud.tsx @@ -1,84 +1,86 @@ import * as api from "./api"; import { AddReq, CreateCrudOptionsProps, CreateCrudOptionsRet, DelReq, EditReq, UserPageQuery, UserPageRes } from "@fast-crud/fast-crud"; +import { useI18n } from "vue-i18n"; export default function ({ crudExpose, context: { authz } }: CreateCrudOptionsProps): CreateCrudOptionsRet { - const pageRequest = async (query: UserPageQuery): Promise => { - return await api.GetList(query); - }; - const editRequest = async ({ form, row }: EditReq) => { - form.id = row.id; - return await api.UpdateObj(form); - }; - const delRequest = async ({ row }: DelReq) => { - return await api.DelObj(row.id); - }; + const { t } = useI18n(); + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + return await api.UpdateObj(form); + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; - const addRequest = async ({ form }: AddReq) => { - return await api.AddObj(form); - }; - return { - crudOptions: { - request: { - pageRequest, - addRequest, - editRequest, - delRequest - }, - rowHandle: { - width: 300, - buttons: { - authz: { - type: "link", - text: "授权", - async click(context) { - await authz.authzOpen(context.record.id); - } - } - } - }, - columns: { - id: { - title: "id", - type: "text", - form: { show: false }, // 表单配置 - column: { - width: 70, - sorter: true - } - }, - name: { - title: "角色名称", - type: "text", - search: { show: true }, - form: { - rules: [ - { required: true, message: "请输入角色名称" }, - { max: 50, message: "最大50个字符" } - ] - }, // 表单配置 - column: { - sorter: true - } - }, - createTime: { - title: "创建时间", - type: "datetime", - column: { - sorter: true - }, - form: { - show: false - } - }, - updateTime: { - title: "更新时间", - type: "datetime", - column: { - sorter: true - }, - form: { show: false } // 表单配置 - } - } - } - }; + const addRequest = async ({ form }: AddReq) => { + return await api.AddObj(form); + }; + return { + crudOptions: { + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + rowHandle: { + width: 300, + buttons: { + authz: { + type: "link", + text: "授权", + async click(context) { + await authz.authzOpen(context.record.id); + } + } + } + }, + columns: { + id: { + title: "id", + type: "text", + form: { show: false }, // 表单配置 + column: { + width: 70, + sorter: true + } + }, + name: { + title: t("certd.roleName"), + type: "text", + search: { show: true }, + form: { + rules: [ + { required: true, message: t("certd.enterRoleName") }, + { max: 50, message: t("certd.max50Chars") } + ] + }, // 表单配置 + column: { + sorter: true + } + }, + createTime: { + title: t("certd.createTime"), + type: "datetime", + column: { + sorter: true + }, + form: { + show: false + } + }, + updateTime: { + title: t("certd.updateTime"), + type: "datetime", + column: { + sorter: true + }, + form: { show: false } // 表单配置 + } + } + } + }; } diff --git a/packages/ui/certd-client/src/views/sys/authority/role/index.vue b/packages/ui/certd-client/src/views/sys/authority/role/index.vue index 487b8ff4..4b868295 100644 --- a/packages/ui/certd-client/src/views/sys/authority/role/index.vue +++ b/packages/ui/certd-client/src/views/sys/authority/role/index.vue @@ -1,15 +1,18 @@ + diff --git a/packages/ui/certd-client/src/views/sys/authority/user/crud.tsx b/packages/ui/certd-client/src/views/sys/authority/user/crud.tsx index 6f844bfb..0bc8ff66 100644 --- a/packages/ui/certd-client/src/views/sys/authority/user/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/authority/user/crud.tsx @@ -42,18 +42,18 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti fixed: "right", buttons: { unlock: { - title: "解除登录锁定", + title: t("certd.unlockLogin"), text: null, type: "link", icon: "ion:lock-open-outline", click: async ({ row }) => { Modal.confirm({ - title: "提示", - content: "确定要解除该用户的登录锁定吗?", + title: t("certd.notice"), + content: t("certd.confirmUnlock"), onOk: async () => { await api.Unlock(row.id); notification.success({ - message: "解除成功", + message: t("certd.unlockSuccess"), }); }, }); @@ -78,7 +78,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, createTime: { - title: "创建时间", + title: t("certd.createTime"), type: "datetime", form: { show: false }, // 表单配置 column: { @@ -96,13 +96,13 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti // } // }, username: { - title: "用户名", + title: t("certd.username"), type: "text", search: { show: true }, // 开启查询 form: { rules: [ - { required: true, message: "请输入用户名" }, - { max: 50, message: "最大50个字符" }, + { required: true, message: t("certd.enterUsername") }, + { max: 50, message: t("certd.max50Chars") }, ], }, editForm: { component: { disabled: false } }, @@ -112,18 +112,18 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, password: { - title: "密码", + title: t("certd.password"), type: "text", key: "password", column: { show: false, }, form: { - rules: [{ max: 50, message: "最大50个字符" }], + rules: [{ max: 50, message: t("certd.max50Chars") }], component: { showPassword: true, }, - helper: "填写则修改密码", + helper: t("certd.modifyPasswordIfFilled"), }, }, nickName: { @@ -138,11 +138,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, email: { - title: "邮箱", + title: t("certd.emaila"), type: "text", search: { show: true }, // 开启查询 form: { - rules: [{ max: 50, message: "最大50个字符" }], + rules: [{ max: 50, message: t("certd.max50Chars") }], }, column: { sorter: true, @@ -150,11 +150,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, mobile: { - title: "手机号", + title: t("certd.mobile"), type: "text", search: { show: true }, // 开启查询 form: { - rules: [{ max: 50, message: "最大50个字符" }], + rules: [{ max: 50, message: t("certd.max50Chars") }], }, column: { sorter: true, @@ -162,12 +162,11 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, avatar: { - title: "头像", + title: t("certd.avatar"), type: "cropper-uploader", column: { width: 70, component: { - //设置高度,修复操作列错位的问题 style: { height: "30px", width: "auto", @@ -205,12 +204,12 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, status: { - title: "状态", + title: t("certd.status"), type: "dict-switch", dict: dict({ data: [ - { label: "启用", value: 1, color: "green" }, - { label: "禁用", value: 0, color: "red" }, + { label: t("certd.enabled"), value: 1, color: "green" }, + { label: t("certd.disabled"), value: 0, color: "red" }, ], }), column: { @@ -220,7 +219,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, validTime: { - title: "有效期", + title: t("certd.validTime"), type: "date", form: { show: userValidTimeEnabled, @@ -235,7 +234,7 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti return ""; } if (value < dayjs().valueOf()) { - return 已过期; + return {t("certd.expired")}; } const date = dayjs(value).format("YYYY-MM-DD"); return ( @@ -257,17 +256,17 @@ export default function ({ crudExpose }: CreateCrudOptionsProps): CreateCrudOpti }, }, remark: { - title: "备注", + title: t("certd.remark"), type: "text", column: { sorter: true, }, form: { - rules: [{ max: 100, message: "最大100个字符" }], + rules: [{ max: 100, message: t("certd.max100Chars") }], }, }, roles: { - title: "角色", + title: t("certd.roles"), type: "dict-select", dict: dict({ url: "/sys/authority/role/list", diff --git a/packages/ui/certd-client/src/views/sys/cname/provider/crud.tsx b/packages/ui/certd-client/src/views/sys/cname/provider/crud.tsx index 269f819c..dda10e7c 100644 --- a/packages/ui/certd-client/src/views/sys/cname/provider/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/cname/provider/crud.tsx @@ -8,244 +8,244 @@ import { useSettingStore } from "/@/store/settings"; import { Modal } from "ant-design-vue"; export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { - const router = useRouter(); - const { t } = useI18n(); - const pageRequest = async (query: UserPageQuery): Promise => { - return await api.GetList(query); - }; - const editRequest = async ({ form, row }: EditReq) => { - form.id = row.id; - const res = await api.UpdateObj(form); - return res; - }; - const delRequest = async ({ row }: DelReq) => { - return await api.DelObj(row.id); - }; + const router = useRouter(); + const { t } = useI18n(); + const pageRequest = async (query: UserPageQuery): Promise => { + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + const res = await api.UpdateObj(form); + return res; + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; - const addRequest = async ({ form }: AddReq) => { - const res = await api.AddObj(form); - return res; - }; + const addRequest = async ({ form }: AddReq) => { + const res = await api.AddObj(form); + return res; + }; - const userStore = useUserStore(); - const settingStore = useSettingStore(); - const selectedRowKeys: Ref = ref([]); - context.selectedRowKeys = selectedRowKeys; + const userStore = useUserStore(); + const settingStore = useSettingStore(); + const selectedRowKeys: Ref = ref([]); + context.selectedRowKeys = selectedRowKeys; - return { - crudOptions: { - settings: { - plugins: { - //这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并 - rowSelection: { - enabled: true, - order: -2, - before: true, - // handle: (pluginProps,useCrudProps)=>CrudOptions, - props: { - multiple: true, - crossPage: true, - selectedRowKeys - } - } - } - }, - request: { - pageRequest, - addRequest, - editRequest, - delRequest - }, - rowHandle: { - minWidth: 200, - fixed: "right" - }, - columns: { - id: { - title: "ID", - key: "id", - type: "number", - column: { - width: 100 - }, - form: { - show: false - } - }, - domain: { - title: "CNAME域名", - type: "text", - editForm: { - component: { - disabled: true - } - }, - search: { - show: true - }, - form: { - component: { - placeholder: "cname.handsfree.work" - }, - helper: "需要一个右边DNS提供商注册的域名(也可以将其他域名的dns服务器转移到这几家来)。\nCNAME域名一旦确定不可修改,建议使用一级子域名", - rules: [{ required: true, message: "此项必填" }] - }, - column: { - width: 200 - } - }, - dnsProviderType: { - title: "DNS提供商", - type: "dict-select", - search: { - show: true - }, - dict: dict({ - url: "pi/dnsProvider/list", - value: "key", - label: "title" - }), - form: { - rules: [{ required: true, message: "此项必填" }] - }, - column: { - width: 150, - component: { - color: "auto" - } - } - }, - accessId: { - title: "DNS提供商授权", - type: "dict-select", - dict: dict({ - url: "/pi/access/list", - value: "id", - label: "name" - }), - form: { - component: { - name: "access-selector", - vModel: "modelValue", - type: compute(({ form }) => { - return form.dnsProviderType; - }) - }, - rules: [{ required: true, message: "此项必填" }] - }, - column: { - width: 150, - component: { - color: "auto" - } - } - }, - isDefault: { - title: "是否默认", - type: "dict-switch", - dict: dict({ - data: [ - { label: "是", value: true, color: "success" }, - { label: "否", value: false, color: "default" } - ] - }), - form: { - value: false, - rules: [{ required: true, message: "请选择是否默认" }] - }, - column: { - align: "center", - width: 100 - } - }, - setDefault: { - title: "设置默认", - type: "text", - form: { - show: false - }, - column: { - width: 100, - align: "center", - conditionalRenderDisabled: true, - cellRender: ({ row }) => { - if (row.isDefault) { - return; - } - const onClick = async () => { - Modal.confirm({ - title: "提示", - content: `确定要设置为默认吗?`, - onOk: async () => { - await api.SetDefault(row.id); - await crudExpose.doRefresh(); - } - }); - }; + return { + crudOptions: { + settings: { + plugins: { + //这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并 + rowSelection: { + enabled: true, + order: -2, + before: true, + // handle: (pluginProps,useCrudProps)=>CrudOptions, + props: { + multiple: true, + crossPage: true, + selectedRowKeys + } + } + } + }, + request: { + pageRequest, + addRequest, + editRequest, + delRequest + }, + rowHandle: { + minWidth: 200, + fixed: "right" + }, + columns: { + id: { + title: "ID", + key: "id", + type: "number", + column: { + width: 100 + }, + form: { + show: false + } + }, + domain: { + title: t("certd.cnameDomain"), + type: "text", + editForm: { + component: { + disabled: true, + }, + }, + search: { + show: true, + }, + form: { + component: { + placeholder: t("certd.cnameDomainPlaceholder"), + }, + helper: t("certd.cnameDomainHelper"), + rules: [{ required: true, message: t("certd.requiredField") }], + }, + column: { + width: 200, + }, + }, + dnsProviderType: { + title: t("certd.dnsProvider"), + type: "dict-select", + search: { + show: true, + }, + dict: dict({ + url: "pi/dnsProvider/list", + value: "key", + label: "title", + }), + form: { + rules: [{ required: true, message: t("certd.requiredField") }], + }, + column: { + width: 150, + component: { + color: "auto", + }, + }, + }, + accessId: { + title: t("certd.dnsProviderAuthorization"), + type: "dict-select", + dict: dict({ + url: "/pi/access/list", + value: "id", + label: "name", + }), + form: { + component: { + name: "access-selector", + vModel: "modelValue", + type: compute(({ form }) => { + return form.dnsProviderType; + }), + }, + rules: [{ required: true, message: t("certd.requiredField") }], + }, + column: { + width: 150, + component: { + color: "auto", + }, + }, + }, + isDefault: { + title: t("certd.isDefault"), + type: "dict-switch", + dict: dict({ + data: [ + { label: t("certd.yes"), value: true, color: "success" }, + { label: t("certd.no"), value: false, color: "default" }, + ], + }), + form: { + value: false, + rules: [{ required: true, message: t("certd.selectIsDefault") }], + }, + column: { + align: "center", + width: 100, + }, + }, + setDefault: { + title: t("certd.setDefault"), + type: "text", + form: { + show: false, + }, + column: { + width: 100, + align: "center", + conditionalRenderDisabled: true, + cellRender: ({ row }) => { + if (row.isDefault) { + return; + } + const onClick = async () => { + Modal.confirm({ + title: t("certd.prompt"), + content: t("certd.confirmSetDefault"), + onOk: async () => { + await api.SetDefault(row.id); + await crudExpose.doRefresh(); + }, + }); + }; - return ( - - 设为默认 - - ); - } - } - }, - disabled: { - title: "禁用/启用", - type: "dict-switch", - dict: dict({ - data: [ - { label: "启用", value: false, color: "success" }, - { label: "禁用", value: true, color: "error" } - ] - }), - form: { - value: false - }, - column: { - width: 100, - component: { - title: "点击可禁用/启用", - on: { - async click({ value, row }) { - Modal.confirm({ - title: "提示", - content: `确定要${!value ? "禁用" : "启用"}吗?`, - onOk: async () => { - await api.SetDisabled(row.id, !value); - await crudExpose.doRefresh(); - } - }); - } - } - } - } - }, - createTime: { - title: "创建时间", - type: "datetime", - form: { - show: false - }, - column: { - sorter: true, - width: 160, - align: "center" - } - }, - updateTime: { - title: "更新时间", - type: "datetime", - form: { - show: false - }, - column: { - show: true, - width: 160 - } - } - } - } - }; + return ( + + {t("certd.setAsDefault")} + + ); + }, + }, + }, + disabled: { + title: t("certd.disabled"), + type: "dict-switch", + dict: dict({ + data: [ + { label: t("certd.enabled"), value: false, color: "success" }, + { label: t("certd.disabledLabel"), value: true, color: "error" }, + ], + }), + form: { + value: false, + }, + column: { + width: 100, + component: { + title: t("certd.clickToToggle"), + on: { + async click({ value, row }) { + Modal.confirm({ + title: t("certd.prompt"), + content: t("certd.confirmToggleStatus", { action: !value ? t("certd.disable") : t("certd.enable") }), + onOk: async () => { + await api.SetDisabled(row.id, !value); + await crudExpose.doRefresh(); + }, + }); + }, + }, + }, + }, + }, + createTime: { + title: t("certd.createTime"), + type: "datetime", + form: { + show: false, + }, + column: { + sorter: true, + width: 160, + align: "center", + }, + }, + updateTime: { + title: t("certd.updateTime"), + type: "datetime", + form: { + show: false, + }, + column: { + show: true, + width: 160, + }, + }, + } + } + }; } diff --git a/packages/ui/certd-client/src/views/sys/cname/provider/index.vue b/packages/ui/certd-client/src/views/sys/cname/provider/index.vue index 15ef5aa6..858da32d 100644 --- a/packages/ui/certd-client/src/views/sys/cname/provider/index.vue +++ b/packages/ui/certd-client/src/views/sys/cname/provider/index.vue @@ -1,60 +1,67 @@ + diff --git a/packages/ui/certd-client/src/views/sys/plugin/crud.tsx b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx index 938a9dd4..01d33229 100644 --- a/packages/ui/certd-client/src/views/sys/plugin/crud.tsx +++ b/packages/ui/certd-client/src/views/sys/plugin/crud.tsx @@ -8,559 +8,527 @@ import { Modal, notification } from "ant-design-vue"; import yaml from "js-yaml"; export default function ({ crudExpose, context }: CreateCrudOptionsProps): CreateCrudOptionsRet { - const router = useRouter(); - const { t } = useI18n(); + const router = useRouter(); + const { t } = useI18n(); - let lastType = ""; - const pageRequest = async (query: UserPageQuery): Promise => { - if (lastType && lastType != query?.query?.type) { - //lastType有变化 - query.page.offset = 0; - } - lastType = query?.query?.type; - return await api.GetList(query); - }; - const editRequest = async ({ form, row }: EditReq) => { - form.id = row.id; - const res = await api.UpdateObj(form); - return res; - }; - const delRequest = async ({ row }: DelReq) => { - return await api.DelObj(row.id); - }; + let lastType = ""; + const pageRequest = async (query: UserPageQuery): Promise => { + if (lastType && lastType != query?.query?.type) { + query.page.offset = 0; + } + lastType = query?.query?.type; + return await api.GetList(query); + }; + const editRequest = async ({ form, row }: EditReq) => { + form.id = row.id; + const res = await api.UpdateObj(form); + return res; + }; + const delRequest = async ({ row }: DelReq) => { + return await api.DelObj(row.id); + }; - const addRequest = async ({ form }: AddReq) => { - const res = await api.AddObj(form); - return res; - }; + const addRequest = async ({ form }: AddReq) => { + const res = await api.AddObj(form); + return res; + }; - const selectedRowKeys: Ref = ref([]); - context.selectedRowKeys = selectedRowKeys; - const { openCrudFormDialog } = useFormWrapper(); + const selectedRowKeys: Ref = ref([]); + context.selectedRowKeys = selectedRowKeys; + const { openCrudFormDialog } = useFormWrapper(); - async function openImportDialog() { - function createCrudOptions() { - return { - crudOptions: { - columns: { - content: { - title: "插件文件", - type: "text", - form: { - component: { - name: "pem-input", - vModel: "modelValue", - textarea: { - rows: 8, - }, - }, - col: { - span: 24, - }, - helper: "选择插件文件", - }, - }, - override: { - title: "同名覆盖", - type: "dict-switch", - dict: dict({ - data: [ - { - value: true, - label: "覆盖", - }, - { - value: false, - label: "不覆盖", - }, - ], - }), - form: { - value: false, - col: { - span: 24, - }, - helper: "如果已有相同名称插件,直接覆盖", - }, - }, - }, - form: { - wrapper: { - title: "导入插件", - saveRemind: false, - }, - afterSubmit() { - notification.success({ message: "操作成功" }); - crudExpose.doRefresh(); - }, - async doSubmit({ form }: any) { - return await api.ImportPlugin({ - ...form, - }); - }, - }, - }, - }; - } - const { crudOptions } = createCrudOptions(); - await openCrudFormDialog({ crudOptions }); - } - return { - crudOptions: { - settings: { - plugins: { - //这里使用行选择插件,生成行选择crudOptions配置,最终会与crudOptions合并 - rowSelection: { - enabled: true, - order: -2, - before: true, - // handle: (pluginProps,useCrudProps)=>CrudOptions, - props: { - multiple: true, - crossPage: true, - selectedRowKeys, - }, - }, - }, - }, - request: { - pageRequest, - addRequest, - editRequest, - delRequest, - }, - actionbar: { - buttons: { - add: { - show: true, - icon: "ion:ios-add-circle-outline", - text: "自定义插件", - }, - import: { - show: true, - icon: "ion:cloud-upload-outline", - text: "导入", - type: "primary", - async click() { - await openImportDialog(); - }, - }, - }, - }, - rowHandle: { - show: true, - minWidth: 200, - fixed: "right", - buttons: { - edit: { - show: compute(({ row }) => { - return row.type === "custom"; - }), - }, - copy: { - show: compute(({ row }) => { - return row.type === "custom"; - }), - }, - remove: { - order: 999, - show: compute(({ row }) => { - return row.type === "custom"; - }), - }, - export: { - text: null, - icon: "ion:cloud-download-outline", - title: "导出", - type: "link", - show: compute(({ row }) => { - return row.type === "custom"; - }), - async click({ row }) { - //将文本内容,作为文件下载 - const content = await api.ExportPlugin(row.id); - if (content) { - const blob = new Blob([content], { type: "text/plain;charset=utf-8" }); - const url = URL.createObjectURL(blob); - const link = document.createElement("a"); - link.href = url; - link.download = `${row.name}.yaml`; - link.click(); - URL.revokeObjectURL(url); - } - }, - }, - }, - }, - table: { - rowKey: "name", - }, - tabs: { - name: "type", - show: true, - defaultOption: { - show: false, - }, - }, - form: { - onSuccess(opts: any) { - if (opts.res?.id) { - router.push({ - name: "SysPluginEdit", - query: { - id: opts.res.id, - }, - }); - } - }, - }, - columns: { - // id: { - // title: "ID", - // key: "id", - // type: "number", - // column: { - // width: 100 - // }, - // form: { - // show: false - // } - // }, - pluginType: { - title: "插件类型", - type: "dict-select", - search: { - show: true, - }, - form: { - order: 0, - rules: [{ required: true }], - component: { - disabled: true, - }, - }, - addForm: { - component: { - disabled: false, - }, - }, - dict: dict({ - data: [ - { label: "授权", value: "access" }, - { label: "DNS", value: "dnsProvider" }, - { label: "部署插件", value: "deploy" }, - ], - }), - column: { - width: 100, - align: "center", - component: { - color: "auto", - }, - }, - }, - icon: { - title: "图标", - type: "icon", - form: { - rules: [{ required: true }], - }, - column: { - width: 70, - align: "center", - component: { - name: "fs-icon", - vModel: "icon", - style: { - fontSize: "22px", - }, - }, - }, - }, - name: { - title: "插件名称", - type: "text", - search: { - show: true, - }, - form: { - show: true, - helper: "必须为英文或数字,驼峰命名,类型作为前缀\n例如AliyunDeployToCDN\n插件一旦被使用,不要修改名称", - rules: [ - { required: true }, - { - type: "regexp", - pattern: /^[a-zA-Z][a-zA-Z0-9]+$/, - message: "必须为英文或数字,驼峰命名,类型作为前缀", - }, - ], - }, - column: { - width: 250, - cellRender({ row }) { - if (row.author) { - return ; - } else { - return ; - } - }, - }, - }, - author: { - title: "作者", - type: "text", - search: { - show: true, - }, - form: { - show: true, - helper: "上传到插件商店时,将作为插件名称前缀,例如:greper/pluginName", - rules: [ - { required: true }, - { - type: "regexp", - pattern: /^[a-zA-Z][a-zA-Z0-9]+$/, - message: "必须为英文字母或数字", - }, - ], - }, - column: { - width: 200, - show: false, - }, - }, - title: { - title: "标题", - type: "text", - form: { - helper: "插件中文名称", - rules: [{ required: true }], - }, - column: { - width: 300, - cellRender({ row }) { - if (row.type === "custom") { - return {row.title}; - } - return
{row.title}
; - }, - }, - }, - desc: { - title: "描述", - type: "textarea", - helper: "插件的描述", - column: { - width: 300, - show: false, - }, - }, - - type: { - title: "来源", - type: "dict-select", - search: { - show: true, - }, - form: { - value: "custom", - component: { - disabled: true, - }, - }, - dict: dict({ - data: [ - { label: "内置", value: "builtIn" }, - { label: "自建", value: "custom" }, - { label: "商店", value: "store" }, - ], - }), - column: { - width: 70, - align: "center", - component: { - color: "auto", - }, - }, - }, - version: { - title: "版本", - type: "text", - column: { - width: 100, - align: "center", - }, - }, - // "extra.dependLibs": { - // title: "第三方依赖", - // type: "text", - // form: { - // helper: "依赖的第三方库,package.dependencies的格式:name[:^version]", - // component: { - // name: "a-select", - // mode: "tags", - // allowClear: true, - // open: false, - // }, - // }, - // column: { - // show: false, - // }, - // }, - "extra.dependPlugins": { - title: "插件依赖", - type: "text", - form: { - component: { - name: "a-select", - mode: "tags", - open: false, - allowClear: true, - }, - helper: "安装时会先安装依赖的插件,格式:[author/]pluginName[:version]", - }, - column: { - show: false, - }, - }, - "extra.showRunStrategy": { - title: "可修改运行策略", - type: "dict-switch", - dict: dict({ - data: [ - { value: true, label: "可修改" }, - { value: false, label: "不可修改" }, - ], - }), - form: { - value: false, - rules: [{ required: true }], - }, - column: { - width: 100, - align: "left", - show: false, - }, - }, - "extra.default.strategy.runStrategy": { - title: "运行策略", - type: "dict-select", - dict: dict({ - data: [ - { value: 0, label: "正常运行" }, - { value: 1, label: "成功后跳过(部署任务)" }, - ], - }), - form: { - value: 1, - rules: [{ required: true }], - helper: "默认运行策略", - show: compute(({ form }) => { - return form.extra.showRunStrategy; - }), - }, - column: { - width: 100, - align: "left", - component: { - color: "auto", - }, - show: false, - }, - valueBuilder({ row }) { - if (row.extra) { - row.extra = yaml.load(row.extra); - } - }, - valueResolve({ row }) { - if (row.extra) { - row.extra = yaml.dump(row.extra); - } - }, - }, - disabled: { - title: "点击禁用/启用", - type: "dict-switch", - dict: dict({ - data: [ - { label: "启用", value: false, color: "success" }, - { label: "禁用", value: true, color: "error" }, - ], - }), - form: { - title: "禁用/启用", - value: false, - }, - column: { - width: 120, - align: "center", - component: { - title: "点击可禁用/启用", - on: { - async click({ value, row }) { - Modal.confirm({ - title: "提示", - content: `确定要${!value ? "禁用" : "启用"}吗?`, - onOk: async () => { - await api.SetDisabled({ - id: row.id, - name: row.name, - type: row.type, - disabled: !value, - }); - await crudExpose.doRefresh(); - }, - }); - }, - }, - }, - }, - }, - group: { - title: "插件分组", - type: "dict-select", - dict: dict({ - url: "/pi/plugin/groupsList", - label: "title", - value: "key", - }), - form: { - rules: [{ required: true }], - show: compute(({ form }) => { - return form.pluginType === "deploy"; - }), - }, - column: { - width: 100, - align: "left", - component: { - color: "auto", - }, - }, - }, - createTime: { - title: "创建时间", - type: "datetime", - form: { - show: false, - }, - column: { - sorter: true, - width: 160, - align: "center", - }, - }, - updateTime: { - title: "更新时间", - type: "datetime", - form: { - show: false, - }, - column: { - show: true, - }, - }, - }, - }, - }; + async function openImportDialog() { + function createCrudOptions() { + return { + crudOptions: { + columns: { + content: { + title: t("certd.pluginFile"), + type: "text", + form: { + component: { + name: "pem-input", + vModel: "modelValue", + textarea: { + rows: 8, + }, + }, + col: { + span: 24, + }, + helper: t("certd.selectPluginFile"), + }, + }, + override: { + title: t("certd.overrideSameName"), + type: "dict-switch", + dict: dict({ + data: [ + { + value: true, + label: t("certd.override"), + }, + { + value: false, + label: t("certd.noOverride"), + }, + ], + }), + form: { + value: false, + col: { + span: 24, + }, + helper: t("certd.overrideHelper"), + }, + }, + }, + form: { + wrapper: { + title: t("certd.importPlugin"), + saveRemind: false, + }, + afterSubmit() { + notification.success({ message: t("certd.operationSuccess") }); + crudExpose.doRefresh(); + }, + async doSubmit({ form }: any) { + return await api.ImportPlugin({ + ...form, + }); + }, + }, + }, + }; + } + const { crudOptions } = createCrudOptions(); + await openCrudFormDialog({ crudOptions }); + } + return { + crudOptions: { + settings: { + plugins: { + rowSelection: { + enabled: true, + order: -2, + before: true, + props: { + multiple: true, + crossPage: true, + selectedRowKeys, + }, + }, + }, + }, + request: { + pageRequest, + addRequest, + editRequest, + delRequest, + }, + actionbar: { + buttons: { + add: { + show: true, + icon: "ion:ios-add-circle-outline", + text: t("certd.customPlugin"), + }, + import: { + show: true, + icon: "ion:cloud-upload-outline", + text: t("certd.import"), + type: "primary", + async click() { + await openImportDialog(); + }, + }, + }, + }, + rowHandle: { + show: true, + minWidth: 200, + fixed: "right", + buttons: { + edit: { + show: compute(({ row }) => { + return row.type === "custom"; + }), + }, + copy: { + show: compute(({ row }) => { + return row.type === "custom"; + }), + }, + remove: { + order: 999, + show: compute(({ row }) => { + return row.type === "custom"; + }), + }, + export: { + text: null, + icon: "ion:cloud-download-outline", + title: t("certd.export"), + type: "link", + show: compute(({ row }) => { + return row.type === "custom"; + }), + async click({ row }) { + const content = await api.ExportPlugin(row.id); + if (content) { + const blob = new Blob([content], { type: "text/plain;charset=utf-8" }); + const url = URL.createObjectURL(blob); + const link = document.createElement("a"); + link.href = url; + link.download = `${row.name}.yaml`; + link.click(); + URL.revokeObjectURL(url); + } + }, + }, + }, + }, + table: { + rowKey: "name", + }, + tabs: { + name: "type", + show: true, + defaultOption: { + show: false, + }, + }, + form: { + onSuccess(opts: any) { + if (opts.res?.id) { + router.push({ + name: "SysPluginEdit", + query: { + id: opts.res.id, + }, + }); + } + }, + }, + columns: { + pluginType: { + title: t("certd.pluginType"), + type: "dict-select", + search: { + show: true, + }, + form: { + order: 0, + rules: [{ required: true }], + component: { + disabled: true, + }, + }, + addForm: { + component: { + disabled: false, + }, + }, + dict: dict({ + data: [ + { label: t("certd.auth"), value: "access" }, + { label: t("certd.dns"), value: "dnsProvider" }, + { label: t("certd.deployPlugin"), value: "deploy" }, + ], + }), + column: { + width: 100, + align: "center", + component: { + color: "auto", + }, + }, + }, + icon: { + title: t("certd.icon"), + type: "icon", + form: { + rules: [{ required: true }], + }, + column: { + width: 70, + align: "center", + component: { + name: "fs-icon", + vModel: "icon", + style: { + fontSize: "22px", + }, + }, + }, + }, + name: { + title: t("certd.pluginName"), + type: "text", + search: { + show: true, + }, + form: { + show: true, + helper: t("certd.pluginNameHelper"), + rules: [ + { required: true }, + { + type: "regexp", + pattern: /^[a-zA-Z][a-zA-Z0-9]+$/, + message: t("certd.pluginNameRuleMsg"), + }, + ], + }, + column: { + width: 250, + cellRender({ row }) { + if (row.author) { + return ; + } else { + return ; + } + }, + }, + }, + author: { + title: t("certd.author"), + type: "text", + search: { + show: true, + }, + form: { + show: true, + helper: t("certd.authorHelper"), + rules: [ + { required: true }, + { + type: "regexp", + pattern: /^[a-zA-Z][a-zA-Z0-9]+$/, + message: t("certd.authorRuleMsg"), + }, + ], + }, + column: { + width: 200, + show: false, + }, + }, + title: { + title: t("certd.titlea"), + type: "text", + form: { + helper: t("certd.titleHelper"), + rules: [{ required: true }], + }, + column: { + width: 300, + cellRender({ row }) { + if (row.type === "custom") { + return {row.title}; + } + return
{row.title}
; + }, + }, + }, + desc: { + title: t("certd.description"), + type: "textarea", + helper: t("certd.descriptionHelper"), + column: { + width: 300, + show: false, + }, + }, + type: { + title: t("certd.sourcee"), + type: "dict-select", + search: { + show: true, + }, + form: { + value: "custom", + component: { + disabled: true, + }, + }, + dict: dict({ + data: [ + { label: t("certd.builtIn"), value: "builtIn" }, + { label: t("certd.custom"), value: "custom" }, + { label: t("certd.store"), value: "store" }, + ], + }), + column: { + width: 70, + align: "center", + component: { + color: "auto", + }, + }, + }, + version: { + title: t("certd.version"), + type: "text", + column: { + width: 100, + align: "center", + }, + }, + "extra.dependPlugins": { + title: t("certd.pluginDependencies"), + type: "text", + form: { + component: { + name: "a-select", + mode: "tags", + open: false, + allowClear: true, + }, + helper: t("certd.pluginDependenciesHelper"), + }, + column: { + show: false, + }, + }, + "extra.showRunStrategy": { + title: t("certd.editableRunStrategy"), + type: "dict-switch", + dict: dict({ + data: [ + { value: true, label: t("certd.editable") }, + { value: false, label: t("certd.notEditable") }, + ], + }), + form: { + value: false, + rules: [{ required: true }], + }, + column: { + width: 100, + align: "left", + show: false, + }, + }, + "extra.default.strategy.runStrategy": { + title: t("certd.runStrategy"), + type: "dict-select", + dict: dict({ + data: [ + { value: 0, label: t("certd.normalRun") }, + { value: 1, label: t("certd.skipOnSuccess") }, + ], + }), + form: { + value: 1, + rules: [{ required: true }], + helper: t("certd.defaultRunStrategyHelper"), + show: compute(({ form }) => { + return form.extra.showRunStrategy; + }), + }, + column: { + width: 100, + align: "left", + component: { + color: "auto", + }, + show: false, + }, + valueBuilder({ row }) { + if (row.extra) { + row.extra = yaml.load(row.extra); + } + }, + valueResolve({ row }) { + if (row.extra) { + row.extra = yaml.dump(row.extra); + } + }, + }, + disabled: { + title: t("certd.enableDisable"), + type: "dict-switch", + dict: dict({ + data: [ + { label: t("certd.enabled"), value: false, color: "success" }, + { label: t("certd.disabled"), value: true, color: "error" }, + ], + }), + form: { + title: t("certd.enableDisable"), + value: false, + }, + column: { + width: 120, + align: "center", + component: { + title: t("certd.clickToToggle"), + on: { + async click({ value, row }) { + Modal.confirm({ + title: t("certd.confirm"), + content: `${t("certd.confirmToggle")} ${!value ? t("certd.disable") : t("certd.enable")}?`, + onOk: async () => { + await api.SetDisabled({ + id: row.id, + name: row.name, + type: row.type, + disabled: !value, + }); + await crudExpose.doRefresh(); + }, + }); + }, + }, + }, + }, + }, + group: { + title: t("certd.pluginGroup"), + type: "dict-select", + dict: dict({ + url: "/pi/plugin/groupsList", + label: "title", + value: "key", + }), + form: { + rules: [{ required: true }], + show: compute(({ form }) => { + return form.pluginType === "deploy"; + }), + }, + column: { + width: 100, + align: "left", + component: { + color: "auto", + }, + }, + }, + createTime: { + title: t("certd.createTime"), + type: "datetime", + form: { + show: false, + }, + column: { + sorter: true, + width: 160, + align: "center", + }, + }, + updateTime: { + title: t("certd.updateTime"), + type: "datetime", + form: { + show: false, + }, + column: { + show: true, + }, + }, + }, + }, + }; } diff --git a/packages/ui/certd-client/src/views/sys/plugin/index.vue b/packages/ui/certd-client/src/views/sys/plugin/index.vue index 80e0c21c..c16ab966 100644 --- a/packages/ui/certd-client/src/views/sys/plugin/index.vue +++ b/packages/ui/certd-client/src/views/sys/plugin/index.vue @@ -1,58 +1,63 @@ + diff --git a/packages/ui/certd-client/src/views/sys/settings/email/index.vue b/packages/ui/certd-client/src/views/sys/settings/email/index.vue index df834df8..9c6843d1 100644 --- a/packages/ui/certd-client/src/views/sys/settings/email/index.vue +++ b/packages/ui/certd-client/src/views/sys/settings/email/index.vue @@ -1,73 +1,86 @@ + diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/base.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/base.vue index 1b6ec753..e1982e61 100644 --- a/packages/ui/certd-client/src/views/sys/settings/tabs/base.vue +++ b/packages/ui/certd-client/src/views/sys/settings/tabs/base.vue @@ -1,54 +1,59 @@ + diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue index 8f395eaa..a0464054 100644 --- a/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue +++ b/packages/ui/certd-client/src/views/sys/settings/tabs/register.vue @@ -1,67 +1,78 @@ diff --git a/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue b/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue index f850c9c9..5e3966f7 100644 --- a/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue +++ b/packages/ui/certd-client/src/views/sys/settings/tabs/safe.vue @@ -1,54 +1,63 @@ +