diff --git a/Directory.Packages.props b/Directory.Packages.props index 9040a4840b..4365925adc 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -30,6 +30,7 @@ + diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json index 2bf4bb3837..8f7ed9cd9f 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Account/Localization/Resources/zh-Hans.json @@ -1,16 +1,16 @@ { "culture": "zh-Hans", "texts": { - "Account": "账户", + "Account": "ABP 账户 - 登录和注册 | ABP.IO", "Welcome": "欢迎", - "UseOneOfTheFollowingLinksToContinue": "使用下面的链接继续", - "FrameworkHomePage": "框架首页", + "UseOneOfTheFollowingLinksToContinue": "使用以下链接之一继续", + "FrameworkHomePage": "框架主页", "FrameworkDocumentation": "框架文档", "OfficialBlog": "官方博客", - "CommercialHomePage": "商业版首页", - "CommercialSupportWebSite": "商业版支持网站", - "CommunityWebSite": "ABP社区网站", - "ManageAccount": "我的帐户 | ABP.IO", + "CommercialHomePage": "商业主页", + "CommercialSupportWebSite": "商业支持网站", + "CommunityWebSite": "ABP 社区网站", + "ManageAccount": "我的账户 | ABP.IO", "ManageYourProfile": "管理您的个人资料", "ReturnToApplication": "返回应用" } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json index e2563fe684..49d3753a98 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/en.json @@ -562,6 +562,8 @@ "SponsorLogo": "Sponsor Logo", "RegistrationUrl": "Registration Url", "AllowAbpStudioBetaAccess": "Allow ABP Studio Beta Access", - "TotalQuestionCanNotBeNullMessage": "Total Question can not be null" + "TotalQuestionCanNotBeNullMessage": "Total Question can not be null", + "Permission:EditWinners": "Edit Winners", + "Permission:ChangeDrawingStatus": "Change Drawing Status" } } diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json index 8952533623..59b617ac0b 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Admin/Localization/Resources/zh-Hans.json @@ -1,16 +1,16 @@ { "culture": "zh-Hans", "texts": { - "Permission:Organizations": "组织", + "Permission:Organizations": "组织机构", "Permission:Manage": "管理组织", - "Permission:DiscountRequests": "折扣请求", - "Permission:DiscountManage": "管理折扣请求", + "Permission:DiscountRequests": "折扣申请", + "Permission:DiscountManage": "管理折扣申请", "Permission:Disable": "禁用", - "Permission:Enable": "启动", - "Permission:EnableSendEmail": "启用发送邮件", - "Permission:SendEmail": "发送邮件", - "Permission:NpmPackages": "NPM包", - "Permission:NugetPackages": "Nuget包", + "Permission:Enable": "启用", + "Permission:EnableSendEmail": "启用发送电子邮件", + "Permission:SendEmail": "发送电子邮件", + "Permission:NpmPackages": "NPM 包", + "Permission:NugetPackages": "Nuget 包", "Permission:Maintenance": "维护", "Permission:Maintain": "维护", "Permission:ClearCaches": "清除缓存", @@ -22,27 +22,27 @@ "Permission:Accounting": "账单", "Permission:Accounting:Quotation": "报价", "Permission:Accounting:Invoice": "发票", - "Menu:Organizations": "组织", + "Menu:Organizations": "组织机构", "Menu:Accounting": "账单", "Menu:Packages": "包", - "Menu:DiscountRequests": "折扣请求", - "NpmPackageDeletionWarningMessage": "该NPM包将会被删除. 你确定吗?", - "NugetPackageDeletionWarningMessage": "该Nuget包将会被删除. 你确定吗?", - "ModuleDeletionWarningMessage": "该模块将会被删除. 你确定吗?", + "Menu:DiscountRequests": "折扣申请", + "NpmPackageDeletionWarningMessage": "此 NPM 包将被删除。你确认吗?", + "NugetPackageDeletionWarningMessage": "此 Nuget 包将被删除。你确认吗?", + "ModuleDeletionWarningMessage": "本模块将被删除。您确认吗?", "Name": "名称", "DisplayName": "显示名称", - "ShortDescription": "简述", + "ShortDescription": "简要说明", "NameFilter": "名称", "CreationTime": "创建时间", "IsPro": "是否为专业版", - "IsFreeToActiveLicenseOwners": "许可证所有者免费", - "ShowOnModuleList": "展示模块列表", - "EfCoreConfigureMethodName": "配置方法法", + "IsFreeToActiveLicenseOwners": "免费提供给许可证所有者", + "ShowOnModuleList": "显示在模块列表中", + "EfCoreConfigureMethodName": "配置方法名称", "IsProFilter": "是否为专业版", - "ApplicationType": "应用程序类型", + "ApplicationType": "应用类型", "Target": "目标", "TargetFilter": "目标", - "ModuleClass": "模块分类", + "ModuleClass": "模块类", "NugetPackageTarget.DomainShared": "Domain Shared", "NugetPackageTarget.Domain": "Domain", "NugetPackageTarget.Application": "Application", @@ -55,260 +55,260 @@ "Edit": "编辑", "Delete": "删除", "Refresh": "刷新", - "NpmPackages": "NPM包", - "NugetPackages": "Nuget包", - "NpmPackageCount": "NPM包数量", - "NugetPackageCount": "Nuget包数量", + "NpmPackages": "NPM 包", + "NugetPackages": "Nuget 包", + "NpmPackageCount": "NPM 包数量", + "NugetPackageCount": "Nuget 包数量", "Module": "模块", "ModuleInfo": "模块信息", - "CreateANpmPackage": "创建NPM包", + "CreateANpmPackage": "创建 NPM 包", "CreateAModule": "创建模块", - "CreateANugetPackage": "创建Nuget包", - "AddNew": "新建", - "PackageAlreadyExist{0}": "\"{0}\"已经被添加.", - "ModuleAlreadyExist{0}": "\"{0}\" 模块已经添加.", + "CreateANugetPackage": "创建 Nuget 包", + "AddNew": "添加新内容", + "PackageAlreadyExist{0}": "已添加\"{0}\"包。", + "ModuleAlreadyExist{0}": "已添加\"{0}\"模块。", "ClearCache": "清除缓存", - "SuccessfullyCleared": "清除成功", - "Menu:NpmPackages": "NPM包", + "SuccessfullyCleared": "成功清除", + "Menu:NpmPackages": "NPM 包", "Menu:Modules": "模块", "Menu:Maintenance": "维护", - "Menu:NugetPackages": "Nuget包", - "CreateAnOrganization": "创建新组织", - "Organizations": "组织", + "Menu:NugetPackages": "Nuget 包", + "CreateAnOrganization": "创建组织", + "Organizations": "组织机构", "LongName": "完整名称", - "LicenseType": "授权类型", - "MissingLicenseTypeField": "许可证类型字段是必需的!", - "LicenseStartTime": "授权开始时间", - "LicenseEndTime": "授权结束时间", + "LicenseType": "许可证类型", + "MissingLicenseTypeField": "许可证类型字段为必填字段!", + "LicenseStartTime": "许可证开始时间", + "LicenseEndTime": "许可证结束时间", "AllowedDeveloperCount": "允许的开发人员数量", "UserNameOrEmailAddress": "用户名或电子邮件地址", "AddOwner": "添加所有者", "UserName": "用户名", - "Email": "电子邮件地址", - "Developers": "开发者", - "AddDeveloper": "添加开发者", + "Email": "电子邮件", + "Developers": "开发人员", + "AddDeveloper": "添加开发人员", "Create": "创建", - "UserNotFound": "用户不存在", - "{0}WillBeRemovedFromDevelopers": "{0} 将从开发者中移除, 你确定吗?", - "{0}WillBeRemovedFromOwners": "{0} 将从所有者中移除, 你确定吗?", - "{0}WillBeRemovedFromMembers": "{0} 将从成员中删除, 你确定吗?", + "UserNotFound": "未找到用户", + "{0}WillBeRemovedFromDevelopers": "{0}将从开发人员中删除,您确认吗?", + "{0}WillBeRemovedFromOwners": "{0}将从所有者中删除,你确认吗?", + "{0}WillBeRemovedFromMembers": "{0}将从成员中删除,您确认吗?", "Computers": "计算机", - "UniqueComputerId": "计算机唯一ID", - "LastSeenDate": "上次查看日期", + "UniqueComputerId": "唯一的计算机 ID", + "LastSeenDate": "最后出现日期", "{0}Computer{1}WillBeRemovedFromRecords": "计算机 {0} ({1}) 将从记录中删除", "OrganizationDeletionWarningMessage": "组织将被删除", - "DeletingLastOwnerWarningMessage": "一个组织必须至少有一个所有者!因此你不能删除此所有者", - "This{0}AlreadyExistInThisOrganization": "该组织中已经存在此 {0}", + "DeletingLastOwnerWarningMessage": "一个组织必须至少有一个所有者!因此,您不能删除该所有者", + "This{0}AlreadyExistInThisOrganization": "该{0}已经存在于该组织中", "AreYouSureYouWantToDeleteAllComputers": "您确定要删除所有计算机吗?", - "DeleteAll": "删除所有", - "DoYouWantToCreateNewUser": "你想要创建一个新用户吗", + "DeleteAll": "全部删除", + "DoYouWantToCreateNewUser": "您想创建新用户吗?", "MasterModules": "主模块", "OrganizationName": "组织名称", - "CreationDate": "创建时间", - "LicenseStartDate": "许可开始时间", - "LicenseEndDate": "许可结束时间", + "CreationDate": "创建日期", + "LicenseStartDate": "许可证开始日期", + "LicenseEndDate": "许可证终止日期", "OrganizationNamePlaceholder": "组织名称...", "TotalQuestionCountPlaceholder": "问题总数...", - "RemainingQuestionCountPlaceholder": "剩下的问题数...", - "LicenseTypePlaceholder": "许可类型...", - "CreationDatePlaceholder": "创建时间...", - "LicenseStartDatePlaceholder": "许可开始时间...", - "LicenseEndDatePlaceholder": "许可结束时间...", - "UsernameOrEmail": "用户名或邮箱", - "UsernameOrEmailPlaceholder": "用户名或邮箱...", + "RemainingQuestionCountPlaceholder": "剩余问题数...", + "LicenseTypePlaceholder": "许可证类型...", + "CreationDatePlaceholder": "创建日期...", + "LicenseStartDatePlaceholder": "许可证开始日期...", + "LicenseEndDatePlaceholder": "许可证终止日期...", + "UsernameOrEmail": "用户名或电子邮件", + "UsernameOrEmailPlaceholder": "用户名或电子邮件...", "Member": "成员", - "PurchaseOrderNo": "订单编号", + "PurchaseOrderNo": "订购单编号", "QuotationDate": "报价日期", "CompanyName": "公司名称", "CompanyAddress": "公司地址", "Price": "价格", - "DiscountText": "折扣文字", + "DiscountText": "折扣文本", "DiscountQuantity": "折扣数量", - "DiscountPrice": "折扣价格", - "Quotation": "报价单", - "ExtraText": "额外文字", + "DiscountPrice": "折扣价", + "Quotation": "报价", + "ExtraText": "附加文本", "ExtraAmount": "额外金额", "DownloadQuotation": "下载报价单", "Invoice": "发票", "TaxNumber": "税号", - "InvoiceNumber": "发票数字", + "InvoiceNumber": "发票号码", "InvoiceDate": "发票日期", - "InvoiceNote": "发票说明", + "InvoiceNote": "发票附注", "Quantity": "数量", "AddProduct": "添加产品", - "AddProductWarning": "你需要添加产品", + "AddProductWarning": "您需要添加产品!", "TotalPrice": "总价", "Generate": "生成", - "MissingQuantityField": "数量字段为必填项!", - "MissingPriceField": "价格字段为必填项!", + "MissingQuantityField": "数量字段为必填字段!", + "MissingPriceField": "价格字段为必填字段!", "CodeUsageStatus": "状态", "Country": "国家", - "DeveloperCount": "开发者数量", - "RequestCode": "请求码", + "DeveloperCount": "开发人员数量", + "RequestCode": "申请代码", "WebSite": "网站", - "GithubUsername": "Github用户名", - "PhoneNumber": "手机号", - "ProjectDescription": "产品描述", + "GithubUsername": "Github 用户名", + "PhoneNumber": "电话号码", + "ProjectDescription": "项目说明", "Referrer": "推荐人", - "DiscountRequests": "折扣请求", - "Copylink": "拷贝链接", + "DiscountRequests": "折扣申请", + "Copylink": "复制链接", "Disable": "禁用", "Enable": "启用", - "EnableSendEmail": "启用发送邮件", - "SendEmail": "发送邮件", - "SuccessfullyDisabled": "禁用成功", - "SuccessfullyEnabled": "启用成功", - "EmailSent": "邮件发送", - "SuccessfullySent": "发送成功", - "SuccessfullyDeleted": "删除成功", - "DiscountRequestDeletionWarningMessage": "折扣成功将被删除", - "BusinessType": "商业类型", + "EnableSendEmail": "启用发送电子邮件", + "SendEmail": "发送电子邮件", + "SuccessfullyDisabled": "成功禁用", + "SuccessfullyEnabled": "成功启用", + "EmailSent": "发送电子邮件", + "SuccessfullySent": "成功发送", + "SuccessfullyDeleted": "成功删除", + "DiscountRequestDeletionWarningMessage": "折扣申请将被删除", + "BusinessType": "业务类型", "TotalQuestionCount": "问题总数", "RemainingQuestionCount": "剩余问题数", - "TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount必须大于RemainingQuestionCount!", - "QuestionCountsMustBeGreaterThanZero": "TotalQuestionCount和RemainingQuestionCount必须为0或大于0", - "UnlimitedQuestionCount": "无限的问题计数", - "Notes": "笔记", + "TotalQuestionMustBeGreaterWarningMessage": "TotalQuestionCount 必须大于 RemainingQuestionCount!", + "QuestionCountsMustBeGreaterThanZero": "总问题数(TotalQuestionCount)和剩余问题数(RemainingQuestionCount)必须为零或大于零!", + "UnlimitedQuestionCount": "问题数量不限", + "Notes": "说明", "Menu:Community": "社区", "Menu:Posts": "文章", "Wait": "等待", "Approve": "批准", "Reject": "拒绝", - "Details": "详情", - "Url": "Url", + "Details": "详细信息", + "Url": "网址", "Title": "标题", - "ContentSource": "内容源", + "ContentSource": "内容来源", "Status": "状态", "ReadPost": "阅读文章", - "PostHasBeenWaiting": "文章还在等待", - "PostHasBeenApproved": "文章已被批准", - "PostHasBeenRejected": "文章已被拒绝", + "PostHasBeenWaiting": "文章一直在等待", + "PostHasBeenApproved": "文章已获批准", + "PostHasBeenRejected": "帖子已被拒绝", "Permission:Community": "社区", - "Permission:CommunityPost": "文字", + "Permission:CommunityPost": "文章", "Link": "链接", "Enum:ContentSource:0": "Github", "Enum:ContentSource:1": "外部", - "Enum:Status:0": "等待中", - "Enum:Status:1": "已拒绝", - "Enum:Status:2": "已批准", - "Summary": "概要", - "AuthorName": "作者名称", + "Enum:Status:0": "等待", + "Enum:Status:1": "拒绝", + "Enum:Status:2": "批准", + "Summary": "摘要", + "AuthorName": "作者姓名", "CoverImage": "封面图片", - "RemoveCacheConfirmationMessage": "你确定要删除\"{0}\" 文章缓存?", - "SuccessfullyRemoved": "清除成功", + "RemoveCacheConfirmationMessage": "您确定删除了\"{0}\"文章的缓存吗?", + "SuccessfullyRemoved": "成功清除", "RemoveCache": "删除缓存", "Language": "语言", - "Optional": "可选的", - "CreatePostLanguageInfo": "发帖所用的语言", - "Enum:ContentSource:2": "视频发布", + "Optional": "可选", + "CreatePostLanguageInfo": "帖子所使用的语言", + "Enum:ContentSource:2": "视频", "VideoPreview": "视频预览", - "VideoPreviewErrorMessage": "无法从YouTube获取给定的视频网址. 可能是由于视频是私有视频,或者给定的URL不可用.", + "VideoPreviewErrorMessage": "无法从 Youtube 获取给定的视频 URL。造成这种情况的原因可能是视频为私人视频或给定的 URL 不可用。", "DeleteCoverImage": "删除封面图片", - "DeleteCoverImageConfirmationMessage": "你确定要删除封面图片吗", - "DeleteCoverImageSuccessMessage": "成功删除封面图片", - "PaymentsOf": "付款的", - "ShowPaymentsOfOrganization": "显示付款", + "DeleteCoverImageConfirmationMessage": "您确定要删除\"{0}\"的封面图像吗?", + "DeleteCoverImageSuccessMessage": "封面图像已成功删除", + "PaymentsOf": "支付", + "ShowPaymentsOfOrganization": "付款", "Date": "日期", - "Products": "商品", + "Products": "产品", "TotalAmount": "总金额", "Currency": "货币", "Gateway": "网关", "State": "状态", "FailReason": "失败原因", "ReIndexAllPosts": "重新索引所有帖子", - "ReIndexAllPostsConfirmationMessage": "你确定要重新索引所有的帖子吗", - "SuccessfullyReIndexAllPosts": "成功索引所有的帖子", + "ReIndexAllPostsConfirmationMessage": "您确定要重新索引所有帖子吗?", + "SuccessfullyReIndexAllPosts": "所有帖子都已成功重新索引。", "Permission:FullSearch": "全文检索", - "Menu:CliAnalytics": "客户端分析", - "Menu:Reports": "报表", + "Menu:CliAnalytics": "Cli 分析", + "Menu:Reports": "报告", "TemplateName": "模板名称", "TemplateVersion": "模板版本", "DatabaseProvider": "数据库提供者", - "IsTiered": "是分层的", - "ProjectName": "项目名", + "IsTiered": "是否分层", + "ProjectName": "项目名称", "Username": "用户名", "Tool": "工具", "Command": "命令", - "UiFramework": "界面框架", + "UiFramework": "UI框架", "Options": "选项", - "CliAnalytics": "客户端分析", - "Reports": "报表", - "Permission:CliAnalyticses": "客户端分析", - "Permission:CliAnalytics": "客户端分析", - "Permission:Reports": "报表", + "CliAnalytics": "Cli 分析", + "Reports": "报告", + "Permission:CliAnalyticses": "Cli Analyticses", + "Permission:CliAnalytics": "Cli 分析", + "Permission:Reports": "报告", "Search": "搜索", - "ClearFilter": "清除过滤", - "LicensePrivateKey": "许可私有密钥", - "LicensePublicKey": "许可公有密钥", - "ApiKey": "NuGet API密钥", - "ShowInvoiceRequestsOfOrganization": "发票请求", + "ClearFilter": "清除过滤器", + "LicensePrivateKey": "许可证私钥", + "LicensePublicKey": "许可证公钥", + "ApiKey": "NuGet API 密钥", + "ShowInvoiceRequestsOfOrganization": "发票申请", "ShowQuestionsOfOrganization": "问题", "Question": "问题", - "Open": "打开", + "Open": "开放", "Questions": "问题", - "InvoiceRequests": "发票请求", + "InvoiceRequests": "发票申请", "Address": "地址", "TaxNo": "税号", - "Permission:InvoiceRequest": "发票请求", + "Permission:InvoiceRequest": "发票申请", "Permission:Question": "问题", - "AddNoteSuccessMessage": "注释添加成功", - "NameSurname": "姓", - "Note": "注释", + "AddNoteSuccessMessage": "成功添加注释", + "NameSurname": "姓名", + "Note": "备注", "Add": "添加", "ProjectDownloads": "项目下载", "ShowProjectDownloadsOfOrganization": "项目下载", - "ShowAuditLogsOfOrganization": "审核日志", - "Enum:EntityChangeType:0": "已建立", - "Enum:EntityChangeType:1": "更新", + "ShowAuditLogsOfOrganization": "审计日志", + "Enum:EntityChangeType:0": "创建", + "Enum:EntityChangeType:1": "已更新", "Enum:EntityChangeType:2": "已删除", - "TenantId": "租户ID", - "ChangeTime": "变更时间", + "TenantId": "租户编号", + "ChangeTime": "更改时间", "EntityTypeFullName": "实体类型全名", - "AuditLogsFor{0}Organization": "\"{0}\" 组织的审核日志", + "AuditLogsFor{0}Organization": "{0}\"组织的审计日志", "Permission:EntityChange": "实体变更", "Permission:ProjectDownload": "项目下载", - "Permission:PaymentRequest": "支付请求", - "CreatorEmailAddress": "创作者的电子邮件地址", + "Permission:PaymentRequest": "付款申请", + "CreatorEmailAddress": "创建者电子邮件地址", "EmailSendDate": "电子邮件发送日期", - "PaymentRequestsFor{0}Organization": "\"{0}\" 组织的付款请求", + "PaymentRequestsFor{0}Organization": "{0}\"组织的付款申请", "PaymentDetails": "付款详情", "PaymentProduct": "付款产品", "ProductName": "产品名称", "Code": "代码", "GenerateInvoice": "生成发票", - "ExportOrganizationsToExcel": "将组织导出到Excel", - "ThisExtensionIsNotAllowed": "不允许此扩展名.", - "TheFileIsTooLarge": "文件过大.", - "PostDeletionConfirmationMessage": "您确定要硬删除这篇文章吗?", - "ChooseCoverImage": "选项一张封面图片", - "Menu:Quotation": "引述", + "ExportOrganizationsToExcel": "导出到 Excel", + "ThisExtensionIsNotAllowed": "不允许延期。", + "TheFileIsTooLarge": "文件太大!", + "PostDeletionConfirmationMessage": "你确定要硬删掉这个帖子吗?", + "ChooseCoverImage": "选择封面图片...", + "Menu:Quotation": "报价", "Menu:Invoice": "发票", - "Menu:PaymentRequests": "付款请求", - "Permission:PaymentRequests": "付款请求", - "PaymentRequests": "付款请求", - "Creator": "创造者", + "Menu:PaymentRequests": "付款申请", + "Permission:PaymentRequests": "付款申请", + "PaymentRequests": "付款申请", + "Creator": "创作者", "ExtraProperties": "额外属性", - "Organization": "组织", + "Organization": "组织结构", "Waiting": "等待", - "Completed": "完全的", - "Failed": "失败的", - "PaymentRequestDeletionWarningMessage": "此付款请求将被删除。你确认吗?", - "Payment": "支付", + "Completed": "已完成", + "Failed": "失败", + "PaymentRequestDeletionWarningMessage": "此付款申请将被删除。您确认吗?", + "Payment": "付款方式", "AddPayment": "添加付款", - "Enum:PurchaseType:1": "新执照", - "Enum:PurchaseType:2": "许可证延长", + "Enum:PurchaseType:1": "新许可证", + "Enum:PurchaseType:2": "许可证扩展", "Enum:PurchaseType:3": "许可证升级", - "Enum:PurchaseType:4": "附加开发人员", + "Enum:PurchaseType:4": "其他开发人员", "LicenceType": "许可证类型", "PurchaseType": "购买类型", - "ReceiptNo": "收据号", + "ReceiptNo": "收据编号", "PaymentTime": "付款时间", "ProductPrice": "产品价格", - "AdditionalDeveloper": "附加开发人员", - "ThisPaymentHasBeenAlreadyUsed": "此付款已被使用", + "AdditionalDeveloper": "其他开发人员", + "ThisPaymentHasBeenAlreadyUsed": "该款项已被使用", "PaymentTimeCannotBeFutureTime": "付款时间不能是未来时间!", - "SaveAndDownload": "保存并下载", - "BillingInfo": "计费信息", + "SaveAndDownload": "保存和下载", + "BillingInfo": "账单信息", "DeleteInvoice": "删除发票", "PaymentStateSetTo": "付款状态设置为 {0}", "ChangeState": "更改状态", @@ -316,248 +316,248 @@ "Menu:TrialLicenses": "试用许可证", "TrialLicenses": "试用许可证", "UserNameFilter": "用户名", - "TrialLicenseStatusFilter": "地位", + "TrialLicenseStatusFilter": "状态", "TrialLicenseStartDateFilter": "开始日期", "TrialLicenseEndDateFilter": "结束日期", - "FirstName": "名字", - "LastName": "姓", + "FirstName": "姓名", + "LastName": "姓氏", "StartDate": "开始日期", "EndDate": "结束日期", "PurchasedDate": "购买日期", - "OrganizationDetail": "组织详情", + "OrganizationDetail": "机构详情", "TrialLicenseStatus": "试用许可证状态", "TrialLicenseDetail": "试用许可证详情", "AcceptsMarketingCommunications": "营销传播", "PurposeOfUsage": "使用目的", - "CountryName": "国家的名字", + "CountryName": "国家名称", "CompanySize": "公司规模", - "DetailTrialLicense": "细节", - "Requested": "已请求", - "Activated": "活性", + "DetailTrialLicense": "详细信息", + "Requested": "要求", + "Activated": "已激活", "PurchasedToNormalLicense": "已购买", - "Expired": "已到期", - "TrialLicenseDeletionWarningMessage": "您确定要删除试用许可证吗?试用许可证、组织、支持帐户将被删除!", - "LicenseCategoryFilter": "执照类别", - "Permission:SendWelcomeEmail": "发送欢迎邮件", - "SendWelcomeEmail": "发送欢迎邮件", - "SendWelcomeEmailWarningMessage": "你确定要发送欢迎邮件给组织成员吗?", - "SendWelcomeEmailSuccessMessage": "欢迎邮件发送成功!", + "Expired": "已过期", + "TrialLicenseDeletionWarningMessage": "您确定要删除试用许可证吗?试用版许可证、组织和支持账户将被删除!", + "LicenseCategoryFilter": "许可证类别", + "Permission:SendWelcomeEmail": "发送欢迎电子邮件", + "SendWelcomeEmail": "发送欢迎电子邮件", + "SendWelcomeEmailWarningMessage": "您确定要向组织成员发送欢迎电子邮件吗?", + "SendWelcomeEmailSuccessMessage": "欢迎电子邮件已成功发送!", "Activate": "激活", - "ActivateTrialLicenseWarningMessage": "激活试用版权限后,将发送欢迎邮件给用户。你确定要激活吗?", - "ActivateTrialLicenseSuccessMessage": "激活成功,欢迎邮件已发送给组织成员。", - "PaymentRequestId": "付款请求编号", - "AdditionalDeveloperCount": "额外开发者数量", - "LicensePrice": "版权价格", + "ActivateTrialLicenseWarningMessage": "激活试用许可证时,将向用户发送一封欢迎电子邮件。您要激活吗?", + "ActivateTrialLicenseSuccessMessage": "已成功激活,并向组织成员发送了欢迎电子邮件。", + "PaymentRequestId": "付款申请编号", + "AdditionalDeveloperCount": "额外的开发人员数量", + "LicensePrice": "许可证价格", "PurchaseDate": "购买日期", - "IsAbpBookDownloaded": "ABP书籍已下载", - "IsMasteringAbpBookDownloadEnabled": "ABP书籍下载已启用", + "IsAbpBookDownloaded": "掌握ABP图书已下载?", + "IsMasteringAbpBookDownloadEnabled": "已启用 ABP 图书下载", "Permission:Accounting:CustomPaymentLinkGenerator": "自定义付款链接", "CustomPaymentLink": "自定义付款链接", "Menu:CustomPaymentLink": "自定义付款链接", "Amount": "金额", "GenerateCustomPaymentLink": "生成自定义付款链接", - "GeneratedPaymentLink": "生成的付款链接", + "GeneratedPaymentLink": "生成付款链接", "CopyText": "复制文本", "Permission:CommunityEvents": "活动", "Menu:Events": "活动", "Events": "活动", "EventType": "活动类型", "Number": "数量", - "RegistrationURL": "报名网址", + "RegistrationURL": "注册网址", "URL": "网址", - "EventDeletionConfirmationMessage": "你确定要删除这个活动吗?", - "Enum:EventType:0": "社区讲话", - "CreateAnEvent": "创建一个活动", - "Permission:CommunitySpeakers": "演讲者", - "CreateASpeaker": "创建一个演讲者", - "Speakers": "演讲者", + "EventDeletionConfirmationMessage": "您确定要删除此事件吗?", + "Enum:EventType:0": "社区讲座", + "CreateAnEvent": "创建活动", + "Permission:CommunitySpeakers": "讲师", + "CreateASpeaker": "创建讲师", + "Speakers": "讲师", "Image": "图片", - "GithubURL": "Github网址", - "SpeakerDeletionConfirmationMessage": "你确定要删除这个演讲者吗?", - "Menu:Speakers": "演讲者", - "ChooseSpeakerImage": "选择一个演讲者图片...", - "SpeakerImage": "演讲者图片", - "AddSpeaker": "添加演讲者", + "GithubURL": "Github URL", + "SpeakerDeletionConfirmationMessage": "您确定要删除这个讲师吗?", + "Menu:Speakers": "讲师", + "ChooseSpeakerImage": "选择讲师图像...", + "SpeakerImage": "讲师图像", + "AddSpeaker": "添加讲师", "ShowPurchaseItemsOfOrganizations": "购买项目", - "Enum:OrganizationPurchaseState:0": "未送达", - "Enum:OrganizationPurchaseState:1": "已送达", + "Enum:OrganizationPurchaseState:0": "未交付", + "Enum:OrganizationPurchaseState:1": "已交付", "PurchaseItems": "购买项目", "SuccessfullyUpdated": "成功更新", "SuccessfullyAdded": "成功添加", "PurchaseState": "购买状态", - "ShowBetweenDayCount": "显示之间的天数", - "PurchaseOrder": "购买订单", + "ShowBetweenDayCount": "日间演出", + "PurchaseOrder": "采购订单", "ShowCreateInvoiceOfOrganization": "创建发票", "ShowCreateQuotationOfOrganization": "创建报价单", - "BookDiscounts": "书籍折扣", - "Permission:BookDiscount": "书籍折扣", - "Menu:BookDiscounts": "书籍折扣", + "BookDiscounts": "图书折扣", + "Permission:BookDiscount": "图书折扣", + "Menu:BookDiscounts": "图书折扣", "BookType": "书籍类型", "PurchasePlatform": "购买平台", "StartTime": "开始时间", "EndTime": "结束时间", - "CreateABookDiscount": "创建一个书籍折扣", - "BookDiscountDeletionConfirmationMessage": "你确定要删除这个书籍折扣吗?", - "CustomPaymentFlexSwitchDescription": "授权", - "AllowFeatureUpgradeOnLicenseExpire": "允许在授权过期时进行功能升级", - "Deleted{0}": "[已删除 {0}]", + "CreateABookDiscount": "创建图书折扣", + "BookDiscountDeletionConfirmationMessage": "您确定要删除此图书折扣吗?", + "CustomPaymentFlexSwitchDescription": "有许可证", + "AllowFeatureUpgradeOnLicenseExpire": "许可证到期时允许功能升级", + "Deleted{0}": "[删除{0}]", "Tags": "标签", - "SetTagsInfo": "标签使用逗号分隔,例如:CSharp, Entity Framework", - "RejectTrialLicenseWarningMessage": "您确定要拒绝这个试用许可证申请吗?", - "ExportToExcel": "导出Excel", + "SetTagsInfo": "标签应以逗号分隔。例如:CSharp、实体框架", + "RejectTrialLicenseWarningMessage": "您确定要拒绝此试用许可申请吗?", + "ExportToExcel": "导出到 Excel", "OverallTotalPrice": "总价", - "OverallDiscountPrice": "折扣价", - "OverallDiscountText": "折扣内容", - "SelectReport": "- 选择报表 -", + "OverallDiscountPrice": "总折扣价", + "OverallDiscountText": "整体折扣文本", + "SelectReport": "- 选择报告", "NoDataAvailable": "无数据", - "StatisticsOfCachedContents": "nuget.abp.io缓存的NuGet包内容统计", + "StatisticsOfCachedContents": "nuget.abp.io 缓存的 NuGet 包内容统计", "Compact": "紧凑型", "EditSettings": "编辑设置", - "CurrentEstimatedSize": "当前预计规模", - "CurrentEntryCount": "当前数量", - "TotalHits": "点击量", - "TotalMisses": "未命中总数", - "NoResponseFrom": "没有收到任何答复", - "ContentCacheSlidingExpirationByDay": "内容缓存按天滑动过期", - "MaxDaysForCaching": "缓存的最大天数", - "Enabled": "启用", - "Menu:NugetPackagesContentCache": "NuGet包缓存", - "NugetPackagesContentCache": "NuGet内容缓存", - "SlidingExpritionByDayInfo": "获取或设置一个缓存在多长时间内不活动(例如,不被访问)才会被删除。这不会使期超过绝对到期时间。", - "MaxDaysForCachingInfo": "获取或设置相对于当前时间的绝对过期时间。", - "CurrentEstimatedSizeInfo": "当前在内存缓存中的所有NuGet包的内容大小的估计总和", - "CurrentEntryCountInfo": "当前在内存缓存中的实例数量。", - "TotalHitsInfo": "缓存未命中总数,当从缓存请求文件并且缓存能够满足该请求时,就会发生缓存命中。。", - "TotalMissesInfo": "缓存命中的总数,缓存未命中是指缓存中不包含请求的内容。", + "CurrentEstimatedSize": "目前的预计规模", + "CurrentEntryCount": "当前条目计数", + "TotalHits": "命中量", + "TotalMisses": "未命中量", + "NoResponseFrom": "没有答复", + "ContentCacheSlidingExpirationByDay": "内容缓存按天滑动到期", + "MaxDaysForCaching": "缓存最长天数", + "Enabled": "已启用", + "Menu:NugetPackagesContentCache": "NuGet 缓存", + "NugetPackagesContentCache": "NuGet 内容缓存", + "SlidingExpritionByDayInfo": "获取或设置缓存条目在多长时间内处于非活动状态(如未被访问)才会被删除。这不会使条目生命周期超出绝对过期时间。", + "MaxDaysForCachingInfo": "获取或设置相对于现在的绝对到期时间。", + "CurrentEstimatedSizeInfo": "表示当前内存缓存中所有 NuGet 包内容大小的估计总和", + "CurrentEntryCountInfo": "表示当前内存缓存中的实例数量。", + "TotalHitsInfo": "表示缓存未命中的总数。缓存命中是指从缓存请求文件,而缓存能够满足该请求。", + "TotalMissesInfo": "表示缓存点击总数。缓存未命中是指缓存中没有请求的内容。", "Permission:VersionHistory": "版本历史", "Caches": "缓存", "VersionHistories": "版本历史", "Version": "版本", - "PublishDate": "发布日期", + "PublishDate": "发布 日期", "IsStableVersion": "稳定版", - "IsActive": "激活", + "IsActive": "活跃", "NewVersion": "新版本", "VersionHistoryDeletionConfirmationMessage": "您确定要删除此版本吗?", - "CreateAbpConsultantLogoInfo": "最大文件大小:1MB
支持的文件类型:jpg, jpeg, png, SVG, WebP", - "UrlCode": "许可证代码", + "CreateAbpConsultantLogoInfo": "最大文件大小:1MB
支持的文件类型:jpg、jpeg、png、SVG、WebP条款 & 条件 和 隐私政策。", "FreeDDDEBook": "免费 DDD 电子书", - "AdditionalServices": "额外服务", + "AdditionalServices": "附加服务", "Learn": "学习", - "AccountOverview": "账户信息", + "AccountOverview": "账户概览", "MyOrganizations": "我的组织", "MySupportQuestions": "我的支持问题", "MyProfile": "我的简介", - "Logout": "登出", - "Home": "主页", + "Logout": "注销", + "Home": "首页", "Posts": "帖子", "Videos": "视频", "JoinTheABPCommunity": "加入 ABP 社区", "SubmitYourPost": "提交您的帖子", "Modules": "模块", "Tools": "工具", - "Pricing": "价格", + "Pricing": "定价", "ChangeLogs": "更改日志", "SubscribeToNewsletter": "订阅时事通讯", - "SubscribeToNewsletterDescription": "获取有关 ABP 的最新相关信息,例如新版本、免费资源、帖子等。", - "EmailAddress": "邮箱地址", + "SubscribeToNewsletterDescription": "获取有关 ABP 的最新相关信息,如新版本、免费资源、帖子等。", + "EmailAddress": "电子邮件地址", "Subscribe": "订阅", "WelcomeToABP": "欢迎来到 ABP", - "EULA": "最终用户许可协议", - "ABPCommercialIntroductionMessage": "预建应用程序模块、高级启动模板、快速应用程序开发工具、专业 UI 主题和高级支持。", + "EULA": "EULA", + "ABPCommercialIntroductionMessage": "预构建应用模块、高级启动模板、快速应用开发工具、专业UI主题和优质支持。", "MasteringAbpFrameworkEBook": "掌握 ABP 框架", - "MasteringTheABPFrameworkExplanation": "本书由 ABP 框架的创建者撰写,将帮助您全面了解框架和现代 Web 应用程序开发技术。", - "Speakers": "发言者", + "MasteringTheABPFrameworkExplanation": "本书由 ABP 框架的创建者撰写,将帮助你全面了解该框架和现代Web应用程序开发技术。", + "Speakers": "发言人", "PreviousEvents": "以往活动", "WatchTheEvent": "观看活动", - "RegisterNow": "现在注册", + "RegisterNow": "立即注册", "ThereIsNoEvent": "没有活动。", "Events": "活动", - "Volo.AbpIo.Domain:080000": "已有一个名为 \"{Name}\" 的购买项目", - "MasteringAbpFrameworkBook": "书籍:掌握 ABP 框架", - "ABPIO-CommonPreferenceDefinition": "获取有关 ABP 平台的最新消息,例如新帖子、活动等。", + "Volo.AbpIo.Domain:080000": "已有一个名为\"{Name}\"的采购项目", + "MasteringAbpFrameworkBook": "书籍掌握 ABP 框架", + "ABPIO-CommonPreferenceDefinition": "获取有关 ABP 平台的最新消息,如新帖子、活动等。", "BuiltOn": "建立在", "AbpFramework": "ABP 框架", "Volo.AbpIo.Domain:080001": "开始时间不能大于结束时间", "Enum:BookType:0": "掌握 ABP 框架", "Enum:PurchasePlatform:0": "亚马逊", - "Enum:PurchasePlatform:1": "Packt", + "Enum:PurchasePlatform:1": "包装", "Copied": "已复制!", "CouldNotCopy": "无法复制!", "CopyNotSupportByYourBrowser": "此功能在您使用的浏览器中不起作用。", @@ -141,93 +141,93 @@ "Address": "地址", "Homepage": "主页", "Year": "年份", - "Year_Plural": "年份", + "Year_Plural": "年数", "Copyright": "版权所有 © {1}", "DomainDrivenDesign": "领域驱动设计", "CrossCuttingConcerns": "横切关注点", "AbpCommunity": "ABP 社区", - "Footer_GithubStarCount": "{0} GitHub 上的星星", - "Footer_NugetDownloadCount": "{0} NuGet 下载量", - "AbpDescription": "ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的 Web 应用程序开发。 Don't repeat yourself,专注于自己的业务代码。", - "Layout_AbpFramework_MetaTitle": "ABP 框架 | ASP.NET Core 的开源 Web 应用程序框架", - "CommunityTalks_CountdownDays": "天", + "Footer_GithubStarCount": "{0} GitHub 上的 Star", + "Footer_NugetDownloadCount": "{0} 在 NuGet 上下载", + "AbpDescription": "ABP 是一个开源应用程序框架,专注于基于 AspNet Core 的Web应用程序开发。不要重复自己,专注于自己的业务代码。", + "Layout_AbpFramework_MetaTitle": "ABP Framework | 面向 ASP.NET Core 的开源Web应用框架", + "CommunityTalks_CountdownDays": "天数", "CommunityTalks_CountdownHours": "小时", "CommunityTalks_CountdownMinutes": "分钟", "CommunityTalks_CountdownSeconds": "秒", - "SeePreviousEvents": "查看以前的活动", + "SeePreviousEvents": "查看以往活动", "CookieConsent_Accept": "接受", - "CookieConsent_Explanation_1": "我们使用 cookie 为您提供在我们网站上的最佳体验。", - "CookieConsent_Explanation_2": "如果您继续浏览,则表示您同意我们的隐私政策和cookie 政策。。", - "Error_Page_400_Title": "提供请求的页面时出现问题。", + "CookieConsent_Explanation_1": "我们使用 cookie 为您提供最佳的网站体验。", + "CookieConsent_Explanation_2": "如果您继续浏览,则表示您同意我们的隐私政策和 Cookie 政策。", + "Error_Page_400_Title": "请求的页面服务出现问题。", "Error_Page_400_Description_1": "通常这意味着在处理您的请求时发生了意外错误。", - "Error_Page_400_Description_2": "如果问题仍然存在,请通过 info@abp.io 联系我们,我们将帮助您开始。", - "GoToHomepage": "去首页", - "Error_Page_404_Title": "页面未找到!", - "Error_Page_404_Description_1": "这不是您要查找的网页。", - "Error_Page_500_Title": "好像出了什么问题!", - "Error_Page_500_Description_1": "我们会自动跟踪这些错误,但如果问题仍然存在,请随时
联系我们。 与此同时,尝试刷新。", - "Error_Page_500_Description_2": "通过 info@abp.io 与我们联系。", + "Error_Page_400_Description_2": "如果问题仍然存在,请通过info@abp.io联系我们,我们将帮助您解决问题。", + "GoToHomepage": "转到主页", + "Error_Page_404_Title": "未找到页面!", + "Error_Page_404_Description_1": "这不是您要找的网页。", + "Error_Page_500_Title": "看来是出了什么问题!", + "Error_Page_500_Description_1": "我们会自动跟踪这些错误,但如果问题仍然存在,请随时
联系我们。同时,请尝试刷新。", + "Error_Page_500_Description_2": "请通过 info@abp.io 与我们联系。", "Books": "书籍", "ABPDiscordServer": "ABP Discord 服务器", - "ABPCommunityTalks": "ABP社区讲话", - "ABPCommunityPosts": "ABP社区文章", - "BuyAndGetMonths": "购买 12 个月,获得 14 个月!", - "GetYourDeal": "得到你的交易", - "BuyOrRenewLicense": "立即购买或续订许可证并额外获得 2 个月!", - "BuyOrRenewLicenseToGetExtra2Months": "立即购买或续订 ABP 商业许可证(适用于所有版本)并额外获得 2 个月!", + "ABPCommunityTalks": "ABP 社区讲座", + "ABPCommunityPosts": "ABP 社区帖子", + "BuyAndGetMonths": "买 12 个月,送 14 个月!黑色 星期五", - "ValidForExistingCustomers": "也适用于
现有用户!", - "CampaignBetweenDates": "从 {0}
至 {1}", - "SaveUpTo": "最多节省${0}K", - "ImplementingDDD": "实现领域驱动设计", - "ExploreTheEBook": "浏览电子书", - "ExploreTheBook": "浏览书籍", - "ConsultantType": "顾问类型", - "Expert": "ABP专家", - "Partner": "ABP合作伙伴", + "GiveAwayForNewPurchases": "新购买的产品将获赠应用开发课堂培训!", + "BlackFriday": "黑色 星期五 现有客户!", + "CampaignBetweenDates": "从 {0}
到 {1}", + "SaveUpTo": "节省高达${0}K", + "ImplementingDDD": "实施领域驱动设计", + "ExploreTheEBook": "探索电子书", + "ExploreTheBook": "探索图书", + "ConsultantType": "咨询类型", + "Expert": "ABP 专家", + "Partner": "ABP 合作伙伴", "Industry": "行业", "Location": "地点", - "Contact": "联系", - "Partner_Year": "合作年份", + "Contact": "联系方式", + "Partner_Year": "伙伴关系年", "Info": "信息", - "SpokenLanguages": "母语", + "SpokenLanguages": "口语", "SocialMedia": "社交媒体", "Activity": "活动", "Type": "类型", "Contribution": "贡献", "WhoWeAre": "关于我们", "Icons": "图标", - "Url": "Url", + "Url": "网址", "Icon": "图标", - "RecentActivities": "最近的活动", + "RecentActivities": "近期活动", "SpringCampaign": "欢迎
春季促销!", - "SpringCampaign2": "限时优惠!
", + "SpringCampaign2": "限时
优惠!个额外月份
", + "More": "更多信息", + "WhyABPIOPlatform": "为什么选择 ABP.IO 平台?", + "AbpStudio": "ABP Studio", + "ExtraMonths": "{0}额外的一个月一个完整的web开发平台基于 框架", - "AbpCommercialShortDescription": "ABP商业版提供了预构建的应用程序模块, 快速的应用程序开发工具, 专业的UI主题, 高级支持等.", + "AbpCommercialShortDescription": "ABP Commercial 提供预建应用程序模块、快速应用程序开发工具、专业UI主题、优质支持等。", "LiveDemo": "在线演示", - "LiveDemoLead": "{1} 到你的ABP账户, {3} 到 abp.io.
或者填写下面的表单立即创建在线演示", - "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "已经有一个使用此电子邮件地址的帐户: {0}
你可以使用你的帐户登录继续.", - "GetLicence": "获得许可", + "LiveDemoLead": "{1}使用您的 ABP 帐户,{3}访问 abp.io。
或填写下表,立即创建在线演示。", + "ThereIsAlreadyAnAccountWithTheGivenEmailAddress": "已存在使用给定电子邮件地址的帐户:{0}
您可以使用您的账户登录,然后继续。", + "GetLicence": "获取许可证", "Application": "应用程序", "StartupTemplates": "启动模板", "Startup": "启动", @@ -65,29 +65,29 @@ "Themes": "主题", "JoinOurNewsletter": "加入我们的时事通讯", "Send": "发送", - "WhatIsABPFramework": "什么是ABP框架?", - "OpenSourceBaseFramework": "开源的框架", - "ABPFrameworkExplanation": "

ABP商业版基于ABP框架, 这是一个开源和社区驱动的ASP.NET Core web应用程序开发框架.

ABP框架提供了出色的基础设施, 使用最佳实践编写可维护,可扩展,可测试的代码.

基于你已经知道的流行工具. 低学习曲线,容易适应,舒适的开发体检.

", + "WhatIsABPFramework": "什么是 Abp 框架?", + "OpenSourceBaseFramework": "开源框架", + "ABPFrameworkExplanation": "

ABP商业版基于ABP框架,ABP框架是面向ASP.NET Core的开源和社区驱动的Web程序框架。

ABP框架提供了出色的基础架构,可帮助您使用最佳实践编写可维护、可扩展和可测试的代码。学习曲线低、适应简单、开发舒适。", "Modular": "模块化", - "MicroserviceCompatible": "微服务兼容", + "MicroserviceCompatible": "兼容微服务", "DomainDrivenDesignInfrastructure": "领域驱动设计基础设施", "MultiTenancy": "多租户", - "DistributedMessaging": "分布式消息", + "DistributedMessaging": "分布式信息", "DynamicProxying": "动态代理", "BackgroundJobs": "后台作业", "AuditLogging": "审计日志", - "BLOBStoring": "BLOB存储", + "BLOBStoring": "BLOB 存储", "BundlingMinification": "捆绑 & 压缩", "AdvancedLocalization": "高级本地化", - "ManyMore": "以及更多", - "ExploreTheABPFramework": "探索ABP框架", - "WhyUseTheABPCommercial": "为什么使用ABP商业版?", + "ManyMore": "更多", + "ExploreTheABPFramework": "探索 ABP 框架", + "WhyUseTheABPCommercial": "为什么使用 ABP 商业版?", "WhyUseTheABPCommercialExplanation": "

构建企业级的web应用程序可能复杂和耗时.

ABP商业版提供所有现代企业级基于ASP.NET Core的解决方案所需要的基础设施. 从设计到部署,整个开发生命周期都由ABP的内置功能和模块提供支持.

", - "StartupTemplatesShortDescription": "启动模板使你在几秒内快速启动项目.", - "UIFrameworksOptions": "UI框架选项;", - "DatabaseProviderOptions": "数据库提供程序选项;", - "PreBuiltApplicationModules": "预构建的应用程序模块", - "PreBuiltApplicationModulesShortDescription": "大多数常见的应用程序需求已经做为可重用的模块为你开发了.", + "StartupTemplatesShortDescription": "启动模板可让您在几秒钟内快速启动项目。", + "UIFrameworksOptions": "UI框架选项;", + "DatabaseProviderOptions": "数据库提供商选项;", + "PreBuiltApplicationModules": "预建应用模块", + "PreBuiltApplicationModulesShortDescription": "大多数常见的应用需求已作为可重用的模块为您开发。", "Account": "账户", "Blogging": "博客", "Identity": "Identity", @@ -95,754 +95,997 @@ "Saas": "Saas", "LanguageManagement": "语言管理", "TextTemplateManagement": "文本模板管理", - "See All Modules": "查看所有的模块", + "See All Modules": "查看所有模块", "ABPSuite": "ABP Suite", - "AbpSuiteShortDescription": "ABP Suite是ABP商业版的辅助工具.", - "AbpSuiteExplanation": "它让你在几分钟内构建web页面. 它是一个.Net Core全局工具,可以使用命令行安装. 它可以创建一个新的ABP解决方案,从数据库生成前端CURD页面.", - "Details": "详情", - "LeptonTheme": "Lepton主题", - "ProfessionalModernUIThemes": "专业, 现代化的UI主题", - "LeptonThemeExplanation": "Lepton提供了一系列的Bootstrap管理主题,为任何需要管理仪表盘的项目提供了坚实的基础.", + "AbpSuiteShortDescription": "ABP Suite 是 ABP 商业软件的辅助工具。", + "AbpSuiteExplanation": "它能让你在几分钟内创建web页面。它是一个 .NET Core Global 工具,可通过命令行安装。它可以创建一个新的 ABP 解决方案,并生成从数据库到前端的 CRUD 页面。", + "Details": "详细信息", + "LeptonTheme": "Lepton 主题", + "ProfessionalModernUIThemes": "专业、现代的UI主题", + "LeptonThemeExplanation": "Lepton 提供各种 Bootstrap 管理主题,为任何需要管理仪表板的项目奠定了坚实的基础。", "DefaultTheme": "默认主题", "MaterialTheme": "Material主题", "Default2Theme": "默认主题2", "DarkTheme": "深色主题", - "DarkBlueTheme": "深蓝主题", + "DarkBlueTheme": "深蓝色主题", "LightTheme": "浅色主题", "ProudToWorkWith": "荣幸与你合作", - "OurConsumers": "全球70多个国家的数百家企业和开发商使用ABP商业版.", - "JoinOurConsumers": "加入他们并快速构建令人惊叹的产品.", - "AdditionalServicesExplanation": "你是否需要额外或自定义的服务? 我们和我们的合作伙伴可以提供;", - "CustomProjectDevelopment": "自定义项目开发", - "CustomProjectDevelopmentExplanation": "专为你的自定义的开发人员.", + "OurConsumers": "全球 70 多个国家数以千计的企业和开发者信赖 ABP Commercial。", + "JoinOurConsumers": "加入他们,快速打造令人惊叹的产品。", + "AdditionalServicesExplanation": "您需要额外或定制服务吗? 我们和我们的合作伙伴可以提供:", + "CustomProjectDevelopment": "定制项目开发", + "CustomProjectDevelopmentExplanation": "为您的定制项目提供专门的开发人员。", "PortingExistingProjects": "移植现有项目", - "PortingExistingProjectsExplanation": "将你的迁移传统项目迁移到ABP平台.", + "PortingExistingProjectsExplanation": "将传统项目迁移到 ABP 平台。", "LiveSupport": "实时支持", - "LiveSupportExplanation": "在你需要时,可以实时提供远程支持选项.", + "LiveSupportExplanation": "在您需要时提供实时远程支持。", "Training": "培训", - "TrainingExplanation": "为你的开发人员提供专门培训.", - "OnBoarding": "管理", - "OnBoardingExplanation": "帮助设置你的开发,CI和CD环境.", - "PrioritizedTechnicalSupport": "优先的技术支持", - "PremiumSupportExplanation": "除了社区对ABP框架出色支持外,我们的支持团队会优先回答商业用户的技术问题.", + "TrainingExplanation": "为您的开发人员提供专门培训。", + "OnBoarding": "引导流程", + "OnBoardingExplanation": "帮助您设置开发、CI 和 CD 环境。", + "PrioritizedTechnicalSupport": "优先技术支持", + "PremiumSupportExplanation": "除了 ABP 框架强大的社区支持外,我们的支持团队还会优先回答商业用户的技术问题。", "SeeTheSupportOptions": "查看支持选项", - "Contact": "联系", - "TellUsWhatYouNeed": "告诉我们你需要什么.", - "YourMessage": "你的消息", - "YourFullName": "你的全名", - "FirstNameField": "名字", + "Contact": "联系方式", + "TellUsWhatYouNeed": "告诉我们您的需求。", + "YourMessage": "您的信息", + "YourFullName": "您的全名", + "FirstNameField": "姓名", "LastNameField": "姓氏", - "EmailField": "E-mail地址", - "YourEmailAddress": "你的e-mail地址", - "ValidEmailAddressIsRequired": "请输入有效的e-mail地址", - "HowMayWeHelpYou": "需要获得购买帮助?(提供中文服务)", - "SendMessage": "发送消息", + "EmailField": "电子邮件地址", + "YourEmailAddress": "您的电子邮件地址", + "ValidEmailAddressIsRequired": "需要有效的电子邮件地址。", + "HowMayWeHelpYou": "我们能为您提供哪些帮助?", + "SendMessage": "发送信息", "Success": "成功", - "WeWillReplyYou": "你的消息已经发送! 我们会在短时间内给你答复.", + "WeWillReplyYou": "我们收到了您的留言,将尽快与您联系。", "GoHome": "回到主页面", "CreateLiveDemo": "创建在线演示", - "CreateLiveDemoDescription": "一旦你提交此表单,你将收到一封包含你的演示链接的电子邮件.", - "RegisterToTheNewsletter": "注册到时事简报以获取有关ABP.IO的消息,比如新发布的内容.", - "EnterYourEmailOrLogin": "输入你的e-mail地址来创建你的演示或者使用你的已有账号登录.", - "ApplicationTemplate": "应用程序模板", - "ApplicationTemplateExplanation": "应用程序启动模板用于创建新的web应用程序.", - "EfCoreProvider": "Entity Framework (支持 SQL Server, MySQL, PostgreSQL, Oracle 和其它)", - "AlreadyIncludedInTemplateModules": "以下模块已经包含并配置在此模板中:", - "ApplicationTemplateArchitecture": "应用程序模板还支持UI,API,身份验证服务器物理分离的分层架构.", - "SeeTheGuideOrGoToTheLiveDemo": "查看开发人员指南或者查看在线演示了解更多关于模板的信息.", + "CreateLiveDemoDescription": "提交表单后,您将收到一封包含演示链接的电子邮件。", + "RegisterToTheNewsletter": "注册时事通讯,以接收有关 ABP.IO 的信息,包括新发布的信息等。", + "EnterYourEmailOrLogin": "输入您的电子邮件地址以创建演示版,或 使用现有帐户登录。", + "ApplicationTemplate": "应用程序模版", + "ApplicationTemplateExplanation": "应用程序启动模板用于创建新的Web应用程序。", + "EfCoreProvider": "实体框架(支持 SQL Server、MySQL、PostgreSQL、Oracle 及其他)", + "AlreadyIncludedInTemplateModules": "本模板已包含并配置了以下模块:", + "ApplicationTemplateArchitecture": "该应用程序模板还支持分层架构,其中UI层、API层和身份验证服务是物理分离的。", + "SeeTheGuideOrGoToTheLiveDemo": "请查看开发人员指南,了解有关此模板的技术信息,或访问在线演示。", "DeveloperGuide": "开发人员指南", "ModuleTemplate": "模块模板", - "ModuleTemplateExplanation1": "你是否想要创建可在不同应用程序之间重用的模块? 这个启动模板准备好了一切来创建可重用的应用程序模块微服务.", - "ModuleTemplateExplanation2": "

你可以为一个模块支持单个或多个UI框架, 单个或多个数据库提供程序. 除了单元测试和集成测试基础架构外,启动模板被配置为在一个最小的应用程序中运行和测试你的模块.

查看开发人员指南了解有关此模板的技术信息.

", - "WithAllStyleOptions": "使用所有的样式选项", + "ModuleTemplateExplanation1": "您想创建一个模块并在不同的应用程序中重用?本启动模板为创建可重用的 应用模块微服务准备了一切。", + "ModuleTemplateExplanation2": "

您可以为单个模块支持单个或多个 UI 框架、单个或多个数据库提供商。除了单元和集成测试基础架构外,启动模板还被配置为在最小应用程序中运行和测试您的模块

有关该模板的技术信息,请查看开发人员指南。", + "WithAllStyleOptions": "所有款式可选", "Demo": "演示", - "SeeAllModules": "查看所有的模块", - "ABPCLIExplanation": "ABP CLI(命令行页面)是一个执行基于ABP解决方案的一些常见操作的命令行工具.", - "ABPSuiteEasilyCURD": "ABP Suite是一个使你轻松创建CURD页面的工具", - "WeAreHereToHelp": "我们在这里为你提供帮助", - "BrowseOrAskQuestion": "你可以浏览我们的帮助主题或搜索常见的问题, 或者你可以使用联系表单向我们提问.", - "SearchQuestionPlaceholder": "搜索常见的问题", - "WhatIsTheABPCommercial": "什么是ABP商业版?", - "WhatAreDifferencesThanAbpFramework": "ABP框架与ABP商业版有什么不同?", - "AbpCommercialMetaTitle": " {0} | ABP 商业版 ", - "AbpCommercialMetaDescription": "ABP 商业版是在开源ABP框架之上构建的一组预构建应用程序模块、快速开发工具、UI主题和服务架构", - "ABPCommercialExplanation": "ABP商业版是一套基于开源ABP框架之上的高级模块,工具,主题和服务. ABP商业版由ABP框架背后的同一团队开发和支持.", - "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP框架是模块化,主题化,微服务兼容的ASP.NET Core应用程序开发框架. 它提供了一个完整的架构和强大的基础设施,让你专注于自己的业务代码而不是重复自己的每一个项目. 它基于软件开发的最佳实践和你已经知道的流行工具

ABP框架是完全免费,开源和由社区驱动的. 它还提供了一个免费的主题和一些预构建的模块 (如 identity管理和租户管理).

", - "VisitTheFrameworkVSCommercialDocument": "访问以下链接,了解更多信息 {1} ", - "ABPCommercialFollowingBenefits": "ABP商业版在ABP框架之上添加了以下好处;", - "Professional": "专业的", + "SeeAllModules": "查看所有模块", + "ABPCLIExplanation": "ABP CLI(命令行界面)是一种命令行工具,用于执行基于 ABP 的解决方案的一些常用操作。", + "ABPSuiteEasilyCURD": "ABP Suite 是一款可让您轻松创建 CRUD 页面的工具", + "WeAreHereToHelp": "我们在这里帮助联系表单向我们提问。", + "SearchQuestionPlaceholder": "在常见问题中搜索", + "WhatIsTheABPCommercial": "ABP Commercial 是什么?", + "WhatAreDifferencesThanAbpFramework": "开源 ABP 框架与 ABP 商业版之间有哪些区别?", + "AbpCommercialMetaTitle": "{0}| ABP 商业", + "AbpCommercialMetaDescription": "基于 ABP 框架的 Web 开发平台,提供预建模块、启动模板、快速开发工具、专业UI主题和高级支持。", + "ABPCommercialExplanation": "ABP 商业版是建立在开源 ABP 框架之上的一套高级模块、工具、主题和服务。ABP 商业版由 ABP 框架背后的同一团队开发和支持。", + "WhatAreDifferencesThanABPFrameworkExplanation": "

ABP 框架是适用于 ASP.NET Core 的模块化、可主题化、微服务兼容的应用程序开发框架。它提供了完整的架构和强大的基础架构,让您可以专注于自己的业务代码,而不必为每个新项目重复自己的工作。它基于软件开发的最佳实践和您已经熟悉的流行工具。

ABP 框架是完全免费、开源和社区驱动的。它还提供免费主题和一些预建模块(如身份管理和租户管理)。", + "VisitTheFrameworkVSCommercialDocument": "请访问以下链接了解更多信息 {1}", + "ABPCommercialFollowingBenefits": "ABP Commercial 在 ABP 框架的基础上增加了以下优势:", + "Professional": "专业人员", "UIThemes": "UI主题", - "EnterpriseModules": "企业就绪,功能丰富,预构建的应用程序模块 (如 Identity Server管理, SaaS管理, 语言管理)", - "ToolingToSupport": "支持你的生产力的工具(如. ABP Suite)", - "PremiumSupportLink": "高级支持", - "WhatDoIDownloadABPCommercial": "购买ABP商业版后我可以下载什么?", - "CreateUnlimitedSolutions": "一旦你购买了ABP商业许可, 你可以创建入门文档中描述的无限的解决方案.", - "ABPCommercialSolutionExplanation": "创建新应用程序时,将根据你的首选项获得Visual Studio解决方案(启动模板). 下载的解决方案已为你安装并配置了商业模块和主题. 你可以删除预装的模块,也可以根据需要添加其他模块. 默认情况下所有模块和主题都使用NuGet/NPM软件包.", - "StartDevelopWithTutorials": "下载的解决方案经过精心设计和记录, 你可以根据教程来开发自己的业务代码.", - "TryTheCommercialDemo": "你可以尝试示例来查看使用ABP商业模板创建的示例应用程序.", - "HowManyProducts": "使用ABP商业版,我可以构建多少不同的产品/解决方案?", - "HowManyProductsExplanation": "创建ABP项目没有限制. 你可以根据需要创建任意数量的项目,进行开发并将其部署到其他服务器.", - "HowManyDevelopers": "有多少开发者可以参与ABP商业版工作?", - "HowManyDevelopersExplanation": "ABP商业许可是针对每个开发人员的. 不同的许可类型具有不同的开发人员限制. 但是你可以在需要时将更多开发人员添加到任何许可类型. 查看许可类型,开发人员限制和额外的开发人员成本的价格页面.", - "ChangingLicenseType": "将来更改我的许可类型吗?", - "ChangingLicenseTypeExplanation": "你始终可以在同一许可中添加新的开发人员. 参阅 \"有多少开发者可以参与ABP商业版工作?\". 你还可以通过支付计算出的价格差来升级到更高的许可. 当你升级到更高的许可计划时,可以享受新计划的好处,但是许可升级不会更改许可的到期日期.", - "LicenseExtendUpgradeDiff": "许可扩展和升级有什么区别?", - "LicenseExtendUpgradeDiffExplanation": "延长: 你通过延长/续费你的许可证,你将继续获得高级支持和主要或次要更新模块和主题。除此之外,你还将继续创建新的项目。并且你仍然可以使用ABP Suite,这将加快你的开发。当你延长你的许可证时,1年将添加到你的许可证到期日。


升级: 你通过升级你的许可证,你将晋升到更高的许可证方案,这将允许你获得额外的奖励。查看许可证比较表来查看许可证方案之间的差异。但是,当你升级时,你的许可证到期日不会更改!要延长你的许可证结束日期,你需要延长你的许可证。", - "LicenseRenewalCost": "一年后的许可续期费用是多少?", - "LicenseRenewalCostExplanation": "标准 Team 许可证的续订(扩展)价格为 ${0},标准 Business License 为 ${1},标准 Enterprise License 为 ${2}。 如果您已经是客户,请登录您的帐户查看可用的续订价格。", - "HowDoIRenewMyLicense": "如何续费我的许可证?", - "HowDoIRenewMyLicenseExplanation": "你可以登录以进行续费. 为了享受我们的续费折扣, 请确保在许可证到期之前进行续费, 我们会在到期前7天和30天发送2封续费提醒邮件.", - "IsSourceCodeIncluded": "我的许可是否包括商业模块和主题的源代码?", - "IsSourceCodeIncludedExplanation1": "取决于你购买的许可类型:", - "IsSourceCodeIncludedExplanation2": "团队: 你的解决方案将这些模块和主题作为NuGet和NPM包使用. 它不包括其源代码. 这样,只要有新版本可用,你就可以轻松升级这些模块和主题. 但是,你无法获取模块和主题的源代码.", - "IsSourceCodeIncludedExplanation3": "商业/企业: 除了团队许可外,你还可以下载所需的任何模块或主题的源代码. 你甚至可以删除特定模块的NuGet/NPM软件包引用,并将其源代码直接添加到你的解决方案中以完全更改它.", - "IsSourceCodeIncludedExplanation4": "

将模块的源代码包含到解决方案中,可以最大程度地自定义该模块. 但是当新版本发布时,将无法自动升级模块.

这些许可均不包含ABP Suite源代码,该源代码是一个外部工具,可以为你生成代码并帮助你进行开发

有关许可类型之间的其它差异查看定价页面.

", - "ChangingDevelopers": "我将来可以更改我组织的注册开发人员吗?", - "ChangingDevelopersExplanation": "除了将新的开发人员添加到你的许可中之外,你还可以更改现有的开发人员(可以删除一个开发人员并将新的开发人员添加到同一位置),而无需任何额外费用.", - "WhatHappensWhenLicenseEnds": "我的许可证期间结束时,会发生什么?", - "WhatHappensWhenLicenseEndsExplanation1": "你的ABP商业许可证是一个永久许可证。你的许可证到期后,你可以继续开发你的项目。并且你不需要续费你的许可证。你的许可证是一年更新和支持方案默认的。为了继续获得新的功能,性能改进,修复,支持和继续使用ABP Suite,你需要续费你的许可证。你的许可证到期后,你将失去以下功能:", - "WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商业创建新的解决方案,但是你可以继续开发你现有的应用程序。", - "WhatHappensWhenLicenseEndsExplanation3": "你将能够获得模块和主题的更新(除了RC或预览版本)。例如,如果你使用模块的v3.2.0版本,你仍然可以获得v3.2.x版本的更新(v3.2.1,v3.2.5...等等)。但是,你不能获得下一个主要或次要版本的更新(例如v3.3.0,v3.3.3,4.x.x...等等)。例如,你的许可证到期后,最新的发行是v4.4.3,之后,它发布了4.4.4版本和4.5.0版本,你将能够访问v4.4.X,但你不能访问v4.5.X。", - "WhatHappensWhenLicenseEndsExplanation4": "你不能在你的许可证到期后安装ABP商业平台上添加的新模块和主题。", - "WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite。", - "WhatHappensWhenLicenseEndsExplanation6": "你不能再获得高级支持。", - "WhatHappensWhenLicenseEndsExplanation7": "如果您想继续获得这些好处,您可以延长(续订)您的许可证。 如果您在许可证到期后 {3} 天内延长许可证,将应用以下折扣:团队许可证 {0}; 营业执照{1}; 企业许可证 {2}。", + "EnterpriseModules": "企业级、功能丰富的预建 应用模块(例如身份服务器管理、SaaS 管理、语言管理)", + "ToolingToSupport": "支持您提高开发效率的工具(例如 ABP Suite)", + "PremiumSupportLink": "Premium 支持", + "WhatDoIDownloadABPCommercial": "购买 ABP 商业版时,我可以下载什么?", + "CreateUnlimitedSolutions": "一旦您购买了 ABP 商业许可证,您就可以创建无限制的解决方案,如文档中所述。", + "ABPCommercialSolutionExplanation": "创建新应用程序时,系统会根据您的偏好为您提供一个 Visual Studio 解决方案(启动模板)。下载的解决方案已为您安装和配置了商业模块和主题。您可以移除预安装的模块,也可以根据需要添加其他模块。所有模块和主题默认使用 NuGet/NPM 包。", + "StartDevelopWithTutorials": "下载的解决方案具有良好的架构和文档。您可以根据教程开始开发自己的业务代码。", + "TryTheCommercialDemo": "您可以尝试 Live Demo 查看使用 ABP 商业启动模板创建的示例应用程序。", + "HowManyProducts": "我可以使用 ABP 商业版构建多少种不同的产品/解决方案?", + "HowManyProductsExplanation": "在许可证有效期内,您可以创建任意数量的项目,没有任何限制!许可证过期后,您将无法创建新项目,但可以继续开发已下载的项目,并将其部署到不限数量的服务器上。", + "HowManyDevelopers": "有多少开发人员可以在 ABP 商业网站上工作?", + "HowManyDevelopersExplanation": "ABP 商业许可证是按开发人员计算的。不同的许可证类型有不同的开发人员限制。但是,您可以根据需要随时向任何许可证类型添加更多开发人员。请查看计划与定价页面,了解许可证类型、开发人员限制和额外的开发人员费用。", + "ChangingLicenseType": "以后可以升级许可证类型吗?", + "ChangingLicenseTypeExplanation": "您可以在有效许可证期限内支付差额,升级到更高的许可证。当您升级到更高的许可证计划时,您将获得新计划的好处,但许可证升级不会改变许可证的到期日。此外,您还可在现有许可证上添加新的开发人员席位,请查看 \"有多少开发者可以参与ABP商业版工作?\" 常见问题。", + "LicenseExtendUpgradeDiff": "许可证扩展和升级有什么区别?", + "LicenseExtendUpgradeDiffExplanation": "扩展:通过扩展/续订许可证,您将继续获得高级支持,并获得模块和主题的主要或次要更新。此外,您还可以继续创建新项目。您仍可使用 ABP Suite,从而加快您的开发速度。当您扩展您的许可证时,您的许可证到期日将增加一年。
升级:通过升级您的许可证,您将升级到更高的许可证计划,这将使您获得额外的好处。请查看许可证对照表,了解许可证计划之间的差异。另一方面,当您升级时,您的许可证到期日不会改变!要延长许可证到期日,您需要扩展您的许可证。", + "LicenseRenewalCost": "1 年后的许可证续期费用是多少?", + "LicenseRenewalCostExplanation": "标准团队许可的续订(扩展)价格为${0},标准商业许可的续订(扩展)价格为${1},标准企业许可的续订(扩展)价格为${2}。如果您已经是客户,登录您的账户查看当前的续订价格。", + "HowDoIRenewMyLicense": "如何更新许可证?", + "HowDoIRenewMyLicenseExplanation": "您可以通过组织管理页面更新许可证。为了享受我们优惠的 \"提前续费 \"折扣,请确保在许可证到期前续费。不必担心不知道提前续订机会何时结束;您将在订阅到期前收到 3 封提醒邮件。我们将分别在到期前 30 天、7 天和 1 天发送。", + "IsSourceCodeIncluded": "我的许可证是否包括商业模块和主题的源代码?", + "IsSourceCodeIncludedExplanation1": "取决于您购买的许可证类型:", + "IsSourceCodeIncludedExplanation2": "团队:您的解决方案将模块和主题作为 NuGet 和 NPM 包使用。它不包括它们的源代码。这样,只要有新版本,您就可以轻松升级这些模块和主题。但是,您无法获得这些模块和主题的源代码。", + "IsSourceCodeIncludedExplanation3": "商业/企业:除了团队许可证外,您还可以下载任何模块或主题的源代码。您甚至可以移除特定模块的 NuGet/NPM 包引用,并将其源代码直接添加到您的解决方案中,以对其进行完全更改。", + "IsSourceCodeIncludedExplanation4": "

在您的解决方案中包含一个模块的源代码可使您最大程度地自由定制该模块。

所有许可证均不包含 ABP Suite 源代码,这是一种外部工具,可为您生成代码并协助您进行开发。

请查看 计划与定价页面,了解许可证类型之间的其他区别。", + "ChangingDevelopers": "将来我可以更换组织的注册开发人员吗?", + "ChangingDevelopersExplanation": "除了在许可证中添加新的开发人员外,您还可以更改现有的开发人员(您可以删除一个开发人员,然后在同一席位上添加一个新的开发人员),而无需支付任何额外费用。", + "WhatHappensWhenLicenseEnds": "许可证有效期结束后怎么办?", + "WhatHappensWhenLicenseEndsExplanation1": "ABP 商业许可证是永久许可证。许可证到期后,您可以继续开发您的项目。您没有义务更新许可证。许可证开箱即附带一年的更新和支持计划。为了继续获得新功能、性能增强、错误修复、支持并继续使用ABP Suite,您需要更新您的许可证。当您的许可证过期时;", + "WhatHappensWhenLicenseEndsExplanation2": "您不能使用 ABP 商业版创建新的解决方案,但您可以永远继续开发现有的应用程序。", + "WhatHappensWhenLicenseEndsExplanation3": "您将可以获得小版本(RC 或预览版除外)中模块和主题的更新。例如,如果您正在使用某个模块的 v3.2.0,您仍然可以获得该模块 v3.2.x 的更新(v3.2.1、v3.2.5......等)。但您无法获得下一个主要或次要版本(如 v3.3.0、v3.3.3、4.x.x......等)的更新。例如,当您的许可证过期时,最新发布的版本是 v4.4.3,随后发布了 4.4.4 版本和 4.5.0 版本,您可以访问 v4.4.X,但无法访问 v4.5.X。", + "WhatHappensWhenLicenseEndsExplanation4": "许可证到期后,您不能安装添加到 ABP 商业平台的新模块和主题。", + "WhatHappensWhenLicenseEndsExplanation5": "您不能使用 ABP Suite。", + "WhatHappensWhenLicenseEndsExplanation6": "您无法再获得高级支持。", + "WhatHappensWhenLicenseEndsExplanation7": "如果您想继续享受这些优惠,可以延长(续签)许可证。如果您在许可证到期后{3}天内延长许可证,将享受以下折扣:团队许可证{0};商业许可证{1};企业许可证{2}。", "discountForYears": "{0}% 折扣 {1} 年", - "WhatHappensWhenLicenseEndsExplanation8": "您生成的 ABP 项目未存储在我们的服务器上。 因此,您有责任保留下载的源代码。 当您的许可证到期时,将无法获取您生成的 ABP 项目源代码。", - "WhenShouldIRenewMyLicense": "我什么时候应该续订我的许可?", - "WhenShouldIRenewMyLicenseExplanation": "如果您在许可证到期后 {3} 天 内续订许可证,将适用以下折扣:团队许可证 {0}; 营业执照{1}; 企业许可证 {2}。 但是,如果您在许可证到期后 {3} 天 后续订许可证,则续订价格将与许可证购买价格相同,并且您的续订不会有任何折扣。", - "TrialPlan": "你们有试用计划吗?", - "TrialPlanExplanation": "不,ABP商业版没有试用版。您可以通过查看社区版了解代码质量和方法。我们还为团队许可证提供30天无条件退款保证!您可以在前30天内申请退款。对于商业和企业许可证,我们在30天内提供60%的退款。这是因为商业和企业许可证包含所有模块和主题的完整源代码。", - "DoYouAcceptBankWireTransfer": "你们接受银行电汇吗?", - "DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇。
在通过银行转账发送许可费后,将您的收据和所需的许可类型通过电子邮件发送至accounting@abp.io。 我们的国际银行账户信息:", - "HowToUpgrade": "可用新版本时如何升级现有应用程序?", - "HowToUpgradeExplanation1": "使用ABP商业版创建新应用程序时,所有模块和主题均用作NuGet和NPM软件包. 因此,当有新版本可用时,你可以轻松升级软件包.", - "HowToUpgradeExplanation2": "除了标准的NuGet/NPM升级之外, ABP CLI 还提供了一条更新命令,该命令可自动查找和升级解决方案中的所有与ABP相关的软件包.", - "DatabaseSupport": "支持哪些数据库系统?", - "DatabaseSupportExplanation": "ABP框架本身与数据库无关,并且就其性质而言,可以与任何数据库提供程序一起使用. 请参阅数据访问文档以获取当前实现的提供程序的列表.", - "UISupport": "支持哪些UI框架?", - "Supported": "支持的", - "UISupportExplanation": "ABP框架本身与UI框架无关,并且可以与任何UI框架一起使用. 但是,并非针对所有UI框架都实现了启动模板,模块UI和主题. 有关UI选项的最新列表,请参见入门文档.", - "MicroserviceSupport": "它是否支持微服务架构?", - "MicroserviceSupportExplanation1": "ABP框架的主要目标之一是为创建微服务解决方案提供便利的基础架构. 请参阅微服务体系结构文档,以了解它如何帮助创建微服务系统.", - "MicroserviceSupportExplanation2": "所有的ABP商业模块通过模块开发最佳实践文档被设计为支持微服务部署场景(使用自己的API和数据库).", - "MicroserviceSupportExplanation3": "我们提供了一个示例微服务演示解决方案,该示例演示了一种微服务架构实现,可帮助你创建自己的解决方案.", - "MicroserviceSupportExplanation4": "所以简短的答案是 \"是的, 它支持微服务体系结构\".", - "MicroserviceSupportExplanation5": "但是,微服务系统是一个解决方案,每个解决方案都有不同的要求,网络拓扑,通信场景,身份验证可能性,数据库分离/共享决策,运行时配置,第三方系统集成等等.", - "MicroserviceSupportExplanation6": "ABP框架和ABP商业版提供了微服务方案,微服务兼容模块,示例和文档的基础结构,以帮助你构建自己的解决方案. 但是不要期望直接下载为你预先构建的梦想解决方案. 你将需要了解它,并根据需要将某些部分组合在一起.", - "WhereCanIDownloadSourceCode": "在哪里可以下载源代码?", - "WhereCanIDownloadSourceCodeExplanation": "你可以通过ABP Suite或ABP CLI下载所有ABP模块,Angular软件包和主题的源代码. 请参见如何下载源代码?", - "ComputerLimitation": "开发人员在开发ABP时可以登录到多少台计算机?", - "ComputerLimitationExplanation": "我们特别允许每个个人/许可的开发人员使用 {0}台计算机. 每当需要开发人员在第三台计算机上开发ABP商业产品时,都应将电子邮件发送到license@abp.io,以说明情况,然后我们将在系统中进行适当分配.", - "RefundPolicy": "你们有退款政策吗?", - "RefundPolicyExplanation": "你可以在购买许可的30天内请求退款.商业和企业许可类型都有源代码下载选项,因此商业和企业(以及任何包含获得源代码的权利的许可)都不能退款.此外,续展和购买第二次许可也不退款.", - "HowCanIRefundVat": "我该如何退还增值税?", - "HowCanIRefundVatExplanation1": "如果你使用2Checkout付款,则可以通过2Checkout帐户退还增值税:", - "HowCanIRefundVatExplanation2": "登录到你的2Checkout账户", - "HowCanIRefundVatExplanation3": "找到适当的订单,然后按\"退还已延期的增值税\"(输入你的增值税ID", - "HowCanIGetMyInvoice": "我如何获得发票?", - "HowCanIGetMyInvoiceExplanation": "有两个用于购买许可的支付网关:Iyzico和2Checkout. 如果你通过2Checkout网关购买许可,则它将PDF发票发送到你的电子邮件地址,请参阅2Checkout发票.如果你是通过Iyzico网关或通过银行电汇购买的,我们将准备并发送你的发票. 你可以从组织管理页面索取发票.", + "WhatHappensWhenLicenseEndsExplanation8": "您生成的 ABP 项目不会存储在我们的服务器上。因此,您有责任保留您下载的源代码。当您的许可证过期时,您将无法获得您生成的 ABP 项目源代码。", + "WhenShouldIRenewMyLicense": "我应该何时更新执照?", + "WhenShouldIRenewMyLicenseExplanation": "如果您在许可证到期后{3}天内续费,将享受以下折扣:团队许可证 {0};商业许可证 {1};企业许可证 {2}。但是,如果您在许可证到期日{3}天后续订许可证,续订价格将与许可证购买价格相同,续订时将没有折扣。", + "TrialPlan": "您有试用计划吗?", + "TrialPlanExplanation": "是的,要开始免费试用,请联系 marketing@volosoft.com。我们还为团队许可证提供 30 天退款保证,无任何问题!您可以在购买许可证的前 30 天内申请全额退款。对于商业和企业许可证,我们在 30 天内提供 60% 的退款。这是因为商业和企业许可证包含所有模块和主题的完整源代码。", + "DoYouAcceptBankWireTransfer": "你们接受银行电汇吗?", + "DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇。
通过银行汇款支付许可证费用后,请将收据和申请的许可证类型发送至 accounting@volosoft.com。
我们的国际银行账户信息:", + "HowToUpgrade": "新版本推出后,如何升级现有应用程序?", + "HowToUpgradeExplanation1": "使用 ABP Commercial 创建新应用程序时,所有模块和主题都作为 NuGet 和 NPM 包使用。因此,当新版本可用时,您可以轻松升级包。", + "HowToUpgradeExplanation2": "除了标准的 NuGet/NPM 升级外,ABP CLI 还提供了一个更新命令,可自动查找并升级解决方案中所有与 ABP 相关的包。", + "DatabaseSupport": "支持哪些数据库系统?", + "DatabaseSupportExplanation": "ABP 框架本身与数据库无关,可与任何数据库提供商协同工作。请查看数据访问文档,了解当前实施的提供商列表。", + "UISupport": "支持哪些UI框架?", + "Supported": "支持", + "UISupportExplanation": "ABP 框架本身与UI框架无关,可与任何UI框架配合使用。然而,启动模板、模块UI和主题并未针对所有UI框架实施。请查看入门文档,了解最新的UI选项列表。", + "MicroserviceSupport": "它支持微服务架构吗?", + "MicroserviceSupportExplanation1": "ABP 框架的主要目标之一是为创建微服务解决方案提供便捷的基础架构。请查看微服务架构文档,了解它如何帮助创建微服务系统。", + "MicroserviceSupportExplanation2": "所有 ABP 商业模块都是按照模块开发最佳实践文档设计的,以支持微服务部署方案(具有自己的API和数据库)。", + "MicroserviceSupportExplanation3": "我们提供了一个示例 微服务演示解决方案,演示了微服务架构的实现,以帮助您创建自己的解决方案。", + "MicroserviceSupportExplanation4": "因此,简短的回答是:\"是的,它支持微服务架构\"。", + "MicroserviceSupportExplanation5": "然而,微服务系统是一种解决方案,每种解决方案都会有不同的要求、网络拓扑结构、通信场景、验证可能性、数据库分片/分区决策、运行时配置、第三方系统集成等等。", + "MicroserviceSupportExplanation6": "ABP Framework 和 ABP Commercial 为微服务场景提供基础架构、微服务兼容模块、示例和文档,帮助您构建自己的解决方案。但不要指望直接下载为你预先构建的梦想解决方案。您需要了解它,并根据自己的需求将特定部分整合在一起。", + "WhereCanIDownloadSourceCode": "在哪里可以下载源代码?", + "WhereCanIDownloadSourceCodeExplanation": "您可以通过 ABP Suite 或 ABP CLI 下载所有 ABP 模块、Angular 包和主题的源代码。查看 如何下载源代码?", + "ComputerLimitation": "开发 ABP 时,开发人员可以登录多少台计算机?", + "ComputerLimitationExplanation": "我们特别允许每位个人/授权开发者使用{0}台计算机。如果开发人员需要在第三台机器上开发 ABP 商业产品,应向 license@abp.io 发送电子邮件说明情况,我们将在系统中进行适当分配。", + "RefundPolicy": "你们有退款政策吗?", + "RefundPolicyExplanation": "您可以在购买许可证后 30 天内申请退款。商业和企业许可证类型有源代码下载选项;因此,我们在 30 天内为商业和企业许可证提供 60% 的退款。此外,续订和第二次购买许可证不退款。", + "HowCanIRefundVat": "如何退还增值税?", + "HowCanIRefundVatExplanation1": "如果您使用 2Checkout 付款,您可以通过您的 2Checkout 账户退还增值税:", + "HowCanIRefundVatExplanation2": "登录您的 2Checkout 账户", + "HowCanIRefundVatExplanation3": "找到相应订单并点击 \"退还延迟退还的增值税\"(输入您的增值税编号)", + "HowCanIGetMyInvoice": "如何获取发票?", + "HowCanIGetMyInvoiceExplanation": "购买许可证有两种付款方式:Iyzico 和 2Checkout。如果您通过 2Checkout 网关购买许可证,它将向您的电子邮箱发送 PDF 发票;请查看 2Checkout 发票。如果您通过 Iyzico 网关、自定义购买链接或银行电汇购买,我们将为您准备并发送发票。您可以从组织管理页面申请或下载发票。在联系我们索取发票之前,请查看您的组织管理页面!", "Forum": "论坛", - "SupportExplanation": "ABP商业版许可包含由ABP框架专家组成的团队提供的高级论坛支持.", - "PrivateTicket": "私有票", - "PrivateTicketExplanation": "企业许可还包含带有电子邮件和票系统的私人支持.", - "AbpSuiteExplanation1": "ABP Suite使你在几分钟内构建web页面. 它是一个.NET Core Global工具,可以使用命令行安装.", - "AbpSuiteExplanation2": "它可以创建一个新的ABP解决方案, 从数据库生成前端CURD页面. 有关技术概述查看文档", - "FastEasy": "快速并且简单", - "AbpSuiteExplanation3": "ABP Suite允许你轻松的创建CURD页面. 你只需要定义你的实体和它的属性, 其它的让ABP Suite帮你完成! ABP Suite会在几秒内为你生成CURD页面和必要的代码. 它支持Angular, MVC和 Blazor用户界面.", + "SupportExplanation": "ABP 商业许可证由 ABP 框架专家组成的团队提供高级论坛支持。", + "PrivateTicket": "私人票务", + "PrivateTicketExplanation": "企业许可证还包括通过电子邮件和票据系统提供的私人支持。", + "AbpSuiteExplanation1": "ABP Suite 可让您在几分钟内创建web页面。它是一个 .NET Core 全局工具,可通过命令行安装。", + "AbpSuiteExplanation2": "它可以创建新的 ABP 解决方案,并生成从数据库到前端的 CRUD 页面。有关技术概述,请参阅文档。", + "FastEasy": "快速简便", + "AbpSuiteExplanation3": "ABP Suite 允许您轻松创建 CRUD 页面。你只需定义你的实体及其属性,剩下的就交给 ABP Suite 吧!ABP Suite 可在几秒钟内为您的 CRUD 页面生成所有必要的代码。它支持 Angular、MVC 和 Blazor UI。", "RichOptions": "丰富的选项", - "AbpSuiteExplanation4": "ABP Suite支持多个UI选项,例如 Razor PagesAngular.它还支持多个数据库, 如 MongoDBEntityFramework Core支持的所有数据库(MS SQL Server, Oracle, MySql, PostgreSQL 和 更多).", - "AbpSuiteExplanation5": "好消息是, 你不必担心这些选项. ABP Suite了解你的项目类型并且将生成的代码放到项目中正确的位置.", - "SourceCode": "源码", - "AbpSuiteExplanation6": "ABP Suite为你生成源代码! 它不会生成魔法文件来生成web页面. ABP Suite为实体, 仓储, 应用程序, Code First迁移, JavaScript/TypeScript 和 CSHTML/HTML以及必要的页面生成源代码. ABP Suite根据软件开发的最佳实践来生成代码, 所以你不必担心生成的代码的质量.", - "AbpSuiteExplanation7": "由于你有应用程序层中生成的CURD页面的构建块的源代码, 因此你可以轻松修改源码并将自定义/业务逻辑注入到所生成的代码中.", + "AbpSuiteExplanation4": "ABP Suite 支持多种UI选项,如 Razor PagesAngular 。它还支持多种数据库,如 MongoDBEntityFramework Core 支持的所有数据库(MS SQL Server、Oracle、MySql、PostgreSQL 和 其他提供商...)。", + "AbpSuiteExplanation5": "好在你不必担心这些选项。ABP Suite 可以理解您的项目类型,为您的项目生成代码,并将生成的代码放置在项目的正确位置。", + "SourceCode": "源代码", + "AbpSuiteExplanation6": "ABP Suite 为您生成源代码!它不会生成神奇的文件来生成网页。ABP Suite为 实体、资源库、应用程序服务、Code First、JavaScript/TypeScript 和 CSHTML/HTML 以及必要的接口生成源代码。ABP Suite 还根据软件开发的最佳实践生成代码,因此您不必担心生成代码的质量。", + "AbpSuiteExplanation7": "由于您在正确的应用层中拥有生成的 CRUD 页面构建模块的源代码,因此您可以轻松修改源代码,并将您的自定义/业务逻辑注入到生成的代码中。", "CrossPlatform": "跨平台", - "AbpSuiteExplanation8": "ABP Suite使用.NET Core构建并且它是跨平台的. 它在你的本地电脑中运行为web应用程序. 你可以在Windows, MacLinux上运行它", + "AbpSuiteExplanation8": "ABP Suite 采用 .NET Core 构建,具有跨平台性。它在本地计算机上以Web应用程序的形式运行。您可以在WindowsMacLinux上运行它。", "OtherFeatures": "其他功能", - "OtherFeatures1": "轻松更新你的解决方案的NuGetNPM包.", - "OtherFeatures2": "重新生成已经生成的页面.", - "OtherFeatures3": "创建新的解决方案", - "ThanksForCreatingProject": "感谢你创建你的项目!", - "HotToRunSolution": "如何运行你的解决方案?", - "HotToRunSolutionExplanation": "查看入门文档来学习如何配置和运行你的解决方案.", + "OtherFeatures1": "轻松更新解决方案中的 NuGetNPM 包。", + "OtherFeatures2": "从头开始重新生成已生成的页面。", + "OtherFeatures3": "创造新的解决方案", + "ThanksForCreatingProject": "您的项目已成功创建!", + "HotToRunSolution": "如何运行您的解决方案?", + "HotToRunSolutionExplanation": "查看入门文档,了解如何配置和运行解决方案。", "GettingStarted": "入门", - "WebAppDevTutorial": "Web应用开发教程", - "WebAppDevTutorialExplanation": "查看web应用程序开发教程文档来一步一步的了解开发示例.", + "WebAppDevTutorial": "Web应用程序开发教程", + "WebAppDevTutorialExplanation": "查看Web应用程序开发教程文档,了解逐步开发示例。", "Document": "文档", - "UsingABPSuiteToCURD": "使用ABP Suite来生成CURD页面", - "SeeABPSuiteDocument": "查看ABP Suite文档学习如何使用ABP Suite.", - "AskQuestionsOnSupport": "你可以在ABP商业支持提出问题.", + "UsingABPSuiteToCURD": "使用 ABP Suite生成 CRUD 页面和工具", + "SeeABPSuiteDocument": "查看 ABP Suite文档,了解 ABP Suite的用法。", + "AskQuestionsOnSupport": "您可以在 ABP 商业支持上提问。", "Documentation": "文档", - "SeeModulesDocument": "查看模块文档获取所有商业(专业)模块列表和它们的文档.", - "Pricing": "价格", - "PricingExplanation": "选择当前业务需要的特性和功能. 随着业务增长轻松升级.", + "SeeModulesDocument": "有关所有 PRO 模块的列表,请参见模块页面。", + "Pricing": "定价", + "PricingExplanation": "选择当前业务所需的特性和功能。随着业务发展,轻松升级。", "Team": "团队", "Business": "商业", "Enterprise": "企业", - "Custom": "自定义", - "IncludedDeveloperLicenses": "包括开发人员许可", - "CustomLicenceOrAdditionalServices": "需要自定义许可与额外服务?", - "CustomOrVolumeLicense": "自定义或批量许可", + "Custom": "定制", + "IncludedDeveloperLicenses": "包括开发人员许可证", + "CustomLicenceOrAdditionalServices": "需要定制许可证或其他服务?", + "CustomOrVolumeLicense": "自定义或批量许可证", "LiveTrainingSupport": "现场培训和支持", - "AndMore": "和更多", - "AdditionalDeveloperLicense": "额外的开发人员许可", - "ProjectCount": "项目数量", - "AllProModules": "所有模块", - "AllProThemes": "所有主题", + "AndMore": "及更多", + "AdditionalDeveloperLicense": "额外的开发人员许可证", + "ProjectCount": "项目计数", + "AllProModules": "所有专业模块", + "AllProThemes": "所有专所有者题", "AllProStartupTemplates": "所有专业启动模板", - "SourceCodeOfAllModules": "所有模块的源码", - "SourceCodeOfAllThemes": "所有主题的源码", - "PerpetualLicense": "永久的许可", - "UnlimitedServerDeployment": "无限制的服务器部署", - "YearUpgrade": "1年升级", - "YearPremiumForumSupport": "1年高级论坛支持", - "ForumSupportIncidentCountYear": "论坛支持事件数量/年", - "PrivateTicketEmailSupport": "私有票和email支持", - "BuyNow": "现在购买", - "PayViaAmexCard": "我如何通过我的AMEX卡付款?", - "PayViaAmexCardDescription": "由于安全措施,默认付款网关'Iyzico'可能会拒绝某些AMEX信用卡. 在这种情况下, 完全可以通过备用付款网关'2Checkout'付款.", + "SourceCodeOfAllModules": "所有模块的源代码", + "SourceCodeOfAllThemes": "所有主题的源代码", + "PerpetualLicense": "永久许可证", + "UnlimitedServerDeployment": "无限制服务器部署", + "YearUpgrade": "1 年升级", + "YearPremiumForumSupport": "1 年高级论坛支持", + "ForumSupportIncidentCountYear": "论坛支持事件计数/年", + "PrivateTicketEmailSupport": "私人票务和电子邮件支持", + "BuyNow": "立即购买", + "PayViaAmexCard": "如何使用 AMEX 卡付款?", + "PayViaAmexCardDescription": "出于安全考虑,默认付款网关 \"Iyzico \"可能会拒绝某些 AMEX 信用卡。在这种情况下,您可以通过替代支付网关 \"2Checkout \"进行支付。", "ThankYou": "谢谢", - "InvalidReCaptchaErrorMessage": "验证reCAPTCHA时出错,请重试.", + "InvalidReCaptchaErrorMessage": "验证 reCAPTCHA 时出现错误。请重试。", "CompanyName": "公司名称", - "YourCompanyName": "你的公司名称", - "FirstName": "名", - "LastName": "姓", - "Optional": "可选的", - "YourFirstName": "你的名字", - "YourLastName": "你的姓氏", + "YourCompanyName": "您的公司名称", + "FirstName": "姓名", + "LastName": "姓氏", + "Optional": "可选", + "YourFirstName": "您的名字", + "YourLastName": "您的姓氏", "SpecialOffer": "特别优惠", - "SpecialOfferMessage": "尽快付款,价格在一定时间内有效.", + "SpecialOfferMessage": "请抓紧时间!价格有效期有限。", "DiscountRequest": "折扣申请", - "DiscountRequestDescribeCustomerQuestion": "以下哪个选项描述了你?", - "DiscountRequestStudentEmailMessage": "Email地址必须包含'edu'.", - "DiscountRequestDeveloperCount": "你有多少开发人员?", - "DiscountRequestDeveloperCountExceedMessage": "对于超过 {0} 开发人员的公司,我们不提供折扣.", + "DiscountRequestDescribeCustomerQuestion": "以下哪项描述了你?", + "DiscountRequestStudentEmailMessage": "电子邮件地址必须包含 \"edu\"。", + "DiscountRequestDeveloperCount": "你们有多少开发人员?", + "DiscountRequestDeveloperCountExceedMessage": "我们不为拥有超过 {0} 名开发人员的公司提供折扣许可。", "DiscountRequestOrganizationName": "公司/组织/学校名称", "Website": "网站", - "GithubUsername": "GitHub用户名", - "PhoneNumber": "手机号", + "GithubUsername": "GitHub 用户名", + "PhoneNumber": "电话号码", "Country": "国家", - "DescribeABPCommercialUsage": "描述你基于ABP商业版进行开发的项目", - "DiscountRequestCertifyInformationMessage": "我证明所有的信息都是真实的.", - "DiscountRequestReceived": "我们收到了你的折扣请求.", - "DiscountRequestStatusMessage": "我们会检查你提供的信息并且给你答复.", + "DescribeABPCommercialUsage": "描述您计划根据《亚太商业评论》开发的项目", + "DiscountRequestCertifyInformationMessage": "本人保证所有信息真实无误。", + "DiscountRequestReceived": "我们已收到您的折扣申请。", + "DiscountRequestStatusMessage": "我们将在核对您提供的信息后给您回复。", "MVCOrRazorPages": "MVC (Razor Pages)", "Angular": "Angular", "Blazor": "Blazor", - "New": "新的", + "New": "新", "MongoDB": "MongoDB", "EBookDDD": "电子书领域驱动设计", - "PracticalGuideForImplementingDDD": "本书是使用 ABP 框架实现领域驱动设计的实用指南。", + "PracticalGuideForImplementingDDD": "本书是利用 ABP 框架实施领域驱动设计的实用指南。", "IntroducingDDD": "介绍领域驱动设计", - "DDDLayersAndCleanArchitecture": "DDD 层和干净的架构", - "LayeringOfADotnetSolution": ".NET 解决方案的分层", - "ImplementingDDDBuildingBlocks": "实现 DDD 构建块", + "DDDLayersAndCleanArchitecture": "DDD 层与简洁架构", + "LayeringOfADotnetSolution": ".NET解决方案的分层", + "ImplementingDDDBuildingBlocks": "实施 DDD 构件", "DomainVsApplicationLogic": "领域逻辑与应用逻辑", - "SamplesAndDiscussions": "示例和讨论", + "SamplesAndDiscussions": "示例与讨论", "Free": "免费", "Download": "下载", - "DDDEBook": "DDD电子书", - "ImplementingDDD": "实现领域驱动设计", - "DDDBookExplanation": "使用 ABP 框架实现领域驱动设计的实用指南。", + "DDDEBook": "电子书", + "ImplementingDDD": "实施领域驱动设计", + "DDDBookExplanation": "使用 ABP 框架实施领域驱动设计的实用指南。", "Overview": "概述", - "DDDBookPracticalGuide": "这是实现领域驱动设计 (DDD) 的实用指南。虽然实现细节依赖于 ABP 框架基础设施,但核心概念、原则和模式适用于任何类型的解决方案,即使它不是 .NET 解决方案。", + "DDDBookPracticalGuide": "这是一本实施领域驱动设计(DDD)的实用指南。虽然实施细节依赖于 ABP 框架基础架构,但核心概念、原则和模式适用于任何类型的解决方案,即使它不是 .NET 解决方案。", "TableOfContents": "目录", - "IntroductionToImplementingDDD": "实现领域驱动设计简介", + "IntroductionToImplementingDDD": "领域驱动设计实施简介", "WhatIsDDD": "什么是领域驱动设计?", - "Implementation": "执行", - "TheBigPicture": "大图", - "TheBuildingBlock": "积木", - "ExampleUseCase": "示例用例", - "DomainAndApplicationLogic": "领域逻辑与应用逻辑", + "Implementation": "实施", + "TheBigPicture": "大局观", + "TheBuildingBlock": "建筑模块", + "ExampleUseCase": "用例示例", + "DomainAndApplicationLogic": "领域逻辑和应用逻辑", "Author": "作者", - "PublishedOn": "发表于", - "Page": "页", + "PublishedOn": "出版日期", + "Page": "页次", "FreeEBook": "免费电子书", "EBookSignInForDownload": "要下载电子书,请登录", - "SignIn": "登入", + "SignIn": "登录", "Or": "或者", - "TellUsAboutYourself": "告诉我们一点关于你自己", - "Surname": "姓", - "DoYouAgreePrivacyPolicy": "我同意条款和条件隐私政策。", - "VolosoftMarketingInformationMessage": "我想要有关企业和组织解决方案以及其他 Volosoft 产品和服务的信息、提示和优惠。", - "VolosoftSharingInformationMessage": "我希望 Volosoft 与选定的合作伙伴共享我的信息,以便我可以收到有关他们的产品和服务的相关信息。", - "WeWillSendYouADownloadLink": "下载电子书的链接已发送至{0}。
检查您的收件箱/垃圾箱/垃圾邮件箱!", - "InvalidFormInputs": "请输入表格中指定的有效信息。", - "DDDBookEmailBody": "谢谢你。
要下载您的图书,请点击此处。", - "StartFree": "免费开始", + "TellUsAboutYourself": "谈谈你自己吧", + "Surname": "姓氏", + "DoYouAgreePrivacyPolicy": "我同意条款与条件隐私政策。", + "VolosoftMarketingInformationMessage": "我想了解有关企业和组织解决方案以及其他 Volosoft 产品和服务的信息、提示和优惠。", + "VolosoftSharingInformationMessage": "我希望 Volosoft 与选定的合作伙伴共享我的信息,以便我能收到他们的产品和服务的相关信息。", + "WeWillSendYouADownloadLink": "电子书下载链接已发送至 {0}。请检查您的收件箱、垃圾邮件箱!", + "InvalidFormInputs": "请输入表单中指定的有效信息。", + "DDDBookEmailBody": "谢谢。
要下载您的书籍,请点击此处。", + "StartFree": "免费启动", "FreeTrial": "免费试用", - "AcceptsMarketingCommunications": " 是的,我想接收 ABP 商业营销通讯。", + "AcceptsMarketingCommunications": "是的,我希望收到ABP商务部的营销通讯。", "PurposeOfUsage": "使用目的", - "Choose": "- 选择 -", + "Choose": "- 选择", "CompanyOrganizationName": "公司/组织名称", "CompanySize": "公司规模", - "Next": "下一个", - "StartTrial": "开始我的免费试用", - "ContactUsQuestions": "如果你有任何问题,请联系我们", - "TrialActivatedWarning": "一个用户只能有 1 个免费试用期。您已经使用了试用期。", - "ActivationRequirement": "你已经距离开始你的试用还有最后一步。
检查你的信息后,我们将激活你的许可证。一旦你的许可证激活,我们将向{0}发送电子邮件。请不要担心,这个过程不会太久!", + "Next": "下一页", + "StartTrial": "开始免费试用", + "ContactUsQuestions": "如有任何问题,请联系我们", + "TrialActivatedWarning": "一个用户只能有一次免费试用期。您已经使用了试用期。", + "ActivationRequirement": "
检查您的信息后,我们将激活您的许可证。许可证激活后,我们将向{0}发送一封电子邮件。别担心,这个过程不会花费太长时间!", "SaveAndDownload": "保存和下载", "CompanyNameValidationMessage": "公司名称太长!", "AddressValidationMessage": "地址太长!", - "TaxNoValidationMessage": "TAX/VAT No 太长了!", - "NotesValidationMessage": "备注字段太长!", - "CheckYourBillingInfo": "您只能创建一次发票!在创建发票之前检查您的帐单信息。", - "StartYourFreeTrial": "开始你的免费试用", + "TaxNoValidationMessage": "税号/增值税号太长!", + "NotesValidationMessage": "备注栏太长!", + "CheckYourBillingInfo": "您只能创建一次发票!创建发票前,请检查您的账单信息。", + "StartYourFreeTrial": "开始免费试用", "TrialLicenseModelInvalidErrorMessage": "以下字段之一无效:国家名称、公司规模、行业或使用目的。", - "Trial": "审判", + "Trial": "试用", "Purchased": "已购买", "PurchaseNow": "立即购买", - "PurchaseTrialLicenseMessage": "您的许可证到期日期是 {0}。
如果您想继续使用您在免费试用期内创建的项目,您需要更改 appsettings.secrets.json 文件中的许可证密钥。这是您的许可证密钥:", - "TrialLicenseExpireMessage": "您正在使用试用许可证,您的试用许可证将于 {0}到期。", + "PurchaseTrialLicenseMessage": "您的许可证到期日期为 {0}。
如果您想继续使用在免费试用期间创建的项目,则需要更改 appsettings.secrets.json 文件中的许可证密钥。以下是您的许可证密钥:", + "TrialLicenseExpireMessage": "您正在使用试用许可证,试用许可证将于 {0} 到期。", "TryForFree": "免费试用", - "TrialLicenseExpiredInfo": "您的试用许可期限已过!", - "DowngradeLicensePlan": "我将来可以降级到较低的许可版本吗?", - "DowngradeLicensePlanExplanation": "您不能降级现有的许可版本。 但是您可以购买新的较低许可版本并继续使用新许可证进行开发。 购买较低的许可版本后,您只需通过 ABP CLI 命令登录到新的许可版本:` abp login -o `。", - "LicenseTransfer": "许可证可以从一个开发者转移到另一个开发者吗?", - "LicenseTransferExplanation": "是的! 购买许可证后,您将成为许可证持有者,因此您可以访问组织管理页面。 组织具有所有者和开发者角色。 业主可以管理开发者席位和分配开发者。 每个分配的开发者都将通过 ABP CLI 命令登录系统,并拥有开发和支持权限。", - "UserOwnerDescription": "组织的“所有者”是此帐户的管理员。 他/她通过购买许可证和分配开发者来管理组织。 “所有者”不能在 ABP 商业项目中编写代码,不能下载 ABP 示例项目,也不能在支持的网站上进行提问。 如果你想拥有这些操作权限,你必须也将自己添加为开发人员。", - "UserDeveloperDescription": "“开发人员”可以在 ABP 商业版项目中编写代码,下载 ABP 示例项目,并在支持的网站上进行提问。 然而另一方面,“开发者”无法管理这个组织。", - "RemoveCurrentUserFromOrganizationWarningMessage": "您正在将自己从自己的组织中移除。 您将无法再管理此组织,您确定吗?", - "RenewExistingOrganizationOrCreateNewOneMessage": "您可以通过单击下面的 \"立即延长\"按钮来更新您组织的许可证,因此您可以将许可证到期日期延长 1 年。 如果您继续结帐,您将拥有一个新的组织。 您想继续开始新的组织许可吗?", - "PurchaseTrialOrganizationOrCreateNewOneMessage": "你有试用许可证。如果你想购买试用许可证,请点击“立即购买”按钮。如果你继续支付,你将会有一个新的组织。你想继续使用一个新的组织吗?", - "ExtendNow": "立即延长", - "CreateNewOrganization": "建立新的组织", - "RenewLicenseEarly": "如果我提前更新我的许可证,我会得到一整年吗?", - "RenewLicenseEarylExplanation": "当您在许可证到期日期之前续订许可证时,您的许可证到期日期仍将增加 1 年。 例如,如果您的许可在 {0}-06-06 到期,而您在 {0}-01-01 续订,那么您的新许可到期日期仍将是 {1}-06-06。", + "TrialLicenseExpiredInfo": "您的试用许可证已过期!", + "DowngradeLicensePlan": "将来可以降级到更低的许可证计划吗?", + "DowngradeLicensePlanExplanation": "您不能降级现有的许可证计划。但您可以购买新的较低许可证计划,并在新许可证上继续您的开发。购买较低许可证后,您只需通过 ABP CLI 命令登录到您的新许可证计划:abp login -o `.", + "LicenseTransfer": "许可证可以从一个开发者转让给另一个开发者吗?", + "LicenseTransferExplanation": "可以!购买许可证后,您将成为许可证持有者,因此可以访问组织管理页面。一个组织有所有者和开发者两个角色。所有者可管理开发人员席位并分配开发人员。每个分配的开发人员将通过 ABP CLI 命令登录系统,并拥有开发和支持权限。", + "UserOwnerDescription": "组织的 \"所有者 \"是该账户的管理员。他/她通过购买许可证和分配开发人员来管理组织。所有者 \"不能在 ABP 商业项目中编写代码,不能下载 ABP 示例项目,也不能在支持网站上提问。如果您想进行所有这些操作,您必须将自己添加为开发人员。", + "UserDeveloperDescription": "开发人员 \"可以在 ABP 商业项目中编写代码,下载 ABP 示例项目,并在支持网站上提问。另一方面,\"开发人员 \"不能管理该组织。", + "RemoveCurrentUserFromOrganizationWarningMessage": "你将从自己的组织中除名。你将不再能够管理这个组织,你确认吗?", + "RenewExistingOrganizationOrCreateNewOneMessage": "您可以通过点击下面的 \"立即延期 \"按钮为您的组织续签许可证,这样您就可以将许可证到期日延长一年。如果您继续结账,您将拥有一个新的组织。您想继续使用新机构吗?", + "PurchaseTrialOrganizationOrCreateNewOneMessage": "您拥有试用许可证。要购买试用许可证,请单击 \"立即购买 \"按钮。如果继续结账,您将拥有一个新的组织。您想继续使用新机构吗?", + "ExtendNow": "立即扩展", + "CreateNewOrganization": "创建新组织", + "RenewLicenseEarly": "如果我提前更新执照,我可以获得全年的执照吗?", + "RenewLicenseEarylExplanation": "如果您在许可证到期日之前更新许可证,许可证到期日将增加 1 年。例如,如果您的许可证到期日为 {0}-06-06,而您在 {0}-01-01 续费,则新的许可证到期日为 {1}-06-06。", "OpenSourceWebApplication": "开源Web应用程序", - "CompleteWebDevelopment": "一个完整的Web开发", - "ABPFrameworkDescription": "ABP 框架是一个完整的基础架构,可通过遵循软件开发和约定的最佳实践来创建现代 Web 应用程序。", + "CompleteWebDevelopment": "完整的网络开发", + "ABPFrameworkDescription": "ABP Framework 是一个完整的基础架构,可通过遵循软件开发的最佳实践和约定来创建现代Web应用程序。", "CommunityDescription": "分享您使用 ABP 框架的经验!", - "GetStarted": "开始使用", - "Views": "意见", - "LatestPosts": "最新的帖子", - "PreBuiltApplication": "预构建应用程序", - "DatabaseProviders": "数据库提供者", - "UIFrameworks": "用户界面框架", - "UsefulLinks": "有用的链接", + "GetStarted": "开始", + "Views": "视图", + "LatestPosts": "最新文章", + "PreBuiltApplication": "预建应用程序", + "DatabaseProviders": "数据库提供商", + "UIFrameworks": "UI框架", + "UsefulLinks": "实用链接", "Platform": "平台", - "CoolestCompaniesUseABPCommercial": "最酷的公司都已经在使用 ABP Commercial。", - "UserInterface": "用户界面", - "APIGateway": "网关", + "CoolestCompaniesUseABPCommercial": "最酷的公司已经在使用 ABP商业软件。", + "UserInterface": "UI", + "APIGateway": "API网关", "Microservice": "微服务", "Database": "数据库", - "Architecture": "结构", - "MicroserviceArchitectureExplanation": "这是一个完整的解决方案架构,由多个应用程序、API 网关、微服务和数据库组成,使用最新技术构建可扩展的微服务解决方案。", + "Architecture": "架构", + "MicroserviceArchitectureExplanation": "这是一个完整的解决方案架构,由多个应用程序、API 网关、微服务和数据库组成,利用最新技术构建可扩展的微服务解决方案。", "BusinessLogic": "业务逻辑", "DataAccessLayer": "数据访问层", - "Monolith": "单体", - "ModularArchitectureExplanation": "此启动模板提供了分层、模块化和基于 DDD 的解决方案架构,以构建清晰且可维护的代码库。", - "SeeDetails": "阅读详情", + "Monolith": "巨石", + "ModularArchitectureExplanation": "该初创企业模板提供了一个分层、模块化和基于 DDD 的解决方案架构,以构建一个简洁、可维护的代码库。", + "SeeDetails": "查看详情", "SeeDocumentation": "查看文档", - "Bs5Compatible": "Bootstrap 5 兼容的专业主题,非常适合您的管理网站。", + "Bs5Compatible": "兼容 Bootstrap 5 的专所有者题,非常适合您的管理网站。", "LeptonXTheme": "LeptonX 主题", - "LeptonXDark": "LeptonX 深色", - "LeptonXLight": "LeptonX 浅色", + "LeptonXDark": "LeptonX Dark", + "LeptonXLight": "LeptonX Light", "LeptonXSemiDark": "LeptonX 半深色", - "BuiltOnBs5Library": "基于 Bootstrap 5 库构建", + "BuiltOnBs5Library": "基于 Bootstrap 5 库", "FullyCompatibleWithBs5": "100% 兼容 Bootstrap 5 HTML 结构和 CSS 类", - "ResponsiveAndMobileCompatible": "响应式、移动兼容、RTL 支持", + "ResponsiveAndMobileCompatible": "响应式、移动兼容、支持 RTL", "ProvidesStylesForDatatables": "为数据表提供样式", "MultipleLayoutOptions": "多种布局选项", - "EasilyInstallAndUpgrade": "轻松安装和升级", + "EasilyInstallAndUpgrade": "易于安装和升级", "SupportForum": "支持论坛", - "TrustedBy": "授信于", - "OurPricing": "我们的 价格", + "TrustedBy": "值得信赖", + "OurPricing": "我们的定价ABP 商业版!", - "YourAccountDetails": "您的帐户详细信息", + "LeptonXThemeExplanation": "Lepton Theme 可根据系统设置更改主题。", + "PRO": "专业", + "WelcomeToABPCommercial": "欢迎访问 ABP商业网站!community.abp.io 是人们可以分享 ABP 相关文章的地方。 搜索文章、教程、代码示例、案例研究并结识与您同路的人。", + "AddDevelopers": "添加开发人员", + "StartDevelopment": "启动开发", + "CreateAndRunApplicationUsingStartupTemplate": "了解如何使用 ABP 商业启动模板创建和运行新的Web应用程序。", + "CommunityDescription2": "社区.abp.io是人们分享 ABP 相关文章的地方。搜索文章、教程、代码示例、案例研究,并结识与您志同道合的朋友。", "UseABPSuiteExplanation": "使用 ABP Suite 下载模块和主题的源代码。", - "ManageModulesWithSuite": "您还可以使用 Suite 管理您的 ABP 模块。", - "LearnHowToInstallSuite": "了解如何安装和使用 ABP 套件。", + "ManageModulesWithSuite": "您还可以使用套件管理 ABP 模块。", + "LearnHowToInstallSuite": "了解如何安装和使用 ABP Suite。", "SeeMore": "查看更多", - "SeeLess": "收起全文", + "SeeLess": "查看更少", "LayeredSolutionStructure": "分层解决方案结构", - "LayeredSolutionStructureExplanation": "该解决方案基于领域驱动设计原则和模式进行分层,以将您的业务逻辑与基础架构和集成隔离开来,并最大限度地提高代码的可维护性和可重用性。 ABP 框架已经提供了抽象、基类和指南来真正为您的应用程序实现 DDD。", - "MultipleUIOptions": "多个用户界面选项", - "MultipleUIOptionsExplanation": "我们喜欢不同的方式来创建用户界面。 此启动解决方案为您的业务应用程序提供了三种不同的 UI 框架选项。", - "MultipleDatabaseOptions": "多个数据库选项", - "MultipleDatabaseOptionsExplanation": "您有两个数据库提供程序选项(除了在单个应用程序中使用两者)。 使用 Entity Framework Core 处理任何关系数据库,当您需要编写低级查询以获得更好的性能时,可以选择使用 Dapper。 如果您需要使用基于文档的 NoSQL 数据库,MongoDB 是另一种选择。 虽然这些提供程序是良好集成、抽象和预配置的,但您实际上可以与任何可与 .NET 一起使用的数据库系统进行交互。", - "ModularArchitectureExplanation2": "模块化是 ABP.IO 平台的一等公民。 所有应用程序功能都被拆分为隔离良好的可选模块。 启动解决方案已经预装了基本的 ABP 商业模块。 您还可以创建自己的模块来为自己的应用程序构建模块化系统。", - "MultiTenancyForSaasBusiness": "SaaS 业务的多租户", - "MultiTenancyForSaasBusinessExplanation": "ABP 商业版 提供完整的端到端多租户系统来创建您的 SaaS(软件即服务)系统。 它允许租户通过动态数据库创建和迁移系统共享或拥有自己的数据库。", + "LayeredSolutionStructureExplanation": "该解决方案基于领域驱动设计原则和模式进行分层,将业务逻辑与基础架构和集成隔离开来,最大限度地提高代码的可维护性和可重用性。ABP 框架已经提供了抽象概念、基类和指南,以便为您的应用程序真正实现领域驱动设计。", + "MultipleUIOptions": "多种UI选项", + "MultipleUIOptionsExplanation": "我们喜欢以不同的方式创建UI。本启动解决方案为您的业务应用程序提供三种不同的UI框架选项。", + "MultipleDatabaseOptions": "多种数据库选项", + "MultipleDatabaseOptionsExplanation": "你有两种数据库提供程序可供选择(此外,你还可以在一个应用程序中同时使用两种数据库提供程序)。使用 Entity Framework Core 可以处理任何关系数据库,当需要编写底层查询以提高性能时,还可以选择使用 Dapper。如果需要使用基于文档的 NoSQL 数据库,MongoDB 是另一个选择。虽然这些提供程序都经过了很好的集成、抽象和预配置,但您实际上可以与任何可以使用.NET的数据库系统进行交互。", + "ModularArchitectureExplanation2": "模块化是 ABP.IO 平台的一等公民。所有应用功能都被分割成独立的可选模块。启动解决方案已经预装了基本的ABP商业模块。您还可以创建自己的模块,为自己的应用程序构建模块化系统。", + "MultiTenancyForSaasBusiness": "为您的 SaaS 业务提供多租户服务", + "MultiTenancyForSaasBusinessExplanation": "ABP Commercial 提供完整的端到端多租户系统,以创建您的 SaaS(软件即服务)系统。通过即时数据库创建和迁移系统,租户可共享或拥有自己的数据库。", "MicroserviceStartupSolution": "微服务启动解决方案", - "MicroserviceArchitectureExplanation2": "您可以将它用于您的下一个微服务系统,以利用预先构建的基础解决方案和提炼的经验。", - "PreIntegratedTools": "预集成到流行工具", - "PreIntegratedToolsExplanation": "该解决方案已集成到行业标准工具和技术中,而您可以随时更改它们并集成到您喜欢的工具中。", - "SingleSignOnAuthenticationServer": "单点登录认证服务器", - "SingleSignOnAuthenticationServerExplanation": "该解决方案有一个身份验证服务器应用程序,其他应用程序将其用作具有 API 访问管理功能的单点登录服务器。 它基于 IdentityServer。", - "WebAppsWithGateways": "2 个 Web 应用程序和 2 个 API 网关", - "WebAppsWithGatewaysExplanation": "该解决方案包含两个 Web 应用程序,每个应用程序都有一个专用的 API 网关(BFF - Backend For Frontend 模式)。", + "MicroserviceArchitectureExplanation2": "您可以为您的下一个微服务系统获取它,以利用预构建的基础解决方案和提炼的经验。", + "PreIntegratedTools": "预集成到常用工具", + "PreIntegratedToolsExplanation": "该解决方案已集成到行业标准工具和技术中,同时您还可以随时更改它们并集成到您最喜欢的工具中。", + "SingleSignOnAuthenticationServer": "单点登录验证服务器", + "SingleSignOnAuthenticationServerExplanation": "该解决方案有一个身份验证服务器应用程序,其他应用程序将其用作具有 API 访问管理功能的单点登录服务器。它以 IdentityServer 为基础。", + "WebAppsWithGateways": "2 个Web应用程序和 2 个API网关", + "WebAppsWithGatewaysExplanation": "该解决方案包含两个Web应用程序,每个程序都有一个专用的 API 网关(BFF - Backend For Frontend 模式)。", "BackOfficeApplication": "后台应用程序", - "BackOfficeApplicationExplanation": "系统的实际 Web 应用程序,具有多个 UI 框架选项。 您可以创建任何类型的业务应用程序。", + "BackOfficeApplicationExplanation": "系统的实际Web应用程序,具有多种UI框架选项。您可以创建任何类型的业务应用程序。", "LandingWebsite": "登陆网站", - "LandingWebsiteExplanation": "可用于多种目的的通用登陆/公共网站,例如介绍您的公司、销售您的产品等。", - "ABPFrameworkEBook": "掌握 ABP 框架电子书", - "MasteringAbpFrameworkEBookDescription": "包含在您的 ABP 商业许可证中", + "LandingWebsiteExplanation": "通用登陆/公共网站,可用于多种用途,如介绍公司、销售产品等。", + "ABPFrameworkEBook": "掌握 ABP 框架》电子书", + "MasteringAbpFrameworkEBookDescription": "包含在 ABP 商业许可证中", "FullName": "全名", - "LicenseTypeNotCorrect": "许可类型不正确!", + "LicenseTypeNotCorrect": "许可证类型不正确!", "Trainings": "培训", "ChooseTrainingPlaceholder": "选择培训...", - "DoYouNeedTrainings": "您需要这些培训之一吗?", - "DoYouNeedTraining": "您需要 {0} 培训吗?", - "GetInTouchUs": "请与我们联系", - "ForMoreInformationClickHere": "如需更多信息,请点击此处。", - "IsGetOnboardingTraining": "您想获得入职和 Web 应用程序开发培训吗?", - "OnboardingWebApplicationDevelopmentTrainingMessage": "要安排您的培训日历,请在创建组织后联系 {0}", - "CustomPurchaseMessage": "对于下一步,单击 {0} 与我们联系。", - "Note": "说明", + "DoYouNeedTrainings": "您需要这些培训吗?", + "DoYouNeedTraining": "您需要{0}培训吗?", + "GetInTouchUs": "联系我们", + "ForMoreInformationClickHere": "如需了解更多信息,请点击此处。", + "ForMoreInformationClickHereByClass": "更多信息,请点击 此处。", + "IsGetOnboardingTraining": "您想参加引导流程和Web应用程序开发培训吗?", + "OnboardingWebApplicationDevelopmentTrainingMessage": "要安排培训日程,请在创建组织后联系 {0}", + "CustomPurchaseMessage": "下一步,请点击 {0} 联系我们。", + "Note": "备注", "AdditionalNote": "附加说明", - "OnboardingTrainingFaqTitle": "你有 ABP 熟练使用培训吗?", - "OnboardingTrainingFaqExplanation": "是的,我们有 ABP 培训服务来帮助您快速启动您的 ABP 项目。 您将从 ABP 核心团队成员那里了解 ABP,并获得开始您的 ABP 项目的技能。 在 ABP 培训中,我们将解释如何设置开发环境、安装所需工具、创建功能齐全的 CRUD 页面。 培训将会以直播的形式并使用 Zoom 应用程序,我们也对使用其他在线会议平台持开放态度。 主要培训语言为英语。 您也可以在会议期间询问有关 ABP 的问题。 我们将安排一个方便双方的时间和日期。 要获取更多信息,请通过 info@abp.io 联系我们。", - "AddBasket": "添加到购物车", - "SendTrainingRequest": "发送培训请求", - "OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* 本文件的英文版本为最新版本,如有任何争议,以英文版本为准。", - "Pricing_Page_Title": "价格和计划", - "Pricing_Page_Description": "现在就选择您的业务及需要的特性和功能。 购买 ABP 商业许可证创建无限量项目。", - "Pricing_Page_HurryUp": "赶快行动吧!", - "Pricing_Page_BuyLicense": "在 1 月 16 日前以 2021 年价格 购买许可证!", - "Pricing_Page_ValidForExistingCustomers": "也适用于现有客户和许可证续订。", - "Pricing_Page_Hint1": "许可价格包括一定数量的开发者席位。 如果您有更多的开发人员,您可以随时购买额外的席位。", - "Pricing_Page_Hint2": "您现在或将来都可以购买更多的开发者许可证。 许可证是基于席位的,因此您可以将席位从开发人员转移到另一个开发人员。", - "Pricing_Page_Hint3": "您可以使用您的许可证开发无限数量的不同产品。", - "Pricing_Page_Hint4": "ABP Suite 是帮助您开发以提高生产力的工具。 它支持生成 CRUD 页面和创建新项目。", - "Pricing_Page_Hint5": "您可以在应用程序中使用所有预构建的模块。", - "Pricing_Page_Hint6": "您可以在应用程序中使用所有预构建的主题。", - "Pricing_Page_Hint7": "启动模板是一种 Visual Studio 解决方案,可让您快速启动项目。 所有基本模块都为您添加和预配置。", - "Pricing_Page_Hint8": "掌握 ABP 框架电子书解释了如何使用最佳实践实施 .NET 解决方案。它在 Amazon.com 上出售,您可以在许可证范围内免费下载该书。", - "Pricing_Page_Hint9": "您可以下载任何模块的源代码。 您可能希望将源代码添加到您的解决方案中以进行彻底的更改,或者出于安全原因将其自己保留。", - "Pricing_Page_Hint10": "许可证是终身的。 这意味着您可以永远继续开发您的应用程序。 在许可期限内(1 年,除非您续订)授予访问最新版本并获得支持。", - "Pricing_Page_Hint11": "部署没有限制! 您可以根据需要部署到任意数量的服务器,包括云服务或本地。", - "Pricing_Page_Hint12": "您可以在有效许可期内将模块、主题和工具更新到最新版本。 在您的许可证到期后,您需要对其进行续订,以继续获取错误修复、新功能和增强功能的更新。", - "Pricing_Page_Hint13": "您可以获得一年的高级支持(您可以续订许可证以延长它)。", - "Pricing_Page_Hint14": "团队和营业许可有事件/问题计数限制。 如果您购买额外的开发者许可,您的事件限制会按开发人员增加 {0}(对于团队许可)或 {1}(对于商业许可)每个开发者增加。", - "Pricing_Page_Hint15": "只有企业许可证包括私人支持。 您可以直接向 ABP 团队发送电子邮件或在 support.abp.io 上使用私人门票选项提问。 私人门票对公众不可见。", - "Pricing_Page_Hint16": "您可以下载所有 ABP 主题的源代码。 您可能希望将源代码添加到您的解决方案中以进行彻底的更改,或者出于安全原因将其自己保留。", - "Pricing_Page_Testimonial_1": "ABP Commercial 允许 SC Ventures 在 9 个月内交付银行级多租户silo数据库 SaaS 平台,以支持来自多个集成锚点的大额发票的应收账款/应付账款供应链融资。 ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化的微服务码部署到生产中。", - "Pricing_Page_Testimonial_2": "我们看到了使用 ABP Commercial 能减少定制开发项目开销的价值。 并且团队能够在不同的项目流中统一代码模式。 我们在框架中看到了能比以前更快地构建新功能的更多潜力。 我们相信我们将会持续地看到使用 ABP Commercial 的价值。", - "Pricing_Page_Testimonial_3": "我们大爱 ABP。 我们不必从头开始编写所有内容。 我们从\"开箱即用\"的功能开始,只需关注我们真正需要编写的内容。 此外,ABP 架构良好,代码质量高,错误少。 如果我们需要自己来编写所需的一切,我们可能需要花费数年时间。 另一点让我们喜欢的是新版本、问题修复或改进每隔一周很快地就会出现。 我们不会等太久。", - "Pricing_Page_Testimonial_4": "ABP 商业版 是一款很值得推荐的出色产品。 是在一个可配置的平台上为我们的客户推向市场的商业产品。 其框架和工具为任何团队提供的快速启动值得每一分钱。 ABP 商业版 最适合我们的需求。", - "Pricing_Page_Testimonial_5": "ABP Framework 不仅是一个框架,它还是项目开发/管理的指南,因为它提供了 DDD、GenericRepository、DI、微服务和模块化培训。 即使你不打算使用框架本身,你也可以通过 docs.abp.io 进行自己的开发,该文档已经做好了专业的准备(OpenIddict、Redis、Quartz 等)。 因为很多东西都是预先构建的,它大大缩短了项目开发时间(例如登录页面、异常处理、数据过滤、种子、审计日志、本地化、自动 API 控制器等)。 作为我们应用程序的一个示例,我使用本地事件总线进行库存控制。 因此我可以通过编写库存处理程序来管理订单移动。 不为 CreationTime,CreatorId 浪费时间真是太好了。 它们正在自动填充。", - "Pricing_Page_Testimonial_6": "ABP Framework 是一个很好的框架,但它需要时间来理解它使用的不同层、类和库(特别是 ABP)。 我花了很多时间阅读代码库,但是 ABP Commercial 为我们节省了创建项目专业实体 (AR) 和链接到每个实体的存储库的时间。 我也喜欢 ABP 中使用的方法非常成熟,我们知道它基于 DDD 和单体。", - "Pricing_Page_Testimonial_7": "作为一家初创公司,我们需要快速迭代并在样板和非核心功能上花费最少的时间。\n我们的工程师从经验丰富的工程师到初级工程师,我们需要一个共同的理解和一种分享技术和领域知识的方式,ABP 允许我们这样做是因为他们提供了很好的指南和文档。\n有些事情我们不必担心,因为它们与 ABP 一起开箱即用。\nABP 帮助我们简化了快速原型设计和开发,从功能开始到生产不到 4 周。凭借许可证中包含的所有高级功能,ABP 在软件工程方面为我们提供了“盒子里的启动”。", - "AbpBookDownloadArea_ClaimYourEBook": "领取您的掌握ABP框架电子书", - "AddMemberModal_Warning_1": "如果您尝试添加的用户名在系统中不存在,请让您的团队成员在 {0} 并与您分享他/她帐户的用户名。", - "MyOrganizations_Detail_WelcomeMessage": "欢迎加入您的组织,{0}", - "MyOrganizations_Detail_OrganizationManagement": "组织管理", + "OnboardingTrainingFaqTitle": "您有 ABP 上岗培训吗?", + "OnboardingTrainingFaqExplanation": "是的,我们有 ABP 培训服务,帮助您快速启动 ABP 项目。您将从 ABP 核心团队成员那里了解 ABP,并获得开始 ABP 项目的技能。在引导流程培训中,我们将讲解如何设置您的开发环境、安装所需的工具以及创建一个功能齐全的 CRUD 页面。培训将是实时的,将使用 Zoom 应用程序,我们也欢迎使用其他在线会议平台。培训语言为英语。您也可以在培训过程中提出有关 ABP 的问题。我们将为双方安排一个方便的时间和日期。如需了解更多信息,请通过info@abp.io与我们联系。", + "AddBasket": "添加到购物篮", + "SendTrainingRequest": "发送培训申请", + "OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* 本文档的英文版本为最新版本,任何争议均以英文版本为准。", + "Pricing_Page_Title": "定价与计划", + "Pricing_Page_Description": "现在就选择您的业务所需的特性和功能。购买 ABP 商业许可证,创建无限项目。", + "Pricing_Page_HurryUp": "快点", + "Pricing_Page_BuyLicense": "在 1 月 16 日前,以 2021 价格购买许可证!", + "Pricing_Page_ValidForExistingCustomers": "同样适用于现有客户和许可证续期。", + "Pricing_Page_Hint1": "许可证价格包含一定数量的开发人员席位。如果您有更多的开发人员,可以随时购买额外的席位。", + "Pricing_Page_Hint2": "您可以现在或将来购买更多的开发人员许可证。许可证以席位为基础,因此您可以将一个席位从一个开发人员转给另一个开发人员。", + "Pricing_Page_Hint3": "您可以使用许可证开发无限量的不同产品。", + "Pricing_Page_Hint4": "ABP Suite 是一款辅助开发工具,可提高您的工作效率。它支持生成 CRUD 页面和创建新项目。", + "Pricing_Page_Hint5": "您可以在应用程序中使用所有预建模块。", + "Pricing_Page_Hint6": "您可以在应用程序中使用所有预置主题。", + "Pricing_Page_Hint7": "启动模板是一种 Visual Studio 解决方案,可帮助您快速启动项目。所有基本模块都已为您添加和预配置。", + "Pricing_Page_Hint8": "Mastering ABP Framework》电子书介绍了如何利用最佳实践实施.NET解决方案。该书在 Amazon.com 上有售,您可凭许可证免费下载。", + "Pricing_Page_Hint9": "您可以下载任何模块的源代码。您可能希望将源代码添加到您的解决方案中,以便进行大刀阔斧的改动,或者出于安全考虑自己保留源代码。", + "Pricing_Page_Hint10": "许可证终身有效。这意味着您可以永远继续开发您的应用程序。在许可证有效期内(1 年,除非您续约),您可以访问最新版本并获得支持。", + "Pricing_Page_Hint11": "部署不受限制!您可以将其部署到任意数量的服务器上,包括云服务或内部部署。", + "Pricing_Page_Hint12": "在许可证有效期内,您可以将模块、主题和工具更新到最新版本。许可证到期后,您需要续费才能继续获得漏洞修复、新功能和增强功能的更新。", + "Pricing_Page_Hint13": "您可以获得为期一年的高级支持(您可以更新许可证以延长支持期限)。", + "Pricing_Page_Hint14": "团队和企业许可证有事件/问题数量限制。如果您购买了额外的开发人员许可证,每个开发人员的事件数限制将增加{0}(团队许可证)或{1}(商业许可证)。", + "Pricing_Page_Hint15": "只有企业许可证包含私人支持。您可以直接向 ABP 团队发送电子邮件,或使用私人票据选项在 support.abp.io 上提问。私人票据对公众不可见。", + "Pricing_Page_Hint16": "您可以下载所有 ABP 主题的源代码。您可能想将源代码添加到您的解决方案中,以便进行彻底的修改,或者出于安全原因将其保留。", + "Pricing_Page_Testimonial_1": "ABP Commercial 使 SC Ventures 能够在 9 个月内交付银行级多租户筒仓数据库 SaaS 平台,以支持应收账款/应付账款供应链融资,处理来自多个集成锚的大额发票。ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化微服务堆栈部署到生产中。", + "Pricing_Page_Testimonial_2": "我们看到了使用 ABP Commercial 减少定制开发项目开销的价值。团队能够统一不同项目流中的代码模式。我们在该框架中看到了更大的潜力,使我们能够比以前更快地构建新功能。我们相信,我们将不断看到利用 ABP 商业软件的价值。", + "Pricing_Page_Testimonial_3": "我们热爱 ABP。我们不必从头开始编写所有内容。我们从开箱即用的功能开始,只需专注于真正需要编写的内容。此外,ABP 结构合理,代码质量高,错误较少。如果我们必须自己编写所有需要的代码,我们可能需要花费数年时间。我们还喜欢的一点是,新版本、问题修复或改进每隔一周就会很快发布。我们不会等太久。", + "Pricing_Page_Testimonial_4": "ABP Commercial 是一款非常出色的产品,值得推荐。在一个可配置的平台上为我们的客户向市场提供商业产品。该框架和工具为任何团队提供的跳跃式启动都是物有所值的。ABP Commercial 最符合我们的需求。", + "Pricing_Page_Testimonial_5": "ABP 框架不仅是一个框架,还是项目开发/管理的指南,因为它提供了 DDD、GenericRepository、DI、Microservice 和 Modularity 培训。即使你不打算使用框架本身,你也可以使用 docs.abp.io 进行开发,因为它为你提供了完善和专业的准备(OpenIddict、Redis、Quartz 等)。由于很多东西都是预构建的,因此大大缩短了项目开发时间(如登录页面、异常处理、数据过滤、播种、审计日志、本地化、自动 API 控制器等)。以我们的应用程序为例,我将本地事件总线用于库存控制。因此,我可以通过编写库存处理程序来管理订单的变动。这样就不会因为创建时间和创建者 ID 而浪费时间了。它们会被自动填充。", + "Pricing_Page_Testimonial_6": "ABP Framework 是一个很好的框架,但需要时间来理解它所使用的不同层、类和库(尤其是 ABP)。我花了很多时间阅读代码库,但 ABP Commercial 节省了我们创建项目专业实体(AR)和与每个实体链接的资源库的时间。我还喜欢 ABP 中使用的非常成熟的方法;我们知道它是基于 DDD 和 monolith 的。", + "Pricing_Page_Testimonial_7": "作为一家初创公司,我们需要快速迭代,并尽量少花时间在模板和非核心功能上。\n我们的工程师从经验丰富的工程师到初级工程师都有,我们需要一种共识和一种分享技术和领域知识的方式,ABP 凭借其出色的指南和文档让我们做到了这一点。\n由于 ABP 提供了开箱即用的功能,所以有些事情我们无需担心。\nABP帮助我们简化了快速原型设计和开发,从功能开始到投入生产不到4周时间。ABP的所有高级功能都包含在许可证中,在软件工程方面为我们提供了 \"盒式启动\"。", + "Pricing_Page_Testimonial_8": "我会向所有希望扩大客户可用产品范围的人推荐 ABP commercial。当需要使用分布式企业环境(Angular、WPF、Win&Linux)时,ABP 的表现非常出色。除了他们的产品,我们还喜欢他们的支持,这让我们的工作变得更快、更轻松。我们已经知道,我们已经找到了未来的最佳合作伙伴,他们将支持我们拓展业务。", + "Pricing_Page_Testimonial_9": "我们公司只有两名员工,已经经营了 20 多年。\n就我们与 ABP Commercial 合作的经历而言,一位客户找到我们,要求我们在现代环境中开发一个新的人力资源应用程序,以取代他们使用了 25 年的 Access 应用程序。我们决定从桌面解决方案过渡到基于网络的解决方案。\n\n当时,我们对Web应用程序和.NET知之甚少,但我们偶然发现了ABP商业软件,在ABP框架、技术文档和ABP Suite的帮助下,我们不仅能够按照客户的要求开发应用程序,还能在一年内成功地在.NET环境中工作。", + "AbpBookDownloadArea_ClaimYourEBook": "申请您的 《掌握 ABP 框架》 电子书", + "AddMemberModal_Warning_1": "如果系统中不存在您要添加的用户名,请让您的团队成员在{0}上注册,并与您共享他/她的用户名。", + "MyOrganizations_Detail_WelcomeMessage": "欢迎贵组织,{0}", + "MyOrganizations_Detail_OrganizationManagement": "组织管理{1} 上的 PRO 包的令牌。 ", - "MyOrganizations_Detail_YourPrivateNugetSource": "您的私有 NuGet 源是 {0}", - "MyOrganizations_Detail_PrivateNugetSourceWarning": "这将自动添加一个源到您的 ABP 解决方案中的 NuGet.Config。 不要与未经授权的用户共享您的私钥!", - "MyOrganizations_Detail_DeveloperSeatInfo": "您正在使用您的 {1} 个开发者席位中的 {0} 个。", - "NeedMoreSeatsForYourTeam": "您的团队需要更多席位吗?", - "MyOrganizations_Detail_PricePerYear": "{0} / 每年", - "MyOrganizations_Detail_PurchaseDeveloperSeats": "购买开发者席位", + "MyOrganizations_Detail_ApiKeyDescription": "API 密钥是 {1}. 上托管的 PRO 包的标记。", + "MyOrganizations_Detail_YourPrivateNugetSource": "您的 NuGet 私有源是 {0}", + "MyOrganizations_Detail_PrivateNugetSourceWarning": "此密钥会自动添加到 ABP 解决方案中的 NuGet.Config 中。请勿与未经授权的用户共享您的私人密钥!", + "MyOrganizations_Detail_DeveloperSeatInfo": "您正在使用{1}个开发人员席位中的{0}个。", + "NeedMoreSeatsForYourTeam": "您的团队需要更多座位?", + "MyOrganizations_Detail_PricePerYear": "{0}/每年", + "MyOrganizations_Detail_PurchaseDeveloperSeats": "购买开发人员席位", "Invoices": "发票", "RequestInvoice": "索取发票", "OrderNumber": "订单号", "Date": "日期", "Products": "产品", - "TotalPrice": "总价格", + "TotalPrice": "总价", "ThereIsNoInvoice": "没有发票", - "MyOrganizations_Detail_PaymentProviderInfo": "如果您通过 {0} 网关购买了许可证,它会将 PDF 发票发送到您的电子邮件地址,请参阅 {0} 发票。", - "MyOrganizations_Detail_PayUInfo": "如果您是通过PayU网关购买的,请点击\"索取发票\"按钮并填写账单信息。", + "MyOrganizations_Detail_PaymentProviderInfo": "如果您通过 {0} 网关购买了许可证,系统会向您的电子邮箱发送 PDF 发票,请参见 {0} invoicing. 。", + "MyOrganizations_Detail_PayUInfo": "如果您通过 Iyzico 网关购买,请单击 \"索取发票 \"按钮并填写账单信息。", "MyOrganizations_Detail_ConclusionInfo": "您的发票申请将在 {0} 个工作日内完成。", - "ExtendYourLicense": "延长您的 {0} 许可", + "ExtendYourLicense": "扩展您的 {0} 许可证", "Continue": "继续", "PurchaseLicense": "购买 {0} 许可证", "DownloadInvoiceModal_DownloadInvoice": "下载发票", "DownloadInvoiceModal_SaveInformationOnlyOnce": "您只能保存一次账单信息。", - "InvoiceModal_EnterCompanyName": "请输入您的法定公司名称...", - "InvoiceModal_EnterCompanyAddress": "请输入您的法定公司地址...", - "InvoiceModal_EnterTaxNumber": "请输入您的税号/增值税号(如果有)...", - "RequestInvoiceModal_EnterNotes": "请输入您的有关发票的额外信息...", - "PrePayment_PayWithIyzico": "您将使用 Iyzico 付款", - "ContinueToCheckout": "继续结帐", - "PrePayment_IyzicoRedirectionInfo": "您将被重定向到 Iyzico 支付网关以安全地完成您的购买。", + "InvoiceModal_EnterCompanyName": "输入您的合法公司名称...", + "InvoiceModal_EnterCompanyAddress": "输入您的法定公司地址...", + "InvoiceModal_EnterTaxNumber": "输入您的税号/增值税号(如果有)...", + "RequestInvoiceModal_EnterNotes": "输入您关于发票的额外信息...", + "PrePayment_PayWithIyzico": "您将使用 Iyzico 支付", + "ContinueToCheckout": "继续结账", + "PrePayment_IyzicoRedirectionInfo": "您将被重定向到 Iyzico 支付网关,安全地完成购买。", "PrePayment_IyzicoAcceptVisaAndMasterCard": "Iyzico 接受 Visa 和 MasterCard。", "Purchase": "购买", - "AcceptTermsAndConditions": "我已阅读、理解并接受隐私政策条款和条件 EULA。", - "AcceptTermsAndConditionsWarningMessage": "请接受隐私政策和条款和条件", - "SelectGatewayToContinue": "请选择一个网关以继续!", + "AcceptTermsAndConditions": "我已阅读、理解并接受隐私政策条款和条件以及 EULA。", + "AcceptTermsAndConditionsWarningMessage": "请接受隐私政策及条款和条件", + "SelectGatewayToContinue": "请选择一个网关继续!", "GatewaySelection_SelectGateway": "选择支付网关", - "GatewaySelection_RedirectionMessage": "接下来,您将被重定向到所选支付网关的交易网站。", - "PaymentSucceed_PaymentSuccessMessage": "支付成功", + "GatewaySelection_RedirectionMessage": "接下来,您将被重定向到所选支付网关的网站进行交易。", + "PaymentSucceed_PaymentSuccessMessage": "付款成功", "PaymentSucceed_ThanksForPurchase": "感谢您的购买!", "PaymentSucceed_CreateYourOrganization": "创建您的组织", - "PaymentSucceed_AddMeAsDeveloper": "我是开发人员,请将我作为开发人员添加到我的组织中。", + "PaymentSucceed_AddMeAsDeveloper": "我也是一名开发人员,请将我作为开发人员加入我的组织。", "PaymentSucceed_CreateOrganization": "创建组织", - "PaymentSucceed_OrganizationDescription": "一个组织由开发人员和所有者组成。 开发人员是在 ABP 项目上编写代码的用户,将受益于 {1} 网站。 所有者是分配开发者席位和管理许可的用户。", - "PaymentSucceed_ViewOrganization": "点击这里查看组织", - "Purchase_TotalAnnualPrice": "总计 (年费)", + "PaymentSucceed_OrganizationDescription": "组织由开发者和所有者组成。开发人员是在 ABP 项目上编写代码的用户,他们将受益于 {1} 网站。所有者是分配开发者席位和管理许可的用户。", + "PaymentSucceed_ViewOrganization": "点击此处查看组织", + "Purchase_TotalAnnualPrice": "总计 (年费){0} 每个开发者", + "Purchase_OnboardingTraining": "引导流程和Web应用程序开发现场培训", + "TotalDeveloperPrice": "开发者总价", + "Purchase_PricePerDeveloper": "{0} {1} 每名开发人员", "Purchase_IncludedDeveloperInfo": "{0} {1} 包括在内。", - "Purchase_LicenseExtraDeveloperPurchaseMessage": "{0} 许可 包含 {1} 个开发者。 您可以现在或以后添加其他开发人员。", - "StartupTemplates_Page_Title": "ABP启动模板", - "StartupTemplates_Page_Description": "ABP 商业版 允许您构建任何复杂程度的解决方案。 它提供了两种主要的预构建启动解决方案。 您可以选择最接近您要求的解决方案,并在此基础上构建您自己的定制解决方案。", + "Purchase_LicenseExtraDeveloperPurchaseMessage": "{0}许可包括{1}个开发人员。您可以添加其他开发人员。", + "StartupTemplates_Page_Title": "ABP 启动模板", + "StartupTemplates_Page_Description": "ABP Commercial 允许您构建任何复杂程度的解决方案。它提供两种主要的预建启动解决方案。您可以选择最符合您要求的方案,并在此基础上构建自己的定制解决方案。", "MicroserviceStartupSolutionForDotnet": ".NET 微服务启动解决方案", - "MonolithSolutionForDotnet": ".NET 的单体(模块化)解决方案", - "TrainingDetailsHeaderInfo_TrainingHour": "{0} 小时", + "MonolithSolutionForDotnet": ".NET的单体(模块化)解决方案", + "TrainingDetailsHeaderInfo_TrainingHour": "{0}小时", "Trainings_Content": "培训内容", - "Trial_Page_StartYourFreeTrial": "开始您的免费试用", - "TrialLicenseFeatures": "你将能够享受所有 ABP 商业特性", - "TrialPeriodDays": "你将有 {0} 天的团队许可证", - "TrialForumSupportIncident": "你将有 {0} 个论坛支持事件", + "Trial_Page_StartYourFreeTrial": "开始免费试用所有账户", - "ProjectCreatedSuccess_Page_Title": "您的项目已创建", + "Faq_Page_OtherCurrenciesInfo": "有关其他货币,请参见 所有账户。", + "ProjectCreatedSuccess_Page_Title": "您创建的项目", "ProjectCreatedSuccess_Page_Description": "您的 ABP 项目创建成功!", "Suite_Page_Title": "ABP Suite", - "Suite_Page_Description": "ABP Commercial 提供快速应用程序开发工具以提高开发人员的工作效率。 ABP 套件 允许您轻松创建 CRUD 页面。", - "Themes_Page_Title": "ABP主题", - "Themes_Page_Description": "ABP 商业版 提供多种专业、现代的 UI 主题。 创建免费演示以快速查看 UI 的外观。", - "Tools_Page_Title": "快速应用程序开发工具", - "Tools_Page_Description": "ABP 商业版 提供快速应用程序开发工具以提高开发人员的工作效率。 ABP 套件 允许您轻松创建 CRUD 页面。", + "Suite_Page_Description": "ABP 商业版提供快速应用程序开发工具,以提高开发人员的工作效率。ABP Suite 可让您轻松创建 CRUD 页面。", + "Themes_Page_Title": "ABP 主题", + "Themes_Page_Description": "ABP Commercial 提供多种专业、现代的UI主题。创建免费演示,快速了解UI的外观。", + "Tools_Page_Title": "快速应用开发工具", + "Tools_Page_Description": "ABP 商业版提供快速应用程序开发工具,以提高开发人员的工作效率。ABP Suite 可让您轻松创建 CRUD 页面。", "DeveloperPrice": "开发者价格", - "AdditionalDeveloperPaymentInfoSection_AdditionalDevelopers": "{0} 开发者", - "LicenseRemainingDays": " {0} 天", - "ExtendPaymentInfoSection_Description": "通过延长/续订您的许可,您将继续获得高级支持。 您还将能够获得模块和主题的重大更新。 您将能够继续创建新项目。 您仍然可以使用 ABP 套件 来加速您的开发。", - "LicenseRenewalPrice": "许可证续订价格", + "AdditionalDeveloperPaymentInfoSection_AdditionalDevelopers": "{0}<小>开发人员 {0} 天", + "ExtendPaymentInfoSection_Description": "延长/续订许可证后,您将继续获得高级支持。您还可以获得模块和主题的主要或次要更新。您还可以继续创建新项目。您还可以使用 ABP Suite 来加快开发速度。", + "LicenseRenewalPrice": "许可证续期价格", "LicensePrice": "许可证价格", - "TrialLicensePaymentInfoSection_Description": "购买许可证:通过购买许可证,您将继续获得高级支持。 您还将能够获得模块和主题的重大更新。 您将能够继续创建新项目。 而且您仍然可以使用 ABP 套件 加速您的开发。
请参阅 许可证比较表来查看许可证类型之间的差异。", + "TrialLicensePaymentInfoSection_Description": "购买许可证:购买许可证后,您将继续获得高级支持。您还可以获得模块和主题的主要或次要更新。您还可以继续创建新项目。ABP Suite可加快您的开发速度。
请参阅许可证对照表,查看许可证类型之间的差异。", "SelectTargetLicense": "选择目标许可证", - "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "是的,将我的许可证到期日期延长 1 年。", - "UpgradePaymentInfoSection_WantToExtendLicense": "您想将许可证再延长 1 年吗?", - "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "升级不会延长您的许可证到期日期!", - "UpgradePaymentInfoSection_LicenseUpgradeDescription": "通过升级您的许可证,您将升级到更高的许可证类型,这将使您获得额外的好处。 请参阅许可证比较表以查看许可证类型之间的差异。", + "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "是,将我的许可证有效期延长一年。", + "UpgradePaymentInfoSection_WantToExtendLicense": "您想将许可证延期一年吗?", + "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "升级不会延长许可证有效期!", + "UpgradePaymentInfoSection_LicenseUpgradeDescription": "升级许可证后,您将升级到更高的许可证类型,从而获得更多好处。请参阅 许可证对照表,查看许可证类型之间的差异。", "Landing_Page_CustomerStories": "客户故事", - "Landing_Page_OurGreatCustomers": "我们的大客户", - "Landing_Page_WebApplicationFramework": "Web应用框架", - "Landing_Page_WebDevelopmentPlatform": "网页开发平台", - "Landing_Page_CompleteWebDevelopmentPlatform": "完整的网页开发平台", - "Landing_Page_TryFreeDemo": "试用免费演示", - "Landing_Page_StartingPointForWebApplications": "基于 ASP.NET Core 的 Web 应用程序的起点! 它是基于最佳 Web 开发的 ABP 框架。", - "Landing_Page_AbpProvidesSoftwareInfrastructure": "ABP 框架提供了一个软件基础架构来开发基于最佳实践的优秀 Web 应用程序。", + "Landing_Page_OurGreatCustomers": "我们伟大的客户", + "Landing_Page_WebApplicationFramework": "Web应用程序框架", + "Landing_Page_WebDevelopmentPlatform": "网络开发平台", + "Landing_Page_CompleteWebDevelopmentPlatform": "完整的网络开发平台", + "Landing_Page_TryFreeDemo": "免费试用", + "Landing_Page_StartingPointForWebApplications": "基于 ASP.NET Core 的Web应用程序的起点!它基于 ABP 框架,可实现最佳网络开发。", + "Landing_Page_AbpProvidesSoftwareInfrastructure": "ABP Framework 提供软件基础架构,以最佳实践开发优秀的Web应用程序。", "Landing_Page_MicroserviceCompatibleArchitecture": "微服务兼容架构", - "Landing_Page_PreBuiltApplicationModulesAndThemes": "预建的应用程序模块和主题", + "Landing_Page_PreBuiltApplicationModulesAndThemes": "预建应用程序模块和主题", "Landing_Page_MultiTenantArchitecture": "多租户架构", - "Landing_Page_MultiTenancyDescription": "SaaS 应用程序变得简单! 从数据库到 UI 的集成多租户。", - "Landing_Page_DDDIntroduction": "基于 DDD 模式和原则设计和开发。 为您的应用程序提供分层模型。", - "Landing_Page_CrossCuttingConcernsInfo": "用于授权、验证、异常处理、缓存、审计日志记录、事务管理等的完整基础架构。", - "Landing_Page_PreBuiltApplicationModules": "预建应用程序模块,其中包括最常见的 Web 应用程序要求。", + "Landing_Page_MultiTenancyDescription": "SaaS 应用程序变得简单!从数据库到UI都集成了多租户功能。", + "Landing_Page_DDDIntroduction": "基于 DDD 模式和原则进行设计和开发。为您的应用程序提供分层模型。", + "Landing_Page_CrossCuttingConcernsInfo": "用于授权、验证、异常处理、缓存、审计日志、事务管理等的完整基础设施。", + "Landing_Page_PreBuiltApplicationModules": "预建应用模块,包括最常见的Web应用需求。", "Landing_Page_ChatModule": "聊天", "Landing_Page_DocsModule": "文档", "Landing_Page_FileManagementModule": "文件管理", - "Landing_Page_CustomerStory_1": "ABP 商业版 允许 SC Ventures 在 9 个月内交付银行级多租户silo数据库 SaaS 平台,以支持来自多个集成锚点的大额发票的应收账款/应付账款供应链融资。 ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化的微服务码部署到生产中。", - "Landing_Page_CustomerStory_2": "我们看到了使用 ABP 商业版 来减少定制开发项目开销的价值。 并且团队能够在不同的项目流中统一代码模式。 我们在框架中看到了比以前更快地构建新功能的更多潜力。 我们相信我们将不断看到使用 ABP 商业版 的价值。", - "Landing_Page_CustomerStory_3": "我们很爱 ABP。 我们不必从头开始编写所有内容。 我们从\"开箱即用\"的功能开始,只关注我们真正需要编写的内容。 此外,ABP 架构良好,代码质量高,错误少。 如果我们必须自己编写所需的一切,我们可能需要花费数年时间。 另一件事是我们喜欢的是新版本、问题修复或改进每隔一周就很快会出现\n。 我们不会等太久。", - "Landing_Page_CustomerStory_4": "ABP 商业版 是一款值得推荐的出色产品。 在一个可配置的平台上为我们的客户推向市场的商业产品。 为任何团队提供的框架和工具的快速启动都值得每一分钱。 ABP 商业版 最适合我们的需求。", - "Landing_Page_AdditionalServices": "定制或批量许可、熟悉使用培训、网上培训和支持、定制项目开发、移植现有项目等等...", - "Landing_Page_IncludedDeveloperLicenses": "包含 {0} 开发者许可", - "Landing_Page_SeeOnDemo": "见演示", - "Landing_Page_LeptonThemes": "Lepton主题", - "Landing_Page_AccountModuleDescription_1": "该模块实现了应用程序的认证系统;", - "Landing_Page_AccountModuleDescription_2": "提供带有用户名和密码的登录页面", - "Landing_Page_AccountModuleDescription_3": "提供一个注册页面来创建一个新账户。", + "Landing_Page_CustomerStory_1": "ABP Commercial 允许 SC Ventures 在 9 个月内交付银行级多租户筒仓数据库 SaaS 平台,以支持应收账款/应付账款供应链融资,处理来自多个集成锚点的大额发票。ABP 的模块化使团队能够在创纪录的时间内交付,通过所有 VAPT,并通过完整的 CI/CD 和管道将容器化微服务堆栈部署到生产中。", + "Landing_Page_CustomerStory_2": "我们看到了使用 ABP Commercial 降低定制开发项目开销的价值。团队可以统一不同项目流中的代码模式。我们在框架中看到了更大的潜力,使我们能够比以前更快地构建新功能。我们相信,我们将不断看到利用 ABP Commercial 的价值。", + "Landing_Page_CustomerStory_3": "我们热爱 ABP。我们不必从头开始编写所有内容。我们从开箱即用的功能开始,只需专注于真正需要编写的内容。此外,ABP 结构合理,代码质量高,错误较少。如果我们必须自己编写所有需要的代码,我们可能需要花费数年时间。我们还喜欢的一点是,新版本、问题修复或改进很快就会推出\n 每隔一周。我们不会等太久。", + "Landing_Page_CustomerStory_4": "ABP Commercial 是一款非常出色的产品,值得推荐。在一个可配置的平台上为我们的客户向市场提供商业产品。该框架和工具为任何团队提供的跳跃式启动都是物有所值的。ABP Commercial 最符合我们的需求。", + "Landing_Page_AdditionalServices": "定制或批量许可证、引导流程、现场培训和支持、定制项目开发、移植现有项目等...", + "Landing_Page_IncludedDeveloperLicenses": "包括 {0} 开发人员许可证", + "Landing_Page_SeeOnDemo": "观看演示", + "Landing_Page_LeptonThemes": "LeptonThemes", + "Landing_Page_AccountModuleDescription_1": "该模块为应用程序实施身份验证系统;", + "Landing_Page_AccountModuleDescription_2": "提供带有用户名和密码的 登录页面", + "Landing_Page_AccountModuleDescription_3": "提供注册页面以创建新账户。", "Landing_Page_AccountModuleDescription_4": "提供忘记密码页面,以电子邮件形式发送密码重置链接。", - "Landing_Page_AccountModuleDescription_5": "通过 UI 提供电子邮件确认功能。", - "Landing_Page_AccountModuleDescription_6": "实现双重身份验证(短信和电子邮件)。", - "Landing_Page_AccountModuleDescription_7": "实现用户锁定(当在一定时间间隔内由于无效凭据发生一定次数的登录失败时,将账户锁定设定的时间)。", - "Landing_Page_AccountModuleDescription_8": "实现 身份验证 身份验证服务器 UI 和功能。", - "Landing_Page_AccountModuleDescription_9": "允许在多租户环境中在租户之间切换。", - "Landing_Page_AccountModuleDescription_10": "允许更改应用程序的UI 语言。", - "Landing_Page_AuditLoggingModuleDescription_1": "此模块为审计基础设施提供审计日志报告 UI。 允许搜索、过滤和显示审计日志条目和实体更改日志。", - "Landing_Page_AuditLoggingModuleDescription_2": "审核日志条目包含有关每个客户端请求的关键数据:", + "Landing_Page_AccountModuleDescription_5": "通过UI提供电子邮件确认功能。", + "Landing_Page_AccountModuleDescription_6": "实施 双因素身份验证(短信和电子邮件)。", + "Landing_Page_AccountModuleDescription_7": "执行 用户锁定(当在一定时间间隔内因无效凭证导致一定次数的登录失败时,在设定时间内锁定账户)。", + "Landing_Page_AccountModuleDescription_8": "实现 Identity Server 身份验证服务器UI和功能。", + "Landing_Page_AccountModuleDescription_9": "允许在多租户环境中在租户之间切换。", + "Landing_Page_AccountModuleDescription_10": "允许更改应用程序的 UI 语言。", + "Landing_Page_AuditLoggingModuleDescription_1": "该模块为审计基础设施提供审计日志报告UI。允许搜索、过滤和显示审计日志条目和实体变更日志。", + "Landing_Page_AuditLoggingModuleDescription_2": "审计日志条目包括每个客户请求的关键数据:", "Landing_Page_AuditLoggingModuleDescription_3": "URL、浏览器、IP 地址、客户端名称", "Landing_Page_AuditLoggingModuleDescription_4": "用户", - "Landing_Page_AuditLoggingModuleDescription_5": "HTTP方法,HTTP返回状态码", - "Landing_Page_AuditLoggingModuleDescription_6": "成功/失败,异常详细信息(如果有)", - "Landing_Page_AuditLoggingModuleDescription_7": "请求执行时长", - "Landing_Page_AuditLoggingModuleDescription_8": "此请求中已创建、删除或更新实体(具有更改的属性)。", - "Landing_Page_BloggingModuleDescription_1": "该模块将一个简单的博客添加到您的 ABP 应用程序;", - "Landing_Page_BloggingModuleDescription_2": "允许在单个应用程序中创建多个博客。", + "Landing_Page_AuditLoggingModuleDescription_5": "HTTP 方法、HTTP 返回状态代码", + "Landing_Page_AuditLoggingModuleDescription_6": "成功/失败,异常详细信息(如有", + "Landing_Page_AuditLoggingModuleDescription_7": "请求执行期限", + "Landing_Page_AuditLoggingModuleDescription_8": "该请求中的实体已创建、删除或更新(属性已更改)。", + "Landing_Page_BloggingModuleDescription_1": "该模块为 ABP 应用程序添加了一个简单的博客;", + "Landing_Page_BloggingModuleDescription_2": "允许在一个应用程序中创建多个博客。", "Landing_Page_BloggingModuleDescription_3": "支持 Markdown 格式。", "Landing_Page_BloggingModuleDescription_4": "允许为帖子写评论。", - "Landing_Page_BloggingModuleDescription_5": "允许为博客文章分配标签。", - "Landing_Page_BloggingModuleDescription_6": "请参阅 blog.abp.io 网站作为博客模块的实时示例。", - "Landing_Page_ChatModuleDescription_1": "该模块用于应用程序中用户之间的实时消息传递。", + "Landing_Page_BloggingModuleDescription_5": "允许为博文指定标签。", + "Landing_Page_BloggingModuleDescription_6": "请参阅blog.abp.io网站,作为博客模块的实时示例。", + "Landing_Page_ChatModuleDescription_1": "该模块用于应用程序中用户之间的实时信息传递。", "Landing_Page_ChatModuleDescription_2": "聊天页面上的实时消息。", - "Landing_Page_ChatModuleDescription_3": "在应用程序中搜索用户以获取新对话。", + "Landing_Page_ChatModuleDescription_3": "在应用程序中搜索用户,查找新对话。", "Landing_Page_ChatModuleDescription_4": "最近对话的联系人列表。", - "Landing_Page_ChatModuleDescription_5": "当用户正在查看另一个页面时的新消息通知。", - "Landing_Page_ChatModuleDescription_6": "菜单图标上的未读消息总数徽章。", - "Landing_Page_ChatModuleDescription_7": "每个对话的未读消息计数。", - "Landing_Page_ChatModuleDescription_8": "延迟加载的对话。", + "Landing_Page_ChatModuleDescription_5": "当用户正在浏览其他页面时收到新信息通知。", + "Landing_Page_ChatModuleDescription_6": "菜单图标上的未读信息总数徽章。", + "Landing_Page_ChatModuleDescription_7": "每次对话的未读信息计数。", + "Landing_Page_ChatModuleDescription_8": "懒得装对话。", "Landing_Page_DocsModuleDescription_1": "该模块用于创建技术文档网站;", - "Landing_Page_DocsModuleDescription_2": "内置 GitHub 集成:直接在 GitHub 上编写和管理文档。", - "Landing_Page_DocsModuleDescription_3": "版本控制支持直接集成到 GitHub 版本。", - "Landing_Page_DocsModuleDescription_4": "支持多语言(回退支持默认语言)。", + "Landing_Page_DocsModuleDescription_2": "内置GitHub 集成:直接在 GitHub 上编写和管理文档。", + "Landing_Page_DocsModuleDescription_3": "版本支持直接集成到 GitHub 发布的版本中。", + "Landing_Page_DocsModuleDescription_4": "支持 多语言(支持默认语言回退)。", "Landing_Page_DocsModuleDescription_5": "支持 Markdown 和 HTML 格式。", - "Landing_Page_DocsModuleDescription_6": "提供导航大纲部分。", + "Landing_Page_DocsModuleDescription_6": "提供导航概述部分。", "Landing_Page_DocsModuleDescription_7": "允许在单个应用程序中托管多个项目文档。", - "Landing_Page_DocsModuleDescription_8": "GitHub 上文件的链接,因此任何人都可以通过单击编辑链接轻松贡献。", - "Landing_Page_DocsModuleDescription_9": "除了 GitHub 源之外,还允许简单地使用文件夹作为文档源。", - "Landing_Page_FileManagementModuleDescription_1": "在分层文件夹结构中上传、下载和组织文件。", - "Landing_Page_FileManagementModuleDescription_2": "该模块用于上传、下载和组织分层文件夹结构中的文件。 它还兼容多租户,您可以确定租户的总大小限制。", - "Landing_Page_FileManagementModuleDescription_3": "本模块基于BLOB Storing系统,因此可以使用不同的存储供应商存储文件内容。", + "Landing_Page_DocsModuleDescription_8": "指向 GitHub 上文件的链接,因此任何人都可以通过点击 编辑链接轻松作出贡献。", + "Landing_Page_DocsModuleDescription_9": "除了 GitHub 源代码外,还允许使用文件夹作为文档源代码。", + "Landing_Page_FileManagementModuleDescription_1": "以分层文件夹结构上传、下载和整理文件。", + "Landing_Page_FileManagementModuleDescription_2": "该模块用于上传、下载和以分层文件夹结构组织文件。它还与多租户兼容,你可以确定租户的总大小限制。", + "Landing_Page_FileManagementModuleDescription_3": "该模块基于 BLOB 存储系统,因此可以使用不同的存储提供商来存储文件内容。", "Landing_Page_IdentityModuleDescription_1": "该模块实现了应用程序的用户和角色系统;", "Landing_Page_IdentityModuleDescription_2": "基于 Microsoft 的 ASP.NET Core Identity 库构建。", - "Landing_Page_IdentityModuleDescription_3": "管理系统中的角色用户。 一个用户可以拥有多个角色。", - "Landing_Page_IdentityModuleDescription_4": "在角色和用户级别设置权限。", - "Landing_Page_IdentityModuleDescription_5": "为每个用户启用/禁用双重身份验证和用户锁定。", - "Landing_Page_IdentityModuleDescription_6": "管理基本的用户个人资料密码。", - "Landing_Page_IdentityModuleDescription_7": "管理系统中的声明类型,为角色和用户设置声明。,", - "Landing_Page_IdentityModuleDescription_8": "设置页面以管理密码复杂性、用户登录、账户和锁定。", + "Landing_Page_IdentityModuleDescription_3": "管理系统中的角色用户。允许一个用户拥有多个角色。", + "Landing_Page_IdentityModuleDescription_4": "在角色和用户级别设置 权限。", + "Landing_Page_IdentityModuleDescription_5": "为每个用户启用/禁用 双因素身份验证和用户 锁定。", + "Landing_Page_IdentityModuleDescription_6": "管理基本的用户配置文件密码。", + "Landing_Page_IdentityModuleDescription_7": "在系统中管理 申请类型,为角色和用户设置申请。", + "Landing_Page_IdentityModuleDescription_8": "设置页面用于管理 密码复杂性、用户登录、账户和锁定。", "Landing_Page_IdentityModuleDescription_9": "支持 LDAP 身份验证。", "Landing_Page_IdentityModuleDescription_10": "提供电子邮件和电话号码验证。", "Landing_Page_IdentityModuleDescription_11": "支持社交登录集成(Twitter、Facebook、GitHub 等)。", - "Landing_Page_IdentityModuleDescription_12": "管理系统中的组织单位。", - "Landing_Page_PaymentModuleDescription_1": "为不同的支付网关提供集成。", - "Landing_Page_PaymentModuleDescription_2": "该模块提供支付网关的集成,因此您可以轻松地从客户那里获得付款。", + "Landing_Page_IdentityModuleDescription_12": "在系统中管理组织单位。", + "Landing_Page_PaymentModuleDescription_1": "提供不同支付网关的集成。", + "Landing_Page_PaymentModuleDescription_2": "该模块集成了支付网关,因此您可以轻松从客户处获得付款。", "Landing_Page_PaymentModuleDescription_3": "该模块支持以下支付网关", - "Welcome_Page_UseSameCredentialForCommercialWebsites": "commercial.abp.iosupport.abp.io使用相同的凭据。", - "WatchCrudPagesVideo": "观看“创建 CRUD 页面的 ABP Suite”视频!", - "WatchGeneratingFromDatabaseVideo": "观看”ABP Suite:从现有数据库表生成 CRUD 页面”视频!", - "WatchTakeCloserLookVideo": "观看“详细了解ABP Suite 的代码生成”视频!", - "ConfirmedEmailAddressRequiredToStartTrial": "你应该有一个确认的电子邮件地址,以便开始试用许可证。", - "EmailVerificationMailNotSent": "电子邮件验证邮件不能发送。", - "GetConfirmationEmail": "点击这里获取确认邮件 如果你还没有收到。", - "WhichLicenseTypeYouAreInterestedIn": "你感兴趣的许可证类型是什么?", - "DontTakeOurWordForIt": "不要相信我们的话......", - "ReadAbpCommercialUsersWantYouToKnow": "阅读 ABP Commercial 用户希望您了解到的内容", - "Testimonial_ShortDescription_1": "ABP 的模块化使得团队能够及时交付项目。", - "Testimonial_ShortDescription_2": "比以前更快地构建新功能。", - "Testimonial_ShortDescription_3": "我们从开箱即用的功能开始,只专注于我们真正需要编写的内容。", - "Testimonial_ShortDescription_4": "ABP Commercial 最适合我们的需求。", - "OnlineReviewersOnAbpCommercial": "ABP Commercial 在线评论", - "SeeWhatToldAboutAbpCommercial": "查看关于 ABP Comemrcial 的报道,并根据需要写下您的想法。", - "BlazoriseLicense": "我们是否需要购买Blazorise许可证?", - "BlazoriseLicenseExplanation": "我公司Volosoft和公司Megabit之间有合作协议,根据此协议,购买将同时包含了Blazorise许可证与ABP商业产品,因此我们的客户不需要再额外购买Blazorise许可证。", - "ExtendPaymentInfoSection_DeveloperPrice": "{0}x 额外的 开发者价格", + "Welcome_Page_UseSameCredentialForCommercialWebsites": "在 commercial.abp.iosupport.abp.io 中使用相同的凭据。", + "WatchCrudPagesVideo": "观看 \"使用 ABP Suite 创建 CRUD 页面 \"视频!", + "WatchGeneratingFromDatabaseVideo": "观看 \"ABP Suite:从现有数据库表生成 CRUD 页面 \"视频!", + "WatchTakeCloserLookVideo": "观看 \"近距离了解代码生成:ABP Suite \"视频!", + "ConfirmedEmailAddressRequiredToStartTrial": "您必须有一个确认的电子邮件地址,才能开始试用许可证。", + "EmailVerificationMailNotSent": "电子邮件验证邮件无法发送。", + "GetConfirmationEmail": "如果您还没有收到验证电子邮件,请单击此处。", + "WhichLicenseTypeYouAreInterestedIn": "您对哪种许可证类型感兴趣?", + "DontTakeOurWordForIt": "不要相信我们的话...", + "ReadAbpCommercialUsersWantYouToKnow": "阅读 ABP 商业用户希望您了解的内容", + "Testimonial_ShortDescription_1": "ABP 的模块化使团队能够及时交付。", + "Testimonial_ShortDescription_2": "比以往更快地构建新功能", + "Testimonial_ShortDescription_3": "我们从开箱即用的功能入手,只关注我们真正需要编写的内容。", + "Testimonial_ShortDescription_4": "ABP Commercial 最符合我们的需求。", + "OnlineReviewersOnAbpCommercial": "关于 ABP 商业公司的在线评论", + "SeeWhatToldAboutAbpCommercial": "查看有关 ABP Commercial 的报道,并写下您的想法。", + "BlazoriseLicense": "我们需要购买 Blazorise 许可证吗?", + "BlazoriseLicenseExplanation": "我们与 Volosoft 和 Megabit 签订了协议,根据该协议,Blazorise 许可证与 ABP 商业产品捆绑在一起,因此我们的客户无需额外购买 Blazorise 许可证。", + "ExtendPaymentInfoSection_DeveloperPrice": "{0}x新增开发人员", "ExtendPaymentInfoSection_DiscountRate": "折扣 {0}%", "TotalNetPrice": "总净价", "EFCore": "实体框架核心", "All": "全部", "Mvc": "MVC", "DataBaseProvider": "数据提供者", - "UIFramework": "UI 框架", - "LeptonXThemeForDashboard": "管理仪表板的 LeptonX 主题", + "UIFramework": "UI框架", + "LeptonXThemeForDashboard": "用于管理控制面板的 LeptonX 主题,由", "AbpPlatform": "ABP 平台", - "YouDeserveGoodUXUI": "您值得拥有良好的用户界面和更好的用户体验。 ABP 的 LeptonX Theme 就是为它服务的。", - "ViewLiveDemo": "查看在线主题演示", + "YouDeserveGoodUXUI": "您值得拥有良好的UI和更好的用户体验。ABP 的 LeptonX 主题就是为您服务的。", + "ViewLiveDemo": "查看实时主题演示", "GetLeptonX": "立即获取 LeptonX", - "SeeLeptonXDocumentation": "请参阅 LeptonX 文档", + "SeeLeptonXDocumentation": "参见 LeptonX 文档", + "SeeLeptonDocumentation": "参见 Lepton 文档", "SimplifiedMenu": "简化菜单", - "SimplifiedMenuDescription": "您可以通过过滤菜单轻松找到您要查找的页面", - "YourFavoritePages": "您最喜欢的页面触手可及", - "YourFavoritePagesDescription": "通过单击页面右上角的星形图标,可以轻松地将页面添加到收藏夹或从中删除。", - "BreadCrumbs": "用于无缝切换的页面路径导航", - "BreadCrumbsDescription": "使用页面路径导航,您可以一键切换到同一级别的页面,即使是左侧菜单关闭,它适用于平板电脑和移动设备响应!", + "SimplifiedMenuDescription": "通过过滤菜单,您可以轻松找到所需的页面", + "YourFavoritePages": "您最喜爱的网页触手可及", + "YourFavoritePagesDescription": "点击页面右上角的星形图标,即可轻松添加或删除收藏夹中的页面。", + "BreadCrumbs": "无缝切换的面包屑", + "BreadCrumbsDescription": "使用面包屑功能,即使左侧菜单关闭,您也可以一键切换到同级页面,而且它还能在平板电脑和移动设备上响应!", "YourMenu": "随心所欲的菜单", - "YourMenuDescription": "根据需要自定义用户菜单上可直接单击的图标和下拉框。 用户菜单可完全根据您的需要定制", - "RtlSupport": "对您的语言的 RTL 支持", - "RtlSupportDescription": "LeptonX 主题支持您的语言的 RTL。 语言选项位于设置菜单中,供您更改语言。", - "YourColors": "您在管理仪表板 UI 上的颜色", - "YourColorsDescription": "LeptonX 主题根据您的系统偏好工作,并具有仪表板浅色主题、仪表板深色主题和仪表板半深色主题选项。", - "ArrangeContentWidth": "轻松安排您的内容宽度", + "YourMenuDescription": "根据需要自定义用户菜单上可直接点击的图标和下拉框。用户菜单可完全根据需要定制", + "RtlSupport": "为您的语言提供 RTL 支持", + "RtlSupportDescription": "LeptonX 主题支持 RTL 语言。语言选项在设置菜单中,您可以更改语言。", + "YourColors": "管理仪表板UI上的颜色", + "YourColorsDescription": "LeptonX 主题可根据系统偏好进行设置,并提供仪表盘浅色主题、仪表盘深色主题和仪表盘半深色主题选项。", + "ArrangeContentWidth": "轻松安排内容宽度", "ArrangeContentWidthDescription": "轻松更改内容区域的宽度。", - "LeptonXCompatibleWith": "与LeptonX主题兼容", - "MobileResponsiveTemplate": "移动设备响应模板", - "MobileResponsiveTemplateDescription1": "从您喜欢的任何设备访问您的LeptonX管理仪表板。", - "MobileResponsiveTemplateDescription2": "它是为您设计的,在您的每一个设备上都可以轻松使用。它可以在移动设备和平板电脑上响应。", - "TopMenuLayoutOption": "菜单顶部布局选项", - "TopMenuLayoutOptionDescription1": "如果你想设置你的网站与相同的管理仪表板,通过使用LeptonX主题是可以做到的!", - "TopMenuLayoutOptionDescription2": "只需尝试LeptonX顶部菜单布局,就可以实现!", - "EasilyCustomizable": "易于定制您的品牌颜色", - "EasilyCustomizableDescription1": "您可以仅使用几个SCSS变量自定义LeptonX主题。没有重写,没有额外的CSS加载!", - "EasilyCustomizableDescription2": "使用LeptonX,您可以随意安排您的管理仪表板。", + "LeptonXCompatibleWith": "LeptonX 主题兼容", + "MobileResponsiveTemplate": "移动响应式模板", + "MobileResponsiveTemplateDescription1": "通过任何设备访问您的 LeptonX 管理面板。", + "MobileResponsiveTemplateDescription2": "它专为您设计,方便您在各种设备上使用。在移动设备和平板电脑上都能响应。", + "TopMenuLayoutOption": "顶部菜单布局选项", + "TopMenuLayoutOptionDescription1": "如果您想使用相同的管理仪表板设置网站,也可以使用 LeptonX 主题!", + "TopMenuLayoutOptionDescription2": "只需尝试一下 LeptonX 顶部菜单布局即可实现!", + "EasilyCustomizable": "可轻松定制品牌颜色", + "EasilyCustomizableDescription1": "您只需使用几个 SCSS 变量,就能定制 LeptonX 主题。无需覆盖,也无需加载额外的 CSS!", + "EasilyCustomizableDescription2": "有了 LeptonX,您可以随心所欲地安排管理仪表板。", "IndependentLayout": "独立的布局和内容区域", - "IndependentLayoutDescription1": "LeptonX 的布局基础设施的设计与内容完全分开。", - "IndependentLayoutDescription2": "这意味着您可以根据需要使用 Bootstrap 以外的内容结构自由设计您的项目。", - "MostUsedLibraries": "与 LeptonX 集成的最常用的库", - "MostUsedLibrariesDescription1": "LeptonX包含您最常用的库。它允许您使用库,如 ApexCharts, DataTables, DropZone, FullCalender, JSTree, Select2, Toastr 并毫不费力。", - "MostUsedLibrariesDescription2": "LeptonX还支持MVC Angular和Blazor特定的库。", - "CreateAndCustomize": "使用LeptonX自定义页面在几秒钟内创建和自定义所需的页面", - "CreateAndCustomizeDescription": "通过使用LeptonX Theme,您还可以访问许多预先制作的html页面。这些包括许多页面,如登录页面,博客,常见问题解答,订阅列表,发票,定价,文件管理。", - "LeptonThemeForAdmin": "为您的管理仪表板的Lepton主题", - "LeptonThemeForAdminDescription": "Lepton主题仍然可用,并将保持。如果您想以Lepton Theme用户的身份切换到LeptonX Theme,您可以查看文档了解如何操作。", - "LeptonCompatibleWith": "Lepton主题兼容", + "IndependentLayoutDescription1": "LeptonX 的布局基础结构设计与内容完全分离。", + "IndependentLayoutDescription2": "这意味着,如果您愿意,可以自由地使用 Bootstrap 以外的内容结构设计您的项目。", + "MostUsedLibraries": "与 LeptonX 集成的最常用库", + "MostUsedLibrariesDescription1": "LeptonX 包含您最常用的库。通过它,您可以毫不费力地使用 ApexCharts、DataTables、DropZone、FullCalender、JSTree、Select2 和 Toastr 等库。", + "MostUsedLibrariesDescription2": "LeptonX 还支持 MVC Angular 和 Blazor 专用库。", + "CreateAndCustomize": "使用 LeptonX 自定义页面在几秒钟内创建和自定义您需要的页面", + "CreateAndCustomizeDescription": "使用 LeptonX 主题,您还可以访问许多预制 HTML 页面。这些页面包括登录页面、博客、常见问题、订阅列表、发票、定价和文件管理等。", + "LeptonThemeForAdmin": "用于管理仪表板的 Lepton 主题,由", + "LeptonThemeForAdminDescription": "Lepton 主题仍然可用,并将得到维护。如果你想以 Lepton 主题用户的身份切换到 LeptonX 主题,可以查看文档了解如何切换。", + "LeptonCompatibleWith": "Lepton 主题兼容", "BlackFridayDiscount": "黑色星期五折扣", - "UpgradePaymentInfoSection_DeveloperPrice": "{0} 对于 {1} 额外的开发人员", + "UpgradePaymentInfoSection_DeveloperPrice": "{0}为{1}个额外的开发人员", "Upgrade": "升级", "Renewal": "续订", - "UpgradePaymentInfoSection_LicensePrice": "{0} 许可证", - "UpgradePaymentInfoSection_LicenseRenewalPrice": "许可证续订", + "UpgradePaymentInfoSection_LicensePrice": "{0}许可证", + "UpgradePaymentInfoSection_LicenseRenewalPrice": "许可证续期", "Total": "总计", - "SupportPolicyFaqTitle": "您的支持政策是什么?", - "SupportPolicyFaqExplanation": "我们只支持有效的和以前的主要版本。 我们不保证为第 3 个和更早的主要版本发布补丁。 例如,如果有效版本是 7.0.0,我们将发布 6.x.x 和 7.x.x 的补丁版本。 此外,我们仅对 ABP Framework 和 ABP Commercial 相关问题提供支持。 这意味着不支持 ABP 产品使用的第 3 方应用程序、云服务和其他外围库。 我们将尽商业上合理的努力在“Volosoft Bilisim A.S”的正式营业时间内为我们的客户提供技术支持。 另一方面,我们不承诺服务级别协议 (SLA) 响应时间,但我们会尽量在我们的官方工作时间内尽快响应技术问题。 除非与客户达成特殊协议,否则我们仅在 https://support.abp.io 上提供支持。 我们还提供私人电子邮件支持,仅适用于企业许可证持有者。", - "TotalDevelopers": "{0}位开发者", - "CustomPurchaseExplanation": "定制您的特定需求", - "WhereDidYouHearAboutUs": "您是从哪里了解到我们的?", - "Twitter": "Twitter", - "Facebook": "Facebook", + "SupportPolicyFaqTitle": "你们的支持政策是什么?", + "SupportPolicyFaqExplanation": "我们只支持当前和之前的主要版本。我们不保证为第 3 个和更早的主要版本发布补丁。此外,我们仅支持 ABP 框架和 ABP 商业相关问题。这意味着不支持第三方应用程序、云服务和 ABP 产品使用的其他外围库。我们将尽商业上的合理努力,在 \"Volosoft Bilisim A.S \"的正式营业时间内为客户提供技术支持。另一方面,我们不承诺服务水平协议(SLA)的响应时间,但我们会尽量在正式工作时间内尽快对技术问题做出响应。除非与客户达成特别协议,否则我们只在 https://support.abp.io 上提供支持。我们还提供私人电子邮件支持,只有企业许可证持有者才能使用。", + "TotalDevelopers": "共计 {0} 名开发人员", + "CustomPurchaseExplanation": "根据您的具体需求量身定制", + "WhereDidYouHearAboutUs": "你从哪里听说我们的?", + "Twitter": "推特", + "Facebook": "在 Facebook 上", "Youtube": "YouTube", - "Google": "Google", + "Google": "谷歌", "Github": "GitHub", - "Friend": "朋友介绍", + "Friend": "朋友赠言", "Other": "其他", - "WhereDidYouHearAboutUs_explain": "请说明...", - "DeletingMemberWarningMessage": "\"{0}\"将从开发者列表中删除。如果您愿意,您可以将此空位分配给另一个开发者。", - "AdditionalInfo": "如果开发人员席位超出您的要求,您可以减少它们。 您可以发送电子邮件至 info@abp.io 以删除您的一些开发人员席位。 清除未使用的开发人员席位将降低许可证续订成本。 如果需要,您可以在有效许可期限内重新购买额外的开发人员席位。 请注意,由于此许可证中有 {0} 个开发人员,因此您无法减少此数量。", - "LinkExpiredErrorMessage": "您正在尝试访问的链接已过期。", - "ExpirationDate": "过期时间", - "SpringCampaignDiscount": "春季促销折扣", - "WhyUseAbpIoPlatform": "为什么我应该使用 ABP.IO 平台而不是从头开始创建新的解决方案?\n", - "WhyUseAbpIoPlatformFaqExplanation": "请参阅该文件以详细解释为什么使用ABP.IO平台比自己做所有事情有显著的优势。", + "WhereDidYouHearAboutUs_explain": "指定 ...", + "DeletingMemberWarningMessage": "\"{0}\"将从开发者列表中删除。如果您愿意,可以稍后将此空位分配给其他开发人员。", + "AdditionalInfo": "如果开发人员席位超出了您的要求,您可以减少这些席位。您可以发送电子邮件至 info@abp.io 删除部分开发人员席位。清除未使用的开发人员席位将减少许可证续订费用。如果需要,您可以在有效许可证期限内重新购买额外的开发人员席位。请注意,由于此许可证包中有 {0} 个开发人员席位,因此无法减少这一数量。", + "LinkExpiredErrorMessage": "您试图访问的链接已过期。", + "ExpirationDate": "有效期", + "SpringCampaignDiscount": "春季活动折扣", + "WhyUseAbpIoPlatform": "为什么要使用 ABP.IO 平台而不是从头开始创建新的解决方案?", + "WhyUseAbpIoPlatformFaqExplanation": "请参阅该页面,详细了解为什么使用 ABP.IO 平台比自己做所有事情都有显著优势。", "EulaPageTitle": "最终用户许可协议(EULA)", - "PrivacyPolicyPageTitle": "隐私政策 - Cookies政策", + "PrivacyPolicyPageTitle": "隐私政策 - Cookie 政策", "TermsConditionsPageTitle": "条款和条件", - "TrainingsPageTitle": "ABP培训套餐", - "ModulesPageTitle": "ABP内置的应用模块", - "DoesTheSubscriptionRenewAutomatically": "许可会自动续费吗?", - "DoesTheSubscriptionRenewAutomaticallyExplanation": "ABP 商业版没有自动续费的计费模式。因此,在您的许可期结束时,您的订阅将不会自动续订。如果您希望继续享受ABP商业版的服务,请在组织管理页面手动进行续费操作。如果您拥有多个组织,您可以点击即将到期的组织上的\"管理\"按钮,然后点击\"立即续费\"按钮来续订您的许可。您还可以查看许可到期后会发生什么?部分了解更多信息。", - "BlazoriseSupport": "如何获取Blazorise许可密钥并获得Blazorise团队的支持?", - "BlazoriseSupportExplanation": "请按照以下步骤获取Blazorise团队的支持并获得您的Blazorise许可密钥:", - "BlazoriseSupportExplanation1": "使用与您的abp.io账户相同的电子邮件地址在blazorise.com/support/register上注册一个新账户。请将“许可密钥”一栏留空,并确保该电子邮件地址与您在abp.io上的电子邮件账户相同。", - "BlazoriseSupportExplanation2": "通过查看您的电子邮件信箱来验证您的电子邮件地址。如果在收件箱中没有看到电子邮件,请检查您的垃圾邮件箱!", - "BlazoriseSupportExplanation3": "在blazorise.com/support/login上登录Blazorise支持网站。", - "BlazoriseSupportExplanation4": "如果您有有效的ABP商业版许可证,您还将拥有Blazorise PRO许可证。您可以在blazorise.com/support/user/manage/license获取您的Blazorise许可密钥。", - "BlazoriseSupportExplanation5": "您可以在support网站上发布您的问题,并为您的应用程序生成一个产品令牌。", - "ExtraQuestionCreditsFaqTitle": "我可以购买额外的问题支持次数吗?", - "ExtraQuestionCreditsFaqExplanation": "是的,您可以购买额外的问题支持次数,请发送电子邮件至info@abp.io,并提供您的组织名称。以下是额外问题支持次数的价格列表:

  • 50次问题 $999
  • 25次问题 $625
  • 15次问题 $450
", + "TrainingsPageTitle": "ABP 培训套餐", + "ModulesPageTitle": "ABP 预建应用模块", + "Volo.AbpIo.Commercial:040001": "API 访问密钥不正确。", + "GetLepton": "立即获取 Lepton", + "MyOrganizations_Detail_LicenseStartDate": "许可证开始日期", + "MyOrganizations_Detail_LicenseExpiryDate": "有效期", + "BlazoriseSupport": "如何从 Blazorise 团队获得 Blazorise 许可证密钥和支持?", + "BlazoriseSupportExplanation": "请按照以下步骤获得 Blazorise 团队的支持并获取 Blazorise 许可证密钥:", + "BlazoriseSupportExplanation1": "在blazorise.com/support/register上注册一个新账户,电子邮件地址应与您的 abp.io 账户相同。将 \"许可证密钥 \"项留空。该电子邮件地址必须与您在 abp.io 上的电子邮件帐户相同。", + "BlazoriseSupportExplanation2": "检查您的电子邮箱,验证您的电子邮件地址。如果收件箱中没有邮件,请检查垃圾邮件箱!", + "BlazoriseSupportExplanation3": "登录 Blazorise 支持网站blazorise.com/support/login。", + "BlazoriseSupportExplanation4": "如果您拥有有效的 ABP 商业许可证,您也将拥有 Blazorise PRO 许可证。您可在 blazorise.com/support/user/manage/license 获取 Blazorise 许可证密钥。", + "BlazoriseSupportExplanation5": "您可以在支持网站上发布您的问题,并为您的应用程序生成产品令牌。", + "AbpLiveTrainingPackages": "ABP 实时培训套餐", + "Releases": "发布", + "ReleasesDescription": "ABP Commercial 的发布日志。", + "ReleaseDate": "发布日期", + "Labels": "标签", + "PreRelease": "预发布", + "AllTypes": "所有类型", + "Enhancement": "增强", + "Bug": "错误", + "Feature": "特点", + "AllUIs": "所有UI", + "MVC": "MVC", + "BlazorServer": "Blazor 服务器", + "MAUI": "毛伊岛", + "HowItWorks_Page_Title": "它是如何工作的?", + "HowItWorks_Page_Description": "ABP Framework 扩展了 .NET 平台。因此,你能用普通 .NET 解决方案做的任何事情,ABP 框架都能实现。因此,学习曲线较低,很容易上手。", + "HowItWorks_Description1": "ABP Framework 扩展了 .NET 平台。因此,你能用普通 .NET 解决方案做的任何事情,ABP 框架都能实现。因此,学习曲线较低,很容易上手。", + "HowItWorks_Description2": "一旦你开始学习和使用 ABP 框架的功能,开发软件将比以往更加轻松愉快。", + "HowItWorks_Description3": "本页基本上介绍了作为 .NET 开发人员如何使用 ABP.IO 平台。", + "CreateANewSolution": "创建新的 .NET 解决方案", + "CreateANewSolution_Description1": "一切从创建新的 ABP 集成 .NET 解决方案开始。", + "StartWithStartupTemplates": "启动一个预建的启动解决方案模板。", + "SimpleMonolithApplicationTemplate": "简单的单体应用程序模板", + "LayeredApplicationTemplate": "分层应用程序模板", + "MicroserviceSolutionTemplate": "微服务解决方案模板", + "CreateEmptySolutionAndUseAbp": "或者创建一个新的空 .NET 解决方案,并自行安装 ABP NuGet 和 NPM 。", + "CreatingSolutionWithMultipleOptions": "在创建新解决方案时,有多个UI和数据库选项。", + "UIFrameworkOptions": "UI框架选项", + "DotnetSolutionWithoutDependency": "现在,您的本地计算机中就有了一个普通的 .NET 解决方案,它不依赖于云平台或外部服务。", + "CheckTheDocumentForDetails": "详情请查看 {1} 文档。", + "UIAndDatabaseIndependent": "ABP 可与.NET 支持的任何UI和任何数据库提供程序协同工作。\n 不过,这些UI和数据库提供商都是预先集成的,并有完善的文档记录。", + "InstallAbpModules": "安装 ABP 模块", + "DevelopYourSolution": "开发解决方案", + "DeployAnywhere": "随时随地部署", + "InstallAbpModule_Description1": "ABP 是一个模块化应用程序开发框架。启动解决方案模板已经安装了基本模块。\n 但您可能希望在解决方案中使用更多应用模块。", + "InstallAbpModule_Description2": "每个模块都由几个 NuGet 和 NPM 包组成,并有一个安装文档。ABP Suite会自动完成大部分工作,然后你可以根据文档手动配置或微调模块。", + "DevelopYourSolution_Description1": "ABP 的基础架构可自动执行重复性工作,并提供预构建的基础架构和应用程序 功能,从而使您专注于自己的业务代码。", + "DevelopYourSolution_Description2": "在下面的代码块中,您可以看到 ABP 框架是如何无缝集成到您的代码中并自动执行重复性任务的。", + "DevelopYourSolution_Description3": "即使在这个简码块中,ABP 也能为您做很多事情。", + "DevelopYourSolution_Description4": "它提供了应用约定的基类,如\n 依赖注入。通用类\n 资源库服务提供了一种方便的\n 与数据库交互的便捷方法。声明式\n 授权与经过微调的权限系统配合使用。", + "DevelopYourSolution_Description5": "ABP 完全自动化\n 工作单元(用于数据库连接和事务管理)、\n 异常处理、\n 验证。\n 以及 审计日志。它提供了更多的构建模块,可简化您的日常开发任务,并在创建生产就绪应用程序的同时专注于您自己的代码。\n 应用程序。", + "DevelopYourSolution_Description6": "可以想象,如果全部由人工完成,代码块会有多么冗长和复杂。", + "SuiteCrudGenerationInFewSeconds": "除了手工编码解决方案外,您还可以使用 ABP Suite 工具在几分钟内创建可全面运行的高级 CRUD 页面。它可将代码生成到您的解决方案中,因此您可以根据您的自定义需求对其进行微调。", + "DeployAnywhere_Description1": "最后,您将拥有一个纯粹的 .NET 解决方案。您可以将解决方案部署到自己的服务器、云平台、Kubernetes 或任何您想部署的地方。您可以部署到任意多的服务器上。ABP 是一种与部署环境无关的工具。", + "ExpertiseAbpFramework": "ABP 框架的专业知识", + "ExpertiseAbpFramework_Description1": "想要超越基础知识,掌握 ABP.IO 平台的专业知识?", + "FreeDownload": "免费下载", + "Read": "阅读", + "HavingTrouble": "有问题?", + "HavingTrouble_Description1": "您在开发解决方案时遇到问题了吗?我们在这里!使用 ABP 支持平台\n 或发送电子邮件,直接向 ABP 核心框架团队成员寻求帮助。", + "WeAreHereToHelp_Description1": "您可以浏览我们的帮助主题或搜索常见问题、\n 或使用联系表向我们提问。", + "OtherModules": "其他模块", + "OtherModules_Description1": "账户、审计日志、聊天、CMS 工具包、文件管理、表单、GDPR、身份、语言管理、支付、Saas 等...", + "HowItWorks_DatabaseProviderOptions": "数据库提供商选项", + "SeeFAQ": "查看常见问题", + "ReleaseLogs": "发布日志", + "ReleaseLogs_Tag": "{0}发布日志", + "ReleaseLogs_Pr": "拉取请求 #{0} - {1}", + "NoLabels": "无标签", + "DoesTheSubscriptionRenewAutomatically": "订阅会自动续订吗?", + "DoesTheSubscriptionRenewAutomaticallyExplanation": "ABP 商业版没有自动续订计费模式。因此,您的訂閱將不會在許可期限結束時自動續期。如果您想继续享受 ABP 商业版的好处,您需要在组织管理页面手动续订。如果您有多个组织,请单击即将到期组织的 \"管理 \"按钮,然后单击 \"立即延长 \"按钮以续订许可证。您可能还需要查看 What Happens When My License Ends? 部分。", + "ExtraQuestionCreditsFaqTitle": "我可以购买额外的支持问题点数吗?", + "ExtraQuestionCreditsFaqExplanation": "可以。要购买额外的问题点数,请发送电子邮件至 info@abp.io 并注明贵组织的名称。以下是额外问题点数的价格表:
  • 50个问题包 999 美元
  • 25个问题包 625 美元
  • 15个问题包 450 美元
。", + "AlreadyBetaTester": "您已经加入了测试版程序。", + "AbpStudio": "ABP Studio", + "AbpStudio_Description": "ABP Studio 仍在开发中。您可以填写下面的表单,成为首批用户之一。", + "AbpStudio_Description1": "ABP Studio 是专为 ABP 开发人员设计的跨平台桌面应用程序。", + "AbpStudio_Description2": "它与 ABP 框架集成得很好,旨在通过自动化、提供有关解决方案的见解,为您提供舒适的开发环境,使开发、运行部署解决方案变得更加容易。", + "AbpStudio_ComingSoon": "即将发布 计划测试版发布日期:计划测试版发布日期:2023年第四季度。", + "AbpStudio_PlannedPreviewDate": "计划预览版发布日期:2023 年第四季度。", + "BetaRequest": "测试版请求", + "CreateNewSolutions": "创建新的解决方案", + "CreateNewSolutions_Description1": "您可以使用大量选项轻松创建从简单应用程序到模块化单体或微服务解决方案。您可以为您的业务获得完整的生产就绪基础软件解决方案。", + "ArchitectYourSolutions": "设计解决方案", + "ArchitectYourSolutions_Description1": "通过创建模块或服务并建立它们之间的关系,可以更轻松地构建单体模块化和微服务解决方案结构。您还可以安装或卸载预置的应用模块。", + "ExploreYourSolution": "探索解决方案", + "ExploreYourSolution_Description1": "ABP Studio 可显示解决方案中组件的高级视图以及解决方案所依赖的模块。你可以探索实体、服务、HTTP API 等,而无需打开你的代码库。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze": "轻松运行多应用或微服务解决方案", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description1": "只需单击即可运行一个、多个所有服务。通过这种方式,可以非常轻松地停止服务,并在 Visual Studio 中运行它来测试调试。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description2": "查看服务列表,查看每个服务的 实时 HTTP 请求异常计数。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description3": "查看来自任何服务的所有HTTP 请求的所有详细信息。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description4": "在任何服务中实时查看异常详细信息,轻松进行筛选和搜索。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description5": "显示 应用程序日志,按日志级别过滤或按文本搜索。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description6": "浏览应用程序的UI,而无需离开解决方案运行程序。", + "IntegrateToYourKubernetesCluster": "集成到 Kubernetes 集群", + "IntegrateToYourKubernetesCluster_Description1": "将本地开发环境连接到本地或远程 Kubernetes 集群,该集群已运行您的微服务解决方案。", + "IntegrateToYourKubernetesCluster_Description2": "使用 Kubernetes 中任何服务的服务名作为 DNS 访问这些服务,就像它们在本地计算机上运行一样。", + "IntegrateToYourKubernetesCluster_Description3": "拦截该集群中的任何服务,因此所有被拦截服务的流量都会自动重定向到你本地机器上运行的服务。当您的服务需要使用 Kubernetes 中的任何服务时,流量会被重定向回群集,就像您的本地服务在 Kubernetes 中运行一样。", + "GetInformed": "获取信息", + "Studio_GetInformed_Description1": "请留下您的联系信息,以便获得通知,并在 ABP Studio 推出后抢先体验。", + "Studio_GetInformed_Description2": "计划预览版发布日期:2023 年第三季度。", + "ThankYou!": "谢谢!", + "SendBetaRequest": "发送测试版申请", + "YouJoinedTheBetaTesterProgram": "您加入了 ABP Studio 测试程序。", + "PricingExplanation2": "30 天退款保证 - 了解更多React Native
.NET MAUI 实现。当您创建基于 ABP 的新解决方案时,您还将拥有连接到后端 API 的基本启动应用程序。", + "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description2": "该应用程序有一个预建的身份验证令牌循环、多语言支持、多租户支持、登录、忘记密码、配置文件管理和用户管理页面。您可以添加自己的业务逻辑,并根据自己的要求进行定制。", + "TwoFrameworkOptions": "两个框架选项", + "TwoFrameworkOptions_Description": "ABP 提供 React Native.NET MAUI 移动启动模板。这样,您就可以选择最适合您需求的模板。这两种应用程序在 iOS 和 Android 平台之间的代码重用率最高。", + "PreIntegratedToYourBackend": "预集成到您的后台", + "PreIntegratedToYourBackend_Description": "ABP 移动应用程序已预集成到您的后端API。它可从服务器获取有效的身份验证令牌,并发出身份验证请求。", + "MultiLanguage": "多语言", + "MultiLanguage_Description": "它开箱即支持 10 多种语言。您还可以添加其他语言。", + "Arabic": "阿拉伯语", + "Czech": "捷克语", + "English": "英语", + "Hungarian": "匈牙利语", + "Finnish": "芬兰语", + "French": "法语", + "Hindi": "北印度语", + "Portuguese": "葡萄牙语", + "Italian": "意大利语", + "Russian": "俄罗斯语", + "Slovak": "斯洛伐克语", + "Turkish": "土耳其语", + "EngageAndRetainYourCustomersWithABPMobileApps": "使用 ABP 移动应用程序吸引并留住您的客户", + "EngageAndRetainYourCustomersWithABPMobileApps_Description1": "您的客户希望随时随地管理他们的产品和订阅。这就要求企业创建移动应用程序,让客户能够快速、无缝地满足他们的要求。", + "EngageAndRetainYourCustomersWithABPMobileApps_Description2": "使用 ABP 移动应用程序,您可以创建适用于 Android 和 iOS 的高质量原生移动应用程序......使用单一代码库,且不会降低安全性、质量或可扩展性。", + "OneCodeBaseMultipleDevices": "一个代码库多种设备", + "OneCodeBaseMultipleDevices_Description": "ABP 移动应用程序是跨平台的。它们可在 iOS 和 Android 设备上安装和运行,并使用单一代码库适应不同的外形因素。开发人员只需创建一次UI和前端代码,无需为您要支持的每种设备调整代码。", + "ComesWithTheSourceCode": "附带源代码", + "ComesWithTheSourceCode_Description": "移动应用程序提供源代码。您可以轻松定制应用程序的用户体验/UI,以符合品牌准则。", + "Purchase_OneYearPrice": "1 年价格", + "Purchase_DeveloperSeatCount": "开发者席位数", + "Purchase_DevelopersAlreadyIncluded": "{0}已包括开发人员", + "1Year": "1 年", + "{0}Years": "{0}年", + "1YearLicense": "1 年许可证", + "{0}YearsLicense": "{0}年许可证", + "1AdditionalDeveloper": "1 名新增开发人员", + "{0}AdditionalDevelopers": "{0} 其他开发人员", + "Discount": "折扣 ({0}%)", + "Summary": "摘要", + "TrainingPack": "培训包", + "TrainingPackDiscount": "培训包折扣", + "Purchase_OnboardingTraining_Description": "此实时培训包适用于 8 人班,此折扣仅在购买新许可证时有效。了解更多 ", + "Purchase_Save": "{0}% 节省 {0}% {1} {2}", + "RemoveBasket": "从购物篮中取出", + "WhyABPIOPlatform?": "为什么选择ABP.IO 平台?", + "DocumentAim": "本文档旨在回答这个重大问题:", + "DocumentAim_Description": "\"为什么要使用 ABP.IO 平台,而不是从头开始创建新的解决方案?", + "DocumentAim_Description2": "该文件介绍了构建现代软件解决方案所面临的挑战,并解释了 ABP 如何应对这些挑战。", + "CreatingANewSolution": "创建新的解决方案", + "CreatingANewSolution_Description": "当你需要开始一个新的解决方案时,你需要问自己很多问题,在开始编写你的第一个业务代码之前,你应该花很多时间。", + "CreatingAnEmptySolution": "创建空解决方案", + "THEPROBLEM": "问题", + "CreatingAnEmptySolution_THEPROBLEM_Description": "即使是创建一个几乎为空的解决方案也具有挑战性;", + "CreatingAnEmptySolution_THEPROBLEM_Description2": "您是如何组织跨项目的代码库的?", + "CreatingAnEmptySolution_THEPROBLEM_Description3": "有哪些层次,它们如何相互作用?", + "CreatingAnEmptySolution_THEPROBLEM_Description4": "如何与第三方资料库和系统集成?", + "CreatingAnEmptySolution_THEPROBLEM_Description5": "如何设置自动测试?", + "ABPSOLUTION": "ABP 解决方案", + "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP 基于领域驱动设计原则,提供了一个架构完善、分层且可投入生产的启动解决方案。该解决方案还包括每个层的预配置单元和集成测试项目。", + "CommonLibraries": "通用库", + "CommonLibraries_THEPROBLEM_Description": "您应该使用哪些库来实现常见需求?软件开发生态系统是高度动态的,要跟上最新的工具、库、趋势和方法具有挑战性。", + "CommonLibraries_ABPSOLUTION_Description": "ABP 将流行、成熟和最新的库预先集成到解决方案中。你不需要花时间集成它们或让它们相互通信。它们开箱即可正常工作。", + "UITheme&Layout": "UI主题和布局", + "UITheme&Layout_THEPROBLEM_Description": "在解决UI问题时,会遇到一系列挑战。这些挑战包括为建立一个具有一致外观和导航菜单、页眉、工具栏、页脚、小工具等一系列功能的响应性、现代性和适应性强的UI套件奠定基础。", + "UITheme&Layout_THEPROBLEM_Description2": "即使您选择了预先设计的主题,将其无缝集成到您的项目中也可能需要数天的开发时间。升级此类主题还会遇到额外的障碍。通常情况下,主题的 HTML/CSS 结构会与您的UI代码交织在一起,从而使未来的主题更改或升级任务变得错综复杂。这种代码和设计的交织使后续调整的灵活性变得更加复杂。", + "UITheme&Layout_ABPSOLUTION_Description": "ABP Framework 提供了一个独特的主题系统,可将UI代码从主题限制中解放出来。主题独立存在,打包为 NuGet 或 NPM 包,使主题的安装或升级成为分分钟的事。您可以选择开发自定义主题或集成现有主题,ABP 商业版提供了一系列精良的现代主题。", + "UITheme&Layout_ABPSOLUTION_Description2": "此外,还有一些UI组件提供商,如 Telerik 和 DevExpress。不过,这些提供商主要提供单个组件,因此您有责任建立自己的布局系统。在基于 ABP 的项目中工作时,您可以无缝整合这些库,就像在任何其他项目中一样。", + "TestInfrastructure": "测试基础设施", + "TestInfrastructure_THEPROBLEM_Description": "建立强大的测试环境是一项耗时的工作。它涉及在解决方案中设置专用测试项目、仔细选择必要的工具、创建服务和数据库模拟、制作基本基类和实用服务以尽量减少测试中的冗余代码,以及处理各种相关任务。", + "TestInfrastructure_ABPSOLUTION_Description": "ABP 启动模板预装了已配置的测试项目,为您简化了流程。这意味着从第一天起,您就可以立即开始编写初始单元或集成测试代码。", + "CodingStandards&Training": "编码标准与培训", + "CodingStandards&Training_THEPROBLEM_Description": "在为开发设置好解决方案后,您通常还需要向开发人员传授系统的工作原理,以及如何使用商定的方法构建系统。即使你对他们进行了培训,保持文档的及时更新也是很困难的。随着时间的推移,每个开发人员都可能以自己的方式编写代码,导致编写代码的规则彼此不同。", + "CodingStandards&Training_ABPSOLUTION_Description": "ABP 解决方案已经整理得井井有条,并有清晰的解释。循序渐进的教程和指南向你展示了 ABP 项目的具体操作方法。", + "KeepingYourSolutionUpToDate": "保持解决方案最新", + "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "开始开发后,您必须跟踪所使用库的新版本,以便进行升级和打补丁。", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "我们会定期将所有包更新至最新版本,并在稳定版本发布前对其进行测试。当你更新 ABP 框架时,它的所有依赖项都会升级到边缘技术。", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description2": "Abp update
CLI 命令可自动发现并升级解决方案中所有依赖 ABP 的 NuGet 和 NPM 包。有了 ABP,使用最新版本变得更加容易。", + "DRY": "不要重复自己", + "DRY_Description": "创建基础解决方案需要大量时间,并需要良好的建筑经验。然而,这仅仅是个开始!在开始开发时,您可能需要编写大量重复的代码;如果所有这些代码都能自动处理,那就再好不过了。", + "DRY_Description2": "ABP 遵循 \"约定重于配置 \"的原则,尽可能自动化和简化重复代码。不过,当您需要切换到手动档时,它也不会限制您。控制权始终掌握在您的手中。", + "Authentication": "认证", + "Authentication_THEPROBLEM_Description": "单点登录、Active Directory / LDAP 集成、OpenIddict 集成、社交登录、双因素验证、忘记/重置密码、电子邮件激活、新用户注册、密码复杂性控制、尝试失败时锁定账户、显示失败的登录尝试......等等。我们知道,您对所有这些通用要求都不陌生。您并不孤单!", + "Authentication_ABPSOLUTION_Description": "ABP Framework 和商业版本提供了所有这些标准内容,并作为可重用的账户模块预先为您实现。你只需启用和配置你所需要的即可。", + "CrossCuttingConcerns": "横向关注", + "CrossCuttingConcerns_THEPROBLEM_Description": "交叉关注点是每个用例都应实施的基本重复逻辑。举例如下", + "CrossCuttingConcerns_THEPROBLEM_Description2": "启动事务,成功时提交,出错时回滚。", + "CrossCuttingConcerns_THEPROBLEM_Description3": "处理和报告异常,向客户端返回正确的错误响应,并在客户端处理错误案例。", + "CrossCuttingConcerns_THEPROBLEM_Description4": "实施授权和验证,返回适当的响应,并在客户端进行处理。", + "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP 框架可自动或简化所有常见的交叉问题。您只需编写与业务相关的代码,ABP 会按照约定处理其余代码。", + "ArchitecturalInfrastructure": "建筑基础设施", + "ArchitecturalInfrastructure_THEPROBLEM_Description": "您通常需要构建基础架构来正确实施您的架构。例如,您一般会实施仓储模式。您需要定义一些基类,以简化和标准化创建实体、服务、控制器和其他对象。", + "ArchitecturalInfrastructure_ABPSOLUTION_Description": "ABP 框架开箱即可提供所有这些功能,甚至更多。它非常成熟,而且文档齐全。", + "EnterpriseApplicationRequirements": "企业应用需求", + "EnterpriseApplicationRequirements_THEPROBLEM_Description": "在每个业务应用程序中,您都要反复执行许多要求;", + "EnterpriseApplicationRequirements_THEPROBLEM_Description2": "详细的权限系统,并根据角色和用户管理UI上的权限。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description3": "编写审计日志和实体历史记录,以跟踪用户何时修改了数据库记录。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description4": "使实体软删除,这样它们就会被标记为已删除,而不是从数据库中物理删除,并在查询时自动过滤已删除的实体。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description5": "创建抽象和包装器,以便从前端代码中使用后端API。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description6": "排队和执行后台作业", + "EnterpriseApplicationRequirements_THEPROBLEM_Description7": "在全球系统中处理多个时区。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description8": "在服务器和客户端之间共享验证、本地化和授权逻辑。", + "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "ABP 提供了轻松实现这些要求的基础架构。同样,您无需花费宝贵的时间反复重新实现所有这些要求。", + "GeneratingInitialCode&Tooling": "生成初始代码和工具", + "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "在一个典型的Web应用程序中,您会创建许多类似的页面。它们中的大多数都会执行类似的 CRUD 操作。重复创建此类页面非常乏味,而且容易出错。", + "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Suite 可在数秒内为您的实体生成一个全栈 CRUD 页面。生成的代码分层且简洁。所有标准验证和授权要求均已实现。此外,还生成了单元测试类。一旦您获得了一个完全运行的页面,您就可以根据您的业务需求对其进行修改。", + "IntegratingTo3rdPartyLibrariesAndSystems": "与第三方图书馆和系统集成", + "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "大多数库的设计都比较低级,您通常需要做一些工作来正确集成它们,而不会在解决方案中到处重复相同的集成和配置代码。例如,假设您必须使用 RabbitMQ 来实现分布式事件总线。您要做的就是向队列发送消息并处理传入消息。但您需要了解消息传递模式、队列和交换细节。要编写高效的代码,必须创建一个池来管理连接、客户端和通道。您还必须处理异常、ACK 消息、失败时重新连接 RabbitMQ 等问题。", + "IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "例如,ABP 的 RabbitMQ 分布式事件总线集成抽象了所有这些细节。您可以发送和接收消息,而无需进行繁琐的操作。您需要编写底层代码吗?没问题,您可以随时这样做。当您需要使用您正在使用的库的底层功能时,ABP 不会限制您。", + "WhyNotBuildYourOwnFramework?": "为什么不建立自己的框架?", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "所有基础设施,即使是最简单的,也需要大量时间来构建、维护和记录。随着时间的推移,这些基础架构会变得越来越庞大,很难在解决方案中对其进行维护。将这些分离成一个可重用的项目,是建立自己内部框架的起点。", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description2": "构建、记录、培训和维护一个内部框架非常困难。如果你没有一个经验丰富的专门框架团队,你的内部框架很快就会变成没有文档的遗留代码,再也没有人能理解和维护。另一方面,这些框架通常由团队中的一两个开发人员开发。这些人正在成为知识孤岛。这对他们有利,但对公司不利,因为他们是项目的单点故障-SPOF-。一旦他们离开公司,项目就会急剧下滑。", + "WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "ABP 框架是一个社区驱动、文档齐全、成熟且通用的应用程序框架。由经验丰富的开发人员组成的团队正在努力使其保持最新、易懂和易于使用。使用这样一个稳定的框架,您可以专注于自己的业务代码,并随时从专家那里获得框架方面的帮助。", + "ArchitecturalInfrastructure_Description": "SaaS 应用程序、模块化或微服务系统是最常用的企业软件模型。构建此类系统不仅需要良好的理解和经验,还需要强大的软件基础设施。否则,你会发现自己要花费很大精力才能在代码库中支持这些架构细节。", + "Modularity": "模块化", + "Modularity_THEPROBLEM_Description": "建立一个真正的模块化系统并非易事!系统的所有方面(数据库、实体、API、UI页面/组件)都可以分割成模块,而且每个模块都可以重用,无需其他模块。普通的 ASP.NET Core 并不提供这样的模块化架构。如果需要,您应该从头开始考虑。", + "Modularity_ABPSOLUTION_Description": "ABP 框架是一种模块化应用程序开发结构。框架中的每项功能都是为兼容模块化而开发的。文档和指南解释了如何以标准方式开发可重用的模块。", + "SaaSMultiTenancy": "SaaS / 多租户", + "SaaSMultiTenancy_THEPROBLEM_Description": " 多租户是实施 SaaS 系统的一种常见方式。但是,实施一致的多用户基础设施可能会变得复杂。", + "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP 框架提供完整的多租户基础架构,并从您的业务代码中抽象出复杂性。您的应用程序代码大部分将具有多租户意识,而 ABP 框架会自动隔离租户之间的数据库、缓存和其他细节。它支持单个数据库、每个租户数据库和混合方法。它能正确配置 Microsoft Identity 和 OpenIddict 等库,这些库通常与多租户不兼容。", + "Microservices": "微服务", + "Microservices_THEPROBLEM_Description": "构建微服务系统需要许多基础设施细节:对应用程序和微服务进行身份验证和授权,以及在微服务之间实施异步消息传递和同步(Rest/GRPC)通信模式是最基本的问题。", + "Microservices_ABPSOLUTION_Description": "ABP 框架提供服务、指南和示例,帮助您使用行业标准工具实施微服务解决方案。", + "Microservices_ABPSOLUTION_Description2": "ABP Commercial 甚至更进一步,提供了完整的 启动模板,以启动您的微服务解决方案。", + "PreBuiltModules": "预制模块", + "PreBuiltModules_THEPROBLEM_Description": "我们每个人都有相似但略有不同的业务需求。但是,我们都应该重新发明轮子,因为没有人的代码可以直接用于我们的解决方案。它们都是更大解决方案的嵌入部分。", + "PreBuiltModules_ABPSOLUTION_Description": "ABP Commercial 模块提供了大量可重用的应用模块,如支付、聊天、文件管理、审计日志报告......等。所有这些模块都可以轻松安装到您的解决方案中并直接运行。我们将不断添加更多模块。", + "PreBuiltModules_ABPSOLUTION_Description2": "所有模块均可根据您的业务需求进行定制。如果您需要完全控制,可以下载任何模块的完整源代码,并根据您的具体业务要求进行完全定制。", + "ABPCommunity": "ABP 社区", + "ABPCommunity_Description": "最后,在一个大社区中,每个人都遵循相似的编码风格和原则,并共享一个共同的基础架构,当你遇到困难或在设计决策上需要帮助时,这将为你带来力量。因为我们的代码编写方式相似,所以我们可以更好地互相帮助。ABP 是一个由社区支持的项目,在 GitHub 上拥有 10K star。", + "ABPCommunity_Description2": "ABP 开发人员之间可以轻松共享代码,甚至是可重用的库。对你有用的代码片段也会对其他人有用。有很多示例和教程可以直接用于您的应用程序。", + "ABPCommunity_Description3": "如果您聘请的开发人员曾使用过 ABP 架构,那么他将立即了解您的解决方案,并在很短的时间内开始开发。", + "WhyAbpIo_Page_Title": "为什么选择 ABP.IO 平台?", + "AbpStudio_Page_Title": "ABP Studio", + "CampaignInfo": "购买新许可证或更新现有许可证,即可免费获得额外 2 个月的使用期!此优惠适用于所有许可证计划。请确保您利用了这一限时促销活动,以扩大您对高级功能和升级的访问权限。", + "HurryUpLastDay": "抓紧时间最后一天{0}", + "CreatingCRUDPagesWithABPSuite": "使用 ABP Suite创建 CRUD 页面", + "Testimonials": "客户感言", + "MultipleYearDiscount": "多年折扣", + "CampaignDiscountText": "黑色星期五折扣", + "CampaignDiscountName": "黑色星期五", + "CampaignName:BlackFriday": "黑色星期五", "MultipleOrganizationInfo": "查看您的所有组织", "PaymentFailedInfo": "抱歉,支付失败!", "UsedPayment": "该付款已被使用" diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json index dce55a0613..ade3b387d5 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json @@ -352,7 +352,7 @@ "VolosoftMarketingInformationMessage": "我想要有關企業和組織解決方案以及其他 Volosoft 產品和服務的信息、提示和優惠。", "VolosoftSharingInformationMessage": "我希望 Volosoft 與選定的合作夥伴共享我的信息,以便我可以收到有關他們的產品和服務的相關信息。", "WeWillSendYouADownloadLink": "下載電子書的鏈接已發送至 {0}。
檢查您的收件箱/垃圾箱/垃圾箱!", - "InvalidFormInputs": "請輸入表格中指定的有效信息。", + "InvalidFormInputs": "請輸入表单中指定的有效信息。", "DDDBookEmailBody": "謝謝你。
要下載您的圖書,請點擊此處。", "FreeDDDEBook": "免費 DDD 電子書", "StartFree": "免費開始", @@ -399,6 +399,674 @@ "LicenseTransferExplanation": "是的!購買許可證後,您將成為許可證持有者,因此您可以訪問組織管理頁面。組織具有所有者和開發者角色。所有者可以管理開發者席位並分配開發者。每個指定的開發人員將通過 ABP CLI 命令登錄到系統,並將擁有開發和支持權限。", "RenewLicenseEarly": "如果我提前更新我的駕照,我會得到一整年嗎?", "RenewLicenseEarylExplanation": "當您在許可證到期日期之前續訂許可證時,您的許可證到期日期將增加 1 年。例如,如果您的許可證在 {0}-06-06 到期,而您在 {0}-01-01 續簽,則新的許可證到期日期將為 {1}-06-06。", + "OpenSourceWebApplication": "開源網路應用程式", + "CompleteWebDevelopment": "一個完整的網站開發", + "ABPFrameworkDescription": "ABP 框架是一個完整的基礎設施,可透過遵循軟體開發和約定的最佳實踐來建立現代 Web 應用程式。", + "CommunityDescription": "分享您使用 ABP 框架的經驗!", + "GetStarted": "開始使用", + "Views": "意見", + "LatestPosts": "最新貼文", + "PreBuiltApplication": "預建應用程式", + "DatabaseProviders": "資料庫提供者", + "UIFrameworks": "使用者介面框架", + "UsefulLinks": "有用的連結", + "Platform": "平台", + "CoolestCompaniesUseABPCommercial": "最酷的公司已經在使用ABP Commercial。", + "UserInterface": "使用者介面", + "APIGateway": "API網關", + "Microservice": "微服務", + "Database": "資料庫", + "Architecture": "建築學", + "MicroserviceArchitectureExplanation": "這是一個完整的解決方案架構,由多個應用程式、API網關、微服務和資料庫組成,利用最新技術建立可擴展的微服務解決方案。", + "BusinessLogic": "商業邏輯", + "DataAccessLayer": "資料存取層", + "Monolith": "巨石", + "ModularArchitectureExplanation": "此啟動範本提供了分層、模組化和基於DDD的解決方案架構,以建立乾淨且可維護的程式碼庫。", + "SeeDetails": "查看具體資訊", + "SeeDocumentation": "查看文件", + "Bs5Compatible": "Bootstrap 5 相容的專業主題,非常適合您的管理網站。", + "LeptonXTheme": "LeptonX主題", + "LeptonXDark": "LeptonX 黑暗", + "LeptonXLight": "輕子X光", + "LeptonXSemiDark": "LeptonX 半暗", + "BuiltOnBs5Library": "基於 Bootstrap 5 庫構建", + "FullyCompatibleWithBs5": "100% 相容於 Bootstrap 5 HTML 結構和 CSS 類", + "ResponsiveAndMobileCompatible": "響應靈敏、移動兼容、RTL 支持", + "ProvidesStylesForDatatables": "提供資料表的樣式", + "MultipleLayoutOptions": "多種佈局選項", + "EasilyInstallAndUpgrade": "輕鬆安裝和升級", + "SupportForum": "支援論壇", + "TrustedBy": "值得信賴", + "OurPricing": "我們的定價", + "Plans": "計劃", + "NameSurname": "名字姓", + "Unspecified": "未指定", + "LicenceType": "許可證類型", + "LicenseDiscountWarning": "此折扣頁面使用預設折扣代碼並適用於 VOLOSOFT 開發者。下面的購買連結不起作用。", + "DiscountedLicenseExplanation": "這些許可證價格適用於小型新創公司、個人開發者、學生、非營利組織和專案!", + "General": "一般的", + "License": "執照", + "Development": "發展", + "Payment": "支付", + "WatchExplainerVideo": "咱們見面吧!觀看講解視頻", + "LightDarkAndSemiDarkThemes": "淺色、深色和半深色", + "LeptonXThemeExplanation": "Lepton Theme可以根據您的系統設定更改您的主題。", + "PRO": "專業版", + "WelcomeToABPCommercial": "歡迎來到ABP商業!", + "YourAccountDetails": "您的帳戶詳細信息", + "OrganizationName": "機構名稱", + "AddDevelopers": "添加開發者", + "StartDevelopment": "開始開發", + "CreateAndRunApplicationUsingStartupTemplate": "了解如何使用 ABP Commercial 啟動範本建立和運行新的 Web 應用程式。", + "CommunityDescription2": "Community.abp.io是一個人們可以分享 ABP 相關文章的地方。搜尋文章、教學、程式碼範例、案例研究並結識與您志同道合的人。", + "UseABPSuiteExplanation": "使用ABP Suite下載模組和主題的原始碼。", + "ManageModulesWithSuite": "您也可以使用 Suite 管理您的 ABP 模組。", + "LearnHowToInstallSuite": "了解如何安裝和使用 ABP Suite。", + "SeeMore": "看更多", + "SeeLess": "少看", + "LayeredSolutionStructure": "分層解決方案結構", + "LayeredSolutionStructureExplanation": "該解決方案基於領域驅動設計原則和模式進行分層,以將業務邏輯與基礎架構和整合隔離,並最大限度地提高程式碼可維護性和可重用性。 ABP 框架已經提供了抽象、基類和指南,以便為您的應用程式真正實現 DDD。", + "MultipleUIOptions": "多個使用者介面選項", + "MultipleUIOptionsExplanation": "我們喜歡用不同的方式來創建使用者介面。此啟動解決方案為您的業務應用程式提供了三種不同的 UI 框架選項。", + "MultipleDatabaseOptions": "多個資料庫選項", + "MultipleDatabaseOptionsExplanation": "您有兩個資料庫提供者選項(除了在單一應用程式中使用這兩個選項)。使用 Entity Framework Core 來處理任何關聯式資料庫,當您需要編寫低階查詢以獲得更好的效能時,可以選擇使用 Dapper。如果您需要使用基於文件的 NoSQL 資料庫,MongoDB 是另一個選擇。雖然這些提供者經過良好整合、抽象化和預先配置,但您實際上可以與可與 .NET 一起使用的任何資料庫系統進行互動。", + "ModularArchitectureExplanation2": "模組化是 ABP.IO 平台的一等公民。所有應用程式功能都分為隔離良好的選用模組。此啟動解決方案已經預先安裝了基本的ABP Commercial 模組。您也可以建立自己的模組,為您自己的應用程式建立模組化系統。", + "MultiTenancyForSaasBusiness": "SaaS 業務的多租戶", + "MultiTenancyForSaasBusinessExplanation": "ABP Commercial 提供完整的端對端多租用戶系統來建立您的 SaaS(軟體即服務)系統。它允許租戶透過動態資料庫創建和遷移系統共享或擁有自己的資料庫。", + "MicroserviceStartupSolution": "微服務啟動解決方案", + "MicroserviceArchitectureExplanation2": "您可以將其用於您的下一個微服務系統,以利用預先建置的基礎解決方案和精煉的經驗。", + "PreIntegratedTools": "預先整合到流行的工具中", + "PreIntegratedToolsExplanation": "該解決方案已整合到行業標準工具和技術中,而您可以隨時更改它們並整合到您最喜歡的工具中。", + "SingleSignOnAuthenticationServer": "單一登入驗證伺服器", + "SingleSignOnAuthenticationServerExplanation": "該解決方案具有一個身份驗證伺服器應用程序,其他應用程式將其用作具有 API 存取管理功能的單一登入伺服器。它基於IdentityServer。", + "WebAppsWithGateways": "2 個 Web 應用程式和 2 個 API 網關", + "WebAppsWithGatewaysExplanation": "該解決方案包含兩個 Web 應用程序,每個應用程式都有一個專用的 API 網關(BFF - Backend For Frontend 模式)。", + "BackOfficeApplication": "後台應用程式", + "BackOfficeApplicationExplanation": "您系統的實際 Web 應用程序,具有多個 UI 框架選項。您可以建立任何類型的業務應用程式。", + "LandingWebsite": "登陸網站", + "LandingWebsiteExplanation": "通用登陸/公共網站,可用於多種目的,例如介紹您的公司、銷售您的產品等。", + "ABPFrameworkEBook": "掌握 ABP 框架電子書", + "MasteringAbpFrameworkEBookDescription": "包含在您的 ABP 商業授權中", + "FullName": "全名", + "LicenseTypeNotCorrect": "許可證類型不正確!", + "Trainings": "訓練", + "ChooseTrainingPlaceholder": "選擇培訓...", + "DoYouNeedTrainings": "您需要其中一項培訓嗎?", + "DoYouNeedTraining": "您需要{0}培訓嗎?", + "GetInTouchUs": "請與我們聯繫", + "ForMoreInformationClickHere": "欲了解更多信息,請點擊此處。", + "ForMoreInformationClickHereByClass": "欲了解更多信息,請點擊此處。", + "IsGetOnboardingTraining": "您想接受入職和網路應用程式開發培訓嗎?", + "OnboardingWebApplicationDevelopmentTrainingMessage": "若要安排您的培訓日曆,請在建立組織後聯絡 {0}", + "CustomPurchaseMessage": "下一步,請點擊 {0} 與我們聯絡。", + "Note": "筆記", + "AdditionalNote": "附加說明", + "AddBasket": "加入購物籃", + "SendTrainingRequest": "發送培訓請求", + "OnlyEnglishVersionOfThisDocumentIsTheRecentAndValid": "* 本文檔英文版為最新版本,如有爭議,以英文版為準。", + "Pricing_Page_Title": "定價和計劃", + "Pricing_Page_Description": "選擇您目前的業務所需的特性和功能。購買 ABP 商業許可證並創建無限的項目。", + "Pricing_Page_HurryUp": "趕快!", + "Pricing_Page_BuyLicense": "在 1 月 16 日之前以2021 年價格購買許可證!", + "Pricing_Page_ValidForExistingCustomers": "也適用於現有客戶和許可證續約。", + "Pricing_Page_Hint1": "許可證價格包含一定數量的開發者席位。如果您有更多開發人員,您可以隨時購買額外的席位。", + "Pricing_Page_Hint2": "您現在或將來可以購買更多開發人員許可證。許可證是基於席位的,因此您可以將席位從一個開發人員轉移到另一個開發人員。", + "Pricing_Page_Hint3": "您可以使用您的許可證開發無限數量的不同產品。", + "Pricing_Page_Hint4": "ABP Suite 是一款輔助您開發、提升生產力的工具。它支援產生CRUD頁面和建立新專案。", + "Pricing_Page_Hint5": "您可以在應用程式中使用所有預先建置的模組。", + "Pricing_Page_Hint6": "您可以在應用程式中使用所有預先建置的主題。", + "Pricing_Page_Hint7": "啟動範本是一個 Visual Studio 解決方案,可讓您快速啟動專案。所有基本模組均已為您新增和預先配置。", + "Pricing_Page_Hint8": "掌握 ABP 框架電子書解釋瞭如何透過最佳實務實施 .NET 解決方案。它在 Amazon.com 上出售,您可以使用許可證免費下載該書。", + "Pricing_Page_Hint9": "您可以下載任何模組的原始碼。您可能希望將原始程式碼添加到您的解決方案中以進行根本性更改,或者出於安全原因僅保留它。", + "Pricing_Page_Hint10": "許可證是終身有效的。這意味著您可以永遠繼續開發您的應用程式。在許可期限內(除非您續訂,否則為 1 年)即可存取最新版本並獲得支援。", + "Pricing_Page_Hint11": "沒有部署限制!您可以根據需要部署到任意數量的伺服器,包括雲端服務或本機伺服器。", + "Pricing_Page_Hint12": "您可以在有效授權期間內將模組、主題和工具更新至最新版本。許可證過期後,您需要續訂才能繼續取得錯誤修復、新功能和增強功能的更新。", + "Pricing_Page_Hint13": "您可以獲得一年的高級支援(您可以續訂許可證以延長期限)。", + "Pricing_Page_Hint14": "團隊和商業許可證有事件/問題計數限制。如果您購買額外的開發者許可證,則每個開發者的事件限額將增加 {0}(對於團隊許可證)或 {1}(對於商業許可證)。", + "Pricing_Page_Hint15": "只有企業許可證包含私人支援。您可以直接向 ABP 團隊發送電子郵件,或使用私人票證選項在 support.abp.io 上提問。私人門票對公眾不可見。", + "Pricing_Page_Hint16": "您可以下載所有 ABP 主題的源代碼。您可能希望將原始程式碼添加到您的解決方案中以進行根本性更改,或者出於安全原因僅保留它。", + "Pricing_Page_Testimonial_1": "ABP Commercial 幫助 SC Ventures 在 9 個月內交付了銀行級多租戶筒倉資料庫 SaaS 平台,以支援來自多個整合錨點的大額發票的應收帳款/應付帳款供應鏈融資。 ABP 的模組化使團隊能夠以創紀錄的時間交付、通過所有 VAPT,並透過完整的 CI/CD 和管道將容器化微服務堆疊部署到生產中。", + "Pricing_Page_Testimonial_2": "我們看到了使用 ABP Commercial 來減少客製化開發專案的開銷的價值。團隊能夠統一不同專案流中的程式碼模式。我們看到該框架具有更大的潛力,可以讓我們比以前更快地建立新功能。我們相信我們將不斷看到利用 ABP Commercial 的價值。", + "Pricing_Page_Testimonial_3": "我們愛 ABP。我們不必從頭開始編寫所有內容。我們從開箱即用的功能開始,只專注於我們真正需要編寫的內容。此外,ABP 架構良好,程式碼品質高,錯誤較少。如果我們必須自己編寫所需的所有內容,我們可能需要花費數年時間。我們喜歡的另一件事是,新版本、問題修復或改進每隔一周很快就會發布。我們不會等太久。", + "Pricing_Page_Testimonial_4": "ABP Commercial 是一款極佳的產品,值得推薦。在單一可配置平台上為我們的客戶推出商業產品。為任何團隊提供的框架和工具的快速啟動都是值得的。 ABP Commercial 最適合我們的需求。", + "Pricing_Page_Testimonial_5": "ABP Framework 不僅僅是一個框架,它也是專案開發/管理的指南,因為它提供了 DDD、GenericRepository、DI、微服務和模組化培訓。即使您不打算使用框架本身,您也可以使用經過充分且專業準備的 docs.abp.io 進行開發(OpenIddict、Redis、Quartz 等)。因為很多東西都是預先建立的,所以它大大縮短了專案開發時間(例如登入頁面、異常處理、資料過濾、播種、稽核日誌記錄、本地化、自動 API 控制器等)。作為我們應用程式的範例,我使用本地事件總線進行庫存控制。因此,我可以透過編寫庫存處理程序來管理訂單變更。不浪費時間給CreationTime、CreatorId真是太好了。它們會被自動填滿。", + "Pricing_Page_Testimonial_6": "ABP框架是一個很好的框架,但是它需要時間來理解它使用的不同層、類別和函式庫(尤其是ABP)。我花了很多時間閱讀程式碼庫,但 ABP Commercial 為我們節省了建立專案專業實體 (AR) 以及連結到每個實體的儲存庫的時間。我還喜歡 ABP 中使用的方法非常成熟;我們知道它是基於 DDD 和 monolith 的。", + "Pricing_Page_Testimonial_7": "作為一家新創公司,我們需要快速迭代,並在樣板和非核心功能上花費最少的時間。 \n我們的工程師既有經驗豐富的工程師,也有初級工程師,我們需要一種共同的理解和一種共享技術和領域知識的方法,ABP 憑藉其出色的指南和文件使我們能夠做到這一點。 \n有些事情我們不必擔心,因為它們與 ABP 一起開箱即用。 \n ABP 幫助我們簡化了快速原型設計和開發,從功能啟動到生產只花了不到 4 週的時間。憑藉許可證中包含的所有高級功能,ABP 為我們提供了軟體工程方面的「Startup in a Box」。", + "Pricing_Page_Testimonial_8": "我會向所有想要擴大客戶可用產品範圍的人推薦 ABP Commercial。當需要使用分散式企業環境(Angular、WPF、Win&Linux)時,它非常棒。除了他們的產品之外,我們還喜歡他們的支持,這使我們的工作更快、更輕鬆。我們已經知道,我們已經找到了一個面向未來的優秀合作夥伴,他將支持我們拓展業務。", + "Pricing_Page_Testimonial_9": "我們是一家擁有 2 名員工的公司,已有 20 多年的經營歷史。 \n根據我們在 ABP Commercial 方面的經驗,一位客戶聯繫我們,要求我們在現代環境中開發一個新的人力資源應用程序,以取代他們使用了 25 年的 Access 應用程式。我們決定從桌面解決方案過渡到基於網路的解決方案。 \n \n當時,我們對 Web 應用和 .NET 的了解很少,但我們偶然發現了 ABP Commercial,在 ABP 框架、技術文件和 ABP Suite 的幫助下,我們不僅能夠將應用程式開發為一年之內,不僅滿足了客戶的規範,而且還成功地在.NET 環境中工作。", + "AbpBookDownloadArea_ClaimYourEBook": "領取您的掌握 ABP 框架電子書", + "AddMemberModal_Warning_1": "如果系統中不存在您嘗試新增的使用者名,請讓您的團隊成員在{0}上註冊並與您共用他/她的帳戶使用者名稱。", + "MyOrganizations_Detail_WelcomeMessage": "歡迎加入您的組織,{0}", + "MyOrganizations_Detail_OrganizationManagement": "組織管理", + "OrganizationDisplayName": "組織顯示名稱", + "MyOrganizations_Detail_EditDisplayName": "編輯顯示名稱", + "MyOrganizations_Detail_UpgradeYourLicense": "升級您的許可證", + "MyOrganizations_Detail_LicenseStartAndExpiryDate": "許可證開始日期 - 到期日期", + "MyOrganizations_Detail_OwnerRightInfo": "您正在使用您的 {1} 項所有者權利中的 {0} 項。", + "MyOrganizations_Detail_CopyApiKey": "複製密鑰", + "MyOrganizations_Detail_ApiKeyDescription": "API 金鑰是{1} 上託管的 PRO 包的令牌。", + "MyOrganizations_Detail_YourPrivateNugetSource": "您的私有 NuGet 來源是{0}", + "MyOrganizations_Detail_PrivateNugetSourceWarning": "這會作為 feed 自動添加到 ABP 解決方案中的 NuGet.Config 中。不要與未經授權的用戶分享您的私鑰!", + "MyOrganizations_Detail_DeveloperSeatInfo": "您正在使用 {1} 個開發者席位中的 {0} 個。", + "NeedMoreSeatsForYourTeam": "您的團隊需要更多座位嗎?", + "MyOrganizations_Detail_PricePerYear": "{0}/每年", + "MyOrganizations_Detail_PurchaseDeveloperSeats": "購買開發者席位", + "Invoices": "發票", + "RequestInvoice": "要求發票", + "OrderNumber": "訂單編號", + "Date": "日期", + "Products": "產品", + "TotalPrice": "總價", + "ThereIsNoInvoice": "沒有發票", + "MyOrganizations_Detail_PaymentProviderInfo": "如果您透過{0}網關購買了許可證,它會將 PDF 發票傳送到您的電子郵件地址,請參閱{0} 發票。", + "MyOrganizations_Detail_PayUInfo": "如果您是透過Iyzico網關購買的,請點擊「索取發票」按鈕並填寫帳單資訊。", + "MyOrganizations_Detail_ConclusionInfo": "您的發票申請將在 {0} 個工作天內完成。", + "ExtendYourLicense": "延長您的{0}許可", + "Continue": "繼續", + "DownloadInvoiceModal_DownloadInvoice": "下載發票", + "DownloadInvoiceModal_SaveInformationOnlyOnce": "您只能儲存一次帳單資訊。", + "InvoiceModal_EnterCompanyName": "輸入您的法定公司名稱...", + "InvoiceModal_EnterCompanyAddress": "輸入您的法定公司地址...", + "InvoiceModal_EnterTaxNumber": "輸入您的稅號/增值稅號(如果有)...", + "RequestInvoiceModal_EnterNotes": "輸入有關發票的額外資訊...", + "PrePayment_PayWithIyzico": "您將使用 Iyzico 付款", + "ContinueToCheckout": "繼續結帳", + "PrePayment_IyzicoRedirectionInfo": "您將被重定向到 Iyzico 支付網關以安全地完成購買。", + "PrePayment_IyzicoAcceptVisaAndMasterCard": "Iyzico 接受 Visa 和 MasterCard。", + "Purchase": "購買", + "AcceptTermsAndConditions": "我已閱讀、瞭解並接受隱私權政策條款與條件以及EULA。", + "AcceptTermsAndConditionsWarningMessage": "請接受隱私權政策以及條款與條件", + "SelectGatewayToContinue": "請選擇一個網關以繼續!", + "GatewaySelection_SelectGateway": "選擇支付網關", + "GatewaySelection_RedirectionMessage": "接下來,您將被重新導向到所選支付網關的網站進行交易。", + "PaymentSucceed_PaymentSuccessMessage": "支付成功", + "PaymentSucceed_ThanksForPurchase": "感謝您的購買!", + "PaymentSucceed_CreateYourOrganization": "建立您的組織", + "PaymentSucceed_AddMeAsDeveloper": "我也是開發人員,請將我作為開發人員加入我的組織。", + "PaymentSucceed_CreateOrganization": "創建組織", + "PaymentSucceed_OrganizationDescription": "組織由開發人員和所有者組成。開發者是在 ABP 專案上編寫程式碼的用戶,他們將從{1}網站中受益。所有者是分配開發人員席位並管理許可的使用者。", + "PaymentSucceed_ViewOrganization": "點擊此處查看組織", + "Purchase_TotalAnnualPrice": "總計(年費)", + "Purchase_TrainingPrice": "培訓價格", + "Purchase_OnboardingTraining": "入職培訓和 Web 應用程式開發現場培訓", + "TotalDeveloperPrice": "開發商總價", + "Purchase_PricePerDeveloper": "每個開發者{0} {1}", + "Purchase_IncludedDeveloperInfo": "包括 {0} {1}。", + "Purchase_LicenseExtraDeveloperPurchaseMessage": "{0} 許可證包括 {1} 開發人員。您可以新增其他開發人員。", + "StartupTemplates_Page_Title": "ABP 啟動模板", + "StartupTemplates_Page_Description": "ABP Commercial 可讓您建立任何複雜程度的解決方案。它提供了兩個主要的預建啟動解決方案。您可以選擇最接近您的要求的解決方案,並在此基礎上建立您自己的自訂解決方案。", + "MicroserviceStartupSolutionForDotnet": ".NET 微服務啟動解決方案", + "MonolithSolutionForDotnet": ".NET 的整體(模組化)解決方案", + "TrainingDetailsHeaderInfo_TrainingHour": "{0} 小時", + "Trainings_Content": "培訓內容", + "Trial_Page_StartYourFreeTrial": "開始你的免費試用", + "TrialLicenseFeatures": "您將能夠受益於所有 ABP 商業功能", + "TrialPeriodDays": "您將擁有 {0} 天的團隊許可證", + "TrialForumSupportIncident": "您將有 {0} 個論壇支援事件", + "Contact_Page_Title": "聯絡ABP開發團隊", + "Contact_Page_Description": "如果您需要任何協助或分享您的想法和意見,請聯絡 ABP 開發團隊! ABP 支援團隊隨時準備提供協助。", + "Demo_Page_Title": "建立演示", + "Demo_Page_Description": "建立免費演示以查看使用 ABP Commercial 啟動範本建立的範例應用程式。不要重複常見的應用程式要求。", + "Discounted_Page_Title": "折扣價格", + "Discounted_Page_Description": "選擇您目前的業務所需的特性和功能。購買 ABP 商業許可證並創建無限個項目", + "Faq_Page_Title": "常見問題 (FAQ)", + "Faq_Page_Description": "你有任何問題嗎?搜尋常見問題或使用聯絡表單向我們提問。", + "Faq_Page_SwiftCode": "SWIFT代碼", + "Faq_Page_BankName": "銀行名", + "Faq_Page_AccountName": "帳戶名稱", + "Faq_Page_AccountNumber": "帳號", + "Faq_Page_Currency": "貨幣", + "Faq_Page_VatNumber": "增值稅號", + "Faq_Page_OtherCurrenciesInfo": "對於其他貨幣,請查看所有帳戶", + "ProjectCreatedSuccess_Page_Title": "您的專案已創建", + "ProjectCreatedSuccess_Page_Description": "您的 ABP 專案創建成功!", + "Suite_Page_Title": "ABP 套件", + "Suite_Page_Description": "ABP Commercial 提供快速應用程式開發工具來提高開發人員的工作效率。 ABP Suite 讓您輕鬆建立 CRUD 頁面。", + "Themes_Page_Title": "總部基地主題", + "Themes_Page_Description": "ABP Commercial 提供多種專業、現代的 UI 主題。建立免費演示以快速查看 UI 的外觀。", + "Tools_Page_Title": "快速應用程式開發工具", + "Tools_Page_Description": "ABP Commercial 提供快速應用程式開發工具來提高開發人員的工作效率。 ABP Suite 讓您輕鬆建立 CRUD 頁面。", + "DeveloperPrice": "開發商價格", + "AdditionalDeveloperPaymentInfoSection_AdditionalDevelopers": "{0}開發者", + "LicenseRemainingDays": "{0}天", + "ExtendPaymentInfoSection_Description": "透過延長/更新您的許可證,您將繼續獲得高級支援。您還可以獲得模組和主題的主要或次要更新。您將能夠繼續建立新專案。而且您仍然可以使用ABP Suite來加快您的開發速度。", + "LicenseRenewalPrice": "許可證更新價格", + "LicensePrice": "許可價格", + "TrialLicensePaymentInfoSection_Description": "購買許可證:透過購買許可證,您將繼續獲得高級支援。您還可以獲得模組和主題的主要或次要更新。您將能夠繼續建立新專案。而且您仍然可以使用ABP Suite來加快您的開發速度。
請參閱許可證比較表以檢查許可證類型之間的差異。", + "SelectTargetLicense": "選擇目標許可證", + "UpgradePaymentInfoSection_ExtendMyLicenseForOneYear": "是的,將我的許可證有效期延長 1 年。", + "UpgradePaymentInfoSection_WantToExtendLicense": "您想將您的駕照再延長一年嗎?", + "UpgradePaymentInfoSection_UpgradingWillNotExtendLicense": "升級不會延長您的許可證有效期限!", + "UpgradePaymentInfoSection_LicenseUpgradeDescription": "透過升級您的許可證,您將升級到更高的許可證類型,這將使您獲得額外的好處。請參閱許可證比較表以檢查許可證類型之間的差異。", + "Landing_Page_CustomerStories": "客戶案例", + "Landing_Page_OurGreatCustomers": "我們的大客戶", + "Landing_Page_WebApplicationFramework": "網路應用框架", + "Landing_Page_WebDevelopmentPlatform": "網頁開發平台", + "Landing_Page_CompleteWebDevelopmentPlatform": "完整的網頁開發平台", + "Landing_Page_TryFreeDemo": "嘗試免費演示", + "Landing_Page_StartingPointForWebApplications": "基於 ASP.NET Core 的 Web 應用程式的起點!它基於最佳 Web 開發的 ABP 框架。", + "Landing_Page_AbpProvidesSoftwareInfrastructure": "ABP 框架提供了一個軟體基礎設施,可以透過最佳實踐開發優秀的 Web 應用程式。", + "Landing_Page_MicroserviceCompatibleArchitecture": "微服務相容架構", + "Landing_Page_PreBuiltApplicationModulesAndThemes": "預先建置的應用程式模組和主題", + "Landing_Page_MultiTenantArchitecture": "多租用戶架構", + "Landing_Page_MultiTenancyDescription": "SaaS 應用程式變得簡單!從資料庫到 UI 的整合多租戶。", + "Landing_Page_DDDIntroduction": "基於DDD模式和原則進行設計和開發。為您的應用程式提供分層模型。", + "Landing_Page_CrossCuttingConcernsInfo": "用於授權、驗證、異常處理、快取、稽核日誌記錄、交易管理等的完整基礎架構。", + "Landing_Page_PreBuiltApplicationModules": "預先建置的應用程式模組,其中包括最常見的 Web 應用程式要求。", + "Landing_Page_ChatModule": "聊天", + "Landing_Page_DocsModule": "文件", + "Landing_Page_FileManagementModule": "文件管理", + "Landing_Page_CustomerStory_1": "ABP Commercial 幫助 SC Ventures 在 9 個月內交付了銀行級多租戶筒倉資料庫 SaaS 平台,以支援來自多個整合錨點的大額發票的應收帳款/應付帳款供應鏈融資。 ABP 的模組化使團隊能夠以創紀錄的時間交付、通過所有 VAPT,並透過完整的 CI/CD 和管道將容器化微服務堆疊部署到生產中。", + "Landing_Page_CustomerStory_2": "我們看到了使用 ABP Commercial 來減少客製化開發專案的開銷的價值。團隊可以統一不同專案流中的程式碼模式。我們看到該框架具有更大的潛力,可以讓我們比以前更快地建立新功能。我們相信我們將不斷看到利用 ABP Commercial 的價值。", + "Landing_Page_CustomerStory_3": "我們愛 ABP。我們不必從頭開始編寫所有內容。我們從開箱即用的功能開始,只專注於我們真正需要編寫的內容。此外,ABP 架構良好,程式碼品質高,錯誤較少。如果我們必須自己編寫所需的所有內容,我們可能需要花費數年時間。我們喜歡的另一件事是新版本、問題修復或改進很快就會每隔一周推出\n 。我們不會等太久。", + "Landing_Page_CustomerStory_4": "ABP Commercial 是一款極佳的產品,值得推薦。在單一可配置平台上為我們的客戶推出商業產品。為任何團隊提供的框架和工具的快速啟動都是值得的。 ABP Commercial 最適合我們的需求。", + "Landing_Page_AdditionalServices": "定製或批量許可證、入職、現場培訓和支援、客製化專案開發、移植現有專案等等...", + "Landing_Page_IncludedDeveloperLicenses": "包含{0} 個開發者許可", + "Landing_Page_SeeOnDemo": "請參閱演示", + "Landing_Page_LeptonThemes": "輕子主題", + "Landing_Page_AccountModuleDescription_1": "該模組實現應用程式的身份驗證系統;", + "Landing_Page_AccountModuleDescription_2": "提供帶有使用者名稱和密碼的登入頁面", + "Landing_Page_AccountModuleDescription_3": "提供註冊頁面來建立新帳戶。", + "Landing_Page_AccountModuleDescription_4": "提供忘記密碼頁面,以透過電子郵件發送密碼重設連結。", + "Landing_Page_AccountModuleDescription_5": "透過 UI 提供電子郵件確認功能。", + "Landing_Page_AccountModuleDescription_6": "實施兩因素身份驗證(簡訊和電子郵件)。", + "Landing_Page_AccountModuleDescription_7": "實現使用者鎖定(在一定時間內因無效憑證而導致登入失敗達到一定次數時,將帳戶鎖定設定的時間)。", + "Landing_Page_AccountModuleDescription_8": "實作Identity Server身份驗證伺服器 UI 和功能。", + "Landing_Page_AccountModuleDescription_9": "允許在多租戶環境中在租戶之間切換。", + "Landing_Page_AccountModuleDescription_10": "允許更改應用程式的UI 語言。", + "Landing_Page_AuditLoggingModuleDescription_1": "此模組為審計基礎設施提供審計日誌報告UI。允許搜尋、過濾和顯示審核日誌條目和實體變更日誌。", + "Landing_Page_AuditLoggingModuleDescription_2": "審核日誌條目包含有關每個客戶端請求的關鍵資料:", + "Landing_Page_AuditLoggingModuleDescription_3": "URL、瀏覽器、IP 位址、客戶端名稱", + "Landing_Page_AuditLoggingModuleDescription_4": "使用者", + "Landing_Page_AuditLoggingModuleDescription_5": "HTTP方法、HTTP回傳狀態碼", + "Landing_Page_AuditLoggingModuleDescription_6": "成功/失敗、異常詳細資訊(如果有)", + "Landing_Page_AuditLoggingModuleDescription_7": "請求執行時長", + "Landing_Page_AuditLoggingModuleDescription_8": "實體已在此請求中建立、刪除或更新(具有變更的屬性)。", + "Landing_Page_BloggingModuleDescription_1": "該模組為您的 ABP 應用程式添加一個簡單的部落格;", + "Landing_Page_BloggingModuleDescription_2": "允許在單一應用程式中建立多個部落格。", + "Landing_Page_BloggingModuleDescription_3": "支援Markdown格式。", + "Landing_Page_BloggingModuleDescription_4": "允許為貼文撰寫評論。", + "Landing_Page_BloggingModuleDescription_5": "允許為部落格文章分配標籤。", + "Landing_Page_BloggingModuleDescription_6": "請參閱blog.abp.io網站作為部落格模組的即時範例。", + "Landing_Page_ChatModuleDescription_1": "此模組用於應用程式中使用者之間的即時訊息傳遞。", + "Landing_Page_ChatModuleDescription_2": "聊天頁面上的即時訊息傳遞。", + "Landing_Page_ChatModuleDescription_3": "在應用程式中搜尋用戶以獲取新對話。", + "Landing_Page_ChatModuleDescription_4": "最近對話的聯絡人清單。", + "Landing_Page_ChatModuleDescription_5": "當使用者查看另一個頁面時有新訊息通知。", + "Landing_Page_ChatModuleDescription_6": "選單圖示上的未讀訊息總數徽章。", + "Landing_Page_ChatModuleDescription_7": "每個對話的未讀訊息計數。", + "Landing_Page_ChatModuleDescription_8": "延遲載入對話。", + "Landing_Page_DocsModuleDescription_1": "此模組用於創建技術文件網站;", + "Landing_Page_DocsModuleDescription_2": "內建GitHub 整合:直接在 GitHub 上撰寫和管理文件。", + "Landing_Page_DocsModuleDescription_3": "版本控制支援直接整合到 GitHub 版本。", + "Landing_Page_DocsModuleDescription_4": "支援多語言(支援預設語言)。", + "Landing_Page_DocsModuleDescription_5": "支援Markdown和 HTML 格式。", + "Landing_Page_DocsModuleDescription_6": "提供導航大綱部分。", + "Landing_Page_DocsModuleDescription_7": "允許在單一應用程式中託管多個專案文件。", + "Landing_Page_DocsModuleDescription_8": "GitHub 上文件的鏈接,因此任何人都可以通過單擊“編輯”鏈接輕鬆做出貢獻。", + "Landing_Page_DocsModuleDescription_9": "除了 GitHub 來源之外,還允許簡單地使用資料夾作為文件來源。", + "Landing_Page_FileManagementModuleDescription_1": "在分層資料夾結構中上傳、下載和組織文件。", + "Landing_Page_FileManagementModuleDescription_2": "此模組用於上傳、下載檔案並以分層資料夾結構組織檔案。它還與多租戶相容,您可以確定租戶的總大小限制。", + "Landing_Page_FileManagementModuleDescription_3": "此模組基於BLOB儲存系統,因此可以使用不同的儲存提供者來儲存檔案內容。", + "Landing_Page_IdentityModuleDescription_1": "該模組實現了應用程式的使用者和角色系統;", + "Landing_Page_IdentityModuleDescription_2": "基於Microsoft 的 ASP.NET Core Identity庫建置。", + "Landing_Page_IdentityModuleDescription_3": "管理系統中的角色使用者。一個使用者可以擁有多個角色。", + "Landing_Page_IdentityModuleDescription_4": "設定角色和使用者層級的權限。", + "Landing_Page_IdentityModuleDescription_5": "啟用/停用每個使用者的兩因素身份驗證和使用者鎖定。", + "Landing_Page_IdentityModuleDescription_6": "管理基本使用者設定檔密碼。", + "Landing_Page_IdentityModuleDescription_7": "管理系統中的聲明類型,為角色和使用者設定聲明。", + "Landing_Page_IdentityModuleDescription_8": "設定頁面來管理密碼複雜性、使用者登入、帳戶和鎖定。", + "Landing_Page_IdentityModuleDescription_9": "支援LDAP認證。", + "Landing_Page_IdentityModuleDescription_10": "提供電子郵件和電話號碼驗證。", + "Landing_Page_IdentityModuleDescription_11": "支援社交登入整合(Twitter、Facebook、GitHub 等)。", + "Landing_Page_IdentityModuleDescription_12": "管理系統中的組織單位。", + "Landing_Page_PaymentModuleDescription_1": "提供不同支付網關的整合。", + "Landing_Page_PaymentModuleDescription_2": "此模組提供支付網關的集成,因此您可以輕鬆地從客戶那裡獲得付款。", + "Landing_Page_PaymentModuleDescription_3": "此模組支援以下支付網關", + "Welcome_Page_UseSameCredentialForCommercialWebsites": "對Commercial.abp.iosupport.abp.io使用相同的憑證。", + "WatchCrudPagesVideo": "觀看「使用 ABP Suite 建立 CRUD 頁面」影片!", + "WatchGeneratingFromDatabaseVideo": "觀看“ABP Suite:從現有資料庫表单產生 CRUD 頁面”影片!", + "WatchTakeCloserLookVideo": "觀看“仔細看看程式碼產生:ABP Suite”影片!", + "ConfirmedEmailAddressRequiredToStartTrial": "您應該有一個確認的電子郵件地址才能開始試用許可證。", + "EmailVerificationMailNotSent": "電子郵件驗證郵件無法傳送。", + "GetConfirmationEmail": "如果您之前沒有收到驗證電子郵件,請按一下此處以取得驗證電子郵件。", + "WhichLicenseTypeYouAreInterestedIn": "您對哪種許可證類型感興趣?", + "DontTakeOurWordForIt": "不要相信我們的話...", + "ReadAbpCommercialUsersWantYouToKnow": "閱讀 ABP Commercial 用戶想讓您了解的內容", + "Testimonial_ShortDescription_1": "ABP的模組化使得團隊及時交付成為可能。", + "Testimonial_ShortDescription_2": "比以前更快地建立新功能。", + "Testimonial_ShortDescription_3": "我們從開箱即用的功能開始,只專注於我們真正需要編寫的內容。", + "Testimonial_ShortDescription_4": "ABP Commercial 最適合我們的需求。", + "OnlineReviewersOnAbpCommercial": "ABP 商業線上評論", + "SeeWhatToldAboutAbpCommercial": "查看有關 ABP Commercial 的內容,並根據需要寫下您的想法。", + "ExtendPaymentInfoSection_DeveloperPrice": "{0}x 個額外開發者", + "ExtendPaymentInfoSection_DiscountRate": "折扣 {0}%", + "TotalNetPrice": "總淨價", + "EFCore": "實體框架核心", + "All": "全部", + "Mvc": "多維控制", + "DataBaseProvider": "數據提供者", + "UIFramework": "使用者介面框架", + "LeptonXThemeForDashboard": "您的管理儀表板的 LeptonX 主題", + "AbpPlatform": "總部基地平台", + "YouDeserveGoodUXUI": "您值得擁有良好的使用者介面和更好的使用者體驗。 ABP 的 LeptonX 主題就是為它服務的。", + "ViewLiveDemo": "查看即時主題演示", + "GetLeptonX": "立即取得 LeptonX", + "SeeLeptonXDocumentation": "請參閱 LeptonX 文檔", + "SeeLeptonDocumentation": "請參閱輕子文檔", + "SimplifiedMenu": "簡化選單", + "SimplifiedMenuDescription": "您可以透過篩選選單輕鬆找到您要找的頁面", + "YourFavoritePages": "您最喜歡的頁面觸手可及", + "YourFavoritePagesDescription": "透過點擊頁面右上角的星形圖標,可以輕鬆地從收藏夾中新增或刪除頁面。", + "BreadCrumbs": "用於無縫切換的麵包屑導航", + "BreadCrumbsDescription": "使用麵包屑,即使左側選單關閉,您也可以一鍵切換到相同等級的頁面,並且它適用於平板電腦和行動裝置回應!", + "YourMenu": "您的菜單如您所願", + "YourMenuDescription": "根據需要自訂使用者選單上可直接點選的圖示和下拉方塊。用戶選單可根據您的需求完全客製化", + "RtlSupport": "對您的語言的 RTL 支持", + "RtlSupportDescription": "LeptonX 主題支援您的語言的 RTL。語言選項位於設定選單中,供您更改語言。", + "YourColors": "您的管理儀表板 UI 上的顏色", + "YourColorsDescription": "LeptonX 主題根據您的系統偏好工作,並具有儀表板淺色主題、儀表板深色主題和儀表板半深色主題選項。", + "ArrangeContentWidth": "輕鬆安排內容寬度", + "ArrangeContentWidthDescription": "輕鬆變更內容區域的寬度。", + "LeptonXCompatibleWith": "LeptonX 主題相容", + "MobileResponsiveTemplate": "移動響應模板", + "MobileResponsiveTemplateDescription1": "從您喜歡的任何裝置存取您的 LeptonX 管理儀表板。", + "MobileResponsiveTemplateDescription2": "它專為您在您的每台設備上輕鬆使用而設計。它對行動裝置和平板電腦尺寸具有響應能力。", + "TopMenuLayoutOption": "頂部選單佈局選項", + "TopMenuLayoutOptionDescription1": "如果您想使用相同的管理儀表板設定您的網站,可以使用 LeptonX 主題來實現!", + "TopMenuLayoutOptionDescription2": "只需嘗試 LeptonX 頂部選單佈局即可實現這一目標!", + "EasilyCustomizable": "輕鬆客製化您的品牌顏色", + "EasilyCustomizableDescription1": "您只需使用幾個 SCSS 變數即可自訂 LeptonX 主題。無需覆蓋,無需額外的 CSS 負載!", + "EasilyCustomizableDescription2": "透過 LeptonX,您可以隨心所欲地安排管理儀表板。", + "IndependentLayout": "獨立的佈局和內容區域", + "IndependentLayoutDescription1": "LeptonX 的佈局基礎設施的設計與內容完全分開。", + "IndependentLayoutDescription2": "這意味著如果您願意,您可以使用 Bootstrap 以外的內容結構自由設計專案。", + "MostUsedLibraries": "最常用的庫與 LeptonX 集成", + "MostUsedLibrariesDescription1": "LeptonX 包含您最常用的函式庫。它允許您輕鬆使用 ApexCharts、DataTables、DropZone、FullCalender、JSTree、Select2 和 Toastr 等庫。", + "MostUsedLibrariesDescription2": "LeptonX 也支援 MVC Angular 和 Blazor 特定的函式庫。", + "CreateAndCustomize": "使用 LeptonX 自訂頁面在幾秒鐘內建立和自訂您需要的頁面", + "CreateAndCustomizeDescription": "透過使用 LeptonX 主題,您還可以存取許多預製的 HTML 頁面。其中包括許多頁面,例如登入頁面、部落格、常見問題、訂閱清單、發票、定價和文件管理。", + "LeptonThemeForAdmin": "您的管理儀表板的 Lepton 主題", + "LeptonThemeForAdminDescription": "Lepton 主題仍然可用並將得到維護。如果您想以 Lepton 主題使用者的身份切換到 LeptonX 主題,您可以查看文件以了解操作方法。", + "LeptonCompatibleWith": "Lepton 主題相容", + "UpgradePaymentInfoSection_DeveloperPrice": "{0}(另外 {1} 個開發者)", + "Upgrade": "升級", + "Renewal": "更新", + "UpgradePaymentInfoSection_LicensePrice": "{0}許可證", + "UpgradePaymentInfoSection_LicenseRenewalPrice": "執照更新", + "Total": "全部的", + "TotalDevelopers": "總共 {0} 個開發者", + "CustomPurchaseExplanation": "根據您的具體需求量身定制", + "WhereDidYouHearAboutUs": "你從哪裡知道我們的?", + "Twitter": "推特", + "Facebook": "Facebook", + "Youtube": "Youtube", + "Google": "Google", + "Github": "GitHub", + "Friend": "來自朋友", + "Other": "其他", + "WhereDidYouHearAboutUs_explain": "指定 ...", + "DeletingMemberWarningMessage": "“{0}”將從開發者清單中刪除。如果需要,您可以稍後將此空位分配給其他開發人員。", + "AdditionalInfo": "如果開發人員席位超出您的要求,您可以減少它們。您可以發送電子郵件至info@abp.io來刪除您的一些開發人員席位。清除未使用的開發人員席位將降低授權續約成本。如果需要,您可以在有效許可期內重新購買額外的開發人員席位。請注意,由於此許可證包中有 {0} 個開發人員,因此您無法減少此數量。", + "LinkExpiredErrorMessage": "您嘗試造訪的連結已過期。", + "ExpirationDate": "截止日期", + "SpringCampaignDiscount": "春季活動折扣", + "WhyUseAbpIoPlatform": "為什麼我應該使用 ABP.IO 平台而不是從頭開始創建新的解決方案?", + "WhyUseAbpIoPlatformFaqExplanation": "請參閱該頁面,以詳細了解為什麼使用 ABP.IO 平台比自己做所有事情具有顯著優勢。", + "EulaPageTitle": "最終用戶許可協議 (EULA)", + "PrivacyPolicyPageTitle": "隱私權政策 - Cookie 政策", + "TermsConditionsPageTitle": "條款與條件", + "TrainingsPageTitle": "ABP 培訓包", + "ModulesPageTitle": "ABP 預建應用模組", + "Volo.AbpIo.Commercial:040001": "API 存取金鑰不正確。", + "GetLepton": "立即取得輕子", + "MyOrganizations_Detail_LicenseStartDate": "許可證開始日期", + "MyOrganizations_Detail_LicenseExpiryDate": "到期日", + "BlazoriseSupport": "如何從 Blazorise 團隊取得 Blazorise 授權金鑰和支援?", + "BlazoriseSupportExplanation": "請依照以下步驟取得 Blazorise 團隊的支援並取得您的 Blazorise 授權金鑰:", + "BlazoriseSupportExplanation1": "使用與您的 abp.io 帳戶相同的電子郵件地址在blazorise.com/support/register註冊新帳戶。將「許可證密鑰」條目留空。它必須與您在 abp.io 上的電子郵件帳戶相同。", + "BlazoriseSupportExplanation2": "透過檢查您的電子郵件地址來驗證您的電子郵件地址。如果您在收件匣中沒有看到電子郵件,請檢查您的垃圾郵件匣!", + "BlazoriseSupportExplanation3": "登入 Blazorise 支援網站: blazorise.com/support/login 。", + "BlazoriseSupportExplanation4": "如果您擁有有效的 ABP 商業許可證,您還將擁有 Blazorise PRO 授權。您可以在blazorise.com/support/user/manage/license取得 Blazorise 授權金鑰。", + "BlazoriseSupportExplanation5": "您可以在支援網站上發布您的問題並為您的應用程式產生產品代幣。", + "AbpLiveTrainingPackages": "ABP 現場培訓包", + "Releases": "發布", + "ReleasesDescription": "ABP商業發布日誌。", + "ReleaseDate": "發布日期", + "Labels": "標籤", + "PreRelease": "預發布", + "AllTypes": "所有類型", + "Enhancement": "強化", + "Bug": "漏洞", + "Feature": "特徵", + "AllUIs": "所有使用者介面", + "MVC": "多維控制", + "BlazorServer": "Blazor伺服器", + "MAUI": "模伊島", + "HowItWorks_Page_Title": "怎麼運作的?", + "HowItWorks_Page_Description": "ABP 架構擴充了.NET 平台。因此,使用普通 .NET 解決方案可以做的任何事情都可以透過 ABP 框架實現。這使得以較低的學習曲線輕鬆上手。", + "HowItWorks_Description1": "ABP 架構擴充了.NET 平台。因此,使用普通 .NET 解決方案可以做的任何事情都可以透過 ABP 框架實現。這使得以較低的學習曲線輕鬆上手。", + "HowItWorks_Description2": "一旦您開始學習和使用 ABP 框架功能,開發您的軟體將比以往更加愉快。", + "HowItWorks_Description3": "本頁主要解釋了作為 .NET 開發人員如何使用 ABP.IO 平台。", + "CreateANewSolution": "建立新的 .NET 解決方案", + "CreateANewSolution_Description1": "一切都從創建新的 ABP 整合 .NET 解決方案開始。", + "StartWithStartupTemplates": "啟動預先建置的啟動解決方案範本之一", + "SimpleMonolithApplicationTemplate": "簡單的整體應用程式模板", + "LayeredApplicationTemplate": "分層應用模板", + "MicroserviceSolutionTemplate": "微服務解決方案模板", + "CreateEmptySolutionAndUseAbp": "或建立一個新的空 .NET 解決方案並自行安裝 ABP NuGet 和 NPM套件。", + "CreatingSolutionWithMultipleOptions": "建立新解決方案時有多個使用者介面和資料庫選項。", + "UIFrameworkOptions": "UI 框架選項", + "DotnetSolutionWithoutDependency": "現在,您的本機電腦中有一個常規的 .NET 解決方案,不依賴雲端平台或外部服務。", + "CheckTheDocumentForDetails": "您可以查看{1}文件以了解詳細資訊。", + "UIAndDatabaseIndependent": "ABP 可以與 .NET 支援的任何 UI 和任何資料庫提供者一起使用。 \n然而,這些 UI 和資料庫提供者是預先整合的並且有詳細記錄。", + "InstallAbpModules": "安裝 ABP 模組", + "DevelopYourSolution": "開發您的解決方案", + "DeployAnywhere": "隨處部署", + "InstallAbpModule_Description1": "ABP是一個模組化的應用程式開發框架。啟動解決方案範本已安裝了必要的模組。 \n但是您可能希望在解決方案中使用更多應用程式模組。", + "InstallAbpModule_Description2": "每個模組都由一些NuGet和NPM包組成,並有一個安裝文件。 ABP Suite會自動完成大部分工作,然後您根據其文件手動配置或微調模組。", + "DevelopYourSolution_Description1": "ABP 的基礎設施透過自動化重複性工作並提供預先建置的基礎架構和應用程式功能,使您能夠專注於自己的業務程式碼。", + "DevelopYourSolution_Description2": "在下面的程式碼區塊中,您可以看到 ABP 框架如何無縫整合到您的程式碼中並自動為您執行重複性任務。", + "DevelopYourSolution_Description3": "即使在這個短代碼區塊中,ABP 也為您做了很多事情。", + "DevelopYourSolution_Description4": "它提供了應用約定的基類,例如\n依賴注入。通用\n儲存庫服務提供了一個方便的\n方式與資料庫互動。聲明式\n授權與微調的權限系統一起使用。", + "DevelopYourSolution_Description5": "ABP 完全自動化了\n工作單元(用於資料庫連接和交易管理)、 \n異常處理、 \n驗證\n和審計日誌記錄。它提供了更多構建塊來簡化您的日常開發任務並專注於您自己的程式碼,同時創建可用於生產的\n應用程式。", + "DevelopYourSolution_Description6": "您可以想像,如果您全部手動完成,該程式碼區塊會變得多麼長和複雜。", + "SuiteCrudGenerationInFewSeconds": "除了手動編碼解決方案之外,您還可以使用 ABP Suite 工具在幾分鐘內建立完全可用的高級 CRUD 頁面。它將程式碼產生到您的解決方案中,以便您可以根據您的自訂要求對其進行微調。", + "DeployAnywhere_Description1": "最終,您將擁有一個純 .NET 解決方案。您可以將解決方案部署到您自己的伺服器、雲端平台、Kubernetes 或您想要的任何地方。您可以根據需要部署到任意數量的伺服器。 ABP 是一個與部署環境無關的工具。", + "ExpertiseAbpFramework": "ABP 框架專業知識", + "ExpertiseAbpFramework_Description1": "想要超越基礎知識並獲得 ABP.IO 平台的專業知識嗎?", + "FreeDownload": "免費下載", + "Read": "讀", + "HavingTrouble": "遇到麻煩?", + "HavingTrouble_Description1": "您在開發解決方案時遇到問題嗎?我們在這裡!使用 ABP 支援平台\n或發送電子郵件直接從核心 ABP 框架團隊成員那裡獲取協助。", + "WeAreHereToHelp_Description1": "您可以瀏覽我們的說明主題或在常見問題、 \n中搜索,也可以使用聯絡表單向我們提問。", + "OtherModules": "其他模組", + "OtherModules_Description1": "帳戶、稽核日誌、聊天、CMS 套件、文件管理、表單、GDPR、身分、語言管理、付款、SaaS 等等...", + "HowItWorks_DatabaseProviderOptions": "資料庫提供者選項", + "SeeFAQ": "查看常見問題", + "ReleaseLogs": "發布日誌", + "ReleaseLogs_Tag": "{0} 發布日誌", + "ReleaseLogs_Pr": "拉取請求 #{0} - {1}", + "NoLabels": "無標籤", + "DoesTheSubscriptionRenewAutomatically": "許可會自動續費嗎?", + "DoesTheSubscriptionRenewAutomaticallyExplanation": "ABP 商業版沒有自動續費的計費模式。因此,在您的許可期結束時,您的訂閱將不會自動續訂。如果您希望繼續享受ABP商業版的服務,請在組織管理頁面手動進行續費操作。如果您擁有多個組織,您可以點擊即將到期的組織上的\"管理\"按鈕,然後點擊\"立即續費\"按鈕來續訂您的許可。您還可以查看許可到期後會發生什麼?部分了解更多信息。", + "ExtraQuestionCreditsFaqTitle": "我可以購買額外的支援問題積分嗎?", + "ExtraQuestionCreditsFaqExplanation": "是的你可以。若要購買額外的問題積分,請發送電子郵件至info@abp.io ,並註明您所在組織的名稱。以下是額外問題學分的價格表:
  • 50 個問題包 999 美元
  • 25 個問題包 625 美元
  • 15 個問題包 450 美元
", + "AlreadyBetaTester": "您已經加入了 Beta 測試員計劃。", + "AbpStudio": "總部基地工作室", + "AbpStudio_Description": "ABP Studio 仍在開發中。您可以填寫下面的表单,成為第一批使用者之一。", + "AbpStudio_Description1": "ABP Studio 是一款針對 ABP 開發人員的跨平台桌面應用程式。", + "AbpStudio_Description2": "它與 ABP 框架很好地集成,旨在透過自動化為您提供一個舒適的開發環境,提供有關您的解決方案的見解,使開發、運行部署您的解決方案變得更加容易。", + "AbpStudio_ComingSoon": "即將推出計劃測試版發布日期:2023 年第四季。", + "AbpStudio_PlannedPreviewDate": "計畫預覽版發布日期:2023 年第四季。", + "BetaRequest": "測試版請求", + "CreateNewSolutions": "建立新的解決方案", + "CreateNewSolutions_Description1": "您可以透過多種選項輕鬆建立從簡單應用程式到模組化整體或微服務解決方案。您將獲得適合您企業的完整生產就緒基礎軟體解決方案。", + "ArchitectYourSolutions": "設計您的解決方案", + "ArchitectYourSolutions_Description1": "透過創建模組或服務並在它們之間建立關係,可以更輕鬆地建立整體模組化和微服務解決方案結構。您也可以安裝或解除安裝預先建置的應用程式模組。", + "ExploreYourSolution": "探索您的解決方案", + "ExploreYourSolution_Description1": "ABP Studio 顯示了解決方案中的元件以及解決方案所依賴的模組的高階視圖。您可以探索實體、服務、HTTP API 等,而無需開啟程式碼庫。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze": "輕鬆運行多應用程式或微服務解決方案", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description1": "只需單擊即可運行一項、多項所有服務。這樣,就可以輕易地停止一個服務,在 Visual Studio 中執行它來測試除錯。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description2": "查看服務列表,查看每個服務的即時 HTTP 請求異常計數。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description3": "查看傳入任何服務的所有HTTP 請求的所有詳細資訊。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description4": "在任何服務中即時探索異常詳細信息,輕鬆過濾和搜尋。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description5": "顯示應用程式日誌,按日誌等級過濾或按文字搜尋。", + "RunMultiApplicationOrMicroserviceSolutionsInABreeze_Description6": "無需離開解決方案運行器即可瀏覽應用程式的 UI。", + "IntegrateToYourKubernetesCluster": "整合到您的 Kubernetes 集群", + "IntegrateToYourKubernetesCluster_Description1": "將本地開發環境連接到本地或遠端 Kubernetes 集群,該集群已在其中運行您的微服務解決方案。", + "IntegrateToYourKubernetesCluster_Description2": "存取 Kubernetes 中的任何服務,其服務名稱為 DNS,就像它們在本機電腦中運作一樣。", + "IntegrateToYourKubernetesCluster_Description3": "攔截該叢集中的任何服務,因此被攔截服務的所有流量都會自動重定向到本機電腦中執行的服務。當您的服務需要使用 Kubernetes 中的任何服務時,流量會被重定向回集群,就像您的本機服務在 Kubernetes 內部運作一樣。", + "GetInformed": "獲取資訊", + "Studio_GetInformed_Description1": "留下您的聯絡訊息,以便在 ABP Studio 上線後第一時間獲得通知試用。", + "Studio_GetInformed_Description2": "計畫預覽版發布日期:2023 年第三季。", + "ThankYou!": "謝謝你!", + "SendBetaRequest": "發送測試版請求", + "YouJoinedTheBetaTesterProgram": "您加入了 ABP Studio beta 測試員計畫。", + "PricingExplanation2": "30 天退款保證 —了解更多", + "MoneyBackGuaranteeText": "* 所有許可證均提供 30 天退款保證!團隊許可證 100% 退款,商業和企業許可證 30 天內退款 60%。", + "MobileApplicationStartupTemplates": "行動應用程式啟動模板", + "MobileApplicationStartupTemplates_Description1": "適用於您的 ABP 商業解決方案的整合式行動應用程式啟動範本。", + "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates": "使用 ABP 行動啟動範本建立強大的業務線應用程式", + "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description1": "ABP Commercial 提供了兩個使用React Native.NET MAUI 實現的行動應用程式啟動範本。當您建立新的基於 ABP 的解決方案時,您還將擁有連接到後端 API 的基本啟動應用程式。", + "CreatePowerfulLineOfBusinessApplicationsUsingABPMobileStartupTemplates_Description2": "該應用程式具有預先建置的身份驗證令牌週期、多語言支援、多租戶支援、登入、忘記密碼、設定檔管理和使用者管理頁面。您可以新增自己的業務邏輯並根據您的需求進行自訂。", + "TwoFrameworkOptions": "兩種框架選項", + "TwoFrameworkOptions_Description": "ABP 提供了React Native.NET MAUI行動啟動範本。這樣,您就可以選擇最適合您需求的需求。這兩個應用程式的程式碼重用率在 iOS 和 Android 平台之間最高。", + "PreIntegratedToYourBackend": "預先整合到您的後端", + "PreIntegratedToYourBackend_Description": "ABP Mobile 應用程式已預先整合到您的後端 API。它從伺服器取得有效的身份驗證令牌並發出經過身份驗證的請求。", + "MultiLanguage": "多語言", + "MultiLanguage_Description": "它已經支援 10 多種開箱即用的語言。您也可以新增下一種語言。", + "Arabic": "阿拉伯", + "Czech": "捷克語", + "English": "英語", + "Hungarian": "匈牙利", + "Finnish": "芬蘭", + "French": "法語", + "Hindi": "印地語", + "Portuguese": "葡萄牙語", + "Italian": "義大利語", + "Russian": "俄文", + "Slovak": "斯洛伐克語", + "Turkish": "土耳其", + "EngageAndRetainYourCustomersWithABPMobileApps": "使用 ABP 行動應用程式吸引並留住客戶", + "EngageAndRetainYourCustomersWithABPMobileApps_Description1": "您的客戶希望隨時隨地管理他們的產品和訂閱。這需要組織創建行動應用程序,使客戶能夠快速、無縫地滿足他們的請求。", + "EngageAndRetainYourCustomersWithABPMobileApps_Description2": "透過 ABP Mobile 應用程序,您可以使用單一程式碼庫為 Android 和 iOS 創建高品質的本機行動應用程序,並且不會影響安全性、品質或可擴展性。", + "OneCodeBaseMultipleDevices": "一種程式碼庫支援多種設備", + "OneCodeBaseMultipleDevices_Description": "ABP Mobile 應用程式是跨平台的。它們可以在 iOS 和 Android 裝置上安裝和運行,並使用單一程式碼庫適應不同的外形尺寸。開發人員只需建立一次 UI 和前端程式碼,無需針對要支援的每個裝置調整程式碼。", + "ComesWithTheSourceCode": "附帶原始碼", + "ComesWithTheSourceCode_Description": "行動應用程式隨原始程式碼一起提供。輕鬆自訂應用程式的 UX/UI,以滿足品牌指南。", + "Purchase_OneYearPrice": "1 年價格", + "Purchase_DeveloperSeatCount": "開發者席位數", + "Purchase_DevelopersAlreadyIncluded": "已包含 {0} 個開發者", + "1Year": "1年", + "{0}Years": "{0} 年", + "1YearLicense": "1 年許可證", + "{0}YearsLicense": "{0} 年許可", + "1AdditionalDeveloper": "1 名額外開發人員", + "{0}AdditionalDevelopers": "{0} 其他開發者", + "Discount": "折扣 ({0}%)", + "Summary": "概括", + "TrainingPack": "訓練包", + "TrainingPackDiscount": "培訓包折扣", + "Purchase_OnboardingTraining_Description": "此現場培訓套餐適用於 8 名學生的班級,且此折扣僅在使用新許可證購買時有效。了解更多", + "Purchase_Save": "省 {0}% {1} {2}", + "RemoveBasket": "從購物籃中取出", + "WhyABPIOPlatform?": "為什麼選擇ABP.IO平台?", + "DocumentAim": "本文檔旨在回答一個大問題:", + "DocumentAim_Description": "“為什麼應該使用 ABP.IO 平台而不是從頭開始創建新的解決方案?”", + "DocumentAim_Description2": "該文件介紹了建立現代軟體解決方案的挑戰,並解釋了 ABP 如何應對這些挑戰。", + "CreatingANewSolution": "建立新的解決方案", + "CreatingANewSolution_Description": "當您需要開始一個新的解決方案時,您需要問自己很多問題,並且在開始編寫第一個業務程式碼之前您應該花費大量時間。", + "CreatingAnEmptySolution": "創建一個空的解決方案", + "THEPROBLEM": "問題", + "CreatingAnEmptySolution_THEPROBLEM_Description": "即使創建一個幾乎空的解決方案也是具有挑戰性的;", + "CreatingAnEmptySolution_THEPROBLEM_Description2": "您如何跨專案組織程式碼庫?", + "CreatingAnEmptySolution_THEPROBLEM_Description3": "有哪些層以及它們如何相互作用?", + "CreatingAnEmptySolution_THEPROBLEM_Description4": "如何整合到第三方函式庫和系統?", + "CreatingAnEmptySolution_THEPROBLEM_Description5": "如何設定自動化測試?", + "ABPSOLUTION": "動態血壓解決方案", + "CreatingAnEmptySolution_ABPSOLUTION_Description": "ABP 基於領域驅動設計原則提供了一個架構良好、分層且可用於生產的啟動解決方案。該解決方案還包括每個層的預先配置單元和整合測試項目。", + "CommonLibraries": "通用函式庫", + "CommonLibraries_THEPROBLEM_Description": "您應該使用哪些函式庫來實現常見需求?軟體開發生態系統是高度動態的,這使得跟上最新的工具、函式庫、趨勢和方法變得具有挑戰性。", + "CommonLibraries_ABPSOLUTION_Description": "ABP 將流行的、成熟的和最新的庫預先整合到解決方案中。您不需要花時間整合它們或使它們相互溝通。它們開箱即用,可以正常工作。", + "UITheme&Layout": "使用者介面主題和佈局", + "UITheme&Layout_THEPROBLEM_Description": "在解決 UI 問題時,會出現一系列挑戰。其中包括為響應式、現代且適應性強的 UI 套件奠定基礎,該套件具有一致的外觀和導航選單、頁首、工具列、頁腳、小部件等一系列功能。", + "UITheme&Layout_THEPROBLEM_Description2": "即使您選擇預先設計的主題,將其無縫整合到您的專案中也可能需要數天的開發時間。另一個障礙在於升級此類主題。通常,主題的 HTML/CSS 結構會與您的 UI 程式碼交織在一起,從而呈現未來的主題變更或升級複雜的任務。程式碼和設計的這種交織使後續調整的靈活性變得複雜。", + "UITheme&Layout_ABPSOLUTION_Description": "ABP 框架提供了一個獨特的主題系統,可以將您的 UI 程式碼從主題約束中解放出來。主題獨立存在,包裝為 NuGet 或 NPM 套件,使主題安裝或升級只需幾分鐘。雖然您保留開發自訂主題或整合現有主題的選項,但 ABP Commercial 提供了一系列精緻且現代的主題。", + "UITheme&Layout_ABPSOLUTION_Description2": "此外,還有 Telerik 和 DevExpress 等 UI 元件提供者。然而,這些提供者主要提供單獨的元件,讓您有責任建立自己的佈局系統。在基於 ABP 的專案中工作時,您可以無縫合併這些庫,就像在任何其他專案中一樣。", + "TestInfrastructure": "測試基礎設施", + "TestInfrastructure_THEPROBLEM_Description": "建立強大的測試環境是一項耗時的工作。它涉及在解決方案中設置專用測試項目,仔細選擇必要的工具,創建服務和資料庫模擬,製作必要的基類和實用服務以最大限度地減少測試中的冗餘程式碼,以及解決各種相關任務。", + "TestInfrastructure_ABPSOLUTION_Description": "ABP 啟動範本預先配備了已設定的測試項目,可為您簡化流程。這意味著從第一天起,您就可以立即開始編寫初始單元或整合測試程式碼。", + "CodingStandards&Training": "編碼標準和培訓", + "CodingStandards&Training_THEPROBLEM_Description": "設定開發解決方案後,您通常必須教導開發人員系統如何運作以及如何使用相同的商定方法來建構它。即使您為他們提供培訓,保持文件最新也可能很困難。隨著時間的推移,每個開發人員可能會以自己的方式編寫程式碼,導致編寫程式碼的規則變得彼此不同。", + "CodingStandards&Training_ABPSOLUTION_Description": "ABP 解決方案已經組織得很整齊,並且有明確的解釋。逐步教學和指南向您準確展示如何處理 ABP 專案。", + "KeepingYourSolutionUpToDate": "讓您的解決方案保持最新", + "KeepingYourSolutionUpToDate_THEPROBLEM_Description": "開始開發後,您必須追蹤用於升級和補丁的庫的新版本。", + "KeepingYourSolutionUpToDate_ABPSOLUTION_Description": "我們定期將所有軟體包更新到最新版本,並在穩定版本發布之前對其進行測試。當您更新 ABP 框架時,其所有相依性都會升級為邊緣技術。", + "DRY": "不要重複自己!", + "DRY_Description": "創建基礎解決方案需要大量時間並且需要良好的架構經驗。然而,這只是開始!當您開始開發時,您可能需要編寫大量重複的程式碼;如果所有這些都能自動處理,那就太好了。", + "DRY_Description2": "ABP 透過遵循約定優於配置的原則,盡可能地自動化和簡化重複程式碼。但是,當您需要切換到手排時,它不會限制您。控制權始終掌握在您手中。", + "Authentication": "驗證", + "Authentication_THEPROBLEM_Description": "單一登入、Active Directory / LDAP 整合、OpenIddict 整合、社群登入、雙重認證、忘記/重設密碼、電子郵件啟動、新使用者註冊、密碼複雜性控制、嘗試失敗時鎖定帳戶、顯示失敗的登入嘗試...等等。我們知道您對所有這些通用要求都很熟悉。你並不孤單!", + "Authentication_ABPSOLUTION_Description": "ABP 框架和商業版本提供了所有這些預先實現的標準內容作為可重複使用的帳戶模組。您只需啟用並配置您需要的內容即可。", + "CrossCuttingConcerns": "跨領域的關注點", + "CrossCuttingConcerns_THEPROBLEM_Description": "橫切關注點是應該為每個用例實現的基本重複邏輯。一些例子;", + "CrossCuttingConcerns_THEPROBLEM_Description2": "啟動事務,成功時提交,錯誤時回滾。", + "CrossCuttingConcerns_THEPROBLEM_Description3": "處理和報告異常,向客戶端傳回正確的錯誤回應並在客戶端處理錯誤情況。", + "CrossCuttingConcerns_THEPROBLEM_Description4": "實現授權和驗證,返回正確的回應並在客戶端處理這些回應。", + "CrossCuttingConcerns_ABPSOLUTION_Description": "ABP 框架自動化或簡化了所有常見的橫切關注點。您只需編寫對您的業務重要的程式碼,ABP 將按照慣例處理其餘部分。", + "ArchitecturalInfrastructure": "建築基礎設施", + "ArchitecturalInfrastructure_THEPROBLEM_Description": "您通常需要建立基礎架構才能正確實施您的架構。例如,您通常實作儲存庫模式。您定義一些基底類別來簡化和標準化建立實體、服務、控制器和其他物件。", + "ArchitecturalInfrastructure_ABPSOLUTION_Description": "ABP 框架提供了所有這些以及更多開箱即用的功能。它是成熟的並且有充分的記錄。", + "EnterpriseApplicationRequirements": "企業應用需求", + "EnterpriseApplicationRequirements_THEPROBLEM_Description": "在每個業務應用中都有很多需求需要重複實現;", + "EnterpriseApplicationRequirements_THEPROBLEM_Description2": "細緻的權限體系,依照角色和使用者對UI進行權限管理。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description3": "寫入審核日誌和實體歷史記錄以追蹤使用者何時修改資料庫記錄。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description4": "對您的實體進行軟刪除,以便將它們標記為已刪除,而不是從資料庫中物理刪除並在查詢中自動過濾已刪除的實體。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description5": "建立抽象和包裝器以從前端程式碼使用後端 API。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description6": "排隊並執行後台作業。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description7": "處理全球系統中的多個時區。", + "EnterpriseApplicationRequirements_THEPROBLEM_Description8": "在伺服器和用戶端之間共用驗證、本地化、授權邏輯。", + "EnterpriseApplicationRequirements_ABPSOLUTION_Description": "ABP 提供了一個基礎設施來輕鬆實現此類需求。同樣,您不必花費寶貴的時間一次又一次地重新實現所有這些。", + "GeneratingInitialCode&Tooling": "產生初始程式碼和工具", + "GeneratingInitialCode&Tooling_THEPROBLEM_Description": "您將在典型的 Web 應用程式中建立許多類似的頁面。他們中的大多數都會執行類似的 CRUD 操作。重複建立這樣的頁面非常繁瑣,而且容易出錯。", + "GeneratingInitialCode&Tooling_ABPSOLUTION_Description": "ABP Suite可以在幾秒鐘內為您的實體產生全端 CRUD 頁面。產生的程式碼是分層且乾淨的。所有標準驗證和授權要求均已實施。另外,也會產生單元測試類別。一旦獲得完全運行的頁面,您可以根據您的業務需求進行修改。", + "IntegratingTo3rdPartyLibrariesAndSystems": "整合到第三方函式庫和系統", + "IntegratingTo3rdPartyLibrariesAndSystems_THEPROBLEM_Description": "大多數庫都被設計為低級別,您通常會做一些工作來正確整合它們,而無需在解決方案中的各處重複相同的整合和配置程式碼。例如,假設您必須使用 RabbitMQ 來實現分散式事件匯流排。你想做的就是;將訊息傳送到佇列並處理傳入的訊息。但您需要了解訊息傳遞模式、佇列和交換細節。要編寫高效的程式碼,您必須建立一個池來管理連線、客戶端和通道。您還必須處理異常、ACK 訊息、失敗時重新連線到 RabbitMQ 等。", + "IntegratingTo3rdPartyLibrariesAndSystems_ABPSOLUTION_Description": "例如,ABP 的 RabbitMQ 分散式事件匯流排整合抽象化了所有這些細節。您可以輕鬆地發送和接收訊息。您需要編寫低階程式碼嗎?沒問題,您隨時都可以這樣做。當您需要使用正在使用的庫的低階功能時,ABP 不會限制您。", + "WhyNotBuildYourOwnFramework?": "為什麼不建構自己的框架?", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description": "所有基礎設施,即使是最簡單的方式,也需要花費大量時間來建造、維護和記錄。隨著時間的推移,它會變得越來越大,並且很難在解決方案中維護它。將它們分離成可重複使用的專案是建立您自己的內部框架的起點。", + "WhyNotBuildYourOwnFramework_THEPROBLEM_Description2": "建置、記錄、培訓和維護內部框架確實很困難。如果您沒有經驗豐富的專門框架團隊,您的內部框架很快就會變成無人能理解和維護的未記錄的遺留程式碼。另一方面,這些框架一般是由團隊中的一、兩個開發人員所開發的。這些人正在成為知識孤島。這對他們有利,但對公司不利,因為他們是專案的單點故障-SPOF- 。一旦他們離開公司,專案就會急劇下降。", + "WhyNotBuildYourOwnFramework_ABPSOLUTION_Description": "ABP框架是一個社群驅動的、文件齊全、成熟且通用的應用程式框架。由經驗豐富的開發人員組成的團隊正在努力使其保持最新、易於理解和舒適使用。使用這樣一個穩定的框架可以讓您專注於自己的業務程式碼,並在需要時獲得專家的框架協助。", + "ArchitecturalInfrastructure_Description": "SaaS 應用程式、模組化或微服務系統是最常用的企業軟體模式。建構這樣的系統不僅需要良好的理解和經驗,還需要強大的軟體基礎設施。否則,您會發現自己花費了大量精力來支援程式碼庫中的這些架構細節。", + "Modularity": "模組化", + "Modularity_THEPROBLEM_Description": "要建立真正的模組化系統並不容易!系統的所有方面(資料庫、實體、API、UI 頁面/元件)都可以拆分為模組,並且每個模組都可以重複使用,無需其他模組。普通的 ASP.NET Core 並不會提供這樣的模組化架構。如果你需要的話,你應該從頭開始考慮。", + "Modularity_ABPSOLUTION_Description": "ABP框架天生就是一個模組化的應用程式開發結構。框架中的每個功能都是為了與模組化相容而開發的。文件和指南解釋如何以標準方式開發可重複使用模組。", + "SaaSMultiTenancy": "SaaS/多租戶", + "SaaSMultiTenancy_THEPROBLEM_Description": "多租戶是實施 SaaS 系統的常用方法。然而,實施一致的多租戶基礎設施可能會變得複雜。", + "SaaSMultiTenancy_ABPSOLUTION_Description": "ABP 框架提供了完整的多租戶基礎設施,並從業務程式碼中抽像出複雜性。您的應用程式程式碼將主要是多租戶感知的,而 ABP 框架會自動將資料庫、快取和租戶的其他詳細資訊相互隔離。它支援單一資料庫、每個租戶資料庫和混合方法。它正確配置了 Microsoft Identity 和 OpenIddict 等程式庫,這些程式庫通常不相容於多租用戶。", + "Microservices": "微服務", + "Microservices_THEPROBLEM_Description": "建構微服務系統需要許多基礎設施細節:對應用程式和微服務進行身份驗證和授權以及在微服務之間實現非同步訊息傳遞和同步(Rest/GRPC)通訊模式是最基本的問題。", + "Microservices_ABPSOLUTION_Description": "ABP 框架提供服務、指南和範例,協助您使用業界標準工具實施微服務解決方案。", + "Microservices_ABPSOLUTION_Description2": "ABP Commercial 甚至更進一步,提供了一個完整的啟動範本來啟動您的微服務解決方案。", + "PreBuiltModules": "預建模區塊", + "PreBuiltModules_THEPROBLEM_Description": "我們所有人都有相似但略有不同的業務需求。然而,我們都應該重新發明輪子,因為沒有人的程式碼可以直接在我們的解決方案中工作。它們都是更大解決方案的嵌入部分。", + "PreBuiltModules_ABPSOLUTION_Description": "ABP Commercial模組提供了大量可重複使用的應用模組,例如付款、聊天、檔案管理、稽核日誌報告等。所有這些模組都可以輕鬆安裝到您的解決方案中並直接運行。我們不斷添加更多模組。", + "PreBuiltModules_ABPSOLUTION_Description2": "所有模組均設計為可根據您的業務需求進行客製化。如果您需要完全控制,您可以下載任何模組的完整原始程式碼,並根據您的特定業務需求進行完全自訂。", + "ABPCommunity": "總部社區", + "ABPCommunity_Description": "最後,在一個每個人都遵循相似的編碼風格和原則並共享通用基礎設施的大社區中,當您遇到麻煩或需要設計決策幫助時,這會帶來力量。由於我們編寫的程式碼相似,因此我們可以更好地互相幫助。 ABP 是一個社區支持的項目,在 GitHub 上擁有超過 10K star。", + "ABPCommunity_Description2": "在 ABP 開發人員之間共用程式碼甚至可重複使用的程式庫很容易。適合您的程式碼片段也適用於其他人。有很多範例和教程,您可以直接為您的應用程式實現。", + "ABPCommunity_Description3": "當您聘請曾經使用過 ABP 架構的開發人員時,他會立即了解您的解決方案並在很短的時間內開始開發。", + "WhyAbpIo_Page_Title": "為什麼選擇ABP.IO平台?", + "AbpStudio_Page_Title": "總部基地工作室", + "CampaignInfo": "購買新許可證或續訂現有許可證即可獲得額外 2 個月的有效期,無需額外費用!此優惠對所有許可計劃均有效。確保您利用此限時促銷來擴大對高級功能和升級的存取範圍。", + "HurryUpLastDay": "趕快!最後一天:{0}", + "CreatingCRUDPagesWithABPSuite": "使用 ABP Suite 建立 CRUD 頁面", + "Testimonials": "感言", + "MultipleYearDiscount": "多年折扣", + "CampaignDiscountText": "黑色星期五折扣", + "CampaignDiscountName": "黑色星期五", + "CampaignName:BlackFriday": "黑色星期五", "WhatHappensWhenLicenseEnds": "當我的許可期限結束時會發生什麼?", "WhatHappensWhenLicenseEndsExplanation1": "ABP 商業許可是永久許可。許可證到期後,您可以繼續開發您的項目。而且您沒有義務更新您的許可證。您的許可證附帶開箱即用的一年更新和支持計劃。為了繼續獲得新功能、性能增強、錯誤修復、支持和繼續使用 ABP Suite,您需要更新您的許可證。當您的許可證到期時;", "WhatHappensWhenLicenseEndsExplanation2": "您無法使用 ABP Commercial 創建新的解決方案,但您可以永遠繼續開發現有的應用程序。", @@ -407,8 +1075,6 @@ "WhatHappensWhenLicenseEndsExplanation5": "您不能使用 ABP 套件。", "WhatHappensWhenLicenseEndsExplanation6": "您無法再獲得高級支持。", "WhatHappensWhenLicenseEndsExplanation7": "如果您想繼續獲得這些好處,您可以延長(更新)您的許可證。如果您在許可到期後 {3} 天 內延長許可,將應用以下折扣:團隊許可 {0};營業執照{1};企業許可證{2}。", - "DoesTheSubscriptionRenewAutomatically": "許可會自動續費嗎?", - "DoesTheSubscriptionRenewAutomaticallyExplanation": "ABP 商業版沒有自動續費的計費模式。因此,在您的許可期結束時,您的訂閱將不會自動續訂。如果您希望繼續享受ABP商業版的服務,請在組織管理頁面手動進行續費操作。如果您擁有多個組織,您可以點擊即將到期的組織上的\"管理\"按鈕,然後點擊\"立即續費\"按鈕來續訂您的許可。您還可以查看許可到期後會發生什麼?部分了解更多信息。", "MultipleOrganizationInfo": "查看您的所有組織", "PaymentFailedInfo": "抱歉,支付失败!", "UsedPayment": "该付款已被使用" diff --git a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json index 42fe514b09..48f6d386ee 100644 --- a/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json +++ b/abp_io/AbpIoLocalization/AbpIoLocalization/Community/Localization/Resources/zh-Hans.json @@ -2,259 +2,259 @@ "culture": "zh-Hans", "texts": { "Permission:CommunityPost": "社区文章", - "Permission:Edit": "修改", - "Waiting": "等待中", - "Approved": "已批准", - "Rejected": "已拒绝", + "Permission:Edit": "编辑", + "Waiting": "等待", + "Approved": "批准", + "Rejected": "拒绝", "Wait": "等待", "Approve": "批准", "Reject": "拒绝", "ReadPost": "阅读文章", "Status": "状态", "ContentSource": "内容来源", - "Details": "详情", + "Details": "详细信息", "Title": "标题", "CreationTime": "创建时间", "Save": "保存", - "SameUrlAlreadyExist": "url已存在,如果你想要添加这篇文章,你需要更改url!", - "UrlIsNotValid": "Url无效.", - "UrlNotFound": "Url未找到.", - "UrlContentNotFound": "Url内容未找到.", + "SameUrlAlreadyExist": "相同的网址已经存在,如果您想添加这个文章,应该更改网址!", + "UrlIsNotValid": "Url 无效。", + "UrlNotFound": "未找到 Url。", + "UrlContentNotFound": "未找到 Url 内容。", "Summary": "摘要", - "MostRead": "阅读最多", + "MostRead": "最多阅读", "Latest": "最新", - "ContributeAbpCommunity": "为ABP社区做贡献", - "SubmitYourPost": "提交你的文章", + "ContributeAbpCommunity": "为 ABP 社区做贡献", + "SubmitYourPost": "提交您的文章", "ContributionGuide": "贡献指南", - "BugReport": "Bug报告", - "SeeAllPosts": "查看所有的文章", - "WelcomeToABP": "欢迎来到ABP", - "EmailNotValid": "请输入有效的电子邮箱地址.", + "BugReport": "错误报告", + "SeeAllPosts": "查看所有文章", + "WelcomeToABP": "欢迎来到 ABP", + "EmailNotValid": "请输入有效的电子邮件地址。", "FeatureRequest": "功能请求", - "CreatePostTitleInfo": "文章标题显示在文章列表中.", - "CreatePostSummaryInfo": "文章的简短摘要将显示在文章列表中.", - "CreatePostCoverInfo": "要创建一个有效的帖子,需要添加封面图片. 上传16:9的图片获取最佳视觉效果. 文件最大支持: 1MB", - "ThisExtensionIsNotAllowed": "不允许此扩展名.", - "TheFileIsTooLarge": "文件过大.", - "GoToThePost": "转到文章", - "GoToTheVideo": "前往视频", - "Contribute": "贡献", - "OverallProgress": "总体流程", - "Done": "完成", - "Open": "打开", + "CreatePostTitleInfo": "文章列表中要显示的文章标题。", + "CreatePostSummaryInfo": "文章的简短摘要,将显示在文章列表中。最大长度:{0}1MB。", + "ThisExtensionIsNotAllowed": "不允许延期。", + "TheFileIsTooLarge": "文件太大。", + "GoToThePost": "前往文章", + "GoToTheVideo": "观看视频", + "Contribute": "投稿", + "OverallProgress": "总体进展", + "Done": "已完成", + "Open": "开放", "Closed": "关闭", - "RecentQuestionFrom": "最近的问题来自 {0}", + "RecentQuestionFrom": "{0}最近提出的问题", "Stackoverflow": "Stackoverflow", - "Votes": "票数", + "Votes": "观看次数", "Answer": "回答", - "Views": "观看次数", + "Views": "视图", "Answered": "已回答", - "WaitingForYourAnswer": "等待你的回答", + "WaitingForYourAnswer": "等待您的答复", "Asked": "提问", - "AllQuestions": "所有的问题", - "NextVersion": "下一个版本", - "MilestoneErrorMessage": "无法从Github获取当前的里程碑详细信息.", - "QuestionItemErrorMessage": "无法从Stackoverflow获取最新的问题详细信息.", - "Oops": "哎呀!", - "CreatePostSuccessMessage": "文章提交成功. 网站管理员审核通过后将被发布.", + "AllQuestions": "所有问题", + "NextVersion": "下一版", + "MilestoneErrorMessage": "无法从 Github 获取当前里程碑的详细信息。", + "QuestionItemErrorMessage": "无法从 Stackoverflow 获取最新问题的详细信息。", + "Oops": "哎呀!", + "CreatePostSuccessMessage": "文章已成功提交。网站管理员审核后将予以发布。", "Browse": "浏览", "CoverImage": "封面图片", - "ShareYourExperiencesWithTheABPFramework": "分享你的ABP Framework经验!", - "Optional": "可选的", - "UpdateUserWebSiteInfo": "示例: https://johndoe.com", - "UpdateUserTwitterInfo": "示例: johndoe", - "UpdateUserGithubInfo": "示例: johndoe", - "UpdateUserLinkedinInfo": "示例: https://www.linkedin.com/...", - "UpdateUserCompanyInfo": "示例v: Volosoft", - "UpdateUserJobTitleInfo": "示例: Software Developer", + "ShareYourExperiencesWithTheABPFramework": "分享您使用 ABP 框架的经验!", + "Optional": "可选", + "UpdateUserWebSiteInfo": "例如:https://johndoe.com", + "UpdateUserTwitterInfo": "示例:johndoe", + "UpdateUserGithubInfo": "示例:johndoe", + "UpdateUserLinkedinInfo": "例如: https://www.linkedin.com/...", + "UpdateUserCompanyInfo": "示例:Volosoft", + "UpdateUserJobTitleInfo": "例如:软件开发人员软件开发人员", "UserName": "用户名", - "Company": "公司", + "Company": "公司名称", "PersonalWebsite": "个人网站", - "RegistrationDate": "注册时间", - "Social": "社交", - "Biography": "传记", + "RegistrationDate": "注册日期", + "Social": "社会", + "Biography": "简历", "HasNoPublishedPostsYet": "尚未发表文章", "Author": "作者", - "LatestGithubAnnouncements": "最新的Github公告", + "LatestGithubAnnouncements": "最新 Github 公告", "SeeAllAnnouncements": "查看所有公告", "LatestBlogPost": "最新博客文章", - "Edit": "修改", - "ProfileImageChange": "更改资料图片", - "BlogItemErrorMessage": "无法从ABP获取最新的博客文章详细信息.", + "Edit": "编辑", + "ProfileImageChange": "更改个人形象", + "BlogItemErrorMessage": "无法从 ABP 获取最新博文的详细信息。", "PlannedReleaseDate": "计划发布日期", - "CommunityPostRequestErrorMessage": "无法从Github获取最新的文章请求.", - "PostRequestFromGithubIssue": "现在没有任何文章请求.", - "LatestPosts": "最新的帖子", - "ArticleRequests": "文章请求", - "ArticleRequestsDescription": "想在这里查看具体内容吗? 您可以要求社区创建它!", - "LatestContentRequests": "最新内容请求", - "AllPostRequests": "查看所有文章请求", - "SubscribeToTheNewsletter": "订阅简讯", - "NewsletterEmailDefinition": "获取有关ABP发生的信息,例如新版本,免费资源,文章等.", - "NoThanks": "不用了,谢谢", - "MaybeLater": "以后再说", - "JoinOurPostNewsletter": "加入我们的文章简讯", + "CommunityPostRequestErrorMessage": "无法从 Github 获取最新的发布请求。", + "PostRequestFromGithubIssue": "现在没有任何职位请求。", + "LatestPosts": "最新文章", + "ArticleRequests": "申请内容", + "ArticleRequestsDescription": "想在这里看到特定内容?您可以要求社区创建!", + "LatestContentRequests": "最新内容申请", + "AllPostRequests": "查看所有职位申请", + "SubscribeToTheNewsletter": "订阅时事通讯", + "NewsletterEmailDefinition": "获取有关 ABP 发生的信息,如新版本、免费资源、文章等。", + "NoThanks": "不,谢谢", + "MaybeLater": "也许以后", + "JoinOurPostNewsletter": "加入我们的邮政通讯", "Community": "社区", - "Marketing": "营销", - "CommunityPrivacyPolicyConfirmation": "我同意条款和条件以及隐私政策.", - "PostRequestMessageTitle": "在GitHub上创建一个Issue,以请求你要在此网站上查看的文章/教程.", - "PostRequestMessageBody": "在这里,是社区请求的文章列表. 您要写一篇要求的文章吗? 请单击该请求并加入讨论.", + "Marketing": "市场营销", + "CommunityPrivacyPolicyConfirmation": "我同意条款和条件以及 隐私政策。", + "PostRequestMessageTitle": "在 GitHub 上打开一个问题,申请您希望在本网站上看到的文章/教程。", + "PostRequestMessageBody": "以下是社区要求撰写的文章列表。您想撰写要求发表的文章吗?请点击请求并加入讨论。", "Language": "语言", - "CreatePostLanguageInfo": "本文所用的语言", + "CreatePostLanguageInfo": "文章内容的语言。", "VideoPost": "视频", - "Post": "文章", + "Post": "职位", "Read": "阅读", - "CreateGithubPostUrlInfo": "文章的原始GitHub链接.", - "CreateVideoContentUrlInfo": "文章的原始Youtube链接.", - "CreateExternalPostUrlInfo": "本文的原始外部网址", - "VideoContentForm": "视频内容来源", - "GithubPostForm": "Github文章来源", - "ExternalPostForm": "外部文章来源", - "HowToPost": "如何发布", - "Posts": "文章", - "VideoUrl": "视频Url", - "GithubPostUrl": "Github文章Url", - "ExternalPostUrl": "外部文章Url", - "ThankYouForContribution": "感谢你对ABP社区的贡献", - "GithubPost": "Github文章", - "GithubPostSubmitStepOne": "1. 用Markdown格式在GitHub的任何公共存储库上写一篇文章. 示例", - "GithubPostSubmitStepTwo": "2. 使用表单提交你的文章URL.", - "GithubPostSubmitStepThree": "3. 你的文章将在这个网站中呈现.", - "YoutubeVideo": "Youtube视频", - "YoutubeVideoSubmitStepOne": "1. 在YouTube上发布你的视频.", - "YoutubeVideoSubmitStepTwo": "2. 使用表单提交视频URL.", - "YoutubeVideoSubmitStepThree": "3. 访客将能够在这个网站上直接观看你的视频内容.", + "CreateGithubPostUrlInfo": "GitHub 上 Markdown 文件的完整 URL(示例)。", + "CreateVideoContentUrlInfo": "文章的原始 Youtube URL。", + "CreateExternalPostUrlInfo": "文章的原始外部网址。", + "VideoContentForm": "在 YouTube 上提交视频", + "GithubPostForm": "在 GitHub 上提交文章", + "ExternalPostForm": "提交外部内容", + "HowToPost": "如何发布?", + "Posts": "职位", + "VideoUrl": "视频网址", + "GithubPostUrl": "GitHub 发布网址", + "ExternalPostUrl": "外部链接", + "ThankYouForContribution": "感谢您为 ABP 社区做出贡献。", + "GithubPost": "GitHub 发布", + "GithubPostSubmitStepOne": "1.使用 Markdown 格式在任何公共 GitHub 仓库上撰写文章。示例", + "GithubPostSubmitStepTwo": "2.使用表单提交您的文章 URL。", + "GithubPostSubmitStepThree": "3.您的文章将在本网站显示。", + "YoutubeVideo": "Youtube 视频", + "YoutubeVideoSubmitStepOne": "1.在 YouTube 上发布视频。", + "YoutubeVideoSubmitStepTwo": "2.使用表单提交视频 URL。", + "YoutubeVideoSubmitStepThree": "3.访问者可以直接在本网站上观看您的视频内容。", "ExternalContent": "外部内容", - "ExternalContentSubmitStepOne": "1. 在任何公开的平台创建内容(medium, 你自己的博客或者任何你喜欢的).", - "ExternalContentSubmitStepTwo": "2. 使用表单提交内容URL.", - "ExternalContentSubmitStepThree": "3. 访客被重定向到原网站的内容.", - "ChooseYourContentType": "请选择你想要添加内容的方式", - "PostContentViaGithub": "我想要使用 GitHub提交markdown格式的文章", - "PostContentViaYoutube": "我想要分享我在 Youtube的可用视频", - "PostContentViaExternalSource": "我想要添加我在其他平台发布的内容", - "GitHubUserNameValidationMessage": "您的Github用户名不能包含空格, 请确认你的Github用户名是正确的.", - "PersonalSiteUrlValidationMessage": "你的个人网站URL不能包含空格, 请确定你的个人网站URL是正确的.", - "TwitterUserNameValidationMessage": "你的Twitter用户名不能包含空格, 请确认你的Twitter用户名是正确的.", - "LinkedinUrlValidationMessage": "你的领英URL不能包含空格, 请确认你的领英URL是正确的", - "NoPostsFound": "没有发现帖子", - "SearchInPosts": "搜索帖子…", + "ExternalContentSubmitStepOne": "1.在任何公共平台(Medium、你自己的博客或任何你喜欢的地方)上创建内容。", + "ExternalContentSubmitStepTwo": "2.使用表单提交您的内容 URL。", + "ExternalContentSubmitStepThree": "3.访问者会被重定向到原始网站的内容。", + "ChooseYourContentType": "请选择添加内容的方式。", + "PostContentViaGithub": "我想根据标记符规则,用 GitHub 添加我的文章。", + "PostContentViaYoutube": "我想在这里分享我在 Youtube 上提供的视频。", + "PostContentViaExternalSource": "我想在这里添加我在另一个平台上发布的内容。", + "GitHubUserNameValidationMessage": "您的 Github 用户名不能包含空格,请确保您的 Github 用户名正确无误。", + "PersonalSiteUrlValidationMessage": "您的个人网站 URL 不能包含空格,请确保您的个人网站 URL 正确无误。", + "TwitterUserNameValidationMessage": "您的 Twitter 用户名不能包含空格,请确保您的 Twitter 用户名正确无误。", + "LinkedinUrlValidationMessage": "您的 Linkedin URL 不能包含空格,请确保您的 Linkedin URL 正确无误。", + "NoPostsFound": "未找到文章!", + "SearchInPosts": "在文章中搜索...", "MinimumSearchContent": "您必须输入至少 3 个字符!", "Volo.AbpIo.Domain:060001": "源 URL(\"{PostUrl}\") 不是 Github URL", - "Volo.AbpIo.Domain:060002": "文章内容无法从 Github(\"{PostUrl}\") 资源中获得。", - "Volo.AbpIo.Domain:060003": "没有找到文章内容!", + "Volo.AbpIo.Domain:060002": "Github(\"{PostUrl}\") 资源中没有文章内容。", + "Volo.AbpIo.Domain:060003": "未找到文章内容!", "SeeMore": "查看更多", "JoinTheABPCommunity": "加入 ABP 社区", - "ABPCommunityTalks": "ABP 社区会谈", - "LiveDemo": "现场演示", - "GetLicense": "获得许可证", - "GetStarted": "开始使用", + "ABPCommunityTalks": "ABP 社区讲座", + "LiveDemo": "在线演示", + "GetLicense": "获取许可证", + "GetStarted": "开始", "SourceCode": "源代码", "LeaveComment": "发表评论", - "ShowMore": "展示更多", - "NoPublishedPostsYet": "还没有发布的帖子。", - "Name": "名字", + "ShowMore": "显示更多", + "NoPublishedPostsYet": "尚未发表文章。", + "Name": "名称", "Surname": "姓氏", "WebSite": "网站", "FullURL": "完整网址", - "JobTitle": "职称", + "JobTitle": "职位名称", "Prev": "上一页", - "Previous": "前面的", + "Previous": "上一页", "Next": "下一页", "Share": "分享", "SortBy": "排序方式", "NoPublishedEventsYet": "尚未发布活动。", "SubscribeYoutubeChannel": "订阅 Youtube 频道", "Enum:EventType:0": "会谈", - "MemberNotPublishedPostYet": "该成员尚未发布任何帖子。", - "TimeAgo": "{0} 前", + "MemberNotPublishedPostYet": "该成员尚未发表任何文章。", + "TimeAgo": "{0}前", "Discord_Page_JoinCommunityMessage": "加入 ABP Discord 社区", "Discord_Page_Announce": "我们很高兴地宣布 ABP 社区 Discord 服务器!", - "Discord_Page_Description_1": "ABP 社区从第一天起就一直在壮大。 我们希望通过创建一个官方的 ABP Discord 服务器将其带入下一步,这样 ABP 社区就可以使用即时消息的功能彼此进行互动。", - "Discord_Page_Description_2": "ABP Community Discord Server 是您可以使用 ABP 框架来展示您的创作、分享对您有用的技巧、了解有关 ABP 框架的最新消息和公告、与社区成员聊天交流想法并玩得开心的地方!", - "Discord_Page_Description_3": "此 ABP 社区 Discord 服务器是 ABP 核心团队的官方服务器,存在于服务器上进行监控。", + "Discord_Page_Description_1": "ABP 社区从第一天起就一直在成长。我们希望通过创建一个官方 ABP Discord 服务器,让 ABP 社区可以利用即时信息的奇妙功能进行互动,从而更上一层楼。", + "Discord_Page_Description_2": "ABP 社区 Discord 服务器是您展示使用 ABP 框架创作的作品、分享对您有用的技巧、了解有关 ABP 框架的最新新闻和公告、与社区成员聊天以交流想法并享受乐趣的地方!", + "Discord_Page_Description_3": "这个 ABP 社区 Discord 服务器是官方服务器,ABP 核心团队会在服务器上进行监控。", "Discord_Page_JoinToServer": "加入 ABP Discord 服务器", "Events_Page_MetaTitle": "ABP 社区活动", - "Events_Page_MetaDescription": "现场活动由 ABP 团队主持,是充满社区内容、演示、问答和围绕 ABP 正在发生的事情的讨论的休闲会议。", - "Events_Page_Title": "ABP社区会谈", - "Members_Page_WritingFromUser": "阅读来自 ABP 社区的 {0} 的文章。", - "Post_Create_Page_MetaTitle": "最新帖子", - "Post_Create_Page_MetaDescription": "创建您的帖子以分享您对 ABP 框架的经验并为 ABP 社区做出贡献。", - "Post_Create_Page_CreateNewPost": "创建新帖子", - "Post_Index_Page_MetaDescription": "ABP 社区的目的是为使用 ABP 框架的开发人员创建一个贡献环境。", - "Layout_Title": "{0} | ABP 社区", - "Layout_MetaDescription": "ABP 社区是一个人们可以分享有关 ABP 框架的帖子并关注项目的环境。", - "Index_Page_CommunityIntroduction": "这是 ABP 框架、.NET 和软件开发的中心。 您可以阅读文章,观看视频教程,了解 ABP 的开发进度和 ABP 相关事件,帮助其他开发人员并与 ABP 社区分享您的专业知识。", + "Events_Page_MetaDescription": "现场表演由 ABP 团队主持,是充满社区内容、演示、问答和围绕 ABP 发生的事情进行讨论的休闲会议。", + "Events_Page_Title": "ABP 社区讲座", + "Members_Page_WritingFromUser": "从 ABP Community 上的 {0} 读写。", + "Post_Create_Page_MetaTitle": "新职位", + "Post_Create_Page_MetaDescription": "创建您的文章,分享您关于 ABP 框架的经验并为 ABP 社区做出贡献。", + "Post_Create_Page_CreateNewPost": "创建新职位", + "Post_Index_Page_MetaDescription": "ABP 社区的宗旨是为使用 ABP 框架的开发人员创建一个贡献环境。", + "Layout_Title": "{0}| ABP 社区", + "Layout_MetaDescription": "ABP Framework、.NET 和软件开发的中心。访问文章、教程、新闻,并为 ABP 社区做出贡献。", + "Index_Page_CommunityIntroduction": "这里是 ABP 框架、.NET 和软件开发的中心。您可以阅读文章、观看视频教程、了解 ABP 的开发进度和 ABP 相关活动、帮助其他开发人员并与 ABP 社区分享您的专业知识。", "TagsInArticle": "文章中的标签", - "IConsentToMedium": "我同意在 https://medium.com/volosoft 上发布这篇文章。", - "SearchResultsFor": " span class=\"fw-bold\">\"{0}\"
的搜索结果", + "IConsentToMedium": "我同意在 https://medium.com/volosoft 上发表此文。", + "SearchResultsFor": "\"{0}\"的搜索结果", "SeeMoreVideos": "查看更多视频", - "DiscordPageTitle": "ABP Discord社区", + "DiscordPageTitle": "ABP Discord 社区", "ViewVideo": "观看视频", - "AbpCommunityTitleContent": "ABP 社区 - 开源 ABP 框架", - "CommunitySlogan": "一个独特的ABP 爱好者社区平台", + "AbpCommunityTitleContent": "ABP 社区 - 开放源码 ABP 框架", + "CommunitySlogan": "ABP 爱好者的独特社区平台莱佛士", - "UpcomingRaffles": "即将开业的莱佛士酒店", - "CompletedRaffles": "莱佛士竣工", - "NoActiveRaffleTitle": "目前没有有效的抽奖活动。", - "NoActiveRaffleDescription": "目前没有有效的抽奖活动。", - "RaffleSubscriptionCodeInputMessage": "本次抽奖需要注册码。请输入以下注册码:", - "RaffleSubscriptionCodeInputErrorMessage": "注册码不正确。请再试一次。", - "GoodJob!": "好工作!", - "RaffleJoinSuccessMessage": "您已成功注册参加抽奖。如果您获奖,我们将通过电子邮件通知您!", - "RaffleLoginAndRegisterMessage": "您应该登录才能参加抽奖。如果您尚未注册,可以免费创建一个帐户。", + "To{0}LuckyWinners": "赠送给 {0} 名幸运获奖者", + "ActiveRaffles": "活跃的 来抽奖抽奖抽奖往届活动", + "GoToConferencePage": "转至会议页面", + "BuyTicket": "购票", + "SeeEvent": "观看活动", + "PreviousEvents": "以前的活动", "OtherLiveEvents": "其他现场活动", "SponsoredConferences": "赞助会议", - "SponsoredConferencesDescription": "我们很荣幸为软件开发人员支持 .NET 社区和活动。", + "SponsoredConferencesDescription": "我们很荣幸能为软件开发人员的 .NET 社区和活动提供支持。", "UpcomingEvents": "即将举行的活动", - "UpcomingCommunityTalkEventDescription": "现场表演由 ABP 团队主持,是休闲会议,充满社区内容、演示、问答以及围绕 ABP 发生的事情的讨论。", - "UpcomingConferenceEventDescription": "ABP .NET 会议是 .NET 开发人员社区聚集在一起聆听有关 .NET 世界、常见软件开发实践和开源 ABP 框架的讨论的虚拟活动。", - "LastOneYear": "过去 1 年", - "AllTimes": "一直", - "TopContributors": "杰出贡献者", - "{0}Posts": "{0} 条帖子", - "LATESTPOSTS": "最新帖子", - "NoContributorsFound": "未找到贡献者!", - "LatestPost": "最新的帖子", - "MEMBERSINCE{0}": "自 {0} 起成为会员", + "UpcomingCommunityTalkEventDescription": "现场表演由 ABP 团队主持,是充满社区内容、演示、问答和围绕 ABP 发生的事情进行讨论的休闲会议。", + "UpcomingConferenceEventDescription": "ABP .NET 会议是.NET 开发人员社区的一次虚拟活动,他们可以齐聚一堂,聆听有关 .NET 世界、常用软件开发实践和开源 ABP 框架的讲座。", + "LastOneYear": "最近 1 年", + "AllTimes": "所有时间", + "TopContributors": "顶级贡献者", + "{0}Posts": "{0}职位", + "LATESTPOSTS": "最新文章", + "NoContributorsFound": "未找到撰稿人!", + "LatestPost": "最新职位", + "MEMBERSINCE{0}": "成员,因为{0}", "CopyLink": "复制链接", - "ShareOnTwitter": "分享到Twitter", - "ShareOnLinkedIn": "在领英上分享", - "MoreFrom{0}": "来自{0}的更多内容", - "SeeAllFrom{0}": "查看来自{0}的全部内容", + "ShareOnTwitter": "在 Twitter 上分享", + "ShareOnLinkedIn": "在 LinkedIn 上分享", + "MoreFrom{0}": "来自 {0} 的更多信息", + "SeeAllFrom{0}": "查看来自 {0} 的所有内容", "MostWatched": "最受关注", "Articles({0})": "文章 ({0})", "Videos({0})": "视频 ({0})", - "LatestArticles": "最新的文章", - "RaffleHeader": "ABP 社区成员您好!", - "RafflesInfo": "
这是抽奖页面,旨在表达我们对您作为活跃社区成员的感谢。我们举办ABP 社区讲座、ABP .NET 会议、参加或赞助 .NET 相关活动,并在活动中赠送一些礼物。

您可以关注此页面查看即将举行的抽奖活动、参加抽奖活动或查看我们之前抽奖的抽奖活动(包括获奖者)。

感谢您成为活跃会员!在即将到来的抽奖活动中再见。", - "RafflesInfoTitle": "ABP 社区莱佛士" + "LatestArticles": "最新文章", + "RaffleHeader": "你好,ABP 社区成员!", + "RafflesInfo": "
这是一个抽奖页面,旨在感谢您成为活跃的社区成员。我们举办 ABP 社区讲座 、ABP .NET 会议,参加或赞助与 .NET 相关的活动,并在活动中赠送一些礼品。

您可以关注此页面,查看即将举行的抽奖活动、参加这些活动或查看我们以前举行的抽奖活动(包括获奖者)。

感谢您成为我们的活跃成员!在即将举行的抽奖活动中再见。", + "RafflesInfoTitle": "ABP 社区来抽奖Hangfire & RabbitMQ集成已经可用.", - "DDDInfrastructure": "DDD基础设施", - "DomainDrivenDesignInfrastructure": "Domain Driven Design基础设施", - "AutoRESTAPIs": "自动REST APIs", + "BackgroundJobsExplanation": "定义简单的类,在后台执行排队作业。使用内置作业管理器或集成自己的作业管理器。HangfireRabbitMQ 集成已经可用。", + "DDDInfrastructure": "DDD 基础设施", + "DomainDrivenDesignInfrastructure": "领域驱动设计基础设施", + "AutoRESTAPIs": "自动 REST API", "DynamicClientProxies": "动态客户端代理", "DistributedEventBus": "分布式事件总线", - "DistributedEventBusWithRabbitMQIntegration": "具有RabbitMQ集成的分布式事件总线", + "DistributedEventBusWithRabbitMQIntegration": "集成 RabbitMQ 的分布式事件总线", "TestInfrastructure": "测试基础设施", "AuditLoggingEntityHistories": "审计日志和实体历史", - "ObjectToObjectMapping": "对象映射", - "ObjectToObjectMappingExplanation": "对象到对象映射 抽象AutoMapper集成.", + "ObjectToObjectMapping": "对象到对象映射", + "ObjectToObjectMappingExplanation": "对象到对象映射抽象与 AutoMapper 集成。", "EmailSMSAbstractions": "电子邮件和短信抽象", - "EmailSMSAbstractionsWithTemplatingSupport": "具有模板支持的电子邮件和短信抽象", - "Localization": "本土化", + "EmailSMSAbstractionsWithTemplatingSupport": "电子邮件和短信抽象,支持模板化", + "Localization": "本地化", "SettingManagement": "设置管理", "ExtensionMethods": "扩展方法", "ExtensionMethodsHelpers": "扩展方法和助手", "AspectOrientedProgramming": "面向切面的编程", "DependencyInjection": "依赖注入", - "DependencyInjectionByConventions": "依据约定的依赖注入", - "ABPCLIExplanation": "ABP CLI(命令行界面)是用于对ABP解决方案执行常见操作的命令行工具.", - "ModularityExplanation": "ABP提供了一个完整的基础设施来构建你自己的应用程序模块,这些模块可能具有实体,服务,数据库集成,API,UI组件等.", - "MultiTenancyExplanation": "ABP框架不仅支持开发多租户应用程序,而且使你的代码几乎无需知道多租户.", - "MultiTenancyExplanation2": "可以自动确定当前租户,将不同租户的数据相互隔离.", - "MultiTenancyExplanation3": "支持单一数据库,或每个租户单独数据库或者混合方式.", - "MultiTenancyExplanation4": "你专注于业务代码,并让该框架为你处理多租户.", - "BootstrapTagHelpersExplanation": "与其手动编写重复细节的bootstrap组件,不如使用ABP的tag helper来简化它并利用智能感知.你当然也可以在需要时直接使用Bootstrap.", - "DynamicFormsExplanation": "动态表单和tag helpers可从作为模型的C#类创建完整的表单.", - "AuthenticationAuthorizationExplanation": "集成到ASP.NET Core Identity和OpenIddict的丰富身份验证和授权选项.提供可扩展且详细的权限系统.", - "CrossCuttingConcernsExplanation": "不要重复自己一次又一次地实现所有这些常见的东西.专注于你的业务代码,并让ABP按照约定自动执行.", + "DependencyInjectionByConventions": "按约定进行依赖注入", + "ABPCLIExplanation": "ABP CLI(命令行界面)是一种命令行工具,用于自动执行基于 ABP 解决方案的一些常见操作。", + "ModularityExplanation": "ABP 提供了一个完整的基础架构,用于构建您自己的应用程序模块,这些模块可能包含实体、服务、数据库集成、API、UI组件等。", + "MultiTenancyExplanation": "ABP 框架不仅支持开发多租户应用程序,还能让你的代码在很大程度上不知道多租户的存在。", + "MultiTenancyExplanation2": "可自动判断当前租户,将不同租户的数据相互隔离。", + "MultiTenancyExplanation3": "支持单一数据库、每个租户数据库和混合方法。", + "MultiTenancyExplanation4": "您只需专注于业务代码,让框架代您处理多租户问题。", + "BootstrapTagHelpersExplanation": "与其手动编写 Bootstrap 组件的重复细节,不如使用 ABP 的Tag helpers来简化它,并利用 IntelliSense 的优势。你当然也可以在需要时直接使用Bootstrap。", + "DynamicFormsExplanation": "动态表单和输入Tag helpers可以从作为模型的 C# 类中创建完整的表单。", + "AuthenticationAuthorizationExplanation": "与 ASP.NET Core Identity 和 IdentityServer4 集成的丰富的身份验证和授权选项。提供可扩展的详细权限系统。", + "CrossCuttingConcernsExplanation": "不要重复实现所有这些常见的东西。专注于您的业务代码,让 ABP 按约定自动执行它们。", "DatabaseConnectionTransactionManagement": "数据库连接和事务管理", - "CorrelationIdTracking": "关联ID跟踪", - "BundlingMinificationExplanation": "ABP提供了一个简单,动态,功能强大,模块化的内置Bundling & Minification系统.", - "VirtualFileSystemnExplanation": "虚拟文件系统使管理文件系统(磁盘)上不存在的文件成为可能.它主要用于将(js,css,image,cshtml...)文件嵌入到程序集中,并在运行时像物理文件一样使用它们.", - "ThemingExplanation": "主题系统允许通过基于最新的Bootstrap框架定义一组通用基础库和布局来独立开发应用程序和模块主题.", - "DomainDrivenDesignInfrastructureExplanation": "基于域驱动设计模式和准则构建分层应用程序的完整基础设施;", - "Specification": "规范", + "CorrelationIdTracking": "相关标识跟踪", + "BundlingMinificationExplanation": "ABP 提供了一个简单、动态、强大、模块化和内置的捆绑与压缩系统。", + "VirtualFileSystemnExplanation": "虚拟文件系统可以管理不存在于文件系统(磁盘)上的文件。它主要用于将(js、css、图像、cshtml......)文件嵌入程序集,并在运行时像使用物理文件一样使用它们。", + "ThemingExplanation": "通过基于最新 Bootstrap 框架定义的一套通用基础库和布局,编辑系统允许开发独立于主题的应用程序和模块。", + "DomainDrivenDesignInfrastructureExplanation": "根据领域驱动设计模式和原则构建分层应用程序的完整基础架构;", + "Specification": "规约", "Repository": "仓储", "DomainService": "领域服务", "ValueObject": "值对象", - "ApplicationService": "应用程序服务", + "ApplicationService": "应用服务", "DataTransferObject": "数据传输对象", - "AggregateRootEntity": "聚合根, 实体", - "AutoRESTAPIsExplanation": "ABP可以按照约定自动将你的应用程序服务配置为API控制器.", - "DynamicClientProxiesExplanation": "从JavaScript和C#客户端轻松使用你的API.", - "DistributedEventBusWithRabbitMQIntegrationExplanation": "使用带有RabbitMQ集成的内置分布式事件总线,可以轻松发布和使用分布式事件.", - "TestInfrastructureExplanation": "框架已经考虑了单元和集成测试.为你提供基类,使其更容易.启动模板已预先配置用于测试.", - "AuditLoggingEntityHistoriesExplanation": "针对关键业务应用程序的内置审计日志记录.请求,服务,方法级别的审计日志记录以及具有属性级别详细信息的实体历史记录.", - "EmailSMSAbstractionsWithTemplatingSupportExplanation": "IEmailSender和ISmsSender抽象使你的应用程序逻辑与基础设施解耦.先进的电子邮件模板系统允许创建和本地化电子邮件模板,并在需要时轻松使用.", - "LocalizationExplanation": "本地化系统允许在纯JSON文件中创建资源,并使用它们来本地化UI.它支持继承,扩展和JavaScript集成等高级方案,同时与AspNet Core的本地化系统完全兼容.", - "SettingManagementExplanation": "定义应用程序的设置,并根据当前配置,租户和用户在运行时获取值.", - "ExtensionMethodsHelpersExplanation": "即使是琐碎的代码部分,也不要重复.标准类型的扩展方法和助手使你的代码更加清晰和易于编写.", - "AspectOrientedProgrammingExplanation": "提供合适的基础设施来创建动态代理并实现面向切面的编程.拦截任何类,并在每次方法执行之前和之后执行代码.", - "DependencyInjectionByConventionsExplanation": "无需手动注册类以进行依赖项注入.按照约定自动注册常用服务类型.对于其他类型的服务,你可以使用接口和属性来使其变得更轻松和就位.", - "DataFilteringExplanation": "定义和使用数据过滤器,这些过滤器在你从数据库中查询实体时会自动应用.当你实现简单的接口时,可立即使用软删除功能和多租户过滤器.", + "AggregateRootEntity": "聚合根、实体", + "AutoRESTAPIsExplanation": "ABP 可按约定自动将您的应用程序服务配置为 API 控制器。", + "DynamicClientProxiesExplanation": "从 JavaScript 和 C# 客户端轻松使用您的 API。", + "DistributedEventBusWithRabbitMQIntegrationExplanation": "使用内置的分布式事件总线(可与 RabbitMQ 集成)轻松发布和消费分布式事件。", + "TestInfrastructureExplanation": "该框架在开发过程中考虑了单元测试和集成测试。为您提供基类,让您更轻松地进行测试。启动模板已为测试预配置。", + "AuditLoggingEntityHistoriesExplanation": "针对关键业务应用程序的内置审计日志。请求、服务、方法级审计日志和包含属性级详细信息的实体历史记录。", + "EmailSMSAbstractionsWithTemplatingSupportExplanation": "IEmailSender 和 ISmsSender 抽象将应用程序逻辑与基础架构分离开来。先进的电子邮件模板系统允许创建和本地化电子邮件模板,并在需要时轻松使用。", + "LocalizationExplanation": "本地化系统允许在纯 JSON 文件中创建资源,并使用它们来本地化UI。它支持继承、扩展和 JavaScript 集成等高级方案,同时与 AspNet Core 的本地化系统完全兼容。", + "SettingManagementExplanation": "为应用程序定义设置,并在运行时根据当前配置、租户和用户获取值。", + "ExtensionMethodsHelpersExplanation": "即使是琐碎的代码部分也无需重复。标准类型的扩展和助手能让你的代码更加简洁易写。", + "AspectOrientedProgrammingExplanation": "为创建动态代理和实现面向切面的编程(Aspect Oriented Programming)提供舒适的基础架构。拦截任何类,并在每个方法执行前后执行代码。", + "DependencyInjectionByConventionsExplanation": "无需手动注册依赖注入类。按约定自动注册常见的服务类型。对于其他类型的服务,您可以使用接口和属性来简化注册过程并就地注册。", + "DataFilteringExplanation": "定义和使用数据过滤器,这些过滤器会在你从数据库中查询实体时自动应用。软删除和多租户过滤器是在您实现简单接口时提供的开箱即用的过滤器。", "PublishEvents": "发布事件", "HandleEvents": "处理事件", - "AndMore": "更多...", - "Code": "编码", + "AndMore": "以及更多...", + "Code": "代码", "Result": "结果", - "SeeTheDocumentForMoreInformation": "查看{0} 文档获得更多信息", - "IndexPageHeroSection": "asp.net core的开源Web应用程序
框架
", + "SeeTheDocumentForMoreInformation": "查看 {0} 文档,了解更多信息", + "IndexPageHeroSection": "open sourceWeb Application
Framework
for asp.net core", "UiFramework": "UI框架", "EmailAddress": "电子邮件地址", - "Mobile": "移动", + "Mobile": "移动电话", "ReactNative": "React Native", - "Strong": "强大的", - "Complete": "完整的", + "Strong": "强大", + "Complete": "完整", "BasedLayeringModel": "基于分层模型", "Microservice": "微服务", "Compatible": "兼容", - "MeeTTheABPCommunityInfo": "我们的使命是创建一个环境使开发人员可以在文章,教程,案例研究等方面互相帮助并结识志趣相投的人.", - "JoinTheABPCommunityInfo": "参与充满活力的社区并成为ABP框架的贡献者", - "AllPosts": "所有的文章", - "SubmitYourPost": "提交你的文章", - "DynamicClientProxyDocument": "参阅JavaScript & C#的动态客户端代理文档.", - "EmailSMSAbstractionsDocument": "参阅emailingSMS sending 文档获得更多信息.", - "CreateProjectWizard": "此向导让你从启动模板创建一个新项目,该启动模板已正确配置为可以快速启动你的项目.", - "TieredOption": "创建一个分层解决方案,其中Web和Http API层在物理上是分离的. 如果没有选中则创建一个不那么复杂且适合大多数场景的分层解决方案.", - "SeparateIdentityServerOption": "将服务器端分离为两个应用程序:第一个应用程序用于身份服务器,第二个应用程序用于服务器端HTTP API.", - "SeparateAuthenticationServerOption": "将服务器端分为两个应用程序:第一个用于身份验证服务器,第二个用于服务器端 HTTP API。", - "ProgressiveWebApplicationOption": "将项目指定为渐进式 Web 应用程序", + "MeeTTheABPCommunityInfo": "我们的使命是创造一个环境,让开发人员可以通过帖子、教程、案例研究等方式互相帮助,并结识志同道合的朋友。", + "JoinTheABPCommunityInfo": "加入充满活力的社区,成为 ABP 框架的贡献者!", + "AllPosts": "所有帖子", + "SubmitYourPost": "提交您的帖子", + "DynamicClientProxyDocument": "查看JavaScriptC#的动态客户端代理文档。", + "EmailSMSAbstractionsDocument": "请查看 电子邮件 短信发送 文档,了解更多信息。", + "CreateProjectWizard": "该向导从启动模板中创建一个新项目,并对其进行适当配置以启动项目。", + "TieredOption": "创建分层解决方案,Web 层和 Http API 层物理上分开。如果不选中,则会创建一个分层解决方案,其复杂性较低,适合大多数情况。", + "SeparateIdentityServerOption": "将服务器端分为两个应用程序:第一个是身份服务器,第二个是服务器端 HTTP API。", + "SeparateAuthenticationServerOption": "将服务器端分为两个应用程序:第一个是身份验证服务器,第二个是服务器端 HTTP API。", + "ProgressiveWebApplicationOption": "指定项目为渐进式Web应用程序", "UseslatestPreVersion": "使用最新的预发布版本", - "ReadTheDocumentation": "阅读文档", + "ReadTheDocumentation": "阅读文档", "Documentation": "文档", "GettingStartedTutorial": "入门教程", "ApplicationDevelopmentTutorial": "应用程序开发教程", "TheStartupTemplate": "启动模板", - "InstallABPCLIInfo": "ABP CLI是使用ABP框架启动新解决方案的最快方式. 使用命令行窗口安装ABP CLI:", - "DifferentLevelOfNamespaces": "你可以使用不同级别的名称空间. 例如 BookStore, Acme.BookStore 或 Acme.Retail.BookStore", - "ABPCLIExamplesInfo": "new命令创建一个 分层的MVC应用程序 使用 Entity Framework Core 做为数据库提供程序. 它还有其他选项. 示例:", - "SeeCliDocumentForMoreInformation": "参阅 ABP CLI 文档 获得更多选项或选择上方的 \"直接下载\" 标签.", - "Optional": "可选的", - "LocalFrameworkRef": "保留框架包的本地项目引用.", - "BlobStoring": "BLOB存储", - "BlobStoringExplanation": "BLOB存储系统提供了BLOB的抽象. ABP提供了一些预构建的存储提供程序集成(Azure,AWS,文件系统,数据库等),你可以轻松的在你的应用程序中使用它们.", + "InstallABPCLIInfo": "ABP CLI 是使用 ABP 框架启动新解决方案的最快方法。使用命令行窗口安装 ABP CLI:", + "DifferentLevelOfNamespaces": "您可以使用不同级别的命名空间;例如,BookStore、Acme.BookStore 或 Acme.Retail.BookStore。", + "ABPCLIExamplesInfo": "new 命令创建了一个 分层 MVC 应用程序,并将 Entity Framework Core 作为数据库提供程序。不过,它还有其他选项。", + "SeeCliDocumentForMoreInformation": "查看 ABP CLI 文档,了解更多选项,或选择上面的 \"直接下载 \"选项卡。", + "Optional": "可选", + "LocalFrameworkRef": "为框架包保留本地项目引用。", + "BlobStoring": "BLOB 存储", + "BlobStoringExplanation": "BLOB 存储系统提供了一种处理 BLOB 的抽象方法。ABP 提供了一些预建的存储提供者集成(Azure、AWS、文件系统、数据库等),您可以在应用程序中轻松使用。", "TextTemplating": "文本模板", - "TextTemplatingExplanation": "文本模板是基于模板和模型(数据对象)使用动态渲染内容. 例如你可以使用预构建的模板来创建动态的电子邮件内容.", - "MultipleUIOptions": "多个UI选项", - "MultipleDBOptions": "多个数据库提供程序", - "MultipleUIOptionsExplanation": "核心框架设计为独立与UI,可以和任何类型的UI系统一起使用. 同时提供了多个开箱即用的预构建集成选项.", - "MultipleDBOptionsExplanation": "该框架可以使用任何数据源,并且以下提供程序已得到正式开发和支持;", + "TextTemplatingExplanation": "文本模板用于根据模板和模型(数据对象)动态呈现内容。例如,你可以用它来创建带有预置模板的动态电子邮件内容。", + "MultipleUIOptions": "多种UI选项", + "MultipleDBOptions": "多个数据库提供者", + "MultipleUIOptionsExplanation": "核心框架的设计与UI无关,可与任何类型的UI系统配合使用,同时还提供多种预建和集成选项。", + "MultipleDBOptionsExplanation": "该框架可与任何数据源协同工作,同时官方开发并支持以下提供者:", "SelectLanguage": "选择语言", - "LatestPostOnCommunity": "关于ABP社区的最新文章", + "LatestPostOnCommunity": "关于 ABP 社区的最新文章", "Register": "注册", "IsDownloadable": "可下载", "DatabaseOptions": "数据库选项", - "BackToPackagesPage": "回到包页面", + "BackToPackagesPage": "返回包页面", "HowToInstall": "如何安装", - "SeeOnNpm": "在NPM查看", - "SeeOnNuget": "在Nuget查看", - "MVCGulpCommandExplanation": "如果你使用MVC (Razor Pages) UI,在包安装完成后运行 \"gulp\" 命令.", + "SeeOnNpm": "在 NPM 查看", + "SeeOnNuget": "在 Nuget 上查看", + "MVCGulpCommandExplanation": "如果使用的是 MVC(Razor Pages)UI,则在安装包后运行 \"gulp \"命令。", "UsingABPCLI": "使用 Abp CLI", "WithoutABPCLI": "不使用 ABP CLI", - "ABPCLIModuleDependency": "ABP CLI会自动添加模块依赖.", - "AddModuleDependency": "然后添加模块依赖", + "ABPCLIModuleDependency": "Abp Cli 自动添加模块依赖性。", + "AddModuleDependency": "然后添加模块依赖关系", "Packages": "包", - "NugetPackages": "Nuget包", - "NPMPackages": "NPM包", + "NugetPackages": "Nuget 包", + "NPMPackages": "NPM 包", "SeeDocs": "查看文档", - "None": "空", + "None": "无", "Application": "应用程序", - "ApplicationExplanation": "基于领域驱动设计实践创建一个完全分层的解决方案。 推荐用于需要可维护和可扩展代码库的长期项目。", + "ApplicationExplanation": "基于领域驱动设计实践,创建完全分层的解决方案。推荐用于需要可维护和可扩展代码库的长期项目。", "ApplicationNoLayer": "应用程序(单层)", - "ApplicationNoLayerExplanation": "创建单层 Web 应用程序。 推荐用于构建具有更简单且易于理解的架构的应用程序。", + "ApplicationNoLayerExplanation": "创建单层Web应用程序。建议用于构建架构简单易懂的应用程序。", "Module": "模块", - "ModuleExplanation": "创建可重用、完全分层的应用程序模块解决方案。 您可以使用此选项为您的模块化应用程序创建模块。", + "ModuleExplanation": "创建可重用、完全分层的应用程序模块解决方案。您可以使用该选项为模块化应用程序创建模块。", "PackageName": "包名称", - "LicenseURL": "许可URL", - "License": "许可", - "ProjectCreationSuccessMessage": "你的项目创建成功", - "HowToRunSolution": "如何运行你的解决方案?", - "GettingStartedMessage": "查看入门文档了解如何配置和运行你的解决方案.", - "WebAppDevTutorial": "Web App 开发教程", - "WebAppDevTutorialMessage": "查看web应用程序开发教程文档,一步一步的开发示例.", - "CommunityPosts": "社区文档", - "CommunityPostMessage": "查看ABP社区平台来阅读关于ABP框架的文档.", - "InvestigateSolutionDetails": "调查解决方案细节", - "StartupTemplateDocumentationMessage": "查看应用程序启动模板文档来学习你的解决方案架构和结构.", - "ClientSideDevelopment": "客户端部分开发", - "ClientSideDevelopmentDocumentationMessage": "查看{0}文档来学习用户页面(客户端部分)开发.", - "DatabaseProviderDocumentationMessage": "查看{0}文档来学习用数据库层开发.", - "ABPCommercialExplanationMessage": "ABP商业版为ABP框架提供了高级模块,主题,工具和支持.", - "ImplementingDDD": "实现领域驱动设计", - "DDDBookExplanation": "使用 ABP 框架实现领域驱动设计的实用指南。", + "LicenseURL": "许可证 URL", + "License": "许可证", + "ProjectCreationSuccessMessage": "您的项目已成功创建", + "HowToRunSolution": "如何运行解决方案?", + "GettingStartedMessage": "查看入门文档,了解如何配置和运行解决方案。", + "WebAppDevTutorial": "Web应用程序开发教程", + "WebAppDevTutorialMessage": "请查看Web应用程序开发教程文档,逐步了解开发示例。", + "CommunityPosts": "社区帖子", + "CommunityPostMessage": "查看 ABP 社区平台,阅读有关 ABP 框架的有用文章。", + "InvestigateSolutionDetails": "查看解决方案详情", + "StartupTemplateDocumentationMessage": "查看应用程序启动模板文档,了解解决方案的架构和结构。", + "ClientSideDevelopment": "客户端开发", + "ClientSideDevelopmentDocumentationMessage": "查看 {0} 文档,了解UI(客户端)开发的要点。", + "DatabaseProviderDocumentationMessage": "查看 {0} 文档,了解数据库层开发的要点。", + "ABPCommercialExplanationMessage": "ABP 商业版为 ABP 框架提供高级模块、主题、工具和支持。", + "ImplementingDDD": "实施领域驱动设计", + "DDDBookExplanation": "使用 ABP 框架实施领域驱动设计的实用指南。", "Overview": "概述", - "DDDBookPracticalGuide": "这是实现领域驱动设计 (DDD) 的实用指南。虽然实现细节基于 ABP 框架基础设施,但基本概念、原则和模型可以应用于任何解决方案,即使它不是 .NET 解决方案。", + "DDDBookPracticalGuide": "这是一本实施领域驱动设计(DDD)的实用指南。虽然实施细节基于 ABP 框架基础架构,但基本概念、原则和模型可应用于任何解决方案,即使不是 .NET 解决方案。", "TableOfContents": "目录", - "IntroductionToImplementingDDD": "实现领域驱动设计简介", + "IntroductionToImplementingDDD": "领域驱动设计实施简介", "WhatIsDDD": "什么是领域驱动设计?", - "Implementation": "执行", + "Implementation": "实施", "TheBigPicture": "大图", - "TheBuildingBlock": "积木", - "ExampleUseCase": "示例用例", - "DomainAndApplicationLogic": "领域逻辑与应用逻辑", + "TheBuildingBlock": "构建模块", + "ExampleUseCase": "用例示例", + "DomainAndApplicationLogic": "领域逻辑和应用逻辑", "Author": "作者", "Pages": "页面", "PublishedOn": "发表于", "FreeEBook": "免费电子书", "Download": "下载", "EBookSignInForDownload": "要下载电子书,请登录", - "SignIn": "登入", + "SignIn": "登录", "Or": "或者", - "TellUsAboutYourself": "告诉我们一点关于你自己", - "Name": "姓名", - "Surname": "姓", - "CompanyName": "公司名", - "DoYouAgreePrivacyPolicy": "我同意条款和条件隐私政策。", + "TellUsAboutYourself": "谈谈你自己吧", + "Name": "名称", + "Surname": "姓氏", + "CompanyName": "公司名称", + "DoYouAgreePrivacyPolicy": "我同意条款和条件以及隐私政策。", "Free": "免费", - "DDDEBook": "DDD电子书", - "PracticalGuideForImplementingDDD": "本书是使用 ABP 框架实现领域驱动设计的实用指南。", - "IntroducingDDD": "介绍领域驱动设计", - "DDDLayersAndCleanArchitecture": "DDD 层和干净的架构", - "LayeringOfADotnetSolution": ".NET 解决方案的分层", - "ImplementingDDDBuildingBlocks": "实现 DDD 构建块", + "DDDEBook": "DDD 电子书", + "PracticalGuideForImplementingDDD": "本书是利用 ABP 框架实施领域驱动设计的实用指南。", + "IntroducingDDD": "领域驱动设计介绍", + "DDDLayersAndCleanArchitecture": "DDD 层与简洁架构", + "LayeringOfADotnetSolution": ".NET解决方案的分层", + "ImplementingDDDBuildingBlocks": "实施 DDD 构件", "DomainVsApplicationLogic": "领域逻辑与应用逻辑", - "SamplesAndDiscussions": "示例和讨论", + "SamplesAndDiscussions": "示例与讨论", "EmailNotValid": "请输入有效的电子邮件地址。", - "WeWillSendYouADownloadLink": "下载电子书的链接已发送至 {0}。检查您的收件箱、垃圾箱或垃圾邮件箱!", - "GoHome": "回家", - "InvalidFormInputs": "请输入表格中指定的有效信息。", - "DDDBookEmailBody": "谢谢你。
要下载您的图书,请点击此处。", - "SubscribeToNewsletter": "订阅时事通讯以获取有关 ABP.IO 平台中发生的事件的信息,例如新版本、文章、优惠等。", + "WeWillSendYouADownloadLink": "电子书下载链接已发送至 {0}。请检查您的收件箱、垃圾邮件箱!", + "GoHome": "回到主页面", + "InvalidFormInputs": "请输入表单中指定的有效信息。", + "DDDBookEmailBody": "谢谢。
要下载您的书籍,请点击此处。", + "SubscribeToNewsletter": "订阅时事通讯,了解 ABP.IO 平台的最新动态,如新版本、文章、优惠等。", "FirstEdition": "第一版", "ThankYou": "谢谢!", - "CheckboxMandatory": "你需要检查这个才能继续!", - "UserInterface": "用户界面", - "APIGateway": "API 网关", + "CheckboxMandatory": "您需要检查这一点才能继续!", + "UserInterface": "UI", + "APIGateway": "API网关", "Database": "数据库", "Saas": "Saas", "OpenSourceWebApp": "开源
Web 应用程序", "Framework": "框架", - "AuditLoggingExplanation": "自动跟踪系统中的所有操作和数据更改。", + "AuditLoggingExplanation": "自动跟踪系统中的所有操作和数据变化。", "AbpNewCommandExplanation": "使用 ABP 启动模板创建新的解决方案。", - "AbpAddModuleCommandExplanation": "将预构建的应用程序模块安装到您的解决方案中", + "AbpAddModuleCommandExplanation": "在解决方案中安装预构建应用模块", "AbpUpdateCommandExplanation": "自动更新解决方案中所有与 ABP 相关的 NuGet 和 NPM 包。", "ExploreAllCLICommands": "探索所有 CLI 命令", "ExploreDocumentationAndGuides": "探索全面的文档和指南。", "Documentations": "文档", "Views": "意见", - "EnterYouEmailToGetNews": "输入您的电子邮件以获取有关 ABP 框架的最新消息", + "EnterYouEmailToGetNews": "输入您的电子邮件,以获取有关 ABP 框架的最新消息", "Tiered": "分层", - "SeparateIdentityServer": "独立的身份服务器", - "SeparateAuthenticationServer": "单独的身份验证服务器", - "ProgressiveWebApplication": "渐进式 Web 应用程序", + "SeparateIdentityServer": "独立身份服务器", + "SeparateAuthenticationServer": "独立的身份验证服务器", + "ProgressiveWebApplication": "渐进式Web应用程序", "Preview": "预览", - "CreateANewSolution": "创建一个新的解决方案", - "ABPFrameworkFeatures": "ABP 框架 功能", + "CreateANewSolution": "创建新解决方案", + "ABPFrameworkFeatures": "ABP 框架 特点条款和条件 和 隐私政策。", - "GetYourFreeEBook": "获取您的 免费 DDD 电子书", - "EverythingYouNeedToKnow": "您需要了解的一切。", - "PreOrderNow": "立即预订", - "UITheming": "用户界面主题", - "UIThemingExplanation": "创建可重用的 UI 主题和布局,或使用预构建的 UI 主题之一。", - "DataFilteringExplanation2": "自动过滤来自数据库的查询,以轻松实现软删除和多租户等模式。", - "NeedHelp": "您需要帮助吗?", - "GiveYourProjectAName": "给您的项目命名", + "JoinOurMarketingNewsletter": "加入我们的营销通讯", + "FrameworkNewsletterConfirmationMessage": "我同意条款和条件以及隐私政策。", + "GetYourFreeEBook": "获取免费的 DDD 电子书。", + "EverythingYouNeedToKnow": "你需要知道的一切", + "PreOrderNow": "立即预购", + "UITheming": "UI设计", + "UIThemingExplanation": "创建可重用的UI主题和布局,或使用预置的UI主题。", + "DataFilteringExplanation2": "自动过滤数据库查询,轻松实现软删除和多租户等模式。", + "NeedHelp": "需要帮助吗?", + "GiveYourProjectAName": "为项目命名", "SelectProjectType": "选择项目类型", - "SelectUIFramework": "选择 UI 框架", + "SelectUIFramework": "选择UI框架", "SelectDatabaseProvider": "选择数据库提供者", "SelectDatabaseManagementSystem": "选择数据库管理系统", "InstallingTheABPCLI": "安装 ABP CLI", "CreateYourProjectNow": "立即创建您的项目", - "OrderOn": "在 {0} 订购", - "DownloadFreeDDDBook": "下载免费的 DDD 书", + "OrderOn": "在{0}上下单", + "DownloadFreeDDDBook": "下载免费的 DDD 书籍", "WhatIsABPFramework": "什么是 ABP 框架?", "TenantDatabase": "租户 {0} 数据库", "SharedDatabase": "共享数据库", "ConnectionResolver": "连接解析器", "TenantBasedDataFilter": "基于租户的数据过滤器", - "ApplicationCode": "申请代码", - "TenantResolution": "租户决议", + "ApplicationCode": "应用代码", + "TenantResolution": "租户解析", "TenantUser": "租户 {0} 用户", "CardTitle": "卡片标题", "View": "查看", "Model": "模型", - "Email": "电子邮箱", + "Email": "电子邮件", "Password": "密码", "Address": "地址", "Gender": "性别", "Male": "男", - "Female": "女", + "Female": "女性", "Submit": "提交", - "Unspecified": "未指定", + "Unspecified": "未说明", "StaticFileMiddleware": "静态文件中间件", "RazorViewEngine": "Razor 视图引擎", - "PhysicalFiles": "物理文件 (wwwroot)", - "EmbeddedFiles": "嵌入式文件(DDL) ", + "PhysicalFiles": "物理文件(wwwroot)", + "EmbeddedFiles": "嵌入式文件 (DLL)", "DynamicFiles": "动态文件(内存)", - "BuildSolutionsWithAbp": "遵循使用 ABP 的软件开发最佳实践,构建可维护的 .NET 解决方案。", + "BuildSolutionsWithAbp": "使用 ABP,遵循软件开发最佳实践,构建可维护的 .NET 解决方案。", "BuyOnAmazon": "在亚马逊上购买", - "BuyOnPackt": "在 Packt 上购买", - "Discounted": "打折", - "MasteringAbpFramework_Book_KeyFeatures": "主要特性", - "MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架构建强大、可维护、模块化和可扩展的软件解决方案。", - "MasteringAbpFramework_Book_Key_Features_Description_2": "了解如何在您的 Web 应用程序中实施 SOLID 原则和领域驱动设计。", - "MasteringAbpFramework_Book_Key_Features_Description_3": "了解 ABP 框架如何通过自动执行重复性任务来加快您的开发周期。", - "MasteringAbpFramework_Book_Description": "书籍说明", - "MasteringAbpFramework_Book_Description_Details_1": "ABP 框架是一个完整的基础架构,用于通过遵循软件 \n 开发最佳实践和约定来创建现代 Web 应用程序。 借助 ABP 的高级框架和生态系统,您可以 \n 实现 Don't Repeat Yourself (DRY) 原则并专注于您的业务代码。", - "MasteringAbpFramework_Book_Description_Details_2": "本书由 ABP 框架的创建者撰写,将帮助您全面了解该框架和现代 Web 应用程序开发技术。 通过对基本概念和实际示例的逐步解释,您将了解现代 Web 解决方案的要求以及 ABP\n 框架如何使开发您自己的解决方案变得轻松愉快。 您将发现\n 企业 Web 应用程序开发的常见需求,并探索 ABP 提供的基础架构。 在整本书中,您将掌握构建可维护和模块化 Web 解决方案的软件开发最佳实践。", - "MasteringAbpFramework_Book_Description_Details_3": "在本书结束时,您将能够创建一个易于开发、\n 维护和测试的完整 Web 解决方案。", - "MasteringAbpFramework_Book_WhatYouWillLearn": "你将会学到什么", + "BuyOnPackt": "在 Packt 购买", + "Discounted": "折扣", + "MasteringAbpFramework_Book_KeyFeatures": "主要功能", + "MasteringAbpFramework_Book_Key_Features_Description_1": "使用 ABP 框架构建稳健、可维护、模块化和可扩展的软件解决方案。", + "MasteringAbpFramework_Book_Key_Features_Description_2": "了解如何在Web应用程序中实施 SOLID 原则和领域驱动设计。", + "MasteringAbpFramework_Book_Key_Features_Description_3": "了解 ABP Framework 如何通过自动化重复性任务加快开发周期。", + "MasteringAbpFramework_Book_Description": "图书简介", + "MasteringAbpFramework_Book_Description_Details_1": "ABP 框架是一个完整的基础架构,用于按照软件开发最佳实践和约定创建现代Web应用程序。\n 的最佳实践和约定,创建现代Web应用程序的完整基础架构。借助 ABP 的高级框架和生态系统,您可以\n 执行 \"不要重复\"(DRY)原则,专注于业务代码。", + "MasteringAbpFramework_Book_Description_Details_2": "本书由 ABP 框架的创建者撰写,将帮助你全面了解该框架和现代Web应用程序开发技术。\n 框架和现代Web应用程序开发技术。通过逐步解释基本\n 概念和实际示例,你将了解现代网络解决方案的要求,以及 ABP\n 框架如何让您愉快地开发自己的解决方案。您将发现\n 企业Web应用程序开发的常见要求,并探索 ABP 提供的基础架构。在整本书中\n 在本书中,你将掌握软件开发的最佳实践,以构建可维护的模块化\n 网络解决方案。", + "MasteringAbpFramework_Book_Description_Details_3": "在本书结束时,你将能够创建一个易于开发、维护和测试的完整网络解决方案、\n 维护和测试。", + "MasteringAbpFramework_Book_WhatYouWillLearn": "你将学到什么", "MasteringAbpFramework_Book_What_You_Will_Learn_1": "设置开发环境并开始使用 ABP 框架。", - "MasteringAbpFramework_Book_What_You_Will_Learn_2": "使用 Entity Framework Core 和 MongoDB 开发您的数据访问层。", + "MasteringAbpFramework_Book_What_You_Will_Learn_2": "使用 Entity Framework Core 和 MongoDB 开发数据访问层。", "MasteringAbpFramework_Book_What_You_Will_Learn_3": "了解横切关注点以及 ABP 如何自动执行重复性任务。", - "MasteringAbpFramework_Book_What_You_Will_Learn_4": "掌握使用 ABP 框架实施领域驱动设计。", - "MasteringAbpFramework_Book_What_You_Will_Learn_5": "使用 ASP.NET Core MVC (Razor Pages) 和 Blazor 构建 UI 页面和组件。", - "MasteringAbpFramework_Book_What_You_Will_Learn_6": "使用多租户创建模块化 Web 应用程序。", - "MasteringAbpFramework_Book_What_You_Will_Learn_7": "了解模块化并创建可重用的应用程序模块。", - "MasteringAbpFramework_Book_What_You_Will_Learn_8": "使用 ABP 框架编写单元、集成和 UI 测试。", - "MasteringAbpFramework_Book_WhoIsThisBookFor": "这本书是给谁看的", - "MasteringAbpFramework_Book_WhoIsThisBookFor_Description": "本书适用于希望学习软件架构和最佳实践的 Web 开发人员,以使用 Microsoft 技术和 ABP 框架构建\n 可维护的基于 Web 的解决方案。 C#\n 和 ASP.NET Core 的基本知识是开始阅读本书所必需的。", + "MasteringAbpFramework_Book_What_You_Will_Learn_4": "使用 ABP 框架掌握领域驱动设计的实施方法。", + "MasteringAbpFramework_Book_What_You_Will_Learn_5": "使用 ASP.NET Core MVC(Razor Pages)和 Blazor 构建UI页面和组件。", + "MasteringAbpFramework_Book_What_You_Will_Learn_6": "使用多租户创建模块化Web应用程序。", + "MasteringAbpFramework_Book_What_You_Will_Learn_7": "了解模块化,创建可重用的应用模块。", + "MasteringAbpFramework_Book_What_You_Will_Learn_8": "使用 ABP 框架编写单元测试、集成测试和UI测试。", + "MasteringAbpFramework_Book_WhoIsThisBookFor": "这本书为谁而写", + "MasteringAbpFramework_Book_WhoIsThisBookFor_Description": "本书适用于希望学习软件架构和最佳实践的网络开发人员。\n 的最佳实践。要开始学习本书\n 和 ASP.NET Core 的基础知识。", "ComputersAndTechnology": "计算机与技术", "BuildingMicroserviceSolutions": "构建微服务解决方案", - "MicroserviceBookPracticalGuide": "本书是使用 ABP 框架开发和管理基于微服务的应用程序的参考指南。 它引用了 .NET 微服务示例参考应用程序:eShopOnContainers,并讨论了使用 ABP 框架的架构设计和实现方法。 读完本书,您将了解 ABP 如何处理常见的微服务复杂性,例如授权、分布式事务、微服务间通信、部署等。", + "MicroserviceBookPracticalGuide": "本书是使用 ABP 框架开发和管理基于微服务的应用程序的参考指南。它参考了.NET 微服务示例参考应用程序:eShopOnContainers,并讨论了使用 ABP 框架的架构设计和实现方法。在本书结束时,您将了解 ABP 如何处理常见的微服务复杂性,如授权、分布式事务、微服务间通信、部署等。", "IntroducingTheSolution": "介绍 eShopOnAbp 解决方案", "RunningTheSolution": "运行解决方案", "UnderstandingTheAuthenticationSystem": "了解身份验证系统", "ExploringTheApplications": "探索应用", - "UnderstandingTheAPIGateways": "了解 API 网关", + "UnderstandingTheAPIGateways": "了解API网关", "DevelopingTheMicroservices": "开发微服务", "UnderstandingTheInfrastructure": "了解基础设施", - "DiggingInTheUseCases": "挖掘用例", + "DiggingInTheUseCases": "挖掘使用案例", "DeployingTheSolution": "部署解决方案", - "ThisBookIsInDraftStageAndIsNotCompletedYet": "这本书正在草案阶段,还没有完成。", + "ThisBookIsInDraftStageAndIsNotCompletedYet": "本书目前处于草稿阶段,尚未完成。", "Authors": "作者", "MicroserviceEBook": "微服务电子书", - "SelectUITheme": "选择 UI 主题", + "SelectUITheme": "选择UI主题", "LeptonXLiteTheme": "LeptonX Lite 主题", "BasicTheme": "基本主题", - "LeptonXLiteThemeInfo": " 现代时尚的 Bootstrap UI 主题。 如果你想要一个生产就绪的 UI 主题,这是理想的选择。 这是最新的主题,也是默认主题。", - "BasicThemeInfo": "具有简单 Bootstrap 颜色和样式的极简 UI 主题。 如果您要构建自己的 UI 主题,则非常适合。", - "SeeDocumentation": "请参阅 文档.", - "SeeFullScreen": "🖼️ 如截图所示", + "LeptonXLiteThemeInfo": "一款现代时尚的 Bootstrap UI 主题。如果你想拥有一个可随时制作的UI主题,它将是你的理想之选。这是最新的主题,也是默认主题。", + "BasicThemeInfo": "极简UI主题,采用纯粹的 Bootstrap 颜色和样式。如果你想创建自己的UI主题,它将是你的理想之选。", + "SeeDocumentation": "请参阅文档。", + "SeeFullScreen": "🖼️ 查看截图", "BuildingMicroserviceSolutionsShortDescription": "本书是使用 ABP 框架开发和管理基于微服务的应用程序的参考指南。", - "InstallAbpCliMessage": "如果之前没有安装,请在命令行终端中安装 ABP CLI:", + "InstallAbpCliMessage": "如果之前未安装 ABP CLI,请在命令行终端中安装:", "Terminal": "终端", "Copy": "复制", - "RunTheFollowingCommand": "在命令行终端中运行以下命令:", + "RunTheFollowingCommand": "在命令行终端运行以下命令", "ChangeSolutionOptionsBelow": "您可以更改下面的解决方案选项。", "MultiLayerApplication": "多层
应用", - "MultiLayerApplicationExplanation1": "基于领域驱动设计实践创建完全分层的解决方案。", - "MultiLayerApplicationExplanation2": "推荐用于需要可维护和可扩展代码库的长期项目。", - "SingleLayerApplication": "单层
应用", - "SingleLayerApplicationExplanation1": "创建单层 Web 应用程序。 ", - "SingleLayerApplicationExplanation2": "推荐用于构建具有更简单且易于理解的体系结构的应用程序。", - "ApplicationModule": "应用程序模块", - "SeeTheScreenshot": "如截图所示", - "ApplicationModuleExplanation1": "创建可重用的、完全分层的应用程序模块解决方案。", - "ApplicationModuleExplanation2": "您可以使用此选项为您的模块化应用程序创建模块。", + "MultiLayerApplicationExplanation1": "根据领域驱动设计实践,创建完全分层的解决方案。", + "MultiLayerApplicationExplanation2": "建议用于需要可维护和可扩展代码库的长期项目。", + "SingleLayerApplication": "单层
应用", + "SingleLayerApplicationExplanation1": "创建单层Web应用程序。 ", + "SingleLayerApplicationExplanation2": "建议用于构建架构简单易懂的应用程序。", + "ApplicationModule": "应用程序
模块", + "SeeTheScreenshot": "请看截图", + "ApplicationModuleExplanation1": "创建一个可重用、完全分层的应用模块解决方案。", + "ApplicationModuleExplanation2": "您可以使用该选项为模块化应用程序创建模块。", "Expert_": "专家", "Partner_": "合作伙伴", "WebSite": "网站", - "Expert_Year": "专业年限", + "Expert_Year": "专业年份", "CompanyInfo": "公司信息", "Date": "日期", - "WhoWeAre_Partner": "关于我们", + "WhoWeAre_Partner": "我们是谁", "WhoWeAre_Expert": "关于我", "CreateSolutionFolder": "创建解决方案文件夹", - "CreateSolutionFolderOption": "指定项目是位于输出文件夹中的新文件夹中,还是直接位于输出文件夹中。", - "BooksPageTitle": "ABP书籍", - "PackageDetailPage_NuGetPackageInstallationOptions": "可通过三种方式将{0} NuGet 包安装到您的项目中", - "PackageDetailPage_InstallingWithABPCLI": "1:使用ABP CLI安装", - "PackageDetailPage_InstallingWithABPCLIDescription1": "如果您尚未安装ABP CLI ,请首先通过在命令行终端中执行以下命令进行安装", - "PackageDetailPage_InstallingWithABPCLIDescription2": "安装 ABP CLI 后,在要安装的项目( .csproj文件)位置打开命令行终端并执行以下命令", - "PackageDetailPage_InstallingWithABPCLIDescription3": "它会将{0}包引用添加到您的项目,并将{1}依赖项添加到您的模块类。", - "PackageDetailPage_ManualInstallation": "2:使用Dotnet CLI安装", - "PackageDetailPage_ManualInstallationDescription1": "使用 IDE 或执行以下命令将{0} NuGet 包引用添加到您的项目", - "PackageDetailPage_ManualInstallationDescription2": "然后将{0}依赖项添加到您的模块类,如以下示例所示", - "PackageDetailPage_SeeDocumentation": "请参阅文档以了解如何在应用程序中使用此包。", - "PackageDetailPage_InstallingUsingPMC": "3:使用包管理器控制台安装", - "PackageDetailPage_InstallingUsingPMCDescription1": "在 Visual Studio 中打开包管理器控制台(工具 -> Nuget 包管理器 -> 包管理器控制台)并执行以下命令", - "UIOptions": "用户界面选项", - "Testimonials": "感言", - "CoolestCompaniesUseABPFramework": "最酷的公司使用ABP 框架", - "Index_Page_Testimonial_1": "ABP 框架不仅仅是一个工具,更是加速我作为开发人员成长的催化剂。它使我能够比以往更快地构建新功能,让人想起其他用户的体验。统一的编码模式简化了我的项目,让我有更多的时间专注于创建而不是故障排除。 \n我想说 ABP 框架是我早期职业生涯的基石。它帮助我从一个有抱负的开发人员转变为一个自信的专业人士,准备在软件世界中留下自己的印记。我期待着等待着我的激动人心的项目,因为我知道 ABP 会在那里指导我。它不仅仅是一个产品;它更是一个产品。它是成功的伙伴。", - "Index_Page_Testimonial_2": "ABP Framework不仅仅是一个框架,它还是项目开发/管理的指南,因为它提供了DDD、GenericRepository、DI、Microservice、Modularity培训。即使您不打算使用框架本身,您也可以使用经过充分专业准备的 docs.abp.io 进行开发。 (OpenIddict、Redis、Quartz 等) \n由于许多东西是预先构建的,因此它大大缩短了项目开发时间。 (例如登录页面、异常处理、数据过滤播种、审核日志记录、本地化、自动 api 控制器等) \n作为我们应用程序的示例,我使用本地事件总线进行库存控制。因此,我可以通过编写库存处理程序来管理订单变动。 \n不为CreationTime、CreatorId浪费时间真是太好了。它们会自动填充。", - "VideosLoginAndRegisterMessage": "您必须登录才能观看视频。如果您还没有,您可以创建一个手表帐户。", + "CreateSolutionFolderOption": "指定项目是放在输出文件夹中的新文件夹中,还是直接放在输出文件夹中。", + "BooksPageTitle": "ABP 图书", + "PackageDetailPage_NuGetPackageInstallationOptions": "在项目中安装 {0} NuGet 包有三种方法", + "PackageDetailPage_InstallingWithABPCLI": "1: 使用 ABP CLI 安装", + "PackageDetailPage_InstallingWithABPCLIDescription1": "如果尚未安装 ABP CLI,请首先在命令行终端执行以下命令进行安装", + "PackageDetailPage_InstallingWithABPCLIDescription2": "安装 ABP CLI 后,在要安装它的项目(.csproj 文件)位置打开命令行终端并执行以下命令", + "PackageDetailPage_InstallingWithABPCLIDescription3": "它将在项目中添加 {0} 包引用,并在模块类中添加 {1} 依赖关系。", + "PackageDetailPage_ManualInstallation": "2: 使用 Dotnet CLI 安装", + "PackageDetailPage_ManualInstallationDescription1": "使用IDE或执行以下命令在项目中添加 {0} NuGet 包引用", + "PackageDetailPage_ManualInstallationDescription2": "然后在 模块类中添加 {0} 依赖关系,如以下示例所示", + "PackageDetailPage_SeeDocumentation": "请参阅文档,了解如何在应用程序中使用此包。", + "PackageDetailPage_InstallingUsingPMC": "3: 使用包管理器控制台安装", + "PackageDetailPage_InstallingUsingPMCDescription1": "在 Visual Studio 中打开 包管理器控制台(工具 -> Nuget 包管理器 -> 包管理器控制台)并执行以下命令", + "UIOptions": "UI选项", + "Testimonials": "客户感言", + "CoolestCompaniesUseABPFramework": "最酷公司使用ABP框架要下載您的圖書,請點擊此處。", "SubscribeToNewsletter": "訂閱時事通訊以獲取有關 ABP.IO 平台中發生的事件的信息,例如新版本、文章、優惠等。", "FirstEdition": "第一版", diff --git a/docs/en/CLI.md b/docs/en/CLI.md index 48858edc74..8c1b320861 100644 --- a/docs/en/CLI.md +++ b/docs/en/CLI.md @@ -527,6 +527,16 @@ Then review changes on your source control system to be sure that it has changed * `--file` or `-f`: Default: `abp-translation.json`. The translation file (use only if you've used the `--output` option before). +#### Online DeepL translate + +The `translate` command also supports online translation. You need to provide your [DeepL Authentication Key](https://support.deepl.com/hc/en-us/articles/360020695820-Authentication-Key). + +It will search all the `en.json(reference-culture)` files in the directory and sub-directory and then translate and generate the corresponding `zh-Hans.json(culture)` files. + +````bash +abp translate -c zh-Hans --online --deepl-auth-key +```` + ### login Some features of the CLI requires to be logged in to abp.io platform. To login with your username write: diff --git a/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md b/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md index b8a55c2ad3..5be57bd4bc 100644 --- a/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md +++ b/docs/en/UI/AspNetCore/Tag-Helpers/Form-elements.md @@ -364,7 +364,8 @@ You can set some of the attributes on your c# property, or directly on HTML tag. * `single-open-and-clear-button`: Shows the open and clear buttons in a single button when it's `True`. The default value is `True`. * `is-utc`: Converts the date to UTC when its `True`. The default value is `False`. * `is-iso`: Converts the date to ISO format when its `True`. The default value is `False`. -* `date-format`: Sets the date format of the input. The default format is the user's culture date format. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. +* `visible-date-format`: Sets the date format of the input. The default format is the user's culture date format. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. +* `input-date-format`: Sets the date format of the hidden input for backend compatibility. The default format is `YYYY-MM-DD`. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. * `date-separator`: Sets a character to separate start and end dates. The default value is `-` * Other non-mapped attributes will be automatically added to the input element as is. See the available [datepicker options](https://www.daterangepicker.com/#options). Eg: `data-start-date="2020-01-01"` @@ -425,7 +426,8 @@ newPicker.insertAfter($('body')); * `singleOpenAndClearButton`: Shows the open and clear buttons in a single button when it's `True`. The default value is `True`. * `isUtc`: Converts the date to UTC when its `True`. The default value is `False`. * `isIso`: Converts the date to ISO format when its `True`. The default value is `False`. -* `dateFormat`: Sets the date format of the input. The default format is the user's culture date format. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. +* `visibleDateFormat`: Sets the date format of the input. The default format is the user's culture date format. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. +* `inputDateFormat`: Sets the date format of the hidden input for backend compatibility. The default format is `YYYY-MM-DD`. You need to provide a JavaScript date format convention. Eg: `YYYY-MM-DDTHH:MM:SSZ`. * `dateSeparator`: Sets a character to separate start and end dates. The default value is `-`. * `startDateName`: Sets the name of the hidden start date input. * `endDateName`: Sets the name of the hidden end date input. diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs index 079431c9c6..64dfdc0fdb 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelper.cs @@ -185,17 +185,28 @@ public abstract class set => _abpDatePickerOptionsImplementation.ParentEl = value; } + [Obsolete("Use VisibleDateFormat instead.")] public string? DateFormat { get => _abpDatePickerOptionsImplementation.DateFormat; set => _abpDatePickerOptionsImplementation.DateFormat = value; } + + public string? VisibleDateFormat { + get => _abpDatePickerOptionsImplementation.VisibleDateFormat; + set => _abpDatePickerOptionsImplementation.VisibleDateFormat = value; + } + + public string? InputDateFormat { + get => _abpDatePickerOptionsImplementation.InputDateFormat; + set => _abpDatePickerOptionsImplementation.InputDateFormat = value; + } public bool OpenButton { get => _abpDatePickerOptionsImplementation.OpenButton; set => _abpDatePickerOptionsImplementation.OpenButton = value; } - public bool ClearButton { + public bool? ClearButton { get => _abpDatePickerOptionsImplementation.ClearButton; set => _abpDatePickerOptionsImplementation.ClearButton = value; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs index d55c08b161..9e03ec800c 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerBaseTagHelperService.cs @@ -125,7 +125,7 @@ public abstract class AbpDatePickerBaseTagHelperService : AbpTagHelp var openButtonContent = TagHelper.OpenButton ? await ProcessButtonAndGetContentAsync(context, output, "calendar", "open") : ""; - var clearButtonContent = TagHelper.ClearButton + var clearButtonContent = TagHelper.ClearButton == true || (!TagHelper.ClearButton.HasValue && TagHelper.AutoUpdateInput != true) ? await ProcessButtonAndGetContentAsync(context, output, "times", "clear", visible:!TagHelper.SingleOpenAndClearButton) : ""; @@ -382,6 +382,16 @@ public abstract class AbpDatePickerBaseTagHelperService : AbpTagHelp { attrList.Add("data-date-format", options.DateFormat); } + + if(!options.VisibleDateFormat.IsNullOrEmpty()) + { + attrList.Add("data-visible-date-format", options.VisibleDateFormat); + } + + if(!options.InputDateFormat.IsNullOrEmpty()) + { + attrList.Add("data-input-date-format", options.InputDateFormat); + } if(options.Ranges != null && options.Ranges.Any()) { diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerOptions.cs index 2007a8a669..295706e4d9 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDatePickerOptions.cs @@ -31,9 +31,13 @@ public class AbpDatePickerOptions : IAbpDatePickerOptions public bool? LinkedCalendars { get; set; } public bool? AutoUpdateInput { get; set; } public string? ParentEl { get; set; } + + [Obsolete("Use VisibleDateFormat instead.")] public string? DateFormat { get; set; } + public string? VisibleDateFormat { get; set; } + public string? InputDateFormat { get; set; } public bool OpenButton { get; set; } = true; - public bool ClearButton { get; set; } = true; + public bool? ClearButton { get; set; } public bool SingleOpenAndClearButton { get; set; } = true; public bool? IsUtc { get; set; } public bool? IsIso { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDateRangePickerTagHelperService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDateRangePickerTagHelperService.cs index 48eeb5ba94..3c2b8aaa03 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDateRangePickerTagHelperService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/AbpDateRangePickerTagHelperService.cs @@ -84,18 +84,24 @@ public class AbpDateRangePickerTagHelperService : AbpDatePickerBaseTagHelperServ protected override void AddBaseTagAttributes(TagHelperAttributeList attributes) { - if (TagHelper.AspForStart != null && - TagHelper.AspForStart.Model != null && + if (TagHelper.AspForStart?.Model != null && SupportedInputTypes.TryGetValue(TagHelper.AspForStart.Metadata.ModelType, out var convertFuncStart)) { - attributes.Add("data-start-date", convertFuncStart(TagHelper.AspForStart.Model)); + var convert = convertFuncStart(TagHelper.AspForStart.Model); + if(!convert.IsNullOrWhiteSpace()) + { + attributes.Add("data-start-date", convert); + } } - - if (TagHelper.AspForEnd != null && - TagHelper.AspForEnd.Model != null && + + if (TagHelper.AspForEnd?.Model != null && SupportedInputTypes.TryGetValue(TagHelper.AspForEnd.Metadata.ModelType, out var convertFuncEnd)) { - attributes.Add("data-end-date", convertFuncEnd(TagHelper.AspForEnd.Model)); + var convert = convertFuncEnd(TagHelper.AspForEnd.Model); + if(!convert.IsNullOrWhiteSpace()) + { + attributes.Add("data-end-date", convert); + } } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/IAbpDatePickerOptions.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/IAbpDatePickerOptions.cs index 5244a844fa..25d1e3cc61 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/IAbpDatePickerOptions.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Form/DatePicker/IAbpDatePickerOptions.cs @@ -134,11 +134,22 @@ public interface IAbpDatePickerOptions /// string? ParentEl { get; set; } + [Obsolete("Use VisibleDateFormat instead.")] string? DateFormat { get; set; } + + /// + /// The date format string that will appear in the input element. For user input. + /// + string? VisibleDateFormat { get; set; } + + /// + /// The date format string that will appear in the hidden input element. For backend compatibility. + /// + string? InputDateFormat { get; set; } bool OpenButton { get; set; } - bool ClearButton { get; set; } + bool? ClearButton { get; set; } bool SingleOpenAndClearButton { get; set; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json index 0e86d66293..e4bb79a4d8 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Volo/Abp/AspNetCore/Mvc/UI/MultiTenancy/Localization/zh-Hans.json @@ -1,13 +1,13 @@ { - "culture": "zh-Hans", - "texts": { - "GivenTenantIsNotExist": "给定的租户不存在: {0}", - "GivenTenantIsNotAvailable": "给定的租户不可用: {0}", - "Tenant": "租户", - "Switch": "切换", - "Name": "名称", - "SwitchTenantHint": "将名称字段留空以切换到宿主端.", - "SwitchTenant": "切换租户", - "NotSelected": "未选中" - } + "culture": "zh-Hans", + "texts": { + "GivenTenantIsNotExist": "给定租户不存在:{0}", + "GivenTenantIsNotAvailable": "给定租户不可用:{0}", + "Tenant": "租户", + "Switch": "切换", + "Name": "名称", + "SwitchTenantHint": "将名称字段留空以切换到主机端。", + "SwitchTenant": "切换租户", + "NotSelected": "未选择" } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs index 2ca7c191c8..27f3760000 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/Bundling/SharedThemeGlobalScriptContributor.cs @@ -48,7 +48,8 @@ public class SharedThemeGlobalScriptContributor : BundleContributor "/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/modal-manager.js", "/libs/abp/aspnetcore-mvc-ui-theme-shared/datatables/datatables-extensions.js", "/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js", - "/libs/abp/aspnetcore-mvc-ui-theme-shared/toastr/abp-toastr.js" + "/libs/abp/aspnetcore-mvc-ui-theme-shared/toastr/abp-toastr.js", + "/libs/abp/aspnetcore-mvc-ui-theme-shared/date-range-picker/date-range-picker-extensions.js" }); } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js index 8e567d626a..c9f7e09c07 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js @@ -197,565 +197,7 @@ }); } - abp.libs.bootstrapDateRangePicker = { - packageName: "bootstrap-daterangepicker", - - createDateRangePicker: function (options) { - options = options || {}; - options.singleDatePicker = false; - return this.createDatePicker(options); - }, - createSinglePicker: function (options) { - options = options || {}; - options.singleDatePicker = true; - return this.createDatePicker(options); - }, - createDatePicker: function (options) { - var $container = $('
') - var label = $('') - if (options.label) { - label.text(options.label) - } - - $container.append(label) - var $datePicker = options.singleDatePicker ? $('') : $(''); - $container.append($datePicker) - - var $inputGroup = $('
'); - var $dateInput = $(''); - - if (options.placeholder) { - $dateInput.attr('placeholder', options.placeholder) - } - - if (options.value) { - $dateInput.val(options.value) - } - - if (options.name) { - $dateInput.attr('name', options.name) - } - - if (options.id) { - $dateInput.attr('id', options.id) - } - - if (options.required) { - $dateInput.attr('required', true) - } - - if (options.disabled) { - $dateInput.attr('disabled', true) - } - - if (options.readonly) { - $dateInput.attr('readonly', true) - } - - if(options.placeholder) { - $dateInput.attr('placeholder', options.placeholder) - } - - if (options.size) { - switch (options.size) { - case 'Small': - $dateInput.addClass('form-control-sm') - break; - case 'Medium': - $dateInput.addClass('form-control-md') - break; - case 'Large': - $dateInput.addClass('form-control-lg') - break; - default: - break; - } - } - - $inputGroup.append($dateInput); - - if (options.openButton !== false) { - var $openButton = $(''); - $inputGroup.append($openButton); - if(options.disabled) { - $openButton.attr('disabled', 'disabled') - } - } - - if (options.clearButton !== false) { - var $clearButton = $(''); - $inputGroup.append($clearButton); - if(options.disabled) { - $clearButton.attr('disabled', 'disabled') - } - } - - $datePicker.append($inputGroup); - - if (options.startDateName) { - var $hiddenStartDateElement = $(''); - $datePicker.append($hiddenStartDateElement); - } - - if (options.endDateName) { - var $hiddenEndDateElement = $(''); - $datePicker.append($hiddenEndDateElement); - } - - if (options.dateName) { - var $hiddenDateElement = $(''); - $datePicker.append($hiddenDateElement); - } - - $datePicker.data('options', options); - abp.dom.initializers.initializeDateRangePickers($datePicker); - $container[0].datePicker = $datePicker[0]; - return $container; - } - }; - - - abp.dom.initializers.initializeDateRangePickers = function ($rootElement) { - function setOptions (options, $datePickerElement, singleDatePicker) { - - options.singleDatePicker = singleDatePicker; - - var defaultOptions = { - showDropdowns: true, - opens: "center", - drops: "down", - autoApply: true, - autoUpdateInput: false, - showTodayButton: true, - showClearButton: true, - minYear: parseInt(moment().subtract(100, 'year').locale('en').format('YYYY')), - maxYear: parseInt(moment().add(100, 'year').locale('en').format('YYYY')), - locale: { - direction: abp.localization.currentCulture.isRightToLeft ? 'rtl' : 'ltr', - todayLabel: abp.localization.localize('Today', 'AbpUi'), - clearLabel: abp.localization.localize('Clear', 'AbpUi'), - applyLabel: abp.localization.localize('Apply', 'AbpUi'), - }, - singleOpenAndClearButton: true - }; - var locale = defaultOptions.locale; - $.extend(options, defaultOptions); - $.extend(options, $datePickerElement.data()); - if ($.isEmptyObject(options.locale)) { - options.locale = locale; - } else { - locale = options.locale; - } - - $.extend(options, $datePickerElement.data("options")); - if ($.isEmptyObject(options.locale)) { - options.locale = locale; - } - - if (options.timePicker && options.timePicker24Hour === undefined) { - options.timePicker24Hour = moment.localeData().longDateFormat('LT').indexOf('A') < 1; - } - - if (options.dateFormat) { - options.locale = options.locale || {}; - options.locale.format = options.dateFormat; - } - - if (options.separator) { - options.locale = options.locale || {}; - options.locale.separator = options.separator; - } - - if (options.ranges) { - $.each(options.ranges, function (key, value) { - let start = value[0]; - let end; - if (value.length > 1) { - end = value[1]; - } else { - end = value[0]; - } - options.ranges[key] = [getMoment(start, options), getMoment(end, options)]; - }); - } - - if (typeof options.template !== 'string' && !(options.template instanceof $)) - options.template = - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - '
' + - ' ' + - '
' + - '
'; - } - - function replaceOpenButton (hasDate,singleOpenAndClearButton, $openButton, $clearButton) { - var hiddenClass = 'd-none'; - - if (singleOpenAndClearButton) { - if (hasDate) { - $openButton.addClass(hiddenClass); - $clearButton.removeClass(hiddenClass); - $clearButton.insertAfter($openButton); - } else { - $openButton.removeClass(hiddenClass); - $clearButton.addClass(hiddenClass); - $openButton.insertAfter($clearButton); - } - } - } - - function getMoment (date, options, dateFormat) { - var isUtc = options.isUtc; - dateFormat = dateFormat || options.dateFormat; - if (!date) { - return isUtc ? moment.utc().startOf('day') : moment().startOf('day'); - } - - if (isUtc) { - return moment.utc(date, dateFormat); - } else { - return moment(date, dateFormat); - } - } - - function getStartDate(options, startDate){ - startDate = startDate ? startDate : options.startDate; - startDate = startDate ? getMoment(startDate, options) : null; - if (options.singleDatePicker && !startDate) { - startDate = options.date ? getMoment(options.date, options) : null; - } - - if(startDate && startDate.isValid()){ - return startDate; - } - - return null; - } - - function getEndDate(options, endDate){ - if (options.singleDatePicker) { - return null; - } - endDate = endDate ? endDate : options.endDate; - endDate = endDate ? getMoment(endDate, options) : null; - - if(endDate && endDate.isValid()){ - return endDate; - } - - return null; - } - - function getTodayButton(options, $input){ - if (options.showTodayButton) { - var $todayBtn = $(''); - if(options.todayButtonClasses){ - $todayBtn.addClass(options.todayButtonClasses); - }else{ - $todayBtn.addClass('btn-default'); - } - - $todayBtn.on('click', function () { - var today = getMoment(undefined, options); - $input.data('daterangepicker').setStartDate(today); - $input.data('daterangepicker').setEndDate(today); - $input.data('daterangepicker').clickApply(); - }); - - return $todayBtn; - } - - return null; - } - - function getClearButton(options, $input, $dateRangePicker){ - if (options.showClearButton) { - var $clearBtn = $(''); - if(options.clearButtonClasses){ - $clearBtn.addClass(options.clearButtonClasses); - }else{ - $clearBtn.addClass('btn-default'); - } - $clearBtn.on('click', function () { - $input.val('').trigger('change'); - $dateRangePicker.hide(); - }); - - return $clearBtn; - } - return null; - } - - function addExtraButtons(options, $dateRangePicker, $input) { - var extraButtons = [getTodayButton(options, $input), getClearButton(options, $input, $dateRangePicker)]; - - if ($dateRangePicker.container.hasClass('auto-apply')) { - var $div = $('
'); - $div.css('display', 'block'); - $.each(extraButtons, function (index, value) { - $div.prepend(value); - }); - - $div.insertAfter($dateRangePicker.container.find('.drp-buttons')); - } else { - $.each(extraButtons, function (index, value) { - $dateRangePicker.container.find('.drp-buttons').prepend(value); - }); - } - } - - function addOpenButtonClick($openButton, $dateRangePicker){ - if(!$openButton){ - return; - } - $dateRangePicker.outsideClick = function (e) { - var target = $(e.target); - // if the page is clicked anywhere except within the daterangerpicker/button itself then call this.hide() - if ( - // ie modal dialog fix - e.type == "focusin" || - target.closest(this.element).length || - target.closest(this.container).length || - target.closest('.calendar-table').length || - target.closest($openButton).length - ) { - return; - } - - this.hide(); - this.element.trigger('outsideClick.daterangepicker', this); - }; - - $openButton.on('click', function () { - $dateRangePicker.toggle(); - }); - } - - function extendDateFormat (format,options) { - if (options.timePicker) { - if (options.timePicker24Hour) { - if (options.timePickerSeconds) { - format += " HH:mm:ss"; - } else { - format += " HH:mm"; - } - } else { - if (options.timePickerSeconds) { - format += ' ' + " hh:mm:ss A" - } else { - format += " hh:mm A"; - } - } - } - - return format; - } - - function fillInput($input, startDate, endDate, options) { - if (options.singleDatePicker) { - if (startDate) { - $input.val(startDate.format(options.dateFormat)); - } - } else { - if (startDate && endDate) { - $input.val(startDate.format(options.dateFormat) + options.separator + endDate.format(options.dateFormat)); - } - } - } - - $rootElement - .findWithSelf('abp-date-picker,abp-date-range-picker') - .each(function () { - var $this = $(this); - var $input = $this.find('.input-group input[type="text"]') - if ($input.data('daterangepicker')) { - return; - } - - var $openButton = $this.find('button[data-type="open"]') - var $clearButton = $this.find('button[data-type="clear"]') - var singleDatePicker = $this.is('abp-date-picker') - var options = {}; - - setOptions(options, $this, singleDatePicker); - - var isIso = options.isIso; - var dateFormat = options.dateFormat; - var separator = options.separator; - var defaultDateFormat = extendDateFormat("YYYY-MM-DD", options); - - var singleOpenAndClearButton = options.singleOpenAndClearButton && $clearButton.length > 0 && $openButton.length > 0; - - var startDate = getStartDate(options); - - var endDate = getEndDate(options); - if (startDate) { - options.startDate = startDate; - } - if (endDate) { - options.endDate = endDate; - } - - $input.daterangepicker(options); - - var $dateRangePicker = $input.data('daterangepicker'); - - addExtraButtons(options, $dateRangePicker, $input); - - addOpenButtonClick($openButton, $dateRangePicker); - - if (!dateFormat) { - dateFormat = extendDateFormat(moment.localeData().longDateFormat('L'), options); - options.dateFormat = dateFormat; - } - - if (!separator) { - separator = $dateRangePicker.locale.separator; - options.separator = separator; - } - - fillInput($input, startDate, endDate, options); - - $input.on('apply.daterangepicker', function (ev, picker) { - if (singleDatePicker) { - $(this).val(picker.startDate.format(dateFormat)); - } else { - $(this).val(picker.startDate.format(dateFormat) + separator + picker.endDate.format(dateFormat)); - } - - $(this).trigger('change'); - }); - - $input.on('cancel.daterangepicker', function (ev, picker) { - $(this).val(''); - $(this).trigger('change'); - }); - - $input.on('show.daterangepicker', function (ev, picker) { - var momentStartDate = getMoment(startDate, options); - var momentEndDate = getMoment(endDate, options); - if (momentStartDate.isValid()) { - picker.setStartDate(momentStartDate); - picker.setEndDate(momentEndDate); - } - if (momentEndDate.isValid() && !singleDatePicker) { - picker.setEndDate(momentEndDate); - } - }); - - $clearButton.on('click', function () { - $input.val(''); - $input.trigger('change'); - }); - - var firstTrigger = true; - $input.on('change', function () { - if ($(this).val() !== '') { - replaceOpenButton(true, singleOpenAndClearButton, $openButton, $clearButton); - } else { - replaceOpenButton(false, singleOpenAndClearButton, $openButton, $clearButton); - } - var dates = $(this).val().split(separator); - if (dates.length === 2) { - startDate = formatDate(getStartDate(options, dates[0])); - endDate = formatDate(getEndDate(options, dates[1])); - } else { - if (dates[0]) { - startDate = formatDate(getStartDate(options, dates[0])); - } - else { - if(!firstTrigger){ - startDate = null; - } - } - - if(!firstTrigger){ - endDate = null; - } - } - - if (!startDate) { - replaceOpenButton(false, singleOpenAndClearButton, $openButton, $clearButton); - $(this).val(''); - } - - if (!singleDatePicker) { - var input1 = $this.find("input[data-start-date]") - input1.val(startDate); - var input2 = $this.find("input[data-end-date]") - input2.val(endDate); - } else { - var input = $this.find("input[data-date]") - input.val(startDate); - } - - if (singleDatePicker) { - $this.data('date', startDate); - $input.data('date', startDate); - } else { - $this.data('startDate', startDate); - $this.data('endDate', endDate); - $input.data('startDate', startDate); - $input.data('endDate', endDate); - } - - firstTrigger = false; - }); - - function formatDate(date) { - if (date) { - if (isIso) { - return date.locale('en').format(); - } - return date.locale('en').format(defaultDateFormat) - } - - return null; - } - - function getFormattedStartDate() { - if (startDate) { - return getMoment(startDate, options).format(dateFormat); - } - - return null; - } - - function getFormattedEndDate() { - if (endDate) { - return getMoment(endDate, options).format(dateFormat); - } - - return null; - } - - if (singleDatePicker) { - $this[0].getFormattedDate = getFormattedStartDate; - $input[0].getFormattedDate = getFormattedStartDate; - $dateRangePicker.getFormattedDate = getFormattedStartDate; - } else { - $dateRangePicker.getFormattedStartDate = getFormattedStartDate; - $dateRangePicker.getFormattedEndDate = getFormattedEndDate; - - $this[0].getFormattedStartDate = getFormattedStartDate; - $this[0].getFormattedEndDate = getFormattedEndDate; - - $input[0].getFormattedStartDate = getFormattedStartDate; - $input[0].getFormattedEndDate = getFormattedEndDate; - } - - $input.trigger('change'); - }); - } + abp.dom.initializers.initializeAbpCspStyles = function ($abpCspStyles){ $abpCspStyles.attr("rel", "stylesheet"); @@ -769,7 +211,6 @@ abp.dom.initializers.initializeScript(args.$el); abp.dom.initializers.initializeAutocompleteSelects(args.$el.findWithSelf('.auto-complete-select')); abp.dom.initializers.initializeAbpCspStyles($("link[abp-csp-style]")); - abp.dom.initializers.initializeDateRangePickers(args.$el); }); abp.dom.onNodeRemoved(function (args) { @@ -788,7 +229,6 @@ abp.dom.initializers.initializePopovers($('[data-bs-toggle="popover"]')); abp.dom.initializers.initializeTimeAgos($('.timeago')); abp.dom.initializers.initializeDatepickers($(document)); - abp.dom.initializers.initializeDateRangePickers($(document)); abp.dom.initializers.initializeForms($('form')); abp.dom.initializers.initializeAutocompleteSelects($('.auto-complete-select')); $('[data-auto-focus="true"]').first().findWithSelf('input,select').focus(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/date-range-picker/date-range-picker-extensions.js b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/date-range-picker/date-range-picker-extensions.js new file mode 100644 index 0000000000..b9e5321e28 --- /dev/null +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/date-range-picker/date-range-picker-extensions.js @@ -0,0 +1,711 @@ +(function ($) { + abp.dom = abp.dom || {}; + + abp.dom.initializers = abp.dom.initializers || {}; + abp.libs.bootstrapDateRangePicker = { + packageName: "bootstrap-daterangepicker", + + createDateRangePicker: function (options) { + options = options || {}; + options.singleDatePicker = false; + return this.createDatePicker(options); + }, + createSinglePicker: function (options) { + options = options || {}; + options.singleDatePicker = true; + return this.createDatePicker(options); + }, + createDatePicker: function (options) { + var $container = $('
') + var label = $('') + if (options.label) { + label.text(options.label) + } + + $container.append(label) + var $datePicker = options.singleDatePicker ? $('') : $(''); + $container.append($datePicker) + + var $inputGroup = $('
'); + var $dateInput = $(''); + + if (options.value) { + $dateInput.val(options.value) + } + + const setAttribute = attr => { + if (options[attr]) { + $dateInput.attr(attr, options[attr]) + } + } + + setAttribute('placeholder'); + setAttribute('name'); + setAttribute('id'); + setAttribute('required'); + setAttribute('disabled'); + setAttribute('readonly'); + + const sizeMap = { + 'Small': 'form-control-sm', + 'Medium': 'form-control-md', + 'Large': 'form-control-lg' + }; + + if (options.size && sizeMap[options.size]) { + $dateInput.addClass(sizeMap[options.size]) + } + + $inputGroup.append($dateInput); + + const addButton = (button, buttonHTML) => { + if (options[button] !== false) { + var $button = $(buttonHTML); + $inputGroup.append($button); + if (options.disabled) { + $button.attr('disabled', 'disabled') + } + } + } + + addButton('openButton', ''); + addButton('clearButton', ''); + + $datePicker.append($inputGroup); + + const addHiddenInput = (name, attributeName) => { + if (name) { + var $hiddenElement = $(``); + $datePicker.append($hiddenElement); + } + } + + addHiddenInput(options.startDateName, 'data-start-date'); + addHiddenInput(options.endDateName, 'data-end-date'); + addHiddenInput(options.dateName, 'data-date'); + + $datePicker.data('options', options); + abp.dom.initializers.initializeDateRangePickers($datePicker); + $container[0].datePicker = $datePicker[0]; + return $container; + } + }; + + function isEmptyDate(date, options) { + if(!date) { + return true; + } + + if(typeof date === 'string') { + return date.trim() === ''; + } + + return !AbpDate(date, options).isValid(); + } + + function AbpDate(originalDate, options, format) { + + var _moment = convertToMoment(originalDate, options, format); + function _clone() { + return AbpDate(_moment, options, format); + } + + function _isSame(date) { + return _format(options.inputDateFormat) === AbpDate(date, options).format(options.inputDateFormat); + } + + function _isValid() { + return _moment && _moment.isValid(); + } + + function _format(format) { + if (_isValid()) { + return _moment.format(format); + } + return ''; + } + + function _valueOf() { + return _isValid() ? _moment.valueOf() : undefined; + } + + function _toString() { + return _moment.toString(); + } + + return { + _moment: _moment, + clone: _clone, + isSame: _isSame, + isValid: _isValid, + format: _format, + valueOf: _valueOf, + toString: _toString, + date: _moment.toISOString(), + isAbpDate: true + }; + } + + function replaceOpenButton(hasDate, singleOpenAndClearButton, $openButton, $clearButton) { + const hideButtonClass = 'd-none'; + if (!singleOpenAndClearButton) { + return; + } + + if (hasDate) { + $openButton.addClass(hideButtonClass); + $clearButton.removeClass(hideButtonClass); + $clearButton.insertAfter($openButton); + } else { + $openButton.removeClass(hideButtonClass); + $clearButton.addClass(hideButtonClass); + $openButton.insertAfter($clearButton); + } + } + + function convertToMoment(value, options, dateFormat) { + if(!value) { + // invalid date + return moment(''); + } + + options = options || {}; + var formats = new Set([dateFormat, options.visibleDateFormat, options.inputDateFormat, undefined]); + + if (typeof value === 'string') { + for(var format of formats) { + var date = moment(value, format); + if(date.isValid()) { + return maybeUtc(date, options); + } + } + } + + if (value.isAbpDate) { + return maybeUtc(value._moment.clone(), options); + } + + if(value.isLuxonDateTime) { + return maybeUtc(moment(value.toISO()), options); + } + + return maybeUtc(moment(value), options); + } + + function maybeUtc(date, options) { + if (options.isUtc) { + date = date.utc(); + }else{ + date = date.local(); + } + + return date; + } + + function getTodayButton(options, $dateRangePicker) { + if (options.showTodayButton) { + var $todayBtn = $(''); + if (options.todayButtonClasses) { + $todayBtn.addClass(options.todayButtonClasses); + } else { + $todayBtn.addClass('btn-default'); + } + + $todayBtn.on('click', function () { + var today = moment(); + $dateRangePicker.setStartDate(today); + $dateRangePicker.setEndDate(today); + + if(options.singleDatePicker && options.autoApply){ + $dateRangePicker.clickApply(); + }else{ + $dateRangePicker.updateView(); + } + }); + + return $todayBtn; + } + + return null; + } + + function getClearButton(options, $input, $dateRangePicker) { + if (options.showClearButton && options.autoUpdateInput !== true) { + var $clearBtn = $(''); + if (options.clearButtonClasses) { + $clearBtn.addClass(options.clearButtonClasses); + } else { + $clearBtn.addClass('btn-default'); + } + $clearBtn.on('click', function () { + $input.trigger('cancel.daterangepicker', $dateRangePicker); + $dateRangePicker.hide(); + }); + + return $clearBtn; + } + return null; + } + + function addExtraButtons(options, $dateRangePicker, $input) { + var extraButtons = [getTodayButton(options, $dateRangePicker), getClearButton(options, $input, $dateRangePicker)]; + + if ($dateRangePicker.container.hasClass('auto-apply')) { + var $div = $('
'); + $div.css('display', 'block'); + $.each(extraButtons, function (index, value) { + $div.prepend(value); + }); + + $div.insertAfter($dateRangePicker.container.find('.drp-buttons')); + } else { + $.each(extraButtons, function (index, value) { + $dateRangePicker.container.find('.drp-buttons').prepend(value); + }); + } + } + + function addOpenButtonClick($openButton, $dateRangePicker) { + if (!$openButton) { + return; + } + $dateRangePicker.outsideClick = function (e) { + var target = $(e.target); + // if the page is clicked anywhere except within the daterangerpicker/button itself then call this.hide() + if ( + // ie modal dialog fix + e.type == "focusin" || + target.closest(this.element).length || + target.closest(this.container).length || + target.closest('.calendar-table').length || + target.closest($openButton).length + ) { + return; + } + + this.hide(); + this.element.trigger('outsideClick.daterangepicker', this); + }; + + $openButton.on('click', function () { + $dateRangePicker.toggle(); + }); + } + + function extendDateFormat(format, options) { + if (options.timePicker) { + if (options.timePicker24Hour) { + if (options.timePickerSeconds) { + format += " HH:mm:ss"; + } else { + format += " HH:mm"; + } + } else { + if (options.timePickerSeconds) { + format += ' ' + " hh:mm:ss A" + } else { + format += " hh:mm A"; + } + } + } + + return format; + } + + function setOptions(options, $datePickerElement, singleDatePicker) { + options.singleDatePicker = singleDatePicker; + var defaultOptions = { + showDropdowns: true, + opens: "center", + drops: "down", + autoApply: true, + autoUpdateInput: false, + showTodayButton: true, + showClearButton: true, + minYear: parseInt(moment().subtract(100, 'year').locale('en').format('YYYY')), + maxYear: parseInt(moment().add(100, 'year').locale('en').format('YYYY')), + locale: { + direction: abp.localization.currentCulture.isRightToLeft ? 'rtl' : 'ltr', + todayLabel: abp.localization.localize('Today', 'AbpUi'), + clearLabel: abp.localization.localize('Clear', 'AbpUi'), + applyLabel: abp.localization.localize('Apply', 'AbpUi'), + }, + singleOpenAndClearButton: true + }; + var locale = defaultOptions.locale; + $.extend(options, defaultOptions); + $.extend(options, $datePickerElement.data()); + if ($.isEmptyObject(options.locale)) { + options.locale = locale; + } else { + locale = options.locale; + } + + $.extend(options, $datePickerElement.data("options")); + if ($.isEmptyObject(options.locale)) { + options.locale = locale; + } + + if(options.timePickerSeconds === true && options.timePicker !== false) { + options.timePicker = true; + } + + if (options.timePicker && options.timePicker24Hour === undefined) { + options.timePicker24Hour = moment.localeData().longDateFormat('LT').indexOf('A') < 1; + } + + options.visibleDateFormat = options.visibleDateFormat || options.dateFormat || extendDateFormat(moment.localeData().longDateFormat('L'), options); + options.locale = options.locale || {}; + options.locale.format = options.visibleDateFormat; + + if (options.separator) { + options.locale = options.locale || {}; + options.locale.separator = options.separator; + } + + if (options.ranges) { + $.each(options.ranges, function (key, value) { + let start = value[0]; + let end; + if (value.length > 1) { + end = value[1]; + } else { + end = value[0]; + } + options.ranges[key] = [AbpDate(start, options), AbpDate(end, options)]; + }); + } + + if (typeof options.template !== 'string' && !(options.template instanceof $)) + options.template = + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + '
' + + ' ' + + '
' + + '
'; + } + + function getAccessorDescriptor(obj, prop) { + if (!obj) { + return; + } + var descriptor = Object.getOwnPropertyDescriptor(obj, prop); + if (descriptor) { + return descriptor; + } + + return getAccessorDescriptor(Object.getPrototypeOf(obj), prop); + } + + function addHiddenDateInputSetListener(obj, prop, listener, options) { + if (!obj) { + return; + } + + var descriptor = getAccessorDescriptor(obj, prop); + if (!descriptor) { + return; + } + var originalSet = descriptor.set; + descriptor.set = function (value) { + originalSet.call(this, formatHiddenDate(value, options)); + if (value.isAbpDate) { + return; + } + listener.call(this, value); + }; + + Object.defineProperty(obj, prop, descriptor); + } + + function formatHiddenDate(date, options) { + date = convertToMoment(date, options, options.inputDateFormat); + if (date.isValid()) { + if (options.isIso) { + return date.toISOString(); + } + return date.locale('en').format(options.inputDateFormat) + } + + return ''; + } + + abp.dom.initializers.initializeDateRangePickers = function ($rootElement) { + $rootElement + .findWithSelf('abp-date-picker,abp-date-range-picker') + .each(function () { + var $this = $(this); + var $input = $this.find('.input-group input[type="text"]') + var $startDateInput = $this.find('input[data-start-date]'); + var $endDateInput = $this.find('input[data-end-date]'); + var $dateInput = $this.find('input[data-date]'); + if ($input.data('daterangepicker')) { + return; + } + + var $openButton = $this.find('button[data-type="open"]') + var $clearButton = $this.find('button[data-type="clear"]') + var singleDatePicker = $this.is('abp-date-picker') + var options = {}; + + setOptions(options, $this, singleDatePicker); + + options.inputDateFormat = options.inputDateFormat || extendDateFormat("YYYY-MM-DD", options); + + var singleOpenAndClearButton = options.singleOpenAndClearButton && $clearButton.length > 0 && $openButton.length > 0; + + var startDate = AbpDate(options.startDate || options.date || (options.autoUpdateInput ? new Date() : undefined), options); + var oldStartDate = AbpDate(undefined, options); + + var endDate = AbpDate(options.endDate || undefined, options); + var oldEndDate = AbpDate(undefined, options); + + options.startDate = convertToMoment(startDate, options); + options.endDate = convertToMoment(endDate, options); + $input.daterangepicker(options); + + var $dateRangePicker = $input.data('daterangepicker'); + + $input.data('format', options.visibleDateFormat); + $this.data('daterangepicker', $dateRangePicker); + $startDateInput.data('daterangepicker', $dateRangePicker); + $startDateInput.data('format', options.inputDateFormat); + $endDateInput.data('daterangepicker', $dateRangePicker); + $endDateInput.data('format', options.inputDateFormat); + $dateInput.data('daterangepicker', $dateRangePicker); + $dateInput.data('format', options.inputDateFormat); + + addExtraButtons(options, $dateRangePicker, $input); + + addOpenButtonClick($openButton, $dateRangePicker); + + if (!options.separator) { + options.separator = $dateRangePicker.locale.separator; + } + + function fillInput() { + if (options.singleDatePicker) { + if (!isEmptyDate(startDate, options)) { + $input.val(startDate.format(options.visibleDateFormat)); + } + } else { + if (!isEmptyDate(startDate, options) && !isEmptyDate(endDate, options)) { + $input.val(startDate.format(options.visibleDateFormat) + options.separator + endDate.format(options.visibleDateFormat)); + } + } + } + + fillInput(); + + function changeDate(isTrigger = true, isInputTrigger = true, isDateRangePickerTrigger = true) { + if (singleDatePicker) { + if (oldStartDate.isSame(startDate)) { + return; + } + setDataDates(startDate, $dateInput, ''); + $dateInput.val(startDate); + if (isTrigger) { + triggerDateChange($dateInput, startDate); + } + } else { + if (!oldStartDate.isSame(startDate)) { + setDataDates(startDate, $startDateInput, 'start'); + $startDateInput.val(startDate); + if (isTrigger) { + triggerDateChange($startDateInput, startDate); + } + } + + if (!oldEndDate.isSame(endDate)) { + setDataDates(endDate, $endDateInput, 'end'); + $endDateInput.val(endDate); + if (isTrigger) { + triggerDateChange($endDateInput, endDate); + } + } + } + + if (isTrigger && isInputTrigger) { + if (!oldStartDate.isSame(startDate) || !oldEndDate.isSame(endDate)) { + triggerDateChange($this, startDate, isDateRangePickerTrigger); + triggerDateChange($input, startDate, isDateRangePickerTrigger); + } + } + } + + function setDataDates(date, $selfInput, prefix){ + date = AbpDate(date, options).date; + $selfInput.data('date', date); + $this.data(prefix + 'date', date); + $input.data(prefix + 'date', date); + } + + function triggerDateChange($selfInput, value, isDateRangePickerTrigger) { + $selfInput.trigger('change'); + if(isDateRangePickerTrigger !== false){ + if(isEmptyDate(value, options)) { + $selfInput.trigger('cancel.daterangepicker', $dateRangePicker); + }else { + $selfInput.trigger('apply.daterangepicker', $dateRangePicker); + } + } + } + + $input.on('apply.daterangepicker', function (ev, picker) { + if(startDate.isSame(picker.startDate) && (singleDatePicker || endDate.isSame(picker.endDate))) { + fillInput(); + picker.hide(); + return; + } + setStartDateByMomentDate(picker.startDate); + setEndDateByMomentEndDate(picker.endDate); + fillInput(); + inputChangeHandler(true, true, false); + }); + + $input.on('show.daterangepicker', function (ev, picker) { + const today = moment(); + if(isEmptyDate(startDate, options)){ + picker.setStartDate(today); + }else{ + picker.setStartDate(convertToMoment(startDate, options, options.inputDateFormat)); + } + + if(singleDatePicker){ + picker.setEndDate(picker.startDate); + }else if(isEmptyDate(endDate, options)){ + picker.setEndDate(today); + } + else{ + picker.setEndDate(convertToMoment(endDate, options, options.inputDateFormat)); + } + + picker.updateView(); + }); + + $input.on('cancel.daterangepicker', function (ev, picker) { + if(!$input.val()){ + picker.hide(); + return; + } + $input.val(''); + setStartDateByMomentDate(); + setEndDateByMomentEndDate(); + inputChangeHandler(true, true, false); + }); + + $clearButton.on('click', function (e) { + $input.trigger('cancel.daterangepicker', $dateRangePicker); + }); + + $input.on('change', function (e) { + var dates = $input.val().split(options.separator); + var newStartDate = convertToMoment(dates[0], options, options.visibleDateFormat); + var newEndDate = undefined; + if (dates.length === 2) { + newEndDate = convertToMoment(dates[1], options, options.visibleDateFormat); + }else{ + newEndDate = convertToMoment(undefined, options, options.visibleDateFormat); + } + + if (startDate.isSame(newStartDate) && (singleDatePicker || endDate.isSame(newEndDate))) { + fillInput(); + return; + } + + setStartDateByMomentDate(newStartDate); + setEndDateByMomentEndDate(newEndDate); + + if(newStartDate.isValid()){ + $dateRangePicker.setStartDate(newStartDate); + }else{ + $dateRangePicker.setStartDate(); + } + + if(newEndDate.isValid()){ + $dateRangePicker.setEndDate(newEndDate); + }else{ + $dateRangePicker.setEndDate(); + } + + fillInput(); + inputChangeHandler(undefined, false); + }); + + function inputChangeHandler(isTrigger, isInputTrigger, isDateRangePickerTrigger) { + var value = $input.val(); + if (value !== '') { + replaceOpenButton(true, singleOpenAndClearButton, $openButton, $clearButton); + } else { + replaceOpenButton(false, singleOpenAndClearButton, $openButton, $clearButton); + } + + if (isEmptyDate(startDate, options)) { + replaceOpenButton(false, singleOpenAndClearButton, $openButton, $clearButton); + $this.val(''); + } + + changeDate(isTrigger, isInputTrigger, isDateRangePickerTrigger); + } + + const setStartDateByMomentDate = (momentDate) => { + oldStartDate = startDate; + startDate = AbpDate(momentDate, options); + } + + const setEndDateByMomentEndDate = (momentDate) => { + if(singleDatePicker){ + return; + } + oldEndDate = endDate; + endDate = AbpDate(momentDate, options); + } + + function startDateInputHandler(value) { + value = convertToMoment(value, options); + + if (startDate.isSame(value)) { + return; + } + + setStartDateByMomentDate(value); + + $dateRangePicker.setStartDate(value); + fillInput(); + inputChangeHandler(false); + } + + function endDateInputHandler(value) { + value = convertToMoment(value, options); + + if (endDate.isSame(value)) { + return; + } + + setEndDateByMomentEndDate(value); + $dateRangePicker.setEndDate(value); + fillInput(); + inputChangeHandler(false); + } + + addHiddenDateInputSetListener($startDateInput[0], 'value', startDateInputHandler, options); + addHiddenDateInputSetListener($endDateInput[0], 'value', endDateInputHandler, options); + addHiddenDateInputSetListener($dateInput[0], 'value', startDateInputHandler, options); + + inputChangeHandler(false, false, false); + }); + } + + $(function () { + abp.dom.initializers.initializeDateRangePickers($('body')); + }); +})(jQuery); \ No newline at end of file diff --git a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json index 81de414162..466a5fa336 100644 --- a/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Authorization/Volo/Abp/Authorization/Localization/zh-Hans.json @@ -1,10 +1,10 @@ { "culture": "zh-Hans", "texts": { - "Volo.Authorization:010001": "授权失败! 提供的策略尚未授予.", - "Volo.Authorization:010002": "授权失败! 提供的策略尚未授予: {PolicyName}", - "Volo.Authorization:010003": "授权失败! 提供的策略未授予提供的资源: {ResourceName}", - "Volo.Authorization:010004": "授权失败! 提供的要求未授予提供的资源: {ResourceName}", - "Volo.Authorization:010005": "授权失败! 提供的要求未授予提供的资源: {ResourceName}" + "Volo.Authorization:010001": "授权失败!提供的策略尚未授予。", + "Volo.Authorization:010002": "授权失败!提供的策略尚未授予: {PolicyName}", + "Volo.Authorization:010003": "授权失败!提供的策略未授予提供的资源:{ResourceName}", + "Volo.Authorization:010004": "授权失败!提供的要求未授予提供的资源:{ResourceName}", + "Volo.Authorization:010005": "授权失败!提供的要求未授予提供的资源:{ResourceName}" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj index 15f7406f76..a27f26562d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj +++ b/framework/src/Volo.Abp.Cli.Core/Volo.Abp.Cli.Core.csproj @@ -24,6 +24,7 @@ + @@ -31,6 +32,7 @@ + diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs index e7289b7edd..90c95d18be 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/AbpCliCoreModule.cs @@ -10,6 +10,7 @@ using Volo.Abp.Domain; using Volo.Abp.Http; using Volo.Abp.IdentityModel; using Volo.Abp.Json; +using Volo.Abp.Localization; using Volo.Abp.Minify; using Volo.Abp.Modularity; @@ -20,7 +21,8 @@ namespace Volo.Abp.Cli; typeof(AbpJsonModule), typeof(AbpIdentityModelModule), typeof(AbpMinifyModule), - typeof(AbpHttpModule) + typeof(AbpHttpModule), + typeof(AbpLocalizationModule) )] public class AbpCliCoreModule : AbpModule { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs index b6fd6e2075..a75a8ff5dd 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/NewCommand.cs @@ -19,6 +19,7 @@ using Volo.Abp.Cli.ProjectBuilding.Events; using Volo.Abp.Cli.ProjectBuilding.Templates.App; using Volo.Abp.Cli.ProjectModification; using Volo.Abp.Cli.Utils; +using Volo.Abp.Cli.Version; using Volo.Abp.DependencyInjection; using Volo.Abp.EventBus.Local; @@ -44,7 +45,8 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien IBundlingService bundlingService, ITemplateInfoProvider templateInfoProvider, TemplateProjectBuilder templateProjectBuilder, - AngularThemeConfigurer angularThemeConfigurer) : + AngularThemeConfigurer angularThemeConfigurer, + CliVersionService cliVersionService) : base(connectionStringProvider, solutionPackageVersionFinder, cmdHelper, @@ -55,7 +57,8 @@ public class NewCommand : ProjectCreationCommandBase, IConsoleCommand, ITransien themePackageAdder, eventBus, bundlingService, - angularThemeConfigurer) + angularThemeConfigurer, + cliVersionService) { TemplateInfoProvider = templateInfoProvider; TemplateProjectBuilder = templateProjectBuilder; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index a2226fa6e2..ae018a88c7 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -22,6 +22,7 @@ using Volo.Abp.Cli.ProjectBuilding.Templates.Microservice; using Volo.Abp.Cli.ProjectBuilding.Templates.Module; using Volo.Abp.Cli.ProjectBuilding.Templates.MvcModule; using Volo.Abp.Cli.Utils; +using Volo.Abp.Cli.Version; using Volo.Abp.EventBus.Local; namespace Volo.Abp.Cli.Commands; @@ -42,6 +43,8 @@ public abstract class ProjectCreationCommandBase public ThemePackageAdder ThemePackageAdder { get; } public AngularThemeConfigurer AngularThemeConfigurer { get; } + + public CliVersionService CliVersionService { get; } public ProjectCreationCommandBase( ConnectionStringProvider connectionStringProvider, @@ -54,7 +57,8 @@ public abstract class ProjectCreationCommandBase ThemePackageAdder themePackageAdder, ILocalEventBus eventBus, IBundlingService bundlingService, - AngularThemeConfigurer angularThemeConfigurer) + AngularThemeConfigurer angularThemeConfigurer, + CliVersionService cliVersionService) { _bundlingService = bundlingService; ConnectionStringProvider = connectionStringProvider; @@ -67,6 +71,7 @@ public abstract class ProjectCreationCommandBase EventBus = eventBus; ThemePackageAdder = themePackageAdder; AngularThemeConfigurer = angularThemeConfigurer; + CliVersionService = cliVersionService; Logger = NullLogger.Instance; } @@ -86,7 +91,7 @@ public abstract class ProjectCreationCommandBase Logger.LogInformation("Preview: yes"); #if !DEBUG - var cliVersion = await CliService.GetCurrentCliVersionAsync(typeof(CliService).Assembly); + var cliVersion = await CliVersionService.GetCurrentCliVersionAsync(); if (!cliVersion.IsPrerelease) { @@ -426,8 +431,17 @@ public abstract class ProjectCreationCommandBase return; } + var isModuleTemplate = ModuleTemplateBase.IsModuleTemplate(projectArgs.TemplateName); var isWebassembly = projectArgs.UiFramework == UiFramework.Blazor; - var message = isWebassembly ? "Generating bundles for Blazor Wasm" : "Generating bundles for MAUI Blazor"; + + var message = isWebassembly || isModuleTemplate + ? "Generating bundles for Blazor Wasm" + : "Generating bundles for MAUI Blazor"; + + var projectType = isWebassembly || isModuleTemplate + ? BundlingConsts.WebAssembly + : BundlingConsts.MauiBlazor; + Logger.LogInformation(message + "..."); await EventBus.PublishAsync(new ProjectCreationProgressEvent @@ -435,19 +449,26 @@ public abstract class ProjectCreationCommandBase Message = message }, false); + var searchPattern = isWebassembly ? "*.Blazor.csproj" : "*.MauiBlazor.csproj"; var path = projectArgs.OutputFolder; - if (projectArgs.TemplateName == MicroserviceProTemplate.TemplateName) + + if (isModuleTemplate) + { + path = Path.Combine(path, "host"); + searchPattern = "*.Blazor.Host.csproj"; + } + else if (MicroserviceTemplateBase.IsMicroserviceTemplate(projectArgs.TemplateName)) { path = Path.Combine(path, "apps"); } var directory = Path.GetDirectoryName( - Directory.GetFiles(path, isWebassembly ? "*.Blazor.csproj" : "*.MauiBlazor.csproj", SearchOption.AllDirectories).First() + Directory.GetFiles(path, searchPattern, SearchOption.AllDirectories).First() ); - await _bundlingService.BundleAsync(directory, true, projectType: isWebassembly ? BundlingConsts.WebAssembly : BundlingConsts.MauiBlazor); + await _bundlingService.BundleAsync(directory, true, projectType); } - + protected virtual bool ShouldRunBundleCommand(ProjectBuildArgs projectArgs) { if ((AppTemplateBase.IsAppTemplate(projectArgs.TemplateName) || AppNoLayersTemplateBase.IsAppNoLayersTemplate(projectArgs.TemplateName)) @@ -456,7 +477,12 @@ public abstract class ProjectCreationCommandBase return true; } - if (projectArgs.TemplateName == MicroserviceProTemplate.TemplateName && projectArgs.UiFramework is UiFramework.Blazor) + if (MicroserviceServiceTemplateBase.IsMicroserviceTemplate(projectArgs.TemplateName) && projectArgs.UiFramework is UiFramework.Blazor) + { + return true; + } + + if (ModuleTemplateBase.IsModuleTemplate(projectArgs.TemplateName) && projectArgs.UiFramework != UiFramework.None) { return true; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs index ea6b1d45f6..cb85b37e17 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/TranslateCommand.cs @@ -5,75 +5,82 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using DeepL; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Volo.Abp.Cli.Args; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization.Json; namespace Volo.Abp.Cli.Commands; public class TranslateCommand : IConsoleCommand, ITransientDependency { public const string Name = "translate"; - + public ILogger Logger { get; set; } - public Task ExecuteAsync(CommandLineArgs commandLineArgs) + public async Task ExecuteAsync(CommandLineArgs commandLineArgs) { var currentDirectory = Directory.GetCurrentDirectory(); - var apply = commandLineArgs.Options.ContainsKey(Options.Apply.Short) || commandLineArgs.Options.ContainsKey(Options.Apply.Long); - if (apply) + // Verify + if (commandLineArgs.Options.ContainsKey(Options.Verify.Long)) { - var inputFile = Path.Combine(currentDirectory, - commandLineArgs.Options.GetOrNull(Options.File.Short, Options.File.Long) - ?? "abp-translation.json"); - - Logger.LogInformation("Abp translate apply..."); - Logger.LogInformation("Input file: " + inputFile); - - ApplyAbpTranslateInfo(currentDirectory, inputFile); + await VerifyJsonAsync(currentDirectory); + return; } - else - { - var targetCulture = commandLineArgs.Options.GetOrNull(Options.Culture.Short, Options.Culture.Long); - if (targetCulture == null) - { - throw new CliUsageException( - "Target culture is missing!" + - Environment.NewLine + Environment.NewLine + - GetUsageInfo() - ); - } - - var referenceCulture = commandLineArgs.Options.GetOrNull(Options.ReferenceCulture.Short, Options.ReferenceCulture.Long) - ?? "en"; - var outputFile = Path.Combine(currentDirectory, - commandLineArgs.Options.GetOrNull(Options.Output.Short, Options.Output.Long) - ?? "abp-translation.json"); + var referenceCulture = commandLineArgs.Options.GetOrNull(Options.ReferenceCulture.Short, Options.ReferenceCulture.Long) ?? "en"; + var allValues = commandLineArgs.Options.ContainsKey(Options.AllValues.Short) || commandLineArgs.Options.ContainsKey(Options.AllValues.Long); - var allValues = commandLineArgs.Options.ContainsKey(Options.AllValues.Short) || - commandLineArgs.Options.ContainsKey(Options.AllValues.Long); + // Apply abp-translation.json file + if (commandLineArgs.Options.ContainsKey(Options.Apply.Short) || commandLineArgs.Options.ContainsKey(Options.Apply.Long)) + { + var inputFile = Path.Combine(currentDirectory, commandLineArgs.Options.GetOrNull(Options.File.Short, Options.File.Long) ?? "abp-translation.json"); + await ApplyAbpTranslateInfoAsync(currentDirectory, inputFile); + return; + } - Logger.LogInformation("Abp translate..."); - Logger.LogInformation("Target culture: " + targetCulture); - Logger.LogInformation("Reference culture: " + referenceCulture); - Logger.LogInformation("Output file: " + outputFile); + var targetCulture = commandLineArgs.Options.GetOrNull(Options.Culture.Short, Options.Culture.Long); + if (targetCulture == null) + { + throw new CliUsageException("Target culture is missing!" + Environment.NewLine + Environment.NewLine + GetUsageInfo()); + } - if (allValues) + // Translate online + if (commandLineArgs.Options.ContainsKey(Options.Online.Long)) + { + var authKey = commandLineArgs.Options.GetOrNull(Options.DeepLAuthKey.Short, Options.DeepLAuthKey.Short); + if (authKey == null) { - Logger.LogInformation("Include all keys"); + throw new CliUsageException("DeepL auth key is missing!" + Environment.NewLine + Environment.NewLine + GetUsageInfo()); } + await TranslateAbpTranslateInfoAsync(currentDirectory, targetCulture, referenceCulture, allValues, authKey); + return; + } - var translateInfo = GetAbpTranslateInfo(currentDirectory, targetCulture, referenceCulture, allValues); - - File.WriteAllText(outputFile, JsonConvert.SerializeObject(translateInfo, Formatting.Indented)); + // Generate abp-translation.json file + var outputFile = Path.Combine(currentDirectory, commandLineArgs.Options.GetOrNull(Options.Output.Short, Options.Output.Long) ?? "abp-translation.json"); + await GenerateAbpTranslateInfoAsync(currentDirectory, targetCulture, referenceCulture, allValues, outputFile); + } - Logger.LogInformation($"The translation file has been created."); + private Task GenerateAbpTranslateInfoAsync(string currentDirectory, string targetCulture, string referenceCulture, bool allValues, string outputFile) + { + Logger.LogInformation("Abp translate..."); + Logger.LogInformation("Target culture: " + targetCulture); + Logger.LogInformation("Reference culture: " + referenceCulture); + Logger.LogInformation("Output file: " + outputFile); + if (allValues) + { + Logger.LogInformation("Include all keys"); } + var translateInfo = GetAbpTranslateInfo(currentDirectory, targetCulture, referenceCulture, allValues); + File.WriteAllText(outputFile, JsonConvert.SerializeObject(translateInfo, Formatting.Indented)); + Logger.LogInformation($"The translation file has been created."); + return Task.CompletedTask; } @@ -140,8 +147,154 @@ public class TranslateCommand : IConsoleCommand, ITransientDependency return translateInfo; } - private void ApplyAbpTranslateInfo(string directory, string filename) + private async Task TranslateAbpTranslateInfoAsync(string directory, string targetCulture, string referenceCulture, bool allValues, string authKey) { + Logger.LogInformation("Abp translate online..."); + Logger.LogInformation("Target culture: " + targetCulture); + Logger.LogInformation("Reference culture: " + referenceCulture); + if (allValues) + { + Logger.LogInformation("Include all keys"); + } + + var translateInfo = GetAbpTranslateInfo(directory, targetCulture, referenceCulture, allValues); + foreach (var resource in translateInfo.Resources) + { + var targetFile = Path.Combine(resource.ResourcePath, translateInfo.TargetCulture + ".json"); + var targetLocalizationInfo = File.Exists(targetFile) + ? GetAbpLocalizationInfoOrNull(targetFile) + : new AbpLocalizationInfo() + { + Culture = translateInfo.TargetCulture, + Texts = new List() + }; + + if (targetLocalizationInfo == null) + { + throw new CliUsageException( + $"Failed to get localization information from {targetFile} file." + + Environment.NewLine + Environment.NewLine + + GetUsageInfo() + ); + } + + var referenceFile = Path.Combine(resource.ResourcePath, translateInfo.ReferenceCulture + ".json"); + if (!File.Exists(referenceFile)) + { + throw new CliUsageException( + $"{referenceFile} file does not exist.." + + Environment.NewLine + Environment.NewLine + + GetUsageInfo() + ); + } + var referenceLocalizationInfo = GetAbpLocalizationInfoOrNull(referenceFile); + if (referenceLocalizationInfo == null) + { + throw new CliUsageException( + $"Failed to get localization information from {referenceFile} file." + + Environment.NewLine + Environment.NewLine + + GetUsageInfo() + ); + } + + var translator = new Translator(authKey); + + var texts = resource.Texts.Select(x => x.Reference); + + var translations = await translator.TranslateTextAsync(texts, await GetDeeplLanguageCode(referenceCulture), await GetDeeplLanguageCode(targetCulture)); + for (var i = 0; i < translations.Length; i++) + { + resource.Texts[i].Target = translations[i].Text; + } + + foreach (var text in resource.Texts) + { + var targetText = targetLocalizationInfo.Texts.FirstOrDefault(x => x.Name == text.LocalizationKey); + if (targetText != null) + { + if (!text.Target.IsNullOrEmpty()) + { + Logger.LogInformation($"Update translation: {targetText.Name} => " + text.Target); + targetText.Value = text.Target; + } + } + else + { + Logger.LogInformation($"Create translation: {text.LocalizationKey} => " + text.Target); + targetLocalizationInfo.Texts.Add(new NameValue(text.LocalizationKey, text.Target)); + } + } + + Logger.LogInformation($"Write translation json to {targetFile}."); + + // sort keys + targetLocalizationInfo = SortLocalizedKeys(targetLocalizationInfo, referenceLocalizationInfo); + File.WriteAllText(targetFile, AbpLocalizationInfoToJsonFile(targetLocalizationInfo)); + } + } + + private Task GetDeeplLanguageCode(string abpCulture) + { + var deeplLanguages = new List() + { + LanguageCode.Bulgarian , + LanguageCode.Czech , + LanguageCode.Danish , + LanguageCode.German , + LanguageCode.Greek , + LanguageCode.English , + LanguageCode.EnglishBritish , + LanguageCode.EnglishAmerican , + LanguageCode.Spanish , + LanguageCode.Estonian , + LanguageCode.Finnish , + LanguageCode.French , + LanguageCode.Hungarian , + LanguageCode.Indonesian , + LanguageCode.Italian , + LanguageCode.Japanese , + LanguageCode.Korean , + LanguageCode.Lithuanian , + LanguageCode.Latvian , + LanguageCode.Norwegian , + LanguageCode.Dutch , + LanguageCode.Polish , + LanguageCode.Portuguese , + LanguageCode.PortugueseBrazilian , + LanguageCode.PortugueseEuropean , + LanguageCode.Romanian , + LanguageCode.Russian , + LanguageCode.Slovak , + LanguageCode.Slovenian , + LanguageCode.Swedish , + LanguageCode.Turkish , + LanguageCode.Ukrainian, + LanguageCode.Chinese + }; + + if (abpCulture == "zh-Hans") + { + return Task.FromResult(LanguageCode.Chinese); + } + + var deeplCulture = deeplLanguages.FirstOrDefault(x => x.Equals(abpCulture, StringComparison.OrdinalIgnoreCase)); + if (deeplCulture == null) + { + throw new CliUsageException( + $"DeepL does not support {abpCulture} culture." + + Environment.NewLine + Environment.NewLine + + GetUsageInfo() + ); + } + + return Task.FromResult(deeplCulture); + } + + private Task ApplyAbpTranslateInfoAsync(string directory, string filename) + { + Logger.LogInformation("Abp translate apply..."); + Logger.LogInformation("Input file: " + filename); + var translateJsonPath = Path.Combine(directory, filename); if (!File.Exists(translateJsonPath)) { @@ -220,22 +373,26 @@ public class TranslateCommand : IConsoleCommand, ITransientDependency File.Delete(translateJsonPath); Logger.LogInformation($"Delete the {translateJsonPath} file, if you need to translate again, please re-run the [abp translate] command."); } + + return Task.CompletedTask; } - private static IEnumerable GetCultureJsonFiles(string path, string cultureName) + private static IEnumerable GetCultureJsonFiles(string path, string cultureName = null) { var excludeDirectory = new List() - { - "node_modules", - Path.Combine("bin", "debug"), - Path.Combine("obj", "debug") - }; - - var allCultureInfos = CultureInfo.GetCultures(CultureTypes.AllCultures); + { + "node_modules", + "wwwroot", + ".git", + "bin", + "obj" + }; + var allCultureNames = CultureInfo.GetCultures(CultureTypes.AllCultures).Where(x => !x.Name.IsNullOrWhiteSpace()).Select(x => x.Name).ToList(); return Directory.GetFiles(path, "*.json", SearchOption.AllDirectories) .Where(file => excludeDirectory.All(x => file.IndexOf(x, StringComparison.OrdinalIgnoreCase) == -1)) - .Where(jsonFile => allCultureInfos.Any(culture => jsonFile.EndsWith($"{cultureName}.json", StringComparison.OrdinalIgnoreCase))); + .Where(file => allCultureNames.Any(x => Path.GetFileName(file).Equals($"{x}.json", StringComparison.OrdinalIgnoreCase))) + .WhereIf(!cultureName.IsNullOrWhiteSpace(), jsonFile => Path.GetFileName(jsonFile).Equals($"{cultureName}.json", StringComparison.OrdinalIgnoreCase)); } private AbpLocalizationInfo GetAbpLocalizationInfoOrNull(string path) @@ -322,6 +479,29 @@ public class TranslateCommand : IConsoleCommand, ITransientDependency return translateInfo; } + private Task VerifyJsonAsync(string currentDirectory) + { + var jsonFiles = GetCultureJsonFiles(currentDirectory); + var hasInvalidJsonFile = false; + foreach (var jsonFile in jsonFiles) + { + try + { + var jsonString = File.ReadAllText(jsonFile); + _ = JsonLocalizationDictionaryBuilder.BuildFromJsonString(jsonString); + } + catch (Exception e) + { + Logger.LogError($"Invalid json file: {jsonFile}"); + hasInvalidJsonFile = true; + } + } + + Logger.LogInformation(!hasInvalidJsonFile ? "All json files are valid." : "Some json files are invalid."); + + return Task.CompletedTask; + } + private static AbpLocalizationInfo SortLocalizedKeys(AbpLocalizationInfo targetLocalizationInfo, AbpLocalizationInfo referenceLocalizationInfo) { var sortedLocalizationInfo = new AbpLocalizationInfo @@ -357,13 +537,18 @@ public class TranslateCommand : IConsoleCommand, ITransientDependency sb.AppendLine("--all-values|-all Include all keys. Default false"); sb.AppendLine("--apply|-a Creates or updates the file for the translated culture."); sb.AppendLine("--file|-f Default: abp-translation.json"); + sb.AppendLine("--online Translate online."); + sb.AppendLine("--deepl-auth-key DeepL auth key for online translation."); + sb.AppendLine("--verify Verify that all localized files are correct JSON format."); sb.AppendLine(""); sb.AppendLine("Examples:"); sb.AppendLine(""); sb.AppendLine(" abp translate -c zh-Hans"); - sb.AppendLine(" abp translate -c zh-Hans -r en -a"); + sb.AppendLine(" abp translate -c zh-Hans -r en"); sb.AppendLine(" abp translate --apply"); sb.AppendLine(" abp translate -a -f my-translation.json"); + sb.AppendLine(" abp translate -c zh-Hans --online --deepl-auth-key "); + sb.AppendLine(" abp translate -c zh-Hans -r tr --online --deepl-auth-key "); sb.AppendLine(""); sb.AppendLine("See the documentation for more info: https://docs.abp.io/en/abp/latest/CLI"); @@ -412,6 +597,21 @@ public class TranslateCommand : IConsoleCommand, ITransientDependency public const string Short = "f"; public const string Long = "file"; } + + public static class Online + { + public const string Long = "online"; + } + + public static class DeepLAuthKey + { + public const string Short = "deepl-auth-key"; + } + + public static class Verify + { + public const string Long = "verify"; + } } public class AbpTranslateInfo diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index 6df7418e9d..35d23e8f21 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -79,7 +79,7 @@ public class UpdateCommand : IConsoleCommand, ITransientDependency await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll, version: version); - Logger.LogInformation($"Volo packages are updated in {solutionName} solution."); + Logger.LogInformation("Volo packages are updated in {SolutionName} solution", solutionName); } return; } @@ -92,7 +92,7 @@ public class UpdateCommand : IConsoleCommand, ITransientDependency await _nugetPackagesVersionUpdater.UpdateProjectAsync(project, checkAll: checkAll, version: version); - Logger.LogInformation($"Volo packages are updated in {projectName} project."); + Logger.LogInformation("Volo packages are updated in {ProjectName} project", projectName); return; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs index 653cbc7b66..3060435928 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/VoloNugetPackagesVersionUpdater.cs @@ -181,6 +181,11 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency packageId = package.Attributes["Include"].Value; var versionAttribute = package.Attributes["Version"]; + if (versionAttribute == null) + { + Logger.LogWarning("Package: {PackageId} uses central package management. Skipped!", packageId); + continue; + } var currentVersion = versionAttribute.Value; var isLeptonXPackage = packageId.Contains("LeptonX"); @@ -194,17 +199,17 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency var isVersionParsed = SemanticVersion.TryParse(currentVersion, out var currentSemanticVersion); if (!isVersionParsed) { - Logger.LogWarning("Could not parse package \"{0}\" version v{1}. Skipped.", packageId, currentVersion); + Logger.LogWarning("Could not parse package \"{PackageId}\" version v{CurrentVersion}. Skipped!", packageId, currentVersion); continue; } - Logger.LogDebug("Checking package: \"{0}\" - Current version: {1}", packageId, currentSemanticVersion); + Logger.LogDebug("Checking package: \"{PackageId}\" - Current version: {CurrentSemanticVersion}", packageId, currentSemanticVersion); if (!specifiedVersion.IsNullOrWhiteSpace()) { if (isLeptonXPackage || isStudioPackage) { - Logger.LogWarning("Package: {0} could not be updated. Please manually update the package version yourself to prevent version mismatches.", packageId); + Logger.LogWarning("Package: {PackageId} could not be updated. Please manually update the package version yourself to prevent version mismatches!", packageId); continue; } @@ -213,17 +218,17 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency var specifiedSemanticVersion = SemanticVersion.Parse(specifiedVersion); if (specifiedSemanticVersion > currentSemanticVersion) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, specifiedVersion); + Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion); versionAttribute.Value = specifiedVersion; } else { - Logger.LogWarning("Unable to update package \"{0}\" version v{1} to v{2}.", packageId, currentVersion, specifiedVersion); + Logger.LogWarning("Unable to update package \"{PackageId}\" version v{CurrentVersion} to v{SpecifiedVersion}", packageId, currentVersion, specifiedVersion); } } else { - Logger.LogWarning("Package \"{0}\" specified version v{1} does not exist.", packageId, specifiedVersion); + Logger.LogWarning("Package \"{PackageId}\" specified version v{SpecifiedVersion} does not exist!", packageId, specifiedVersion); } } else @@ -253,18 +258,18 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency if(latestVersion == null) { - Logger.LogWarning("Package: {0} could not be updated. Please manually update the package version yourself to prevent version mismatches.", packageId); + Logger.LogWarning("Package: {PackageId} could not be updated. Please manually update the package version yourself to prevent version mismatches!", packageId); continue; } if (currentVersion != latestVersion) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentVersion, latestVersion); + Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentVersion} to v{LatestVersion}", packageId, currentVersion, latestVersion); versionAttribute.Value = latestVersion; } else { - Logger.LogDebug("Package: \"{0}-v{1}\" is up to date.", packageId, currentVersion); + Logger.LogDebug("Package: \"{PackageId}-v{CurrentVersion}\" is up to date", packageId, currentVersion); } } else @@ -285,12 +290,12 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency if (latestVersion != null && (currentSemanticVersion < latestVersion || (currentSemanticVersion.IsPrerelease && switchToStable))) { - Logger.LogInformation("Updating package \"{0}\" from v{1} to v{2}.", packageId, currentSemanticVersion.ToString(), latestVersion.ToString()); + Logger.LogInformation("Updating package \"{PackageId}\" from v{CurrentSemanticVersion} to v{LatestVersion}", packageId, currentSemanticVersion.ToString(), latestVersion.ToString()); versionAttribute.Value = latestVersion.ToString(); } else { - Logger.LogInformation("Package: \"{0}-v{1}\" is up to date.", packageId, currentSemanticVersion); + Logger.LogInformation("Package: \"{PackageId}-v{CurrentSemanticVersion}\" is up to date", packageId, currentSemanticVersion); } } } @@ -301,7 +306,7 @@ public class VoloNugetPackagesVersionUpdater : ITransientDependency } catch (Exception ex) { - Logger.LogError("Cannot update Volo.* packages! An error occurred while updating the package \"{0}\". Error: {1}", packageId, ex.Message); + Logger.LogError("Cannot update Volo.* packages! An error occurred while updating the package \"{PackageId}\". Error: {ErrorMessage}", packageId, ex.Message); Logger.LogException(ex); } diff --git a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json index 0bc563e702..bc57671e43 100644 --- a/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json +++ b/framework/src/Volo.Abp.Ddd.Application.Contracts/Volo/Abp/Application/Localization/Resources/AbpDdd/zh-Hans.json @@ -1,6 +1,6 @@ { "culture": "zh-Hans", "texts": { - "MaxResultCountExceededExceptionMessage": "{0}不能超过 {1}! 在服务器端增加{2}.{3}以获得更多结果." + "MaxResultCountExceededExceptionMessage": "{0}不能多于{1}!在服务器端增加{2}.{3},以获得更多结果。" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/zh-Hans.json b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/zh-Hans.json index 08213a79a7..cc408a8b75 100644 --- a/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.ExceptionHandling/Volo/Abp/ExceptionHandling/Localization/zh-Hans.json @@ -1,26 +1,26 @@ { "culture": "zh-Hans", "texts": { - "InternalServerErrorMessage": "对不起,在处理你的请求期间,产生了一个服务器内部错误!", - "ValidationErrorMessage": "你的请求无效!", - "ValidationNarrativeErrorMessageTitle": "验证时发现以下错误.", - "DefaultErrorMessage": "发生错误!", - "DefaultErrorMessageDetail": "服务器未发送错误的详细信息.", - "DefaultErrorMessage401": "未通过身份验证!", - "DefaultErrorMessage401Detail": "你需要进行身份认证(登录)后再执行此操作.", - "DefaultErrorMessage403": "你没有权限!", - "DefaultErrorMessage403Detail": "你不能执行此操作!", - "DefaultErrorMessage404": "未找到资源!", - "DefaultErrorMessage404Detail": "未在服务中找到请求的资源!", - "EntityNotFoundErrorMessage": "实体 {0} 不存在,id = {1}!", - "AbpDbConcurrencyErrorMessage": "你提交的数据已经被其他用户/客户端修改.请放弃你所做的修改并再次尝试.", + "InternalServerErrorMessage": "对不起,在处理您的请求期间产生了一个服务器内部错误!!", + "ValidationErrorMessage": "您的请求无效!", + "ValidationNarrativeErrorMessageTitle": "验证过程中检测到以下错误。", + "DefaultErrorMessage": "发生错误!", + "DefaultErrorMessageDetail": "服务器未发送错误详细信息。", + "DefaultErrorMessage401": "您未通过身份验证!", + "DefaultErrorMessage401Detail": "您需要进行身份认证(登录)后再执行此操作。", + "DefaultErrorMessage403": "您未获得授权!", + "DefaultErrorMessage403Detail": "不允许执行此操作!", + "DefaultErrorMessage404": "未找到资源!", + "DefaultErrorMessage404Detail": "服务器上找不到所请求的资源!", + "EntityNotFoundErrorMessage": "不存在 id = {1} 的实体 {0}!", + "AbpDbConcurrencyErrorMessage": "您提交的数据已被其他用户/客户更改。请放弃您所做的更改并从头开始尝试。", "Error": "错误", - "UnhandledException": "未处理的异常!", - "401Message": "未授权", - "403Message": "禁止访问", - "404Message": "网页未找到", + "UnhandledException": "未处理异常!", + "401Message": "未经授权", + "403Message": "禁止", + "404Message": "未找到页面", "500Message": "内部服务器错误", - "403MessageDetail": "您没有权限执行此操作", - "404MessageDetail": "抱歉, 这个地址是空的" + "403MessageDetail": "您无权执行此操作!", + "404MessageDetail": "抱歉,这个地址没有任何信息。" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json index be90fcf76e..9f2ed5f49c 100644 --- a/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Features/Volo/Abp/Features/Localization/zh-Hans.json @@ -5,4 +5,4 @@ "Volo.Feature:010002": "必要的功能未启用. 这些功能需要启用: {FeatureNames}", "Volo.Feature:010003": "必要的功能未启用. 需要启用这些功能中的一项:{FeatureNames}" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/zh-Hans.json b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/zh-Hans.json index 17349c4cfe..c8a21333c4 100644 --- a/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.GlobalFeatures/Volo/Abp/GlobalFeatures/Localization/zh-Hans.json @@ -1,6 +1,6 @@ { "culture": "zh-Hans", "texts": { - "Volo.GlobalFeature:010001": "'{ServiceName}'服务需要启用'{GlobalFeatureName}'功能." + "Volo.GlobalFeature:010001": "'{ServiceName}' 服务需要启用 '{GlobalFeatureName}'。" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/Localization/zh-Hans.json b/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/Localization/zh-Hans.json index 09b7283b83..3e391272b6 100644 --- a/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Ldap.Abstractions/Volo/Abp/Ldap/Localization/zh-Hans.json @@ -16,4 +16,4 @@ "DisplayName:Abp.Ldap.Password": "密码", "Description:Abp.Ldap.Password": "密码" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json index 7167aac9fd..aa1867955a 100644 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/Resources/AbpLocalization/zh-Hans.json @@ -2,6 +2,6 @@ "culture": "zh-Hans", "texts": { "DisplayName:Abp.Localization.DefaultLanguage": "默认语言", - "Description:Abp.Localization.DefaultLanguage": "应用程序的默认语言." + "Description:Abp.Localization.DefaultLanguage": "应用程序的默认语言。" } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/Localization/zh-Hans.json b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/Localization/zh-Hans.json index b093513c77..7ba586be3e 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/Localization/zh-Hans.json @@ -1,9 +1,9 @@ { "culture": "zh-Hans", "texts": { - "TenantNotFoundMessage": "找不到租户!", - "TenantNotFoundDetails": "无法找到ID或名称为{0}的租户", - "TenantNotActiveMessage": "租户未启用!", - "TenantNotActiveDetails": "ID或名称为{0}的租户未启用" + "TenantNotFoundMessage": "未找到租户!", + "TenantNotFoundDetails": "没有租户的 ID 或名称为:{0}的租户。", + "TenantNotActiveMessage": "租户未启用!", + "TenantNotActiveDetails": "租户未启用,租户 ID 或名称为:{0}。" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/zh-Hans.json b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/zh-Hans.json index 41315bbfb0..d3edb78166 100644 --- a/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Timing/Volo/Abp/Timing/Localization/zh-Hans.json @@ -2,6 +2,6 @@ "culture": "zh-Hans", "texts": { "DisplayName:Abp.Timing.Timezone": "时区", - "Description:Abp.Timing.Timezone": "应用程序的时区" + "Description:Abp.Timing.Timezone": "应用时区" } -} +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json index 262b2e08fa..e67e32f8bb 100644 --- a/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json +++ b/framework/src/Volo.Abp.Validation/Volo/Abp/Validation/Localization/zh-Hans.json @@ -36,4 +36,4 @@ "ThisFieldIsNotAValidFullyQualifiedHttpHttpsOrFtpUrl": "字段{0}不是有效的完全限定的http,https或ftp URL.", "ThisFieldIsInvalid.": "该字段无效." } -} +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs b/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs index b6a0195e27..7c9504a586 100644 --- a/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs +++ b/framework/test/Volo.Abp.Authorization.Tests/Microsoft/AspNetCore/Authorization/AbpAuthorizationServiceExtensions_Tests.cs @@ -22,27 +22,27 @@ public class AbpAuthorizationServiceExtensions_Tests : AuthorizationTestBase { var exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGranted); var errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予."); + errorInfo.Message.ShouldBe("授权失败!提供的策略尚未授予。"); exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedWithPolicyName) .WithData("PolicyName", "my_policy_name"); errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("授权失败! 提供的策略尚未授予: my_policy_name"); + errorInfo.Message.ShouldBe("授权失败!提供的策略尚未授予: my_policy_name"); exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenPolicyHasNotGrantedForGivenResource) .WithData("ResourceName", "my_resource_name"); errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("授权失败! 提供的策略未授予提供的资源: my_resource_name"); + errorInfo.Message.ShouldBe("授权失败!提供的策略未授予提供的资源:my_resource_name"); exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementHasNotGrantedForGivenResource) .WithData("ResourceName", "my_resource_name"); errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name"); + errorInfo.Message.ShouldBe("授权失败!提供的要求未授予提供的资源:my_resource_name"); exception = new AbpAuthorizationException(code: AbpAuthorizationErrorCodes.GivenRequirementsHasNotGrantedForGivenResource) .WithData("ResourceName", "my_resource_name"); errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("授权失败! 提供的要求未授予提供的资源: my_resource_name"); + errorInfo.Message.ShouldBe("授权失败!提供的要求未授予提供的资源:my_resource_name"); } } } diff --git a/framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/AbpGlobalFeatureNotEnableException_Localization_Test.cs b/framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/AbpGlobalFeatureNotEnableException_Localization_Test.cs index 5917bde11d..bc45ada9ad 100644 --- a/framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/AbpGlobalFeatureNotEnableException_Localization_Test.cs +++ b/framework/test/Volo.Abp.GlobalFeatures.Tests/Volo/Abp/GlobalFeatures/AbpGlobalFeatureNotEnableException_Localization_Test.cs @@ -23,7 +23,7 @@ public class AbpGlobalFeatureNotEnableException_Localization_Test : GlobalFeatur .WithData("ServiceName", "MyService") .WithData("GlobalFeatureName", "TestFeature"); ; var errorInfo = _exceptionToErrorInfoConverter.Convert(exception); - errorInfo.Message.ShouldBe("'MyService'服务需要启用'TestFeature'功能."); + errorInfo.Message.ShouldBe("'MyService' 服务需要启用 'TestFeature'。"); } } } diff --git a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json index 635971e7db..e6af1b3b7e 100644 --- a/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json +++ b/modules/account/src/Volo.Abp.Account.Application.Contracts/Volo/Abp/Account/Localization/Resources/zh-Hans.json @@ -2,72 +2,72 @@ "culture": "zh-Hans", "texts": { "Menu:Account": "账户", - "UserName": "用户名称", - "EmailAddress": "邮箱地址", - "UserNameOrEmailAddress": "用户名称或邮箱地址", + "UserName": "用户名", + "EmailAddress": "电子邮件地址", + "UserNameOrEmailAddress": "用户名或电子邮件地址", "Password": "密码", "RememberMe": "记住我", - "UseAnotherServiceToLogin": "使用另一个服务登录", - "UserLockedOutMessage": "登录失败,用户账户已被锁定.请稍后再试.", - "InvalidUserNameOrPassword": "用户名或密码错误!", - "LoginIsNotAllowed": "无法登录!你的账号未激活或者需要验证邮箱地址/手机号.", - "SelfRegistrationDisabledMessage": "应用程序未开放注册,请联系管理员添加新用户.", - "LocalLoginDisabledMessage": "应用程序未开放本地账户登录.", + "UseAnotherServiceToLogin": "使用其他服务登录", + "UserLockedOutMessage": "由于尝试登录无效,用户账户已被锁定。请稍候再试。", + "InvalidUserNameOrPassword": "用户名或密码无效!", + "LoginIsNotAllowed": "您不能登录!您的帐户未激活或需要确认您的电子邮件/电话号码。", + "SelfRegistrationDisabledMessage": "应用程序未开放注册。请联系应用程序管理员注册新用户。", + "LocalLoginDisabledMessage": "应用程序禁用本地登录。", "Login": "登录", "Cancel": "取消", "Register": "注册", - "AreYouANewUser": "你是新用户吗?", - "AlreadyRegistered": "已经注册过了?", + "AreYouANewUser": "您是新用户吗?", + "AlreadyRegistered": "已经注册?", "InvalidLoginRequest": "登录请求无效", - "ThereAreNoLoginSchemesConfiguredForThisClient": "没有为此客户端配置登录方案.", - "LogInUsingYourProviderAccount": "使用你的{0}帐户登录", + "ThereAreNoLoginSchemesConfiguredForThisClient": "该客户端未配置登录方案。", + "LogInUsingYourProviderAccount": "使用您的 {0} 账户登录", "DisplayName:CurrentPassword": "当前密码", "DisplayName:NewPassword": "新密码", "DisplayName:NewPasswordConfirm": "确认新密码", - "PasswordChangedMessage": "你的密码已修改成功.", + "PasswordChangedMessage": "您的密码已成功更改。", "DisplayName:UserName": "用户名", "DisplayName:Email": "电子邮件", - "DisplayName:Name": "名字", - "DisplayName:Surname": "姓", + "DisplayName:Name": "名称", + "DisplayName:Surname": "姓氏", "DisplayName:Password": "密码", "DisplayName:EmailAddress": "电子邮件地址", - "DisplayName:PhoneNumber": "手机号码", + "DisplayName:PhoneNumber": "电话号码", "PersonalSettings": "个人设置", - "PersonalSettingsSaved": "个人设置已保存", + "PersonalSettingsSaved": "保存个人设置", "PersonalSettingsChangedConfirmationModalTitle": "个人信息已更改", - "PersonalSettingsChangedConfirmationModalDescription": "重新登录以应用这些更改,您要退出登录吗?", - "PasswordChanged": "修改密码", - "NewPasswordConfirmFailed": "请确认新密码", - "NewPasswordSameAsOld": "新密码不能与旧密码相同", + "PersonalSettingsChangedConfirmationModalDescription": "如果要应用这些更改,您必须先登录。要退出吗?", + "PasswordChanged": "密码已更改", + "NewPasswordConfirmFailed": "请确认新密码。", + "NewPasswordSameAsOld": "新密码必须与旧密码不同。", "Manage": "管理", "MyAccount": "我的账户", - "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "启用自行注册", - "Description:Abp.Account.IsSelfRegistrationEnabled": "是否允许用户自行注册帐户.", - "DisplayName:Abp.Account.EnableLocalLogin": "使用本地帐户进行身份验证", - "Description:Abp.Account.EnableLocalLogin": "服务器是否将允许用户使用本地帐户进行身份验证。", + "DisplayName:Abp.Account.IsSelfRegistrationEnabled": "是否启用了自行注册", + "Description:Abp.Account.IsSelfRegistrationEnabled": "用户是否可以自己注册账户。", + "DisplayName:Abp.Account.EnableLocalLogin": "使用本地账户进行身份验证", + "Description:Abp.Account.EnableLocalLogin": "表示服务器是否允许用户使用本地账户进行身份验证。", "LoggedOutTitle": "注销", - "LoggedOutText": "你已成功注销并将马上返回.", - "ReturnToText": "单击此处返回到应用程序", - "OrLoginWith": "或登录:", - "ForgotPassword": "忘记密码?", - "SendPasswordResetLink_Information": "密码重置链接将发送到您的电子邮件以重置密码. 如果您在几分钟内没有收到电子邮件,请重试.", - "PasswordResetMailSentMessage": "帐户恢复电子邮件已发送到您的电子邮件地址. 如果您在15分钟内未在收件箱中看到此电子邮件,请检查垃圾邮件,并标记为非垃圾邮件.", - "ResetPassword": "重设密码", + "LoggedOutText": "您已注销,很快将重新定向。", + "ReturnToText": "单击此处返回应用", + "OrLoginWith": "或使用以下方式登录", + "ForgotPassword": "忘记密码?", + "SendPasswordResetLink_Information": "您的电子邮件中将收到重置密码的链接。如果您在几分钟内没有收到电子邮件,请重试。", + "PasswordResetMailSentMessage": "帐户恢复电子邮件已发送到您的电子邮箱。如果您在 15 分钟内未在收件箱中看到此电子邮件,请在垃圾邮件文件夹中查找。如果在那里找到,请将其标记为 \"非垃圾邮件\"。", + "ResetPassword": "重置密码", "ConfirmPassword": "确认密码", - "ResetPassword_Information": "请输入您的新密码.", - "YourPasswordIsSuccessfullyReset": "您的密码已经被重置成功.", + "ResetPassword_Information": "请输入您的新密码。", + "YourPasswordIsSuccessfullyReset": "您的密码重置成功。", "GoToTheApplication": "转到应用程序", "BackToLogin": "返回登录", "ProfileTab:Password": "更改密码", "ProfileTab:PersonalInfo": "个人信息", - "ReturnToApplication": "返回到应用程序", - "Volo.Account:InvalidEmailAddress": "找不到给定的电子邮件地址:{0}", - "PasswordReset": "重设密码", - "PasswordResetInfoInEmail": "我们收到了帐户恢复请求!如果你发起了此请求,请单击以下链接以重置密码.", - "ResetMyPassword": "重置我的密码", - "AccessDenied": "拒绝访问!", - "AccessDeniedMessage": "你无权访问此资源.", - "OrRegisterWith": "或注册:", - "RegisterUsingYourProviderAccount": "使用你的{0}帐户注册" + "ReturnToApplication": "返回应用", + "Volo.Account:InvalidEmailAddress": "无法找到给定的电子邮件地址:{0}", + "PasswordReset": "密码重置", + "PasswordResetInfoInEmail": "我们收到了账户恢复请求!如果您发起了该请求,请单击以下链接重置密码。", + "ResetMyPassword": "重置密码", + "AccessDenied": "拒绝访问!", + "AccessDeniedMessage": "您无法访问此资源。", + "OrRegisterWith": "或注册", + "RegisterUsingYourProviderAccount": "使用您的 {0} 账户注册" } } \ No newline at end of file diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs index f229253c4a..ebd556f8e2 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/AccountPageModel.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; using Microsoft.Extensions.Options; using Volo.Abp.Account.Localization; @@ -55,22 +54,4 @@ public abstract class AccountPageModel : AbpPageModel return exception.Message; } - - protected virtual async Task GetUserNameFromEmail(string email) - { - var userName = email.Split('@')[0]; - var existUser = await UserManager.FindByNameAsync(userName); - while (existUser != null) - { - var randomUserName = userName + RandomHelper.GetRandom(1000, 9999); - existUser = await UserManager.FindByNameAsync(randomUserName); - if (existUser == null) - { - userName = randomUserName; - break; - } - } - - return userName; - } } diff --git a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs index 9e0a2c191b..c481715a16 100644 --- a/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs +++ b/modules/account/src/Volo.Abp.Account.Web/Pages/Account/Register.cshtml.cs @@ -102,7 +102,7 @@ public class RegisterModel : AccountPageModel return; } - var userName = await GetUserNameFromEmail(emailClaim.Value); + var userName = await UserManager.GetUserNameFromEmailAsync(emailClaim.Value); Input = new PostInput { UserName = userName, EmailAddress = emailClaim.Value }; } } @@ -128,7 +128,7 @@ public class RegisterModel : AccountPageModel } if (Input.UserName.IsNullOrWhiteSpace()) { - Input.UserName = await GetUserNameFromEmail(Input.EmailAddress); + Input.UserName = await UserManager.GetUserNameFromEmailAsync(Input.EmailAddress); } await RegisterExternalUserAsync(externalLoginInfo, Input.UserName, Input.EmailAddress); } diff --git a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json index 1c782932a4..23ab2cf949 100644 --- a/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json +++ b/modules/audit-logging/src/Volo.Abp.AuditLogging.Domain.Shared/Volo/Abp/AuditLogging/Localization/zh-Hans.json @@ -5,45 +5,45 @@ "Permission:AuditLogs": "审计日志", "Menu:AuditLogging": "审计日志", "AuditLogs": "审计日志", - "HttpStatus": "Http状态", - "HttpMethod": "Http方法", - "HttpMethodFilter": "Http方法过滤", - "HttpRequest": "Http请求", + "HttpStatus": "HTTP 状态", + "HttpMethod": "HTTP 方法", + "HttpMethodFilter": "HTTP 方法过滤器", + "HttpRequest": "HTTP 请求", "User": "用户", - "UserNameFilter": "用户过滤", - "HasException": "存在异常", - "IpAddress": "IP地址", + "UserNameFilter": "用户过滤器", + "HasException": "有例外情况", + "IpAddress": "IP 地址", "Time": "时间", "Date": "日期", "Duration": "持续时间", - "Detail": "详情", + "Detail": "详细信息", "Overall": "总体", "Actions": "操作", - "ClientIpAddress": "客户端IP地址", - "ClientName": "客户端名称", + "ClientIpAddress": "客户端 IP 地址", + "ClientName": "客户名称", "BrowserInfo": "浏览器信息", - "Url": "Url", + "Url": "网址", "UserName": "用户名", "TenantImpersonator": "租户模拟", "UserImpersonator": "用户模拟", - "UrlFilter": "Url过滤", + "UrlFilter": "URL 过滤器", "Exceptions": "异常", "Comments": "评论", - "HttpStatusCode": "Http状态码", - "HttpStatusCodeFilter": "Http状态码过滤", - "ServiceName": "服务名称", - "MethodName": "方法名称", - "CorrelationId": "关联Id", + "HttpStatusCode": "HTTP 状态代码", + "HttpStatusCodeFilter": "HTTP 状态代码过滤器", + "ServiceName": "服务", + "MethodName": "方法", + "CorrelationId": "相关标识", "ApplicationName": "应用名称", "ExecutionDuration": "持续时间", "ExtraProperties": "额外属性", "MaxDuration": "最大持续时间", - "MinDuration": "最小持续时间", - "MinMaxDuration": "持续时间(最小-最大)", - "{0}Milliseconds": "{0} 毫秒", + "MinDuration": "分钟持续时间", + "MinMaxDuration": "持续时间(最短 - 最长)", + "{0}Milliseconds": "{0}毫秒", "ExecutionTime": "时间", "Parameters": "参数", - "EntityTypeFullName": "实体类型全名", + "EntityTypeFullName": "实体类型 全名", "Entity": "实体", "ChangeType": "更改类型", "ChangeTime": "时间", @@ -51,33 +51,33 @@ "OriginalValue": "原始值", "PropertyName": "属性名称", "PropertyTypeFullName": "属性类型全名", - "Yes": "Yes", - "No": "No", + "Yes": "是", + "No": "没有", "Changes": "变化", - "AverageExecutionDurationInLogsPerDay": "平均处理时间(每天日志)", - "AverageExecutionDurationInMilliseconds": "平均处理时间(毫秒)", + "AverageExecutionDurationInLogsPerDay": "平均执行时间", + "AverageExecutionDurationInMilliseconds": "平均执行时间(毫秒)", "ErrorRateInLogs": "日志中的错误率", "Success": "成功", "Fault": "故障", - "NoChanges": "没有变化", - "EntityChanges": "实体变更", - "EntityId": "实体Id", + "NoChanges": "无变化", + "EntityChanges": "实体变化", + "EntityId": "实体 ID", "EntityChangeStartTime": "最小更改日期", "EntityChangeEndTime": "最大更改日期", "EntityHistory": "实体历史", "DaysAgoTitle": "{0} {1}.", - "DaysAgoWithUserTitle": "{0} {1} 通过 {2}.", + "DaysAgoWithUserTitle": "{0} {1} by {2}。", "Created": "创建", - "Updated": "更新", + "Updated": "已更新", "Deleted": "已删除", "ChangeHistory": "变更记录", - "FullChangeHistory": "完整的变更记录", + "FullChangeHistory": "全部变更记录", "ChangeDetails": "变更详情", - "DurationMs": "持续时间(毫秒)", - "StartDate": "开始时间", - "EndDate": "结束时间", + "DurationMs": "持续时间(毫秒)", + "StartDate": "开始日期", + "EndDate": "结束日期", "Feature:AuditLoggingGroup": "审计日志", - "Feature:AuditLoggingEnable": "启用审计日志页面", - "Feature:AuditLoggingEnableDescription": "在应用程序中启用审计日志页面." + "Feature:AuditLoggingEnable": "启用审计记录页面", + "Feature:AuditLoggingEnableDescription": "在应用程序中启用审计日志页面。" } } \ No newline at end of file diff --git a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/zh-Hans.json b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/zh-Hans.json index 6c680d0b66..295eeb2f05 100644 --- a/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/zh-Hans.json +++ b/modules/blob-storing-database/src/Volo.Abp.BlobStoring.Database.Domain.Shared/Volo/Abp/BlobStoring/Database/Localization/zh-Hans.json @@ -1,6 +1,6 @@ { "culture": "zh-Hans", "texts": { - "MyAccount": "我的账户" + "MyAccount": "我的账户" } } \ No newline at end of file diff --git a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/zh-Hans.json b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/zh-Hans.json index e472f6509b..a28905eff8 100644 --- a/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/zh-Hans.json +++ b/modules/blogging/src/Volo.Blogging.Domain.Shared/Volo/Blogging/Localization/Resources/zh-Hans.json @@ -43,9 +43,9 @@ "Posts": "帖子", "Edit": "编辑", "BLOG": "博客", - "CommentDeletionWarningMessage": "评论将被删除.", + "CommentDeletionWarningMessage": "评论将被删除。", "PostDeletionWarningMessage": "帖子将被删除", - "BlogDeletionWarningMessage": "博客将被删除.", + "BlogDeletionWarningMessage": "博客将被删除。", "AreYouSure": "你确定吗?", "CommentWithCount": "{0}个评论", "Comment": "评论", @@ -69,12 +69,12 @@ "PostDescriptionHint": "*将在文章链接预览中呈现,支持HTML", "ReadMore": "继续阅读", "MemberNotPublishedPostYet": "还没有帖子!", - "UpdateUserWebSiteInfo": "示例:https://johndoe.com", - "UpdateUserTwitterInfo": "示例:约翰多", - "UpdateUserGithubInfo": "示例:约翰多", - "UpdateUserLinkedinInfo": "示例:https://www.linkedin.com/...", - "UpdateUserCompanyInfo": "示例:沃洛软件", - "UpdateUserJobTitleInfo": "示例:软件开发人员", + "UpdateUserWebSiteInfo": "例如:https://johndoe.com", + "UpdateUserTwitterInfo": "示例:johndoe", + "UpdateUserGithubInfo": "示例:johndoe", + "UpdateUserLinkedinInfo": "例如: https://www.linkedin.com/..。", + "UpdateUserCompanyInfo": "示例:Volosoft", + "UpdateUserJobTitleInfo": "例如:软件开发人员软件开发人员", "WebSite": "网站", "UserName": "用户名", "FullURL": "完整网址", diff --git a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json index bc3aa227f2..76c8f2b2a1 100644 --- a/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json +++ b/modules/cms-kit/src/Volo.CmsKit.Domain.Shared/Volo/CmsKit/Localization/Resources/zh-Hans.json @@ -3,91 +3,91 @@ "texts": { "AddSubMenuItem": "添加子菜单项", "AreYouSure": "你确定吗?", - "BlogDeletionConfirmationMessage": "博客 '{0}' 将被删除. 你确定吗?", - "BlogFeatureNotAvailable": "这个功能目前不可用. 使用 `GlobalFeatureManager` 来启用它.", + "BlogDeletionConfirmationMessage": "博客'{0}'将被删除。你确定吗?", + "BlogFeatureNotAvailable": "此功能现在不可用。请使用 \"GlobalFeatureManager \"启用以使用该功能。", "BlogId": "博客", - "BlogPostDeletionConfirmationMessage": "博客帖子 '{0}' 将被删除. 你确定吗?", - "BlogPosts": "博客帖子", + "BlogPostDeletionConfirmationMessage": "博文\"{0}\"将被删除。你确定吗?", + "BlogPosts": "博客文章", "Blogs": "博客", - "ChoosePreference": "选择首选项...", + "ChoosePreference": "选择偏好...", "Cms": "CMS", "CmsKit.Comments": "评论", "CmsKit.Ratings": "评分", "CmsKit.Reactions": "反应", "CmsKit.Tags": "标签", - "CmsKit:0002": "内容已经存在!", - "CmsKit:0003": "实体 {0} 不可标记.", - "CmsKit:Blog:0001": "给定的slug ({Slug}) 已经存在!", - "CmsKit:BlogPost:0001": "给定的slug已经存在!", - "CmsKit:Comments:0001": "实体不可 {0} 不可评论.", - "CmsKit:Media:0001": "'{Name}' 不是有效的媒体名称.", - "CmsKit:Media:0002": "实体不可以含有媒体", - "CmsKit:Page:0001": "给定的url ({0}) 已经存在.", - "CmsKit:Rating:0001": "无法对实体 {EntityType} 进行评级。", + "CmsKit:0002": "内容已经存在!", + "CmsKit:0003": "实体 {0} 不可标签。", + "CmsKit:Blog:0001": "给定的slug ({Slug}) 已经存在!", + "CmsKit:BlogPost:0001": "给定的slug已经存在!", + "CmsKit:Comments:0001": "实体 {EntityType} 不可注释。", + "CmsKit:Media:0001": "{Name}'不是有效的媒体名称。", + "CmsKit:Media:0002": "实体不能拥有媒体。", + "CmsKit:Page:0001": "给定的网址 ({Slug}) 已经存在。请尝试使用其他网址。", + "CmsKit:Rating:0001": "无法对实体 {EntityType} 进行评分。", "CmsKit:Reaction:0001": "实体 {EntityType} 不能有反应。", - "CmsKit:Tag:0002": "实体不可标记!", - "CommentAuthorizationExceptionMessage": "这些评论不允许公开显示", - "CommentDeletionConfirmationMessage": "此评论和所有回复将被删除!", + "CmsKit:Tag:0002": "实体不可标签!", + "CommentAuthorizationExceptionMessage": "这些评论不允许公开展示。", + "CommentDeletionConfirmationMessage": "此评论和所有回复将被删除!", "Comments": "评论", "Content": "内容", - "ContentDeletionConfirmationMessage": "你确定要删除这个内容吗?", - "Contents": "内容", + "ContentDeletionConfirmationMessage": "您确定要删除这些内容吗?", + "Contents": "目录", "CoverImage": "封面图片", - "CreateBlogPostPage": "新博客帖子", + "CreateBlogPostPage": "新博客文章", "CreationTime": "创建时间", "Delete": "删除", - "Detail": "详情", - "Details": "详情", + "Detail": "详细信息", + "Details": "详细信息", "DisplayName": "显示名称", - "DoYouPreferAdditionalEmails": "你是否更喜欢额外的邮件?", - "Edit": "修改", - "EndDate": "结束时间", - "EntityId": "实体Id", + "DoYouPreferAdditionalEmails": "您希望收到更多电子邮件吗?", + "Edit": "编辑", + "EndDate": "结束日期", + "EntityId": "实体 ID", "EntityType": "实体类型", - "ExportCSV": "导出CSV", + "ExportCSV": "导出 CSV", "Features": "功能", - "GenericDeletionConfirmationMessage": "你确定删除 '{0}' 吗?", - "IsActive": "积极的", + "GenericDeletionConfirmationMessage": "您确定要删除\"{0}\"吗?", + "IsActive": "活跃", "LastModification": "最后一次修改", "LastModificationTime": "最后修改时间", - "LoginToAddComment": "登录添加评论", - "LoginToRate": "登录进行评分", - "LoginToReact": "登录以作出反应", - "LoginToReply": "登录进行回复", + "LoginToAddComment": "登录后添加评论", + "LoginToRate": "登录后评分", + "LoginToReact": "登录后作出反应", + "LoginToReply": "登录后回复", "MainMenu": "主菜单", "MakeMainMenu": "制作主菜单", "Menu:CMS": "CMS", "Menus": "菜单", - "MenuDeletionConfirmationMessage": "菜单“{0}”将被删除。你确定吗?", + "MenuDeletionConfirmationMessage": "菜单\"{0}\"将被删除。你确定吗?", "MenuItemDeletionConfirmationMessage": "确定要删除此菜单项吗?", - "MenuItemMoveConfirmMessage": "确定要将“{0}”移到“{1}”下吗?", - "MenuItems": "菜单项", - "Message": "消息", - "MessageDeletionConfirmationMessage": "这条评论将被完全删除", + "MenuItemMoveConfirmMessage": "您确定要将\"{0}\"移到\"{1}\"下面吗?", + "MenuItems": "菜单项目", + "Message": "留言", + "MessageDeletionConfirmationMessage": "此评论将被彻底删除。", "NewBlog": "新博客", - "NewBlogPost": "新博文", + "NewBlogPost": "新博客文章", "NewMenu": "新菜单", "NewMenuItem": "新的根菜单项", - "NewPage": "新的一页", + "NewPage": "新页面", "NewTag": "新标签", - "NoMenuItems": "还没有菜单项!", - "OK": "OK", - "PageDeletionConfirmationMessage": "你确定删除这个页面吗?", - "PageId": "页", + "NoMenuItems": "目前还没有菜单项!", + "OK": "好的", + "PageDeletionConfirmationMessage": "您确定要删除此页面吗?", + "PageId": "页次", "Pages": "页面", - "PageSlugInformation": "Slug用于url. 你的url将是 '/{{slug}}'.", - "BlogSlugInformation": "Slug用于url. 你的url将是 '/{0}/{{slug}}'.", + "PageSlugInformation": "Slug 用于 URL。您的网址将是\"/{{slug}}\"。", + "BlogSlugInformation": "Slug 用于 URL。您的网址将是\"/{0}/{{slug}}\"。", "Permission:BlogManagement": "博客管理", "Permission:BlogManagement.Create": "创建", "Permission:BlogManagement.Delete": "删除", - "Permission:BlogManagement.Features": "删除", + "Permission:BlogManagement.Features": "功能", "Permission:BlogManagement.Update": "更新", - "Permission:BlogPostManagement": "博客帖子管理", + "Permission:BlogPostManagement": "博文管理", "Permission:BlogPostManagement.Create": "创建", "Permission:BlogPostManagement.Delete": "删除", "Permission:BlogPostManagement.Update": "更新", "Permission:BlogPostManagement.Publish": "发布", - "Permission:CmsKit": "Cms工具包", + "Permission:CmsKit": "CmsKit 管理员", "Permission:Comments": "评论管理", "Permission:Comments.Delete": "删除", "Permission:Contents": "内容管理", @@ -97,7 +97,7 @@ "Permission:MediaDescriptorManagement": "媒体管理", "Permission:MediaDescriptorManagement:Create": "创建", "Permission:MediaDescriptorManagement:Delete": "删除", - "Permission:MenuItemManagement": "菜单项管理", + "Permission:MenuItemManagement": "菜单项目管理", "Permission:MenuItemManagement.Create": "创建", "Permission:MenuItemManagement.Delete": "删除", "Permission:MenuItemManagement.Update": "更新", @@ -105,10 +105,10 @@ "Permission:MenuManagement.Create": "创建", "Permission:MenuManagement.Delete": "删除", "Permission:MenuManagement.Update": "更新", - "Permission:Menus": "Menu Management", - "Permission:Menus.Create": "Create", - "Permission:Menus.Delete": "Delete", - "Permission:Menus.Update": "Update", + "Permission:Menus": "菜单管理", + "Permission:Menus.Create": "创建", + "Permission:Menus.Delete": "删除", + "Permission:Menus.Update": "更新", "Permission:PageManagement": "页面管理", "Permission:PageManagement:Create": "创建", "Permission:PageManagement:Delete": "删除", @@ -119,114 +119,114 @@ "Permission:TagManagement.Delete": "删除", "Permission:TagManagement.Update": "更新", "Permission:GlobalResources": "全局资源", - "Permission:CmsKitPublic": "CmsKit公共", - "Permission:Comments.DeleteAll": "删除全部", - "PickYourReaction": "选择你的回应", + "Permission:CmsKitPublic": "CmsKit 公共", + "Permission:Comments.DeleteAll": "全部删除", + "PickYourReaction": "选择你的反应", "Rating": "评分", - "RatingUndoMessage": "您的评分将被撤消", + "RatingUndoMessage": "您的评分将被撤销。", "Reactions": "反应", "Read": "阅读", "RepliesToThisComment": "回复此评论", - "Reply": "回复", - "ReplyTo": "回复", - "SamplePageMessage": "Pro模块的示例页面", + "Reply": "答复", + "ReplyTo": "答复", + "SamplePageMessage": "专业模块的示例页面", "SaveChanges": "保存更改", "Script": "脚本", - "SelectAll": "选择所有", + "SelectAll": "全部选择", "Send": "发送", - "SendMessage": "发送消息", + "SendMessage": "发送信息", "SelectedAuthor": "作者", - "ShortDescription": "简介", + "ShortDescription": "简要说明", "Slug": "Slug", "Source": "源", - "SourceUrl": "源URL", + "SourceUrl": "源网址", "Star": "星", - "StartDate": "开始时间", + "StartDate": "开始日期", "Style": "风格", "Subject": "主题", "SubjectPlaceholder": "请输入主题", "Submit": "提交", "Subscribe": "订阅", - "SuccessfullySaved": "保存成功!", - "TagDeletionConfirmationMessage": "你确定删除 '{0}' 标签吗?", + "SuccessfullySaved": "成功保存!", + "TagDeletionConfirmationMessage": "您确定要删除\"{0}\"标签吗?", "Tags": "标签", "Text": "文本", - "ThankYou": "谢谢你", + "ThankYou": "谢谢", "Title": "标题", "Undo": "撤消", "Update": "更新", - "UpdatePreferenceSuccessMessage": "您的首选项已经保存", - "UpdateYourEmailPreferences": "更新你的邮件首选项", - "UnMakeMainMenu": "取消主菜单", - "UploadFailedMessage": "上传失败", - "UserId": "用户Id", - "Username": "用户名称", - "YourComment": "你的评论", - "YourEmailAddress": "你的邮件地址", - "YourFullName": "你的全称", - "YourMessage": "你的消息", - "YourReply": "你的回复", + "UpdatePreferenceSuccessMessage": "您的首选项已保存。", + "UpdateYourEmailPreferences": "更新您的电子邮件首选项", + "UnMakeMainMenu": "取消制作主菜单", + "UploadFailedMessage": "上传失败。", + "UserId": "用户名", + "Username": "用户名", + "YourComment": "您的意见", + "YourEmailAddress": "您的电子邮件地址", + "YourFullName": "您的全名", + "YourMessage": "您的信息", + "YourReply": "您的回复", "MarkdownSupported": "Markdown 支持。", - "GlobalResources": "全局资源", + "GlobalResources": "全局", "SavedSuccessfully": "保存成功", "CmsKit.BlogPost.Status.0": "草稿", "CmsKit.BlogPost.Status.1": "已发布", "CmsKit.BlogPost.Status.2": "等待审核", - "BlogPostPublishConfirmationMessage": "你确定要发布博客文章“{0}”吗?", + "BlogPostPublishConfirmationMessage": "您确定要发布博文\"{0}\"吗?", "SuccessfullyPublished": "成功发布!", - "Draft": "草稿", + "Draft": "草案", "Publish": "发布", - "BlogPostDraftConfirmationMessage": "你确定要将博客文章“{0}”设置为草稿吗?", - "BlogPostSendToReviewConfirmationMessage": "你确定要将博客文章“{0}”发送给管理员审核发布吗?", + "BlogPostDraftConfirmationMessage": "您确定将博文\"{0}\"设置为草稿吗?", + "BlogPostSendToReviewConfirmationMessage": "您确定要将博文\"{0}\"发送给管理员审核发布吗?", "SaveAsDraft": "保存为草稿", - "SendToReview": "发送到审核", - "SendToReviewToPublish": "发送到审核并发布", - "BlogPostSendToReviewSuccessMessage": "博客文章“{0}”已发送给管理员审核发布。", - "HasBlogPostWaitingForReviewMessage": "你有一篇博客文章等待审核。点击查看。", - "SelectAStatus": "选择一个状态", + "SendToReview": "发送审核", + "SendToReviewToPublish": "送审发布", + "BlogPostSendToReviewSuccessMessage": "博文\"{0}\"已送交管理员审核发布。", + "HasBlogPostWaitingForReviewMessage": "您有一篇博文等待审核。点击列表。", + "SelectAStatus": "选择状态", "Status": "状态", - "CmsKit.BlogPost.ScrollIndex": "博客文章快速导航栏", - "CmsKit.BlogPost.PreventXssFeature": "防止XSS攻击", + "CmsKit.BlogPost.ScrollIndex": "博客文章中的快速导航栏", + "CmsKit.BlogPost.PreventXssFeature": "防止 XSS", "Add": "添加", - "AddWidget": "添加组件", - "PleaseConfigureWidgets": "请配置组件", - "SelectAnAuthor": "选择一个作者", - "InThisDocument": "在此文档", - "GoToTop": "跳至顶部", - "SetAsHomePage": "更改首页状态", - "CompletedSettingAsHomePage": "设为首页", - "IsHomePage": "是否为首页", - "RemovedSettingAsHomePage": "删除首页设置", - "Feature:CmsKitGroup": "Cms Kit", + "AddWidget": "添加小工具", + "PleaseConfigureWidgets": "请配置部件", + "SelectAnAuthor": "选择作者", + "InThisDocument": "在本文档中", + "GoToTop": "返回页首", + "SetAsHomePage": "更改主页状态", + "CompletedSettingAsHomePage": "设置为主页", + "IsHomePage": "是主页", + "RemovedSettingAsHomePage": "删除了主页设置", + "Feature:CmsKitGroup": "内容管理系统套件", "Feature:BlogEnable": "博客文章", - "Feature:BlogEnableDescription": "CMS Kit的博客文章系统,允许在应用程序中动态创建博客和文章。", + "Feature:BlogEnableDescription": "CMS Kit 的博客帖子系统可在应用程序中动态创建博客和帖子。", "Feature:CommentEnable": "评论", - "Feature:CommentEnableDescription": "CMS Kit的评论系统允许对博客文章等实体进行评论。", - "Feature:GlobalResourceEnable": "全局资源", - "Feature:GlobalResourceEnableDescription": "CMS Kit的全局资源功能,允许管理全局样式和脚本。", + "Feature:CommentEnableDescription": "CMS Kit 的评论系统允许对 BlogPost 等实体发表评论。", + "Feature:GlobalResourceEnable": "全局配置", + "Feature:GlobalResourceEnableDescription": "CMS Kit 的全局资源功能允许管理全局样式和脚本。", "Feature:MenuEnable": "菜单", - "Feature:MenuEnableDescription": "CMS Kit的动态菜单系统,允许动态添加/删除应用程序菜单。", + "Feature:MenuEnableDescription": "CMS Kit 的动态菜单系统可动态添加/删除应用程序菜单。", "Feature:PageEnable": "分页", - "Feature:PageEnableDescription": "CMS Kit的页面系统,允许使用特定URL创建静态页面。", + "Feature:PageEnableDescription": "CMS Kit 的页面系统可创建具有特定 URL 的静态页面。", "Feature:RatingEnable": "评分", - "Feature:RatingEnableDescription": "CMS Kit的评分系统允许用户对博客文章等实体进行评分。", + "Feature:RatingEnableDescription": "CMS Kit 的评分系统允许用户对 BlogPost 等实体进行评分。", "Feature:ReactionEnable": "反应", - "Feature:ReactionEnableDescription": "CMS Kit的反应系统允许用户对博客文章、评论等实体发送反应。", + "Feature:ReactionEnableDescription": "CMS Kit 的反应系统允许用户向 BlogPost、Comments 等实体发送反应。", "Feature:TagEnable": "标签", - "Feature:TagEnableDescription": "CMS Kit的标签系统允许对博客文章等实体进行标记。", - "DeleteBlogPostMessage": "是否确认删除博客?", + "Feature:TagEnableDescription": "CMS Kit 的标签系统允许标签 BlogPost 等实体。", + "DeleteBlogPostMessage": "博客将被删除。你确定吗?", "CaptchaCode": "验证码", "CommentTextRequired": "请输入评论", "CaptchaCodeErrorMessage": "验证码错误,请重试", "CaptchaCodeMissingMessage": "请输入验证码!", - "UnAllowedExternalUrlMessage": "您包含了不允许的外部 URL。请在没有外部 URL 的情况下重试。", + "UnAllowedExternalUrlMessage": "您包含了一个不允许的外部 URL。请在不包含外部 URL 的情况下重试。", "URL": "网址", "PopularTags": "热门标签", - "RemoveCoverImageConfirmationMessage": "您确定要删除封面图片吗?", - "RemoveCoverImage": "删除封面图片", - "CssClass": "CSS类", - "TagsHelpText": "标签应以逗号分隔(例如:tag1、tag2、tag3)", - "ThisPartOfContentCouldntBeLoaded": "无法加载此部分内容", - "DuplicateCommentAttemptMessage": "检测到重复的评论帖子尝试。您的评论已经提交。" + "RemoveCoverImageConfirmationMessage": "您确定要移除封面图像吗?", + "RemoveCoverImage": "移除封面图像", + "CssClass": "CSS 类", + "TagsHelpText": "标签应以逗号分隔(例如:标签 1,标签 2,标签 3)", + "ThisPartOfContentCouldntBeLoaded": "这部分内容无法加载。", + "DuplicateCommentAttemptMessage": "检测到重复发表评论。您的评论已经提交。" } } \ No newline at end of file diff --git a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/zh-Hans.json b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/zh-Hans.json index 9925b1a507..eaaafb576c 100644 --- a/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/zh-Hans.json +++ b/modules/docs/app/VoloDocs.Web/Localization/Resources/VoloDocs/Web/zh-Hans.json @@ -2,9 +2,9 @@ "culture": "zh-Hans", "texts": { "DocsTitle": "VoloDocs", - "WelcomeVoloDocs": "欢迎使用VoloDocs!", - "NoProjectWarning": "当前没有定义的项目!", - "CreateYourFirstProject": "点击这里开始你的第一个项目", - "NoProject": "没有项目!" + "WelcomeVoloDocs": "欢迎来到 VoloDocs!", + "NoProjectWarning": "目前还没有确定的项目!", + "CreateYourFirstProject": "单击此处开始您的第一个项目", + "NoProject": "没有项目!" } } \ No newline at end of file diff --git a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json index 8ddbe55ae7..3f30cf0d09 100644 --- a/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json +++ b/modules/docs/src/Volo.Docs.Domain/Volo/Docs/Localization/Domain/zh-Hans.json @@ -2,41 +2,41 @@ "culture": "zh-Hans", "texts": { "Documents": "文档", - "BackToWebsite": "返回主网站", + "BackToWebsite": "返回网站", "Contributors": "贡献者", "ShareOn": "分享到", "Version": "版本", "Edit": "编辑", - "LastEditTime": "上次编辑", + "LastEditTime": "最后编辑", "Delete": "删除", "ClearCache": "清除缓存", - "ClearCacheConfirmationMessage": "你确定清除 \"{0}\" 项目所有的缓存吗", - "ReIndexAllProjects": "重新索引所有的项目", + "ClearCacheConfirmationMessage": "您确定要清除项目\"{0}\"的所有缓存吗?", + "ReIndexAllProjects": "重新索引所有项目", "ReIndexProject": "重新索引项目", - "ReIndexProjectConfirmationMessage": "你确定重新索引 \"{0}\" 项目", - "SuccessfullyReIndexProject": "成功重新索引 \"{0}\" 项目", - "ReIndexAllProjectConfirmationMessage": "你确定重新索引所有的项目", - "SuccessfullyReIndexAllProject": "成功重新索引所有的项目", - "InThisDocument": "在本文中", - "GoToTop": "到顶部", + "ReIndexProjectConfirmationMessage": "您确定要为项目\"{0}\"重新索引吗?", + "SuccessfullyReIndexProject": "成功重新索引:\"{0}\"", + "ReIndexAllProjectConfirmationMessage": "您确定要重新索引所有项目吗?", + "SuccessfullyReIndexAllProject": "成功重新索引了所有项目", + "InThisDocument": "在本文档中", + "GoToTop": "返回页首", "Projects": "项目", - "NoProjectWarning": "还没有项目!", - "DocumentNotFound": "找不到请求的文档!", - "ProjectNotFound": "找不到请求的项目!", - "NavigationDocumentNotFound": "这个版本没有导航文件!", - "DocumentNotFoundInSelectedLanguage": "本文档不适用于所选语言, 将以默认语言显示文档.", - "FilterTopics": "过滤主题", - "FullSearch": "搜索文档", - "Volo.Docs.Domain:010001": "Elastic search未启用.", - "MultipleVersionDocumentInfo": "本文档有多个版本. 选择最适合你的选项", - "New": "新文档", - "Upd": "更新", - "NewExplanation": "在最近两周内创建.", - "UpdatedExplanation": "在最近两周内更新.", - "Volo.Docs.Domain:010002": "简称 {ShortName} 已经存在.", + "NoProjectWarning": "目前还没有任何项目!", + "DocumentNotFound": "哎呀,没有找到所需的文档!", + "ProjectNotFound": "哎呀,没有找到请求的项目!", + "NavigationDocumentNotFound": "该版本没有导航文档!", + "DocumentNotFoundInSelectedLanguage": "未找到所需语言的文档。显示默认语言的文档。", + "FilterTopics": "筛选主题", + "FullSearch": "在文档中搜索", + "Volo.Docs.Domain:010001": "未启用Elastic search。", + "MultipleVersionDocumentInfo": "本文档有多个版本。请选择最适合您的选项。", + "New": "新", + "Upd": "更新文档", + "NewExplanation": "最近两周创建。", + "UpdatedExplanation": "最近两周更新。", + "Volo.Docs.Domain:010002": "简称 {ShortName} 已经存在。", "Preview": "预览", "Search": "搜索", "SearchResults": "搜索结果", - "SearchInTheAllDocuments": "搜索所有文档" + "SearchInTheAllDocuments": "在所有文档中搜索" } } \ No newline at end of file diff --git a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json index dc63ddf34a..6663b0de00 100644 --- a/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json +++ b/modules/feature-management/src/Volo.Abp.FeatureManagement.Domain.Shared/Volo/Abp/FeatureManagement/Localization/Domain/zh-Hans.json @@ -2,16 +2,16 @@ "culture": "zh-Hans", "texts": { "Features": "功能", - "NoFeatureFoundMessage": "没有可用的功能.", - "ManageHostFeatures": "管理Host功能", - "ManageHostFeaturesText": "您可以通过单击以下按钮来管理宿主功能。", + "NoFeatureFoundMessage": "没有任何可用的功能。", + "ManageHostFeatures": "管理主机功能", + "ManageHostFeaturesText": "点击以下按钮即可管理主机端功能。", "Permission:FeatureManagement": "功能管理", - "Permission:FeatureManagement.ManageHostFeatures": "管理Host功能", - "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0}功能的值无效!", + "Permission:FeatureManagement.ManageHostFeatures": "管理主机功能", + "Volo.Abp.FeatureManagement:InvalidFeatureValue": "{0}功能值无效!", "Menu:FeatureManagement": "功能管理", "ResetToDefault": "重置为默认值", "ResetedToDefault": "已重置为默认值", - "AreYouSure": "是否确认?", - "AreYouSureToResetToDefault": "你确定要重置为默认值吗?" + "AreYouSure": "你确定吗?", + "AreYouSureToResetToDefault": "您确定要重置为默认设置吗?" } } \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json index 05c0ab490b..d244c98f5c 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json +++ b/modules/identity/src/Volo.Abp.Identity.Domain.Shared/Volo/Abp/Identity/Localization/zh-Hans.json @@ -16,8 +16,8 @@ "Password": "密码", "PersonalInfo": " 个人信息", "PersonalSettings": "个人设置", - "UserDeletionConfirmationMessage": "用户 '{0}' 将被删除. 你确定吗?", - "RoleDeletionConfirmationMessage": "角色 '{0}' 将被删除. 你确定吗?", + "UserDeletionConfirmationMessage": "用户 '{0}' 将被删除. 你确定吗?", + "RoleDeletionConfirmationMessage": "角色 '{0}' 将被删除. 你确定吗?", "DisplayName:RoleName": "角色名称", "DisplayName:UserName": "用户名称", "DisplayName:Name": "名", @@ -35,49 +35,49 @@ "DisplayName:CurrentPassword": "当前密码", "DisplayName:NewPassword": "新密码", "DisplayName:NewPasswordConfirm": "确认新密码", - "PasswordChangedMessage": "你已成功更改密码.", - "PersonalSettingsSavedMessage": "你的个人设置保存成功.", - "Volo.Abp.Identity:DefaultError": "发生了一个未知错误.", - "Volo.Abp.Identity:ConcurrencyFailure": "乐观并发检查失败. 你正在处理的对象已被其他用户修改. 请放弃你的更改, 然后重试.", - "Volo.Abp.Identity:DuplicateEmail": "邮箱 '{0}' 已存在.", - "Volo.Abp.Identity:DuplicateRoleName": "角色名 '{0}' 已存在.", - "Volo.Abp.Identity:DuplicateUserName": "用户名 '{0}' 已存在.", - "Volo.Abp.Identity:InvalidEmail": "邮箱 '{0}' 无效.", - "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 无效.", - "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "迭代计数必须是正整数.", - "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效.", - "Volo.Abp.Identity:InvalidToken": "token无效.", - "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字.", - "InvalidUserName": "用户名 '{0}' 无效.", - "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在.", - "Volo.Abp.Identity:PasswordMismatch": "密码错误.", - "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9').", - "Volo.Abp.Identity:PasswordRequiresLower": "密码至少包含一位小写字母 ('a'-'z').", - "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密码至少包含一位非字母数字字符.", - "Volo.Abp.Identity:PasswordRequiresUpper": "密码至少包含一位大写字母 ('A'-'Z').", - "Volo.Abp.Identity:PasswordTooShort": "密码至少为{0}个字符.", - "Volo.Abp.Identity:PasswordRequiresUniqueChars": "密码至少包含{0}个唯一字符.", - "Volo.Abp.Identity:RoleNotFound": "角色 {0} 不存在.", - "Volo.Abp.Identity:UserAlreadyHasPassword": "用户已设置密码.", - "Volo.Abp.Identity:UserAlreadyInRole": "用户已具有角色 '{0}'.", - "Volo.Abp.Identity:UserLockedOut": "用户被锁定.", - "Volo.Abp.Identity:UserLockoutNotEnabled": "该用户未启用锁定.", - "Volo.Abp.Identity:UserNameNotFound": "用户 {0} 不存在.", - "Volo.Abp.Identity:UserNotInRole": "用户不具有 '{0}' 角色.", - "Volo.Abp.Identity:PasswordConfirmationFailed": "密码或确认密码不一致.", - "Volo.Abp.Identity:NullSecurityStamp": "用户安全标识不能为空.", - "Volo.Abp.Identity:RecoveryCodeRedemptionFailed": "恢复代码兑换失败.", + "PasswordChangedMessage": "你已成功更改密码。", + "PersonalSettingsSavedMessage": "你的个人设置保存成功。", + "Volo.Abp.Identity:DefaultError": "发生了一个未知错误。", + "Volo.Abp.Identity:ConcurrencyFailure": "乐观并发检查失败. 你正在处理的对象已被其他用户修改. 请放弃你的更改, 然后重试。", + "Volo.Abp.Identity:DuplicateEmail": "邮箱 '{0}' 已存在。", + "Volo.Abp.Identity:DuplicateRoleName": "角色名 '{0}' 已存在。", + "Volo.Abp.Identity:DuplicateUserName": "用户名 '{0}' 已存在。", + "Volo.Abp.Identity:InvalidEmail": "邮箱 '{0}' 无效。", + "Volo.Abp.Identity:InvalidPasswordHasherCompatibilityMode": "提供的 PasswordHasherCompatibilityMode 无效。", + "Volo.Abp.Identity:InvalidPasswordHasherIterationCount": "迭代计数必须是正整数。", + "Volo.Abp.Identity:InvalidRoleName": "角色名 '{0}' 无效。", + "Volo.Abp.Identity:InvalidToken": "token无效。", + "Volo.Abp.Identity:InvalidUserName": "用户名 '{0}' 无效, 只能包含字母或数字。", + "InvalidUserName": "用户名 '{0}' 无效。", + "Volo.Abp.Identity:LoginAlreadyAssociated": "此登录名的用户已存在。", + "Volo.Abp.Identity:PasswordMismatch": "密码错误。", + "Volo.Abp.Identity:PasswordRequiresDigit": "密码至少包含一位数字 ('0'-'9')。", + "Volo.Abp.Identity:PasswordRequiresLower": "密码至少包含一位小写字母 ('a'-'z')。", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密码至少包含一位非字母数字字符。", + "Volo.Abp.Identity:PasswordRequiresUpper": "密码至少包含一位大写字母 ('A'-'Z')。", + "Volo.Abp.Identity:PasswordTooShort": "密码至少为{0}个字符。", + "Volo.Abp.Identity:PasswordRequiresUniqueChars": "密码至少包含{0}个唯一字符。", + "Volo.Abp.Identity:RoleNotFound": "角色 {0} 不存在。", + "Volo.Abp.Identity:UserAlreadyHasPassword": "用户已设置密码。", + "Volo.Abp.Identity:UserAlreadyInRole": "用户已具有角色 '{0}'。", + "Volo.Abp.Identity:UserLockedOut": "用户被锁定。", + "Volo.Abp.Identity:UserLockoutNotEnabled": "该用户未启用锁定。", + "Volo.Abp.Identity:UserNameNotFound": "用户 {0} 不存在。", + "Volo.Abp.Identity:UserNotInRole": "用户不具有 '{0}' 角色。", + "Volo.Abp.Identity:PasswordConfirmationFailed": "密码或确认密码不一致。", + "Volo.Abp.Identity:NullSecurityStamp": "用户安全标识不能为空。", + "Volo.Abp.Identity:RecoveryCodeRedemptionFailed": "恢复代码兑换失败。", "Volo.Abp.Identity:010001": "你无法删除自己的帐户!", "Volo.Abp.Identity:010002": "不能为用户设置超过{MaxUserMembershipCount}个组织单位!", "Volo.Abp.Identity:010003": "无法更改外部登录用户的密码!", - "Volo.Abp.Identity:010004": "已存在名为 {0} 的组织单位. 无法在同一级别创建相同名称的组织单位.", - "Volo.Abp.Identity:010005": "无法重命名静态角色.", - "Volo.Abp.Identity:010006": "无法删除静态角色.", + "Volo.Abp.Identity:010004": "已存在名为 {0} 的组织单位. 无法在同一级别创建相同名称的组织单位。", + "Volo.Abp.Identity:010005": "无法重命名静态角色。", + "Volo.Abp.Identity:010006": "无法删除静态角色。", "Volo.Abp.Identity:010007": "你不能修改你的双因素身份验证设置", - "Volo.Abp.Identity:010008": "不允许修改双因素身份验证设置.", - "Volo.Abp.Identity:010009": "你不能委托给自己.", + "Volo.Abp.Identity:010008": "不允许修改双因素身份验证设置。", + "Volo.Abp.Identity:010009": "你不能委托给自己。", "Identity.OrganizationUnit.MaxUserMembershipCount": "组织单位最大允许的成员资格计数", - "ThisUserIsNotActiveMessage": "该用户不可用.", + "ThisUserIsNotActiveMessage": "该用户不可用。", "Permission:IdentityManagement": "身份标识管理", "Permission:RoleManagement": "角色管理", "Permission:Create": "创建", @@ -102,22 +102,22 @@ "DisplayName:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "要求验证的手机号码", "DisplayName:Abp.Identity.User.IsUserNameUpdateEnabled": "启用用户名更新", "DisplayName:Abp.Identity.User.IsEmailUpdateEnabled": "启用电子邮箱更新", - "Description:Abp.Identity.Password.RequiredLength": "密码的最小长度.", - "Description:Abp.Identity.Password.RequiredUniqueChars": "密码必须包含唯一字符的数量.", - "Description:Abp.Identity.Password.RequireNonAlphanumeric": "密码是否必须包含非字母数字.", - "Description:Abp.Identity.Password.RequireLowercase": "密码是否必须包含小写字母.", - "Description:Abp.Identity.Password.RequireUppercase": "密码是否必须包含大写字母.", - "Description:Abp.Identity.Password.RequireDigit": "密码是否必须包含数字.", - "Description:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "是否强制用户定期更改密码.", - "Description:Abp.Identity.Password.PasswordChangePeriodDays": "用户必须更改密码的周期(天).", - "Description:Abp.Identity.Lockout.AllowedForNewUsers": "允许新用户被锁定.", - "Description:Abp.Identity.Lockout.LockoutDuration": "当锁定发生时用户被的锁定的时间(秒).", - "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "如果启用锁定, 当用户被锁定前失败的访问尝试次数.", - "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登录时是否需要验证的电子邮箱.", + "Description:Abp.Identity.Password.RequiredLength": "密码的最小长度。", + "Description:Abp.Identity.Password.RequiredUniqueChars": "密码必须包含唯一字符的数量。", + "Description:Abp.Identity.Password.RequireNonAlphanumeric": "密码是否必须包含非字母数字。", + "Description:Abp.Identity.Password.RequireLowercase": "密码是否必须包含小写字母。", + "Description:Abp.Identity.Password.RequireUppercase": "密码是否必须包含大写字母。", + "Description:Abp.Identity.Password.RequireDigit": "密码是否必须包含数字。", + "Description:Abp.Identity.Password.ForceUsersToPeriodicallyChangePassword": "是否强制用户定期更改密码。", + "Description:Abp.Identity.Password.PasswordChangePeriodDays": "用户必须更改密码的周期(天)。", + "Description:Abp.Identity.Lockout.AllowedForNewUsers": "允许新用户被锁定。", + "Description:Abp.Identity.Lockout.LockoutDuration": "当锁定发生时用户被的锁定的时间(秒)。", + "Description:Abp.Identity.Lockout.MaxFailedAccessAttempts": "如果启用锁定, 当用户被锁定前失败的访问尝试次数。", + "Description:Abp.Identity.SignIn.RequireConfirmedEmail": "登录时是否需要验证的电子邮箱。", "Description:Abp.Identity.SignIn.EnablePhoneNumberConfirmation": "用户是否可以确认电话号码", - "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登录时是否需要验证的手机号码.", - "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允许用户更新用户名.", - "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱.", + "Description:Abp.Identity.SignIn.RequireConfirmedPhoneNumber": "登录时是否需要验证的手机号码。", + "Description:Abp.Identity.User.IsUserNameUpdateEnabled": "是否允许用户更新用户名。", + "Description:Abp.Identity.User.IsEmailUpdateEnabled": "是否允许用户更新电子邮箱。", "Details": "详情", "CreatedBy": "创建者", "ModifiedBy": "修改者", @@ -126,4 +126,4 @@ "LockoutEndTime": "锁定结束时间", "FailedAccessCount": "访问失败次数" } -} +} \ No newline at end of file diff --git a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs index f8bfe5b603..a8e6a08ead 100644 --- a/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs +++ b/modules/identity/src/Volo.Abp.Identity.Domain/Volo/Abp/Identity/IdentityUserManager.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Numerics; using System.Threading; using System.Threading.Tasks; using JetBrains.Annotations; @@ -82,7 +83,7 @@ public class IdentityUserManager : UserManager, IDomainService return await CreateAsync(user); } - + public async override Task DeleteAsync(IdentityUser user) { user.Claims.Clear(); @@ -397,4 +398,126 @@ public class IdentityUserManager : UserManager, IDomainService await UserRepository.UpdateOrganizationAsync(sourceOrganizationId, targetOrganizationId, CancellationToken); } + + public virtual async Task ValidateUserNameAsync(string userName, Guid? userId = null) + { + if (string.IsNullOrWhiteSpace(userName)) + { + return false; + } + + if (!string.IsNullOrEmpty(Options.User.AllowedUserNameCharacters) && userName.Any(c => !Options.User.AllowedUserNameCharacters.Contains(c))) + { + return false; + } + + var owner = await FindByNameAsync(userName); + if (owner != null && owner.Id != userId) + { + return false; + } + + return true; + } + + public virtual Task GetRandomUserNameAsync(int length) + { + var allowedUserNameCharacters = Options.User.AllowedUserNameCharacters; + if (allowedUserNameCharacters.IsNullOrWhiteSpace()) + { + allowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; + } + + var randomUserName = string.Empty; + var random = new Random(); + while (randomUserName.Length < length) + { + randomUserName += allowedUserNameCharacters[random.Next(0, allowedUserNameCharacters.Length)]; + } + + return Task.FromResult(randomUserName); + } + + public virtual async Task GetUserNameFromEmailAsync(string email) + { + const int maxTryCount = 20; + var tryCount = 0; + + var userName = email.Split('@')[0]; + + if (await ValidateUserNameAsync(userName)) + { + // The username is valid. + return userName; + } + + if (Options.User.AllowedUserNameCharacters.IsNullOrWhiteSpace()) + { + // The AllowedUserNameCharacters is not set. So, we are generating a random username. + tryCount = 0; + do + { + var randomUserName = userName + RandomHelper.GetRandom(1000, 9999); + if ( await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); + } + else if (!userName.All(Options.User.AllowedUserNameCharacters.Contains)) + { + // The username contains not allowed characters. So, we are generating a random username. + do + { + var randomUserName = await GetRandomUserNameAsync(userName.Length); + if ( await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); + } + else if (Options.User.AllowedUserNameCharacters.Where(char.IsDigit).Distinct().Count() >= 4) + { + // The AllowedUserNameCharacters includes 4 numbers. So, we are generating 4 random numbers and appending to the username. + var numbers = Options.User.AllowedUserNameCharacters.Where(char.IsDigit).OrderBy(x => Guid.NewGuid()).Take(4).ToArray(); + var minArray = numbers.OrderBy(x => x).ToArray(); + if (minArray[0] == '0') + { + var secondItem = minArray[1]; + minArray[0] = secondItem; + minArray[1] = '0'; + } + var min = int.Parse(new string(minArray)); + var max = int.Parse(new string(numbers.OrderByDescending(x => x).ToArray())); + tryCount = 0; + do + { + var randomUserName = userName + RandomHelper.GetRandom(min, max); + if ( await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); + } + else + { + tryCount = 0; + do + { + // The AllowedUserNameCharacters does not include numbers. So, we are generating 4 random characters and appending to the username. + var randomUserName = userName + await GetRandomUserNameAsync(4); + if (await ValidateUserNameAsync(randomUserName)) + { + return randomUserName; + } + tryCount++; + } while (tryCount < maxTryCount); + } + + Logger.LogError($"Could not get a valid user name for the given email address: {email}, allowed characters: {Options.User.AllowedUserNameCharacters}, tried {maxTryCount} times."); + throw new AbpIdentityResultException(IdentityResult.Failed(new IdentityErrorDescriber().InvalidUserName(userName))); + } } diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs index ec29d3d29a..da26de3e3d 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/IdentityUserManager_Tests.cs @@ -2,8 +2,10 @@ using System.Collections.Generic; using System.Linq; using System.Security.Claims; +using System.Text.RegularExpressions; using System.Threading.Tasks; using Microsoft.AspNetCore.Identity; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using Microsoft.Extensions.Options; @@ -378,6 +380,88 @@ public class IdentityUserManager_Tests : AbpIdentityDomainTestBase } } + [Fact] + public async Task ValidateUserNameAsync() + { + var result = await _identityUserManager.ValidateUserNameAsync("M_y+User-001@abp.io"); + result.ShouldBeTrue(); + + var user = CreateRandomUser(); + (await _identityUserManager.CreateAsync(user)).CheckErrors(); + + result = await _identityUserManager.ValidateUserNameAsync(user.UserName, user.Id); + result.ShouldBeTrue(); + + result = await _identityUserManager.ValidateUserNameAsync(user.UserName); + result.ShouldBeFalse(); + + result = await _identityUserManager.ValidateUserNameAsync("无效的字符"); + result.ShouldBeFalse(); + } + + [Fact] + public async Task GetRandomUserNameAsync() + { + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+"; + var username = await _identityUserManager.GetRandomUserNameAsync(15); + username.Length.ShouldBe(15); + username.All(c => _identityUserManager.Options.User.AllowedUserNameCharacters.Contains(c)).ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz0123456789"; + username = await _identityUserManager.GetRandomUserNameAsync(15); + username.Length.ShouldBe(15); + username.All(c => _identityUserManager.Options.User.AllowedUserNameCharacters.Contains(c)).ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "0123456789"; + username = await _identityUserManager.GetRandomUserNameAsync(15); + username.Length.ShouldBe(15); + username.All(c => _identityUserManager.Options.User.AllowedUserNameCharacters.Contains(c)).ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = null!; + username = await _identityUserManager.GetRandomUserNameAsync(15); + username.Length.ShouldBe(15); + username.All(c => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._@+".Contains(c)).ShouldBeTrue(); + } + + [Fact] + public async Task GetUserNameFromEmailAsync() + { + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz0123456789"; + var username = await _identityUserManager.GetUserNameFromEmailAsync("Yönetici@abp.io"); + username.Length.ShouldBe("Yönetici".Length); //random username + username.All(c => "abcdefghijklmnopqrstuvwxyz0123456789".Contains(c)).ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz0123456789"; + username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); + username.Length.ShouldBe(9); //admin and random 4 numbers + username.ShouldContain("admin"); + Regex.IsMatch(username, @"\d{4}$").ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "admin01234"; + username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); + username.Length.ShouldBe(9); //admin and random 4 numbers + username.ShouldContain("admin"); + Regex.IsMatch(username, @"[0-4]{3}$").ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyz"; + username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); + username.Length.ShouldBe(9); //admin and random 4 characters + username.ShouldContain("admin"); + Regex.IsMatch(username, @"[a-z]{4}$").ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + username = await _identityUserManager.GetUserNameFromEmailAsync("ADMIN@abp.io"); + username.Length.ShouldBe(9); //admin and random 4 characters + username.ShouldContain("ADMIN"); + Regex.IsMatch(username, @"[A-Z]{4}$").ShouldBeTrue(); + + _identityUserManager.Options.User.AllowedUserNameCharacters = null!; + username = await _identityUserManager.GetUserNameFromEmailAsync("admin@abp.io"); + username.Length.ShouldBe(9); //admin and random 4 numbers + username.ShouldContain("admin"); + Regex.IsMatch(username, @"[0-9]{4}$").ShouldBeTrue(); + } + private async Task CreateRandomDefaultRoleAsync() { await _identityRoleRepository.InsertAsync( diff --git a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/zh-Hans.json b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/zh-Hans.json index f835afb592..abf03808f9 100644 --- a/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/zh-Hans.json +++ b/modules/identity/test/Volo.Abp.Identity.Domain.Tests/Volo/Abp/Identity/LocalizationExtensions/zh-Hans.json @@ -1,7 +1,7 @@ { "culture": "zh-Hans", "texts": { - "Volo.Abp.Identity:PasswordTooShort": "密码长度必须大于{0}字符. ", - "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密码必须至少包含一个非字母数字字符." + "Volo.Abp.Identity:PasswordTooShort": "密码长度必须大于 {0} 字符。", + "Volo.Abp.Identity:PasswordRequiresNonAlphanumeric": "密码必须至少包含一个非字母数字字符。" } } \ No newline at end of file diff --git a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/zh-Hans.json b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/zh-Hans.json index a2d828bab2..afb5824356 100644 --- a/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/zh-Hans.json +++ b/modules/identityserver/src/Volo.Abp.IdentityServer.Domain.Shared/Volo/Abp/IdentityServer/Localization/Resources/zh-Hans.json @@ -6,11 +6,11 @@ "Volo.IdentityServer:DuplicateApiScopeName": "Api Scope已存在: {Name}", "Volo.IdentityServer:DuplicateClientId": "ClientId已经存在: {ClientId}", "UserLockedOut": "登录失败,用户账户已被锁定.请稍后再试.", - "InvalidUserNameOrPassword": "用户名或密码错误!", - "LoginIsNotAllowed": "无法登录!你的账号未激活或者需要验证邮箱地址/手机号.", - "InvalidUsername": "用户名或密码错误!", - "InvalidAuthenticatorCode": "验证码无效!", - "InvalidRecoveryCode": "恢复代码无效!", - "TheTargetUserIsNotLinkedToYou": "目标用户未和你有关联!" + "InvalidUserNameOrPassword": "用户名或密码错误!", + "LoginIsNotAllowed": "无法登录!你的账号未激活或者需要验证邮箱地址/手机号.", + "InvalidUsername": "用户名或密码错误!", + "InvalidAuthenticatorCode": "验证码无效!", + "InvalidRecoveryCode": "恢复代码无效!", + "TheTargetUserIsNotLinkedToYou": "目标用户与您没有关联!" } -} +} \ No newline at end of file diff --git a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json index dc3f86a812..f00a7c9e37 100644 --- a/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json +++ b/modules/openiddict/src/Volo.Abp.OpenIddict.Domain.Shared/Volo/Abp/OpenIddict/Localization/OpenIddict/zh-Hans.json @@ -1,15 +1,15 @@ { "culture": "zh-Hans", "texts": { - "TheOpenIDConnectRequestCannotBeRetrieved": "无法检索 OpenID Connect 请求.", - "TheUserDetailsCannotBbeRetrieved" : "无法检索用户详细信息.", - "TheApplicationDetailsCannotBeFound": "找不到应用详情.", - "DetailsConcerningTheCallingClientApplicationCannotBeFound": "找不到有关调用客户端应用程序的详细信息.", - "TheSpecifiedGrantTypeIsNotImplemented": "未实施指定的授权类型 {0}.", + "TheOpenIDConnectRequestCannotBeRetrieved": "无法检索 OpenID Connect 请求。", + "TheUserDetailsCannotBbeRetrieved": "无法检索用户详细信息。", + "TheApplicationDetailsCannotBeFound": "找不到应用详情。", + "DetailsConcerningTheCallingClientApplicationCannotBeFound": "无法找到有关调用客户端应用程序的详细信息。", + "TheSpecifiedGrantTypeIsNotImplemented": "指定的授权类型 {0} 未实现。", "Authorization": "授权", - "DoYouWantToGrantAccessToYourData": "是否要授予 {0} 访问你的数据的权限?", + "DoYouWantToGrantAccessToYourData": "是否要授予 {0} 访问你的数据的权限?", "ScopesRequested": "要求的Scope", - "Accept": "同意", + "Accept": "接受", "Deny": "拒绝" } -} +} \ No newline at end of file diff --git a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json index 9cd430ef99..afcdb60351 100644 --- a/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json +++ b/modules/permission-management/src/Volo.Abp.PermissionManagement.Domain.Shared/Volo/Abp/PermissionManagement/Localization/Domain/zh-Hans.json @@ -2,10 +2,10 @@ "culture": "zh-Hans", "texts": { "Permissions": "权限", - "OnlyProviderPermissons": "只有这个提供商", + "OnlyProviderPermissons": "只有这个提供者", "All": "所有", "SelectAllInAllTabs": "授予所有权限", "SelectAllInThisTab": "全选", - "SaveWithoutAnyPermissionsWarningMessage": "你确定要保存没有任何权限吗?" + "SaveWithoutAnyPermissionsWarningMessage": "您确定要在没有任何权限的情况下保存吗?" } } \ No newline at end of file diff --git a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json index 5c8539f440..f024f9f775 100644 --- a/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json +++ b/modules/setting-management/src/Volo.Abp.SettingManagement.Domain.Shared/Volo/Abp/SettingManagement/Localization/Resources/AbpSettingManagement/zh-Hans.json @@ -19,7 +19,7 @@ "Menu:Emailing": "邮件", "Menu:TimeZone": "时区", "DisplayName:Timezone": "时区", - "TimezoneHelpText": "此设置用于应用程序范围或基于租户.", + "TimezoneHelpText": "此设置用于应用程序范围或基于租户。", "SmtpHost": "主机", "SmtpPort": "端口", "SmtpUserName": "用户名", @@ -31,8 +31,8 @@ "DefaultFromDisplayName": "默认显示名称", "Feature:SettingManagementGroup": "设置管理", "Feature:SettingManagementEnable": "启用设置管理", - "Feature:SettingManagementEnableDescription": "在应用程序中启用设置管理系统.", - "Feature:AllowChangingEmailSettings": "允许更改邮件设置.", - "Feature:AllowChangingEmailSettingsDescription": "允许更改邮件设置." + "Feature:SettingManagementEnableDescription": "在应用程序中启用设置管理系统。", + "Feature:AllowChangingEmailSettings": "允许更改邮件设置。", + "Feature:AllowChangingEmailSettingsDescription": "允许更改邮件设置。" } -} +} \ No newline at end of file diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json index 0367489a5a..8cff1a09b7 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain.Shared/Volo/Abp/TenantManagement/Localization/Resources/zh-Hans.json @@ -1,13 +1,13 @@ { "culture": "zh-Hans", "texts": { - "Volo.Abp.TenantManagement:DuplicateTenantName": "租户名称已存在: {Name}", + "Volo.Abp.TenantManagement:DuplicateTenantName": "租户名称已存在:{Name}", "Menu:TenantManagement": "租户管理", "Tenants": "租户", "NewTenant": "新租户", "TenantName": "租户名称", "DisplayName:TenantName": "租户名称", - "TenantDeletionConfirmationMessage": "租户 '{0}' 将被删除. 你确定吗?", + "TenantDeletionConfirmationMessage": "租户'{0}'将被删除。您确认吗?", "ConnectionStrings": "连接字符串", "DisplayName:DefaultConnectionString": "默认连接字符串", "DisplayName:UseSharedDatabase": "使用共享数据库", diff --git a/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/zh-Hans.json b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/zh-Hans.json index f45b24c0ee..46e5e4b811 100644 --- a/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/zh-Hans.json +++ b/modules/virtual-file-explorer/src/Volo.Abp.VirtualFileExplorer.Web/Localization/Resources/zh-Hans.json @@ -1,14 +1,14 @@ { "culture": "zh-Hans", "texts": { - "VirtualFileExplorer" : "虚拟文件浏览器", - "VirtualFileType" : "虚拟文件类型", - "Menu:VirtualFileExplorer" : "虚拟文件浏览器", - "LastUpdateTime" : "最后更新时间", - "VirtualFileName" : "虚拟文件名称", - "FileContent" : "文件内容", - "Size" : "文件大小", - "BackToRoot" : "回到根目录", - "EmptyFileInfoList" : "这里没有任何虚拟文件" + "VirtualFileExplorer": "虚拟文件资源管理器", + "VirtualFileType": "虚拟文件类型", + "Menu:VirtualFileExplorer": "虚拟文件资源管理器", + "LastUpdateTime": "最后更新时间", + "VirtualFileName": "虚拟文件名", + "FileContent": "文件内容", + "Size": "文件大小", + "BackToRoot": "返回根目录", + "EmptyFileInfoList": "没有虚拟文件" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server.Mongo/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.Server/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Shared/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Shared/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Shared/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Blazor.WebAssembly/Shared/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host.Mongo/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Host/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc.Mongo/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Localization/MyProjectName/zh-Hans.json b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Localization/MyProjectName/zh-Hans.json index 6a66abeb9c..a43366df48 100644 --- a/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Localization/MyProjectName/zh-Hans.json +++ b/templates/app-nolayers/aspnet-core/MyCompanyName.MyProjectName.Mvc/Localization/MyProjectName/zh-Hans.json @@ -2,7 +2,7 @@ "culture": "zh-Hans", "texts": { "Welcome_Title": "欢迎", - "Welcome_Text": "这是ABP框架的极简单层应用程序启动模板.", + "Welcome_Text": "这是 ABP 框架的极简单层应用程序启动模板。", "Menu:Home": "首页" } -} +} \ No newline at end of file diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json index 23790bde50..65828f39b2 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json @@ -1,8 +1,8 @@ { - "culture": "zh-Hans", - "texts": { - "Menu:Home": "首页", - "Welcome": "欢迎", - "LongWelcomeMessage": "欢迎来到该应用程序. 这是一个基于ABP框架的启动项目. 有关更多信息, 请访问 abp.io." - } - } \ No newline at end of file + "culture": "zh-Hans", + "texts": { + "Menu:Home": "首页", + "Welcome": "欢迎", + "LongWelcomeMessage": "欢迎使用本应用程序。这是一个基于 ABP 框架的启动项目。更多信息,请访问 abp.io。" + } +} \ No newline at end of file diff --git a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json index 12390e11fe..b3ba618dcd 100644 --- a/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json +++ b/templates/module/aspnet-core/src/MyCompanyName.MyProjectName.Domain.Shared/Localization/MyProjectName/zh-Hans.json @@ -2,6 +2,6 @@ "culture": "zh-Hans", "texts": { "MyAccount": "我的账户", - "SamplePageMessage": "MyProjectName模块的示例页面" + "SamplePageMessage": "MyProjectName 模块的示例页面" } } \ No newline at end of file