Browse Source

Merge branch 'dev' into maliming/IValueValidatorFactory

pull/10732/head
maliming 5 years ago
parent
commit
36fe11a0aa
No known key found for this signature in database GPG Key ID: 96224957E51C89E
  1. 4
      .github/workflows/build-and-test.yml
  2. 11
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json
  3. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json
  4. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de-DE.json
  5. 4
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json
  6. 92
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json
  7. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json
  8. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json
  9. 18
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json
  10. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json
  11. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json
  12. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json
  13. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json
  14. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json
  15. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json
  16. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json
  17. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json
  18. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json
  19. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json
  20. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json
  21. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json
  22. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json
  23. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json
  24. 13
      abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json
  25. 4
      codecov.yml
  26. 2
      common.props
  27. 11
      docs/en/Authorization.md
  28. 30
      docs/en/Background-Workers-Hangfire.md
  29. 76
      docs/en/Connection-Strings.md
  30. 11
      docs/en/Modules/Cms-Kit/Index.md
  31. 45
      docs/en/Tutorials/Part-1.md
  32. 86
      docs/en/Tutorials/Part-2.md
  33. 86
      docs/en/Tutorials/Part-3.md
  34. 4
      docs/en/Tutorials/Part-5.md
  35. 74
      docs/en/Tutorials/Todo/Index.md
  36. 67
      docs/en/UI/Angular/Theming.md
  37. 25
      docs/zh-Hans/Autofac-Integration.md
  38. 30
      docs/zh-Hans/Background-Workers-Hangfire.md
  39. 3
      docs/zh-Hans/Modules/Cms-Kit.md
  40. 3
      docs/zh-Hans/Modules/Cms-Kit/Blogging.md
  41. 3
      docs/zh-Hans/Modules/Cms-Kit/Comments.md
  42. 79
      docs/zh-Hans/Modules/Cms-Kit/Index.md
  43. 3
      docs/zh-Hans/Modules/Cms-Kit/Menus.md
  44. 3
      docs/zh-Hans/Modules/Cms-Kit/Pages.md
  45. 3
      docs/zh-Hans/Modules/Cms-Kit/Ratings.md
  46. 3
      docs/zh-Hans/Modules/Cms-Kit/Reactions.md
  47. 3
      docs/zh-Hans/Modules/Cms-Kit/Tags.md
  48. 310
      docs/zh-Hans/Modules/Identity.md
  49. 36
      docs/zh-Hans/Modules/IdentityServer.md
  50. 107
      docs/zh-Hans/Modules/Tenant-Management.md
  51. 3
      docs/zh-Hans/Modules/Tentant-Management.md
  52. 636
      docs/zh-Hans/Tutorials/Part-5.md
  53. 279
      docs/zh-Hans/Tutorials/Part-6.md
  54. 239
      docs/zh-Hans/Tutorials/Part-7.md
  55. 575
      docs/zh-Hans/Tutorials/Part-8.md
  56. 1250
      docs/zh-Hans/Tutorials/Part-9.md
  57. BIN
      docs/zh-Hans/Tutorials/images/bookstore-efcore-migration-authors.png
  58. 2
      docs/zh-Hans/docs-nav.json
  59. BIN
      docs/zh-Hans/images/features-modal.png
  60. BIN
      docs/zh-Hans/images/identity-module-menu.png
  61. BIN
      docs/zh-Hans/images/identity-module-permissions.png
  62. BIN
      docs/zh-Hans/images/identity-module-roles.png
  63. BIN
      docs/zh-Hans/images/identity-module-users.png
  64. BIN
      docs/zh-Hans/images/module-tenant-management-actions.png
  65. BIN
      docs/zh-Hans/images/module-tenant-management-new-tenant.png
  66. BIN
      docs/zh-Hans/images/module-tenant-management-page.png
  67. 4
      framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs
  68. 2
      framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs
  69. 2
      framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj
  70. 3
      framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpAspNetCoreComponentsModule.cs
  71. 8
      framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs
  72. 5
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Bootstrap/BootstrapScriptContributor.cs
  73. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js
  74. 10
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs
  75. 4
      framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConventionalRegistrar.cs
  76. 4
      framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs
  77. 6
      framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs
  78. 2
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/AbpBackgroundWorkersHangfireModule.cs
  79. 31
      framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs
  80. 12
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs
  81. 5
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs
  82. 43
      framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzPeriodicBackgroundWorkerAdapter.cs
  83. 20
      framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs
  84. 6
      framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs
  85. 18
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor
  86. 16
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs
  87. 22
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor
  88. 13
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs
  89. 6
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor
  90. 83
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs
  91. 8
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor
  92. 45
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs
  93. 26
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor
  94. 11
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor.cs
  95. 19
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor
  96. 17
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor.cs
  97. 18
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor
  98. 13
      framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor.cs
  99. 8
      framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj
  100. 7
      framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultBlobProviderSelector.cs

4
.github/workflows/build-and-test.yml

@ -41,12 +41,12 @@ jobs:
dotnet-version: 6.0.100
- name: Build All
run: .\build-all.ps1
run: .\build-all.ps1 -f
working-directory: .\build
shell: powershell
- name: Test All
run: .\test-all.ps1
run: .\test-all.ps1 -f
working-directory: .\build
shell: powershell

11
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ar.json

@ -197,14 +197,13 @@
"WhatHappensWhenLicenseEndsExplanation4": "لا يمكنك تثبيت وحدات وسمات جديدة مضافة إلى منصة ABP Commercial بعد انتهاء ترخيصك.",
"WhatHappensWhenLicenseEndsExplanation5": "لا يمكنك استخدام مجموعة ABP.",
"WhatHappensWhenLicenseEndsExplanation6": "لا يمكنك الحصول على <a href=\"{0}\"> الدعم المتميز </a> بعد الآن.",
"WhatHappensWhenLicenseEndsExplanation7": "يمكنك تجديد اشتراكك إذا كنت ترغب في الاستمرار في الحصول على هذه المزايا. إذا قمت بتجديد اشتراكك في غضون شهر واحد بعد انتهاء صلاحية ترخيصك ، فسيتم تطبيق خصم بنسبة 20٪.",
"WhatHappensWhenLicenseEndsExplanation7": "يمكنك تمديد (تجديد) الترخيص الخاص بك إذا كنت ترغب في الاستمرار في الحصول على هذه المزايا. في حالة تمديد ترخيصك في غضون <strong> شهر واحد </ strong> بعد انتهاء صلاحية الترخيص ، فسيتم تطبيق الخصومات التالية: ترخيص الفريق {0}٪ خصم ، ترخيص تجاري {1}٪ خصم ، ترخيص Enterprise {2}٪ خصم .",
"WhenShouldIRenewMyLicense": "متى يجب أن أجدد رخصتي؟",
"WhenShouldIRenewMyLicenseExplanation1": "إذا جددت ترخيصك في غضون <strong> شهر واحد </ strong> بعد انتهاء صلاحية الترخيص ، فسيتم تطبيق خصم بنسبة 20٪.",
"WhenShouldIRenewMyLicenseExplanation2": "إذا قمت بتجديد ترخيصك بعد شهر واحد من تاريخ انتهاء صلاحية الترخيص الخاص بك ، فسيكون سعر التجديد هو نفسه سعر شراء الترخيص ولن يكون هناك خصم على التجديد.",
"WhenShouldIRenewMyLicenseExplanation": "إذا جددت ترخيصك في غضون <strong> شهر واحد </ strong> بعد انتهاء صلاحية الترخيص ، فسيتم تطبيق الخصومات التالية: ترخيص الفريق {0}٪ خصم ، ترخيص تجاري {1}٪ خصم ، ترخيص Enterprise {2}٪ خصم . إذا قمت بتجديد ترخيصك بعد <strong> شهر واحد </ strong> من تاريخ انتهاء صلاحية الترخيص ، فسيكون سعر التجديد هو نفسه سعر شراء الترخيص ولن يكون هناك خصم على التجديد.",
"TrialPlan": "هل لديك خطة تجريبية؟",
"TrialPlanExplanation": "في الوقت الحالي ، لا تمتلك ABP Commercial خطة تجريبية. بالنسبة لتراخيص الفريق ، نقدم ضمان استرداد الأموال لمدة 30 يومًا. يمكنك فقط طلب استرداد الأموال في أول 30 يومًا. بالنسبة إلى تراخيص الأعمال والمؤسسات ، نقدم استردادًا بنسبة 60٪ في غضون 30 يومًا. وذلك لأن تراخيص Business and Enterprise تتضمن كود المصدر الكامل لجميع الوحدات والسمات.",
"DoYouAcceptBankWireTransfer": "هل تقبل التحويل البنكي؟",
"DoYouAcceptBankWireTransferExplanation": "نعم ، نحن نقبل التحويل المصرفي. <br /> بعد إرسال رسوم الترخيص عبر التحويل المصرفي ، أرسل لنا بريدًا إلكترونيًا على info@abp.io إيصالك ونوع الترخيص المطلوب. معلومات حسابنا المصرفي الدولي:",
"DoYouAcceptBankWireTransferExplanation": "نعم ، نحن نقبل التحويل البنكي. <br /> بعد إرسال رسوم الترخيص عبر التحويل المصرفي ، أرسل لنا بريدًا إلكترونيًا على accounting@abp.io إيصالك ونوع الترخيص المطلوب. معلومات حسابنا المصرفي الدولي:",
"HowToUpgrade": "كيفية ترقية التطبيقات الموجودة عند توفر إصدار جديد؟",
"HowToUpgradeExplanation1": "عند إنشاء تطبيق جديد باستخدام ABP Commercial ، يتم استخدام جميع الوحدات والقوالب كحزم NuGet و NPM. لذلك ، يمكنك ترقية الحزم بسهولة عند توفر إصدار جديد.",
"HowToUpgradeExplanation2": "بالإضافة إلى ترقيات NuGet/NPM القياسية ، يوفر <a href=\"{0}\"> ABP CLI </a> أمر تحديث يقوم تلقائيًا بالعثور على جميع الحزم المتعلقة بـ ABP في الحل الخاص بك وترقيتها.",
@ -390,6 +389,8 @@
"TrialLicenseExpireMessage": "أنت تستخدم الترخيص التجريبي وستنتهي صلاحية الترخيص التجريبي في {0}.",
"TryForFree": "حاول مجانا",
"TrialLicenseExpiredInfo": "انتهت فترة الترخيص التجريبي الخاص بك!",
"CommercialNewsletterConfirmationMessage": "أوافق على <a href=\"https://commercial.abp.io/TermsConditions\"> البنود والشروط </a> و <a href=\"https://commercial.abp.io/Privacy\"> سياسة الخصوصية </a>."
"CommercialNewsletterConfirmationMessage": "أوافق على <a href=\"https://commercial.abp.io/TermsConditions\"> البنود والشروط </a> و <a href=\"https://commercial.abp.io/Privacy\"> سياسة الخصوصية </a>.",
"RenewLicenseEarly": "إذا قمت بتجديد رخصتي في وقت مبكر ، هل سأحصل على السنة كاملة؟",
"RenewLicenseEarylExplanation": "عند تجديد الترخيص الخاص بك قبل تاريخ انتهاء الترخيص الخاص بك ، ستتم إضافة سنة واحدة إلى تاريخ انتهاء الترخيص الخاص بك. على سبيل المثال ، إذا انتهت صلاحية ترخيصك في {0} -06-06 وقمت بتجديده في {0} -01-01 ، فسيكون تاريخ انتهاء صلاحية الترخيص الجديد {1} -06-06."
}
}

18
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/cs.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Jaký je rozdíl mezi rozšířením licence a upgradem?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Prodloužení:</strong> Prodloužením/obnovením licence budete i nadále získávat prémiovou podporu a důležité aktualizace pro moduly a motivy. Kromě toho budete moci pokračovat ve vytváření nových projektů. A stále budete moci používat ABP Suite, který urychlí váš vývoj.<hr/><strong>Upgrade:</strong> Upgradováním licence povýšíte na vyšší licenční plán, který vám umožní získat další výhody . Rozdíly mezi licenčními plány naleznete v <a href=\"/pricing\">tabulce porovnání licencí</a>.<strong>Na druhou stranu, když upgradujete, datum vypršení platnosti vaší licence se nezmění!</strong> >Chcete-li prodloužit datum ukončení licence, musíte prodloužit licenci.",
"LicenseRenewalCost": "Kolik stojí obnovení licence po 1 roce?",
"LicenseRenewalCostExplanation": "Míra obnovení (prodloužení) všech trvalých licencí ABP Commercial je {0} z ceníkové ceny licencí. Cena obnovení standardní týmové licence je ${1}, standardní obchodní licence je ${2} a standardní podnikové licence je ${3}. Pokud již jste zákazníkem, <a href='{4}' target='_blank'>přihlaste se ke svému účtu</a> a zkontrolujte dostupné ceny za obnovení.",
"LicenseRenewalCostExplanation": "Cena za obnovení (prodloužení) standardní týmové licence je ${0}, standardní obchodní licence je ${1} a standardní podnikové licence je ${2}. Pokud již jste zákazníkem, <a href='{3}' target='_blank'>přihlaste se ke svému účtu</a> a zkontrolujte dostupné ceny za obnovení.",
"HowDoIRenewMyLicense": "Jak obnovím licenci?",
"HowDoIRenewMyLicenseExplanation": "Licenci můžete obnovit tak, že přejdete na <a href='{0}' target='_blank'>stránku správy organizace</a>. Abyste mohli využít našich zvýhodněných sazeb za předčasné obnovení, ujistěte se, že jste licenci obnovili před vypršením platnosti. Nebojte se však, že byste nevěděli, kdy vaše příležitost k předčasnému obnovení skončí. Před vypršením předplatného obdržíte 3 e-maily s upomínkou. Odešleme je 30 dní, 7 dní a 1 den před vypršením platnosti.",
"IsSourceCodeIncluded": "Obsahuje moje licence zdrojový kód komerčních modulů a témat?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Mohu v budoucnu změnit registrované vývojáře své organizace?",
"ChangingDevelopersExplanation": "Kromě přidání nových vývojářů do vaší licence můžete také změnit stávající vývojáře (můžete odebrat vývojáře a přidat nového na stejné místo) bez jakýchkoli dalších nákladů.",
"WhatHappensWhenLicenseEnds": "Co se stane, když moje licenční období skončí?",
"WhatHappensWhenLicenseEndsExplanation1": "Typ komerční licence ABP je <a href=\"{0}\" target=\"_blank\">trvalá licence</a>. Po vypršení platnosti licence můžete pokračovat ve vývoji projektu. A nejste povinni prodlužovat licenci. Vaše licence je dodávána s ročním plánem aktualizací a podpory ihned po vybalení. Chcete-li i nadále dostávat nové funkce, vylepšení výkonu, opravy chyb, podporu a nadále používat ABP Suite, obnovte svůj plán každý rok. Po vypršení platnosti vaší licence nebudete moci získat další z následujících výhod;",
"WhatHappensWhenLicenseEndsExplanation1": "Typ komerční licence ABP je <a href=\"{0}\" target=\"_blank\">trvalá licence</a>. Po vypršení platnosti licence můžete pokračovat ve vývoji projektu. A nejste povinni prodlužovat licenci. Vaše licence je dodávána s roční aktualizací a plánem podpory ihned po vybalení. Chcete-li i nadále získávat nové funkce, vylepšení výkonu, opravy chyb, podporu a nadále používat ABP Suite, musíte si obnovit licenci. Po vypršení platnosti vaší licence nezískáte následující výhody;",
"WhatHappensWhenLicenseEndsExplanation2": "Pomocí ABP Commercial nemůžete vytvářet nová řešení, ale můžete pokračovat ve vývoji svých stávajících aplikací navždy.",
"WhatHappensWhenLicenseEndsExplanation3": "Budete moci získat aktualizace pro moduly a témata ve vaší HLAVNÍ verzi. Například; pokud používáte v3.2.0 modulu, stále můžete získat aktualizace pro v3.x.x (v3.3.0, v3.5.2... atd.) tohoto modulu. Nemůžete však získat aktualizace pro další hlavní verzi (jako v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Budete moci získat aktualizace pro moduly a motivy ve vaší MAJOR verzi (kromě RC nebo Preview verzí). Například; pokud používáte v3.2.0 modulu, stále můžete získat aktualizace pro v3.x.x (v3.3.0, v3.5.2... atd.) tohoto modulu. Nemůžete však získat aktualizace pro další hlavní verzi (jako v4.x, v5.x). Když například vypršela platnost vaší licence, nejnovější verze byla v4.4.3 a nejnovější verze náhledu byla v5.0.0-rc.2, máte přístup k verzi 4.X.X, ale nemáte přístup k verzi 5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Po skončení licence nemůžete instalovat nové moduly a motivy přidané do platformy ABP Commercial.",
"WhatHappensWhenLicenseEndsExplanation5": "Nemůžete používat ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Již nemůžete získat <a href=\"{0}\">prémiovou podporu</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Pokud chcete i nadále využívat tyto výhody, můžete si předplatné obnovit. Pokud předplatné obnovíte do 1 měsíce po vypršení platnosti licence, uplatní se sleva 20 %.",
"WhatHappensWhenLicenseEndsExplanation7": "Pokud chcete i nadále využívat tyto výhody, můžete svou licenci prodloužit (obnovit). Pokud prodloužíte licenci do <strong>1 měsíce</strong> po vypršení platnosti licence, budou uplatněny následující slevy: Týmová licence {0}% sleva, Obchodní licence {1}% sleva, Enterprise License {2}% sleva .",
"WhenShouldIRenewMyLicense": "Kdy bych měl obnovit licenci?",
"WhenShouldIRenewMyLicenseExplanation1": "Pokud svou licenci obnovíte do <strong>1 měsíce</strong> po vypršení platnosti licence, uplatní se sleva 20 %.",
"WhenShouldIRenewMyLicenseExplanation2": "Pokud obnovíte licenci po 1 měsíci od data vypršení platnosti licence, cena za obnovení bude stejná jako cena za zakoupení licence a za obnovení nebude poskytnuta žádná sleva.",
"WhenShouldIRenewMyLicenseExplanation": "Pokud si licenci obnovíte do <strong>1 měsíce</strong> po vypršení platnosti licence, budou uplatněny následující slevy: Týmová licence {0}% sleva, Obchodní licence {1}% sleva, Enterprise License {2}% sleva . Pokud si licenci obnovíte <strong>1 měsíc</strong> po datu vypršení platnosti vaší licence, cena za obnovení bude stejná jako cena nákupu licence a na obnovení nebude poskytnuta žádná sleva.",
"TrialPlan": "Máte zkušební plán?",
"TrialPlanExplanation": "ABP Commercial zatím nemá zkušební plán. Pro týmové licence poskytujeme 30denní záruku vrácení peněz. Během prvních 30 dnů můžete pouze požádat o vrácení peněz. U licencí Business a Enterprise poskytujeme vrácení 60 % do 30 dnů. Je to proto, že licence Business a Enterprise obsahují úplný zdrojový kód všech modulů a témat.",
"DoYouAcceptBankWireTransfer": "Přijímáte bankovní převod?",
"DoYouAcceptBankWireTransferExplanation": "Ano, přijímáme bankovní převod.<br />Po zaslání licenčního poplatku bankovním převodem nám zašlete e-mail na adresu info@abp.io potvrzení a požadovaný typ licence. Informace o našem mezinárodním bankovním účtu:",
"DoYouAcceptBankWireTransferExplanation": "Ano, přijímáme bankovní převod.<br />Po zaslání licenčního poplatku bankovním převodem nám zašlete e-mail na adresu accounting@abp.io potvrzení a požadovaný typ licence. Informace o našem mezinárodním bankovním účtu:",
"HowToUpgrade": "Jak upgradovat stávající aplikace, když je k dispozici nová verze?",
"HowToUpgradeExplanation1": "Když vytvoříte novou aplikaci pomocí ABP Commercial, všechny moduly a téma se použijí jako balíčky NuGet a NPM. Takže můžete snadno upgradovat balíčky, když je k dispozici nová verze.",
"HowToUpgradeExplanation2": "Kromě standardních upgradů NuGet/NPM poskytuje <a href=\"{0}\">ABP CLI</a> aktualizační příkaz, který automaticky vyhledá a upgraduje všechny balíčky související s ABP ve vašem řešení.",
@ -390,6 +389,9 @@
"TrialLicenseExpireMessage": "Používáte zkušební licenci a platnost vaší zkušební licence vyprší dne {0}.",
"TryForFree": "Zkus zadarmo",
"TrialLicenseExpiredInfo": "Vaše zkušební licenční období vypršelo!",
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>."
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>.",
"ContinueWithNewOrganization": "Pokračujte s novou organizací",
"RenewLicenseEarly": "Pokud si předčasně obnovím licenci, dostanu celý rok?",
"RenewLicenseEarylExplanation": "Když obnovíte licenci před datem vypršení platnosti licence, bude k datu vypršení platnosti licence přidán 1 rok. Pokud například platnost vaší licence vyprší dne {0}-06-06 a obnovíte ji dne {0}-01-01, bude vaše nové datum vypršení platnosti licence {1}-06-06."
}
}

18
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/de-DE.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Was ist der Unterschied zwischen Lizenzverlängerung und Upgrade?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Verlängern:</strong> Durch die Verlängerung/Erneuerung Ihrer Lizenz erhalten Sie weiterhin Premium-Support und wichtige Updates für die Module und Themen. Außerdem können Sie weiterhin neue Projekte erstellen. Und Sie können weiterhin die ABP Suite verwenden, was Ihre Entwicklung beschleunigt.<hr/><strong>Upgrade:</strong> Durch das Upgrade Ihrer Lizenz steigen Sie zu einem höheren Lizenzplan auf, mit dem Sie zusätzliche Vorteile erhalten . Sehen Sie sich die <a href=\"/pricing\">Lizenzvergleichstabelle</a> an, um die Unterschiede zwischen den Lizenzplänen zu überprüfen.<strong>Andererseits ändert sich das Ablaufdatum Ihrer Lizenz bei einem Upgrade nicht!</strong >Um das Enddatum Ihrer Lizenz zu verlängern, müssen Sie Ihre Lizenz verlängern.",
"LicenseRenewalCost": "Wie hoch sind die Kosten für die Lizenzverlängerung nach 1 Jahr?",
"LicenseRenewalCostExplanation": "Die Verlängerungsrate (Verlängerung) aller unbefristeten Lizenzen von ABP Commercial beträgt {0} des Lizenzlistenpreises. Der Verlängerungspreis der Standard-Team-Lizenz beträgt ${1}, die Standard-Business-Lizenz ${2} und die Standard-Unternehmens-Lizenz ${3}. Wenn Sie bereits Kunde sind, <a href='{4}' target='_blank'>melden Sie sich in Ihrem Konto an</a>, um die verfügbaren Verlängerungspreise zu überprüfen.",
"LicenseRenewalCostExplanation": "Der Verlängerungspreis (Erweiterung) der Standard-Teamlizenz beträgt {0}$, die Standard-Business-Lizenz beträgt ${1} und die Standard-Enterprise-Lizenz beträgt ${2}. Wenn Sie bereits Kunde sind, <a href='{3}' target='_blank'>melden Sie sich in Ihrem Konto an</a>, um die verfügbaren Verlängerungspreise zu überprüfen.",
"HowDoIRenewMyLicense": "Wie erneuere ich meine Lizenz?",
"HowDoIRenewMyLicenseExplanation": "Sie können Ihre Lizenz erneuern, indem Sie zur <a href='{0}' target='_blank'>Organisationsverwaltungsseite</a> navigieren. Um von unseren ermäßigten Tarifen für die vorzeitige Verlängerung zu profitieren, vergewissern Sie sich, dass Sie vor Ablauf Ihrer Lizenz verlängern. Machen Sie sich jedoch keine Sorgen, dass Sie nicht wissen, wann Ihre Gelegenheit zur vorzeitigen Verlängerung endet. Sie erhalten 3 Erinnerungs-E-Mails, bevor Ihr Abonnement abläuft. Wir versenden sie 30 Tage, 7 Tage und 1 Tag vor Ablauf.",
"IsSourceCodeIncluded": "Enthält meine Lizenz den Quellcode der kommerziellen Module und Themes?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Kann ich die registrierten Entwickler meiner Organisation in Zukunft ändern?",
"ChangingDevelopersExplanation": "Sie können nicht nur neue Entwickler zu Ihrer Lizenz hinzufügen, sondern auch die vorhandenen Entwickler ändern (Sie können einen Entwickler entfernen und einen neuen zum selben Arbeitsplatz hinzufügen) ohne zusätzliche Kosten.",
"WhatHappensWhenLicenseEnds": "Was passiert, wenn mein Lizenzzeitraum endet?",
"WhatHappensWhenLicenseEndsExplanation1": "Der kommerzielle ABP-Lizenztyp ist <a href=\"{0}\" target=\"_blank\">unbefristete Lizenz</a>. Nach Ablauf Ihrer Lizenz können Sie Ihr Projekt weiter entwickeln. Und Sie sind nicht verpflichtet, Ihre Lizenz zu erneuern. Im Lieferumfang Ihrer Lizenz ist ein einjähriger Update- und Supportplan enthalten. Um weiterhin neue Funktionen, Leistungsverbesserungen, Fehlerkorrekturen und Support zu erhalten und die ABP Suite weiterhin zu nutzen, sollten Sie Ihren Plan jedes Jahr erneuern. Wenn Ihre Lizenz abläuft, können Sie die folgenden Vorteile nicht mehr nutzen;",
"WhatHappensWhenLicenseEndsExplanation1": "Der kommerzielle ABP-Lizenztyp ist <a href=\"{0}\" target=\"_blank\">unbefristete Lizenz</a>. Nach Ablauf Ihrer Lizenz können Sie Ihr Projekt weiter entwickeln. Und Sie sind nicht verpflichtet, Ihre Lizenz zu erneuern. Ihre Lizenz wird standardmäßig mit einem einjährigen Update- und Supportplan geliefert. Um weiterhin neue Funktionen, Leistungsverbesserungen, Fehlerkorrekturen und Support zu erhalten und die ABP Suite weiterhin nutzen zu können, müssen Sie Ihre Lizenz erneuern. Wenn Ihre Lizenz abläuft, erhalten Sie die folgenden Vorteile nicht;",
"WhatHappensWhenLicenseEndsExplanation2": "Sie können mit dem ABP Commercial keine neuen Lösungen erstellen, aber Sie können Ihre bestehenden Anwendungen für immer weiterentwickeln.",
"WhatHappensWhenLicenseEndsExplanation3": "Sie können Updates für die Module und Themen Ihrer MAJOR-Version erhalten. Zum Beispiel; Wenn Sie v3.2.0 eines Moduls verwenden, können Sie weiterhin Updates für v3.x.x (v3.3.0, v3.5.2... etc.) dieses Moduls erhalten. Sie können jedoch keine Updates für die nächste Hauptversion (wie v4.x, v5.x) erhalten.",
"WhatHappensWhenLicenseEndsExplanation3": "Sie können Updates für die Module und Themen Ihrer MAJOR-Version (außer RC- oder Preview-Versionen) erhalten. Beispielsweise; Wenn Sie v3.2.0 eines Moduls verwenden, können Sie immer noch Updates für v3.x.x (v3.3.0, v3.5.2... etc.) dieses Moduls erhalten. Sie können jedoch keine Updates für die nächste Hauptversion (wie v4.x, v5.x) erhalten. Wenn beispielsweise Ihre Lizenz abgelaufen ist, die neueste Version v4.4.3 und die neueste Vorschauversion v5.0.0-rc.2 war, können Sie auf v4.X.X zugreifen, aber nicht auf v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Sie können nach Ablauf Ihrer Lizenz keine neuen Module und Themen installieren, die der ABP Commercial-Plattform hinzugefügt wurden.",
"WhatHappensWhenLicenseEndsExplanation5": "Sie können die ABP-Suite nicht verwenden.",
"WhatHappensWhenLicenseEndsExplanation6": "Sie können den <a href=\"{0}\">Premium-Support</a> nicht mehr erhalten.",
"WhatHappensWhenLicenseEndsExplanation7": "Sie können Ihr Abonnement verlängern, wenn Sie diese Vorteile weiterhin nutzen möchten. Wenn Sie Ihr Abonnement innerhalb von 1 Monat nach Ablauf Ihrer Lizenz verlängern, wird ein Rabatt von 20 % gewährt.",
"WhatHappensWhenLicenseEndsExplanation7": "Sie können Ihre Lizenz verlängern (erneuern), wenn Sie diese Vorteile weiterhin nutzen möchten. Wenn Sie Ihre Lizenz innerhalb von <strong>1 Monat</strong> nach Ablauf Ihrer Lizenz verlängern, werden die folgenden Rabatte gewährt: Team-Lizenz {0}% Rabatt, Business-Lizenz {1}% Rabatt, Enterprise-Lizenz {2}% Rabatt .",
"WhenShouldIRenewMyLicense": "Wann sollte ich meine Lizenz erneuern?",
"WhenShouldIRenewMyLicenseExplanation1": "Wenn Sie Ihre Lizenz innerhalb von <strong>1 Monat</strong> nach Ablauf Ihrer Lizenz erneuern, wird ein Rabatt von 20 % gewährt.",
"WhenShouldIRenewMyLicenseExplanation2": "Wenn Sie Ihre Lizenz 1 Monat nach dem Ablaufdatum Ihrer Lizenz verlängern, entspricht der Verlängerungspreis dem Lizenzkaufpreis und es wird kein Rabatt für Ihre Verlängerung gewährt.",
"WhenShouldIRenewMyLicenseExplanation": "Wenn Sie Ihre Lizenz innerhalb von <strong>1 Monat</strong> nach Ablauf Ihrer Lizenz erneuern, werden die folgenden Rabatte gewährt: Team-Lizenz {0}% Rabatt, Business-Lizenz {1}% Rabatt, Enterprise-Lizenz {2}% Rabatt . Wenn Sie Ihre Lizenz <strong>1 Monat</strong> nach dem Ablaufdatum Ihrer Lizenz verlängern, entspricht der Verlängerungspreis dem Lizenzkaufpreis und es wird kein Rabatt auf Ihre Verlängerung gewährt.",
"TrialPlan": "Hast du einen Probeplan?",
"TrialPlanExplanation": "Derzeit hat ABP Commercial keinen Testplan. Für die Team-Lizenzen bieten wir eine 30-tägige Geld-zurück-Garantie. Sie können nur innerhalb der ersten 30 Tage eine Rückerstattung beantragen. Für die Business- und Enterprise-Lizenzen gewähren wir innerhalb von 30 Tagen eine Rückerstattung von 60 %. Dies liegt daran, dass Business- und Enterprise-Lizenzen den vollständigen Quellcode aller Module und Themes enthalten.",
"DoYouAcceptBankWireTransfer": "Akzeptieren Sie Banküberweisungen?",
"DoYouAcceptBankWireTransferExplanation": "Ja, wir akzeptieren Banküberweisungen.<br />Nachdem Sie die Lizenzgebühr per Banküberweisung gesendet haben, senden Sie uns Ihre Quittung und den gewünschten Lizenztyp per E-Mail an info@abp.io. Unsere internationale Bankverbindung:",
"DoYouAcceptBankWireTransferExplanation": "Ja, wir akzeptieren Banküberweisungen.<br />Nachdem Sie die Lizenzgebühr per Banküberweisung gesendet haben, senden Sie uns Ihre Quittung und den gewünschten Lizenztyp per E-Mail an accounting@abp.io. Unsere internationale Bankverbindung:",
"HowToUpgrade": "Wie aktualisiere ich bestehende Anwendungen, wenn eine neue Version verfügbar ist?",
"HowToUpgradeExplanation1": "Wenn Sie mit ABP Commercial eine neue Anwendung erstellen, werden alle Module und das Design als NuGet- und NPM-Pakete verwendet. So können Sie die Pakete problemlos aktualisieren, wenn eine neue Version verfügbar ist.",
"HowToUpgradeExplanation2": "Zusätzlich zu den standardmäßigen NuGet/NPM-Upgrades bietet die <a href=\"{0}\">ABP CLI</a> einen Update-Befehl, der automatisch alle ABP-bezogenen Pakete in Ihrer Lösung findet und aktualisiert.",
@ -390,6 +389,9 @@
"TrialLicenseExpireMessage": "Sie verwenden die Testlizenz und Ihre Testlizenz läuft am {0} ab.",
"TryForFree": "Kostenlos testen",
"TrialLicenseExpiredInfo": "Ihr Testlizenzzeitraum ist abgelaufen!",
"CommercialNewsletterConfirmationMessage": "Ich stimme den <a href=\"https://commercial.abp.io/TermsConditions\">Allgemeinen Geschäftsbedingungen</a> und der <a href=\"https://commercial.abp.io/Privacy\">Datenschutzerklärung . zu </a>."
"CommercialNewsletterConfirmationMessage": "Ich stimme den <a href=\"https://commercial.abp.io/TermsConditions\">Allgemeinen Geschäftsbedingungen</a> und der <a href=\"https://commercial.abp.io/Privacy\">Datenschutzerklärung . zu </a>.",
"ContinueWithNewOrganization": "Weiter mit einer neuen Organisation",
"RenewLicenseEarly": "Erhalte ich das ganze Jahr, wenn ich meine Lizenz vorzeitig erneuere?",
"RenewLicenseEarylExplanation": "Wenn Sie Ihre Lizenz vor dem Ablaufdatum Ihrer Lizenz erneuern, wird Ihr Lizenzablaufdatum um 1 Jahr verlängert. Wenn Ihre Lizenz beispielsweise am {0}-06-06 abläuft und Sie sie am {0}-01-01 erneuern, ist das neue Ablaufdatum der Lizenz der {1}-06-06."
}
}

4
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en-GB.json

@ -106,6 +106,8 @@
"RemoveCurrentUserFromOrganizationWarningMessage": "You are removing yourself from your own organization. You will no longer be able to manage this organization, do you confirm?",
"RenewExistingOrganizationOrCreateNewOneMessage": "You can renew the license of your organization(s) by clicking the below \"Extend Now\" button(s) and thus you can extend the license expiry date by 1 year. If you continue to checkout, you will have a new organization. Do you want to continue with a new organization?",
"ExtendNow": "Extend Now",
"ContinueWithNewOrganization": "Continue with a new organization"
"ContinueWithNewOrganization": "Continue with a new organization",
"RenewLicenseEarly": "If I renew my license early, will I get the full year?",
"RenewLicenseEarylExplanation": "When you renew your license before your license expiry date, 1 year will be added to your license expiry date. For example, if your license expires on {0}-06-06 and you renew it on {0}-01-01, your new license expiry date will be {1}-06-06."
}
}

92
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/en.json

@ -155,83 +155,82 @@
"WeAreHereToHelp": "We are Here to <span class=\"zero-text\">Help</span>",
"BrowseOrAskQuestion": "You can browse our help topics or search in frequently asked questions, or you can ask us a question by using the <a href=\"{0}\" class=\"text-success\">contact form</a>.",
"SearchQuestionPlaceholder": "Search in frequently asked questions",
"WhatIsTheABPCommercial": "What is the ABP Commercial?",
"WhatAreDifferencesThanAbpFramework": "What are the differences between the open source ABP Framework and the ABP Commercial?",
"ABPCommercialExplanation": "ABP Commercial is a set of premium modules, tools, themes and services built on top of the open source <a target=\"_blank\" href=\"{0}\">ABP framework</a>. ABP Commercial is being developed and supported by the same team behind the ABP framework.",
"WhatAreDifferencesThanABPFrameworkExplanation": "<p> <a target=\"_blank\" href=\"{0}\">ABP framework</a> is a modular, themeable, micro-service compatible application development framework for ASP.NET Core. It provides a complete architecture and a strong infrastructure to make you focusing on your own business code rather than repeating yourself for every new project. It is based on software development best practices and popular tools you already know. </p> <p> ABP framework is completely free, open source and community-driven. It also provides a free theme and some pre-built modules (e.g. identity management and tenant management).</p>",
"VisitTheFrameworkVSCommercialDocument": "Visit the following link, for more information <a href=\"{0}\" target=\"_blank\"> {1} </a>",
"ABPCommercialFollowingBenefits": "ABP Commercial adds the following benefits on top of the ABP framework;",
"WhatIsTheABPCommercial": "What is ABP Commercial?",
"WhatAreDifferencesThanAbpFramework": "What are the differences between the open source ABP Framework and ABP Commercial?",
"ABPCommercialExplanation": "ABP Commercial is a set of premium modules, tools, themes and services that are built on top of the open source <a target=\"_blank\" href=\"{0}\">ABP framework</a>. ABP Commercial is being developed and supported by the same team behind the ABP framework.",
"WhatAreDifferencesThanABPFrameworkExplanation": "<p> <a target=\"_blank\" href=\"{0}\">ABP framework</a> is a modular, themeable, micro-service compatible application development framework for ASP.NET Core. It provides a complete architecture and a strong infrastructure to let you focus on your own business code rather than repeating yourself for every new project. It is based on the best practices of software development and popular tools you already know. </p> <p> ABP framework is completely free, open source and community-driven. It also provides a free theme and some pre-built modules (e.g. identity management and tenant management).</p>",
"VisitTheFrameworkVSCommercialDocument": "Visit the following link for more information <a href=\"{0}\" target=\"_blank\"> {1} </a>",
"ABPCommercialFollowingBenefits": "ABP Commercial adds the following benefits on top of the ABP framework:",
"Professional": "Professional",
"UIThemes": "UI themes",
"EnterpriseModules": "Enterprise ready, feature rich, pre-built <a href=\"{0}\">application modules</a> (e.g. Identity Server management, SaaS management, language management)",
"UIThemes": "UI Themes",
"EnterpriseModules": "Enterprise ready, feature rich, pre-built <a href=\"{0}\">Application Modules</a> (e.g. Identity Server management, SaaS management, language management)",
"ToolingToSupport": "Tooling to support your development productivity (e.g. <a href=\"{0}\">ABP Suite</a>)",
"PremiumSupportLink": "Premium <a href=\"{0}\" target=\"_blank\">support</a>",
"PremiumSupportLink": "Premium <a href=\"{0}\" target=\"_blank\">Support</a>",
"WhatDoIDownloadABPCommercial": "What do I download when I purchase the ABP Commercial?",
"CreateUnlimitedSolutions": "Once you purchase an ABP Commercial license, you will be able to create unlimited solutions like described in the <a href=\"{0}\">Getting Started</a> document.",
"ABPCommercialSolutionExplanation": "When you create a new application, you get a Visual Studio solution (a startup template) based on your preferences. The downloaded solution has commercial modules and themes already installed and configured for you. You can remove a pre-installed module or add another module if you like. All modules and themes are used a NuGet/NPM packages by default.",
"StartDevelopWithTutorials": "The downloaded solution is well architected and documented. You can start to develop your own business code based on it following <a href=\"{0}\">the tutorials</a>",
"TryTheCommercialDemo": "You can try <a href=\"{0}\">the demo</a> to see a sample application created using the ABP Commercial startup template.",
"ABPCommercialSolutionExplanation": "When you create a new application, you get a Visual Studio solution (a startup template) based on your preferences. The downloaded solution has commercial modules and themes already installed and configured for you. You can remove a pre-installed module or add another module if you like. All modules and themes use NuGet/NPM packages by default.",
"StartDevelopWithTutorials": "The downloaded solution is well architected and documented. You can start developing your own business code based on it following the <a href=\"{0}\">tutorials</a>.",
"TryTheCommercialDemo": "You can try the <a href=\"{0}\">Live Demo</a> to see a sample application created using the ABP Commercial startup template.",
"HowManyProducts": "How many different products/solutions can I build using the ABP Commercial?",
"HowManyProductsExplanation": "There is no limit to create an ABP project. You can create as many project as you want, develop and upload them to different servers.",
"HowManyProductsExplanation": "You can create as many projects as you want during your active license period, there is no limit! After your license expires, you cannot create new projects, but you can continue to develop the projects you have downloaded and deploy them to an unlimited count of servers.",
"HowManyDevelopers": "How many developers can work on the ABP Commercial?",
"HowManyDevelopersExplanation": "ABP Commercial licenses are per developer. Different license types have different developer limits. However, you can add more developers to any license type whenever you need. See <a href=\"{0}\">the prices</a> page for license types, developer limits and additional developer costs.",
"HowManyDevelopersExplanation": "ABP Commercial licenses are per developer. Different license types have different developer limits. However, you can add more developers to any license type whenever you need. Check out the <a href=\"{0}\">Plans & Pricing</a> page for license types, developer limits and additional developer costs.",
"ChangingLicenseType": "Can I upgrade my license type later?",
"ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, see \"How many developers can work on the ABP Commercial?\"",
"ChangingLicenseTypeExplanation": "You can upgrade to a higher license by paying the difference within your active license period. When you upgrade to a higher license plan, you get the benefits of the new plan, but the license upgrade does not change the license expiry date. Besides, you can also add new developer seats to your existing license, check out the \"How many developers can work on the ABP Commercial?\" FAQ.",
"LicenseExtendUpgradeDiff": "What is the difference between license extend and upgrade?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development. When you extend your license, 1 year is added to your license expiry date. <hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development. When you extend your license, 1 year is added to your license expiry date. <hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. Check out the <a href=\"/pricing\">license comparison table</a> to see the differences between the license plans. <strong>On the other hand, when you upgrade, your license expiry date will not change!</strong> To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "What is the license renewal cost after 1 year?",
"LicenseRenewalCostExplanation": "The renewal (extend) rate of all ABP Commercial perpetual licenses is {0} of the license list price. The renewal price of the standard Team License is ${1}, standard Business License is ${2} and standard Enterprise License is ${3}. If you are already a customer, <a href='{4}' target='_blank'>log into your account</a> to review the available renewal pricing.",
"LicenseRenewalCostExplanation": "The renewal (extend) price of the standard Team License is ${0}, standard Business License is ${1} and standard Enterprise License is ${2}. If you are already a customer, <a href='{3}' target='_blank'>log into your account</a> to review the current renewal pricing.",
"HowDoIRenewMyLicense": "How do I renew my license?",
"HowDoIRenewMyLicenseExplanation": "You can renew your license by navigating to the <a href='{0}' target='_blank'>organization management page</a>. In order to take advantage of our discounted Early Renewal rates, make sure you renew before your license expires. Don't worry about not knowing when your Early Renewal opportunity closes, however. You'll receive 3 reminder e-mails before your subscription expires. We'll send them at 30 days, 7 days and 1 day before expiration.",
"HowDoIRenewMyLicenseExplanation": "You can renew your license by navigating to the <a href='{0}' target='_blank'>organization management page</a>. In order to take advantage of our discounted Early Renewal rates, make sure you renew before your license expires. Don't worry about not knowing when your Early Renewal opportunity closes, you'll however receive 3 reminder e-mails before your subscription expires. We'll send them 30 days, 7 days and 1 day before expiration.",
"IsSourceCodeIncluded": "Does my license include the source code of the commercial modules and themes?",
"IsSourceCodeIncludedExplanation1": "Depends on the license type you've purchased:",
"IsSourceCodeIncludedExplanation2": "<strong>Team</strong>: Your solution uses the modules and the themes as NuGet and NPM packages. It doesn't include their source code. In this way, you can easily upgrade these modules and themes whenever a new version is available. However, you can not get the source code of the modules and the themes.",
"IsSourceCodeIncludedExplanation2": "<strong>Team</strong>: Your solution uses the modules and themes as NuGet and NPM packages. It doesn't include their source code. In this way, you can easily upgrade these modules and themes whenever a new version is available. However, you can not get the source code of these modules and themes.",
"IsSourceCodeIncludedExplanation3": "<strong>Business/Enterprise</strong>: In addition to the Team license, you are able to download the source code of any module or theme you need. You can even remove the NuGet/NPM package references for a particular module and add its source code directly to your solution to fully change it.",
"IsSourceCodeIncludedExplanation4": "<p>Including the source code of a module to your solution gives you the maximum freedom to customize that module. However, then it will not be possible to automatically upgrade the module when a new version is released.</p><p>None of the licenses include the ABP Suite source code, which is an external tool that generates code for you and assist to your development.</p><p>See <a href=\"{0}\">the pricing</a> page for other differences between the license types.</p>",
"IsSourceCodeIncludedExplanation4": "<p>Including the source code of a module to your solution gives you the maximum freedom to customize that module. However, it will then not be possible to automatically upgrade the module when a new version is released.</p><p>None of the licenses include the ABP Suite source code, which is an external tool that generates code for you and assists your development.</p><p>Check out the <a href=\"{0}\">Plans & Pricing</a> page for other differences between the license types.</p>",
"ChangingDevelopers": "Can I change the registered developers of my organization in the future?",
"ChangingDevelopersExplanation": "In addition to add new developers to your license, you can also change the existing developers (you can remove a developer and add a new one to the same seat) without any additional cost.",
"ChangingDevelopersExplanation": "In addition to adding new developers to your license, you can also change the existing developers (you can remove a developer and add a new one to the same seat) without any additional cost.",
"WhatHappensWhenLicenseEnds": "What happens when my license period ends?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial license type is <a href=\"{0}\" target=\"_blank\">perpetual license</a>. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year Updates and Support plan out of the box. To continue to receive new features, performance enhancements, bug fixes, support and continue to use ABP Suite, make sure to renew your plan each year. When your license expires, you will not be able to get more of the following benefits;",
"WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue to develop your existing applications forever.",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version (except RC or Preview versions). For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x). Let's say, when your license expired, the latest release was v4.4.3 and the latest preview version was v5.0.0-rc.2, you can only access the v4.X.X but you cannot access the v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation1": "The ABP Commercial license is a <a href=\"{0}\" target=\"_blank\">perpetual license</a>. After your license expires, you can continue developing your project. And you are not obliged to renew your license. Your license comes with a one-year update and support plan out of the box. In order to continue to get new features, performance enhancements, bug fixes, support and continue using ABP Suite, you need to renew your license. When your license expires, you will not get the following benefits:",
"WhatHappensWhenLicenseEndsExplanation2": "You can not create new solutions using the ABP Commercial, but you can continue developing your existing applications forever.",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version (except RC or Preview versions). For example: if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x). For example, when your license expired, the latest release was v4.4.3 and the latest preview version was v5.0.0-rc.2, you would be able to access the v4.X.X but you wouldn't be access the v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "You can not install new modules and themes added to the ABP Commercial platform after your license ends.",
"WhatHappensWhenLicenseEndsExplanation5": "You can not use the ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "You can not get the <a href=\"{0}\">premium support</a> anymore.",
"WhatHappensWhenLicenseEndsExplanation7": "You can renew your subscription if you want to continue to get these benefits. If you renew your subscription within 1 month after your license expires, a 20% discount is applied.",
"WhatHappensWhenLicenseEndsExplanation7": "You can extend (renew) your license if you want to continue getting these benefits. If you extend your license within <strong>1 month</strong> after your license expires, the following discounts will be applied: Team License {0}% discount, Business License {1}% discount, Enterprise License {2}% discount.",
"WhenShouldIRenewMyLicense": "When should I renew my license?",
"WhenShouldIRenewMyLicenseExplanation1": "If you renew your license within <strong>1 month</strong> after your license expires, a %20 discount is be applied.",
"WhenShouldIRenewMyLicenseExplanation2": "If you renew your license after 1 month from your license expire date, the renew price will be same as license purchase price and there will be no discount for your renewal.",
"WhenShouldIRenewMyLicenseExplanation": "If you renew your license within <strong>1 month</strong> after your license expires, the following discounts will be applied: Team License {0}% discount, Business License {1}% discount, Enterprise License {2}% discount. However, if you renew your license after <strong>1 month</strong> since the expiry date of your license, the renewal price will be the same as the license purchase price and there will be no discount on your renewal.",
"TrialPlan": "Do you have a trial plan?",
"TrialPlanExplanation": "For now, ABP Commercial doesn't have a trial plan. For the Team licenses we provide 30 days money back guarantee. You can just request a refund in the first 30 days. For the Business and Enterprise licenses, we provide 60% refund in 30 days. This is because Business and Enterprise licenses include the full source code of all the modules and the themes.",
"DoYouAcceptBankWireTransfer": "Do you accept bank wire transfer?",
"DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfer.<br />After sending the license fee via bank transfer, email us at info@abp.io your receipt and the type of license requested. Our international bank account information:",
"DoYouAcceptBankWireTransfer": "Do you accept bank wire transfers?",
"DoYouAcceptBankWireTransferExplanation": "Yes, we accept bank wire transfers.<br />After sending the license fee via bank transfer, email us your receipt and the type of license requested at accounting@abp.io, here's our international bank account information:",
"HowToUpgrade": "How to upgrade existing applications when a new version is available?",
"HowToUpgradeExplanation1": "When you create a new application using ABP Commercial, all the modules and the theme are used as NuGet and NPM packages. So, you can easily upgrade the packages when a new version is available.",
"HowToUpgradeExplanation1": "When you create a new application using ABP Commercial, all the modules and theme are used as NuGet and NPM packages. So, you can easily upgrade the packages when a new version is available.",
"HowToUpgradeExplanation2": "In addition to the standard NuGet/NPM upgrades, <a href=\"{0}\">ABP CLI</a> provides an update command that automatically finds and upgrades all ABP related packages in your solution.",
"DatabaseSupport": "Which database systems are supported?",
"DatabaseSupportExplanation": "ABP Framework itself is database agnostic and can work with any database provider by its nature. See <a href=\"{0}\" target=\"_blank\">the data access document</a> for a list of currently implemented providers.",
"DatabaseSupportExplanation": "ABP Framework itself is database agnostic and can work with any database provider by its nature. Check out the <a href=\"{0}\" target=\"_blank\">Data Access document</a> for a list of currently implemented providers.",
"UISupport": "Which UI frameworks are supported?",
"Supported": "Supported",
"UISupportExplanation": "ABP Framework itself is UI framework agnostic and can work with any UI framework. However, startup templates, module UIs and themes were not implemented for all UI frameworks. See <a href=\"{0}\">the getting started document</a> for the up-to-date list of UI options.",
"UISupportExplanation": "ABP Framework itself is UI framework agnostic and can work with any UI framework. However, startup templates, module UIs and themes were not implemented for all UI frameworks. Check out the <a href=\"{0}\">Getting Started document</a> for the up-to-date list of UI options.",
"MicroserviceSupport": "Does it support the micro-service architecture?",
"MicroserviceSupportExplanation1": "One of the major goals of the ABP framework is to provide a convenient infrastructure to create micro-service solutions. See the <a href=\"{0}\">micro-service architecture</a> document to understand how it helps to create micro-service systems.",
"MicroserviceSupportExplanation2": "All the ABP Commercial modules are designed to support micro-service deployment scenarios (with its own API and database) by following the <a href=\"{0}\">module development best practices</a> document.",
"MicroserviceSupportExplanation3": "We provide a sample <a href=\"{0}\">micro-service demo solution</a>that demonstrates a micro-service architecture implementation to help you to create your own solution.",
"MicroserviceSupportExplanation4": "So, the short answer is \"<strong>yes, it supports micro-service architecture</strong>\".",
"MicroserviceSupportExplanation1": "One of the major goals of the ABP framework is to provide a convenient infrastructure to create micro-service solutions. Check out the <a href=\"{0}\">Micro-service Architecture document</a> to understand how it helps with creating micro-service systems.",
"MicroserviceSupportExplanation2": "All the ABP Commercial modules are designed to support micro-service deployment scenarios (with its own API and database) by following the <a href=\"{0}\">Module Development Best Practices document</a>.",
"MicroserviceSupportExplanation3": "We provide a sample <a href=\"{0}\">Micro-service Demo Solution</a> that demonstrates a micro-service architecture implementation to help you create your own solution.",
"MicroserviceSupportExplanation4": "So, the short answer is: \"<strong>Yes, it supports micro-service architecture</strong>\".",
"MicroserviceSupportExplanation5": "However, a micro-service system is a solution and every solution will have different requirements, network topology, communication scenarios, authentication possibilities, database separation/sharing decisions, runtime configurations, 3rd party system integrations and many more.",
"MicroserviceSupportExplanation6": "The ABP Framework and the ABP Commercial provides infrastructure for micro-service scenarios, micro-service compatible modules, samples and documentation to help you to build your own solution. But don't expect to directly download your dream solution pre-built for you. You will need to understand it and bring some parts together based on your requirements.",
"WhereCanIDownloadSourceCode": "Where can I download source-code?",
"WhereCanIDownloadSourceCodeExplanation": "You can download the source code of all ABP modules, Angular packages and themes via ABP Suite or ABP CLI. See <a href=\"{0}\">How to download source-code?</a>",
"MicroserviceSupportExplanation6": "The ABP Framework and ABP Commercial provide infrastructure for micro-service scenarios, micro-service compatible modules, samples and documentation to help you build your own solution. But don't expect to directly download your dream solution pre-built for you. You will need to understand it and bring specific parts together based on your requirements.",
"WhereCanIDownloadSourceCode": "Where can I download the source-code?",
"WhereCanIDownloadSourceCodeExplanation": "You can download the source code of all the ABP modules, Angular packages and themes via ABP Suite or ABP CLI. Check out <a href=\"{0}\">How to download the source-code?</a>",
"ComputerLimitation": "How many computers can a developer login when developing ABP?",
"ComputerLimitationExplanation": "We specifically permit <strong>{0} computers</strong> per individual/licensed developer. Whenever there is a need for a developer to develop ABP Commercial products on a third machine, an e-mail should be sent to license@abp.io explaining the situation and we will then make the appropriate allocation in our system.",
"RefundPolicy": "Do you have a refund policy?",
"RefundPolicyExplanation": "You can request a refund within <strong>30 days</strong> of your license purchase. The Business and Enterprise license types have source-code download option, therefore refunds are not available for the Business and Enterprise (and any licenses that include a right to receive source-code). In addition, no refunds are made for renewals and second license purchases.",
"RefundPolicyExplanation": "You can request a refund within <strong>30 days</strong> of your license purchase. The Business and Enterprise license types have source-code download option, therefore refunds are not available for the Business and Enterprise (along with any licenses that include a right to receive source-code). In addition, no refunds are made for renewals and second license purchases.",
"HowCanIRefundVat": "How can I refund VAT?",
"HowCanIRefundVatExplanation1": "If you made the payment using 2Checkout, you can refund VAT via your 2Checkout account:",
"HowCanIRefundVatExplanation2": "Log in into your <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\">2Checkout</a> account",
"HowCanIRefundVatExplanation2": "Log in to your <a href=\"https://secure.2checkout.com/cpanel/login.php\" target=\"_blank\">2Checkout</a> account",
"HowCanIRefundVatExplanation3": "Find the appropriate order and press \"Refund Belated VAT\" (enter your VAT ID)",
"HowCanIGetMyInvoice": "How can I get my invoice?",
"HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: Iyzico and 2Checkout. If you purchase your license through the 2Checkout gateway, it sends the PDF invoice to your email address, see <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\">2Checkout invoicing.</a> If you purchase through the Iyzico gateway, with custom purchase link or via bank wire transfer, we will prepare and send your invoice. You can request or download your invoice from the <a href=\"{0}\">organization management page</a>. Before contacting us for the invoice, check your organization management page!",
"HowCanIGetMyInvoiceExplanation": "There are 2 payment gateways for purchasing a license: Iyzico and 2Checkout. If you purchase your license through the 2Checkout gateway, it sends the PDF invoice to your email address, check out <a href=\"https://knowledgecenter.2checkout.com/Documentation/03Billing-and-payments/Payment-operations/How-do-invoices-work\">2Checkout invoicing.</a> If you purchase through the Iyzico gateway, with a custom purchase link or via a bank wire transfer, we will prepare and send your invoice. You can request or download your invoice from the <a href=\"{0}\">organization management page</a>. Before contacting us for the invoice, check your organization management page!",
"Forum": "Forum",
"SupportExplanation": "ABP Commercial licenses provides a premium forum support by a team consists of the ABP Framework experts.",
"PrivateTicket": "Private Ticket",
@ -290,7 +289,7 @@
"PrivateTicketEmailSupport": "Private ticket & email support",
"BuyNow": "Buy Now",
"PayViaAmexCard": "How can I pay via my AMEX card?",
"PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to the security measures. In this case, you can pay through the alternative payment gateway '2Checkout'.",
"PayViaAmexCardDescription": "The default payment gateway 'Iyzico' may decline some AMEX credit cards due to security measures. In this case, you can pay through the alternative payment gateway '2Checkout'.",
"ThankYou": "Thank you",
"InvalidReCaptchaErrorMessage": "There was an error verifying reCAPTCHA. Please try again.",
"CompanyName": "Company name",
@ -392,7 +391,7 @@
"TrialLicenseExpiredInfo": "Your trial license period has expired!",
"CommercialNewsletterConfirmationMessage": "I agree to the <a href=\"https://commercial.abp.io/TermsConditions\">Terms & Conditions</a> and <a href=\"https://commercial.abp.io/Privacy\">Privacy Policy</a>.",
"DowngradeLicensePlan": "Can I downgrade to a lower license plan in the future?",
"DowngradeLicensePlanExplanation": "You cannot downgrade your existing license plan. But you can purchase a new lower license plan and continue to your development on the new license. After you purchase a lower license, you just need to login to your new license plan via ABP CLI command: ` abp login <username> -o <organization> `.",
"DowngradeLicensePlanExplanation": "You cannot downgrade your existing license plan. But you can purchase a new lower license plan and continue your development on the new license. After you purchase a lower license, you just need to login to your new license plan via ABP CLI command: ` abp login <username> -o <organization> `.",
"LicenseTransfer": "Can a license be transferred from one developer to another?",
"LicenseTransferExplanation": "Yes! When you purchase a license, you become the license holder, hence you will have access to the organization management page. An organization has owner and developer roles. Owners can manage the developer seats and assign developers. Each assigned developer will login via ABP CLI command into the system and will have development and support permissions.",
"UserOwnerDescription": "The 'Owner' of the organization is the admin of this account. He/she manages the organization by purchasing licenses, allocating developers. An 'Owner' cannot write code in the ABP Commercial projects, cannot download the ABP sample projects, or cannot ask questions on the support website. If you want to do all these, you have to add yourself as a developer too.",
@ -400,6 +399,9 @@
"RemoveCurrentUserFromOrganizationWarningMessage": "You are removing yourself from your own organization. You will no longer be able to manage this organization, do you confirm?",
"RenewExistingOrganizationOrCreateNewOneMessage": "You can renew the license of your organization(s) by clicking the below \"Extend Now\" button(s) and thus you can extend the license expiry date by 1 year. If you continue to checkout, you will have a new organization. Do you want to continue with a new organization?",
"ExtendNow": "Extend Now",
"ContinueWithNewOrganization": "Continue with a new organization"
"ContinueWithNewOrganization": "Continue with a new organization",
"RenewLicenseEarly": "If I renew my license early, will I get the full year?",
"RenewLicenseEarylExplanation": "When you renew your license before your license expiry date, 1 year will be added to your license expiry date. For example, if your license expires on {0}-06-06 and you renew it on {0}-01-01, your new license expiry date will be {1}-06-06."
}
}

18
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/es.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "¿Cuál es la diferencia entre ampliar y actualizar la licencia?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "¿Cuál es el costo de renovación de la licencia después de 1 año?",
"LicenseRenewalCostExplanation": "La tasa de renovación (extensión) de todas las licencias perpetuas comerciales de ABP es {0} del precio de lista de la licencia. El precio de renovación de la licencia de equipo estándar es de $ {1}, la licencia comercial estándar es de $ {2} y la licencia empresarial estándar es de $ {3}. Si ya es cliente, <a href='{4}' target='_blank'> inicie sesión en su cuenta </a> para revisar los precios de renovación disponibles.",
"LicenseRenewalCostExplanation": "El precio de renovación (extensión) de la Licencia de equipo estándar es de $ {0}, la Licencia comercial estándar es de $ {1} y la Licencia empresarial estándar es de $ {2}. Si ya es cliente, <a href='{3}' target='_blank'> inicie sesión en su cuenta </a> para revisar los precios de renovación disponibles.",
"HowDoIRenewMyLicense": "¿Cómo renuevo mi licencia?",
"HowDoIRenewMyLicenseExplanation": "Puede renovar su licencia navegando a la <a href='{0}' target='_blank'> página de administración de la organización </a>. Para aprovechar nuestras tarifas de renovación anticipada con descuento, asegúrese de renovar antes de que expire su licencia. Sin embargo, no se preocupe por no saber cuándo se cierra su oportunidad de Renovación Temprana. Recibirá 3 correos electrónicos de recordatorio antes de que expire su suscripción. Los enviaremos 30 días, 7 días y 1 día antes del vencimiento.",
"IsSourceCodeIncluded": "¿Mi licencia incluye el código fuente de los módulos y temas comerciales?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "¿Puedo cambiar los desarrolladores registrados de mi organización en el futuro?",
"ChangingDevelopersExplanation": "Además de agregar nuevos desarrolladores a su licencia, también puede cambiar los desarrolladores existentes (puede eliminar un desarrollador y agregar uno nuevo al mismo puesto) sin ningún costo adicional.",
"WhatHappensWhenLicenseEnds": "¿Qué sucede cuando finaliza mi período de licencia?",
"WhatHappensWhenLicenseEndsExplanation1": "El tipo de licencia comercial de ABP es <a href=\"{0}\" target=\"_blank\"> licencia perpetua </a>. Una vez que expire su licencia, puede continuar desarrollando su proyecto. Y no está obligado a renovar su licencia. Su licencia viene con un plan de soporte y actualizaciones de un año listo para usar. Para continuar recibiendo nuevas funciones, mejoras de rendimiento, corrección de errores, soporte y continuar usando ABP Suite, asegúrese de renovar su plan cada año. Cuando su licencia expire, no podrá obtener más de los siguientes beneficios;",
"WhatHappensWhenLicenseEndsExplanation1": "El tipo de licencia comercial de ABP es <a href=\"{0}\" target=\"_blank\"> licencia perpetua </a>. Una vez que expire su licencia, puede continuar desarrollando su proyecto. Y no está obligado a renovar su licencia. Su licencia viene con una actualización de un año y un plan de soporte listo para usar. Para continuar obteniendo nuevas funciones, mejoras de rendimiento, corrección de errores, soporte y continuar usando ABP Suite, necesita renovar su licencia. Cuando su licencia expire, no obtendrá los siguientes beneficios;",
"WhatHappensWhenLicenseEndsExplanation2": "No puede crear nuevas soluciones utilizando ABP Commercial, pero puede continuar desarrollando sus aplicaciones existentes para siempre.",
"WhatHappensWhenLicenseEndsExplanation3": "Podrá obtener actualizaciones para los módulos y temas dentro de su versión PRINCIPAL. Por ejemplo; si está utilizando la v3.2.0 de un módulo, aún puede obtener actualizaciones para la v3.x.x (v3.3.0, v3.5.2 ... etc.) de ese módulo. Pero no puede obtener actualizaciones para la próxima versión principal (como v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Podrá obtener actualizaciones para los módulos y temas dentro de su versión PRINCIPAL (excepto las versiones RC o Preview). Por ejemplo; Si está utilizando la v3.2.0 de un módulo, aún puede obtener actualizaciones para la v3.x.x (v3.3.0, v3.5.2 ... etc.) de ese módulo. Pero no puede obtener actualizaciones para la próxima versión principal (como v4.x, v5.x). Por ejemplo, cuando su licencia expiró, la última versión fue la v4.4.3 y la última versión preliminar fue la v5.0.0-rc.2, puede acceder a la v4.X.X pero no a la v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "No puede instalar nuevos módulos y temas agregados a la plataforma comercial de ABP después de que finalice su licencia.",
"WhatHappensWhenLicenseEndsExplanation5": "No puede utilizar ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Ya no puede obtener la <a href=\"{0}\"> asistencia premium </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Puede renovar su suscripción si desea continuar obteniendo estos beneficios. Si renueva su suscripción dentro de 1 mes después de que expire su licencia, se aplica un descuento del 20%.",
"WhatHappensWhenLicenseEndsExplanation7": "Puede extender (renovar) su licencia si desea continuar recibiendo estos beneficios. Si extiende su licencia dentro de <strong> 1 mes </strong> después de que caduque su licencia, se aplicarán los siguientes descuentos: Licencia de equipo {0}% de descuento, Licencia comercial {1}% de descuento, Licencia empresarial {2}% de descuento .",
"WhenShouldIRenewMyLicense": "¿Cuándo debo renovar mi licencia?",
"WhenShouldIRenewMyLicenseExplanation1": "Si renueva su licencia dentro de <strong> 1 mes </strong> después de que caduque, se aplicará un descuento del 20%.",
"WhenShouldIRenewMyLicenseExplanation2": "Si renueva su licencia después de 1 mes desde la fecha de vencimiento de su licencia, el precio de renovación será el mismo que el precio de compra de la licencia y no habrá descuento por su renovación.",
"WhenShouldIRenewMyLicenseExplanation": "Si renueva su licencia dentro de <strong> 1 mes </strong> después de su vencimiento, se aplicarán los siguientes descuentos: Licencia de equipo {0}% de descuento, Licencia comercial {1}% de descuento, Licencia empresarial {2}% de descuento . Si renueva su licencia <strong> 1 mes </strong> después de la fecha de vencimiento de su licencia, el precio de renovación será el mismo que el precio de compra de la licencia y no habrá descuento en su renovación.",
"TrialPlan": "¿Tiene un plan de prueba?",
"TrialPlanExplanation": "Por ahora, ABP Commercial no tiene un plan de prueba. Para las licencias Team ofrecemos 30 días de garantía de devolución de dinero. Solo puede solicitar un reembolso en los primeros 30 días. Para las licencias Business y Enterprise, proporcionamos un reembolso del 60% en 30 días. Esto se debe a que las licencias Business y Enterprise incluyen el código fuente completo de todos los módulos y temas.",
"DoYouAcceptBankWireTransfer": "¿Aceptan transferencia bancaria?",
"DoYouAcceptBankWireTransferExplanation": "Sí, aceptamos transferencia bancaria. <br /> Después de enviar la tarifa de la licencia mediante transferencia bancaria, envíenos un correo electrónico a info@abp.io con su recibo y el tipo de licencia solicitada. Nuestra información de cuenta bancaria internacional:",
"DoYouAcceptBankWireTransferExplanation": "Sí, aceptamos transferencia bancaria. <br /> Después de enviar la tarifa de la licencia mediante transferencia bancaria, envíenos un correo electrónico a accounting@abp.io con su recibo y el tipo de licencia solicitada. Nuestra información de cuenta bancaria internacional:",
"HowToUpgrade": "¿Cómo actualizar las aplicaciones existentes cuando hay una nueva versión disponible?",
"HowToUpgradeExplanation1": "Cuando crea una nueva aplicación utilizando ABP Commercial, todos los módulos y el tema se utilizan como paquetes NuGet y NPM. Por lo tanto, puede actualizar fácilmente los paquetes cuando haya una nueva versión disponible.",
"HowToUpgradeExplanation2": "Además de las actualizaciones estándar de NuGet/NPM, <a href=\"{0}\"> ABP CLI </a> proporciona un comando de actualización que busca y actualiza automáticamente todos los paquetes relacionados con ABP en su solución.",
@ -390,6 +389,9 @@
"TrialLicenseExpireMessage": "Está utilizando la licencia de prueba y su licencia de prueba caducará el {0}.",
"TryForFree": "Prueba gratis",
"TrialLicenseExpiredInfo": "¡Su período de licencia de prueba ha expirado!",
"CommercialNewsletterConfirmationMessage": "Acepto los <a href=\"https://commercial.abp.io/TermsConditions\"> Términos y condiciones </a> y la <a href=\"https://commercial.abp.io/Privacy\"> Política de privacidad </a>."
"CommercialNewsletterConfirmationMessage": "Acepto los <a href=\"https://commercial.abp.io/TermsConditions\"> Términos y condiciones </a> y la <a href=\"https://commercial.abp.io/Privacy\"> Política de privacidad </a>.",
"ContinueWithNewOrganization": "Continuar con una nueva organización",
"RenewLicenseEarly": "Si renuevo mi licencia antes, ¿obtendré el año completo?",
"RenewLicenseEarylExplanation": "Cuando renueve su licencia antes de la fecha de vencimiento de su licencia, se agregará 1 año a la fecha de vencimiento de su licencia. Por ejemplo, si su licencia vence el {0} -06-06 y la renueva el {0} -01-01, la fecha de vencimiento de su nueva licencia será {1} -06-06."
}
}

18
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fi.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Mitä eroa on lisenssin laajennuksella ja päivityksellä?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Extension: </strong> en prolongeant/renouvelant votre licence, vous continuerez à bénéficier d'une assistance premium et à des mises à jour majeures pour les modules et les thèmes. De plus, vous pourrez continuer à créer de nouveaux projets. Et vous pourrez toujours utiliser ABP Suite, ce qui accélère votre développement.<hr/><strong> Mise à niveau: </strong> En mettant à jour votre licence, vous passerez à un plan de licence supérieur qui vous permettra d’obtenir des avantages supplémentaires . Consultez le <a href=\"/pricing\"> tableau de comparaison des licences </a> pour vérifier les différences entre les plans de licence.<strong> En revanche, lors de la mise à niveau, la date d'expiration de votre licence ne changera pas! </strong> Pour prolonger la date de fin de votre licence, vous devez prolonger votre licence.",
"LicenseRenewalCost": "Mitkä ovat lisenssin uusimiskustannukset vuoden kuluttua?",
"LicenseRenewalCostExplanation": "Kaikkien ABP Commercial perpetual -lisenssien uusimis- (laajennus) hinta on {0} lisenssiluettelohinnasta. Tavallisen tiimilisenssin uusimishinta on $ {1}, tavallinen yrityslisenssi on $ {2} ja tavallinen yrityslisenssi on $ {3}. Jos olet jo asiakas, <a href='{4}' target='_blank'> kirjaudu tilillesi </a> ja tarkista käytettävissä oleva uusimishinta.",
"LicenseRenewalCostExplanation": "Standardin tiimilisenssin uusimishinta (pidennys) on ${0}, normaalin yrityslisenssin hinta on {1} $ ja normaalin yrityslisenssin hinta on {2} $. Jos olet jo asiakas, <a href='{3}' target='_blank'>kirjaudu sisään tiliisi</a> ja tarkista käytettävissä olevat uusimishinnat.",
"HowDoIRenewMyLicense": "Kuinka uusin lisenssin?",
"HowDoIRenewMyLicenseExplanation": "Voit uusia käyttöoikeutesi siirtymällä <a href='{0}' target='_blank'> organisaation hallintasivulle </a>. Jotta voisit hyödyntää alennettujen varhaisen uusimisen hintojamme, muista uusia ennen lisenssin voimassaolon päättymistä. Älä huoli siitä, ettet tiedä, milloin Varhaisen uudistamisen mahdollisuus sulkeutuu. Saat kaksi muistutussähköpostia ennen tilauksesi päättymistä. Lähetämme ne 30 päivää, 7 päivää ennen vanhenemista.",
"IsSourceCodeIncluded": "Sisältääkö lisenssini kaupallisten moduulien ja teemojen lähdekoodin?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Voinko muuttaa organisaationi rekisteröityneitä kehittäjiä tulevaisuudessa?",
"ChangingDevelopersExplanation": "Uusien kehittäjien lisäämisen lisenssiin lisäksi voit myös muuttaa olemassa olevia kehittäjiä (voit poistaa kehittäjän ja lisätä uuden samalle paikalle) ilman lisäkustannuksia.",
"WhatHappensWhenLicenseEnds": "Mitä tapahtuu, kun lisenssikauteni päättyy?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial -lisenssityyppi on <a href=\"{0}\" target=\"_blank\"> jatkuva lisenssi </a>. Kun lisenssi vanhenee, voit jatkaa projektisi kehittämistä. Ja sinun ei tarvitse uudistaa lisenssiäsi. Lisenssisi mukana toimitetaan yhden vuoden päivitys- ja tukisuunnitelma. Jos haluat edelleen saada uusia ominaisuuksia, suorituskyvyn parannuksia, virhekorjauksia, tukea ja jatkaa ABP Suite -sovelluksen käyttöä, muista uusia suunnitelma joka vuosi. Kun lisenssi vanhenee, et voi saada enemmän seuraavista eduista;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial -lisenssityyppi on <a href=\"{0}\" target=\"_blank\">ikuinen lisenssi</a>. Kun lisenssisi vanhenee, voit jatkaa projektisi kehittämistä. Et ole velvollinen uusimaan ajokorttiasi. Lisenssi sisältää yhden vuoden päivityksen ja tukisuunnitelman. Jotta voit jatkaa uusien ominaisuuksien, suorituskyvyn parannuksia, virheenkorjauksia, tukea ja jatkaa ABP Suiten käyttöä, sinun on uusittava lisenssisi. Kun lisenssisi vanhenee, et saa seuraavia etuja;",
"WhatHappensWhenLicenseEndsExplanation2": "Et voi luoda uusia ratkaisuja ABP Commercial -sovelluksella, mutta voit jatkaa olemassa olevien sovellusten kehittämistä ikuisesti.",
"WhatHappensWhenLicenseEndsExplanation3": "Voit saada päivityksiä moduuleista ja teemoista MAJOR-versiostasi. Esimerkiksi; jos käytät moduulin v3.2.0-versiota, voit silti saada päivityksiä kyseisen moduulin versiolle v3.x.x (v3.3.0, v3.5.2... jne.). Mutta et voi saada päivityksiä seuraavaan pääversioon (kuten v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Voit saada päivityksiä moduuleille ja teemoille MAJOR-versiosi sisällä (paitsi RC- tai esikatseluversiot). Esimerkiksi; jos käytät moduulin v3.2.0:aa, voit silti saada päivityksiä kyseisen moduulin v3.x.x:lle (v3.3.0, v3.5.2... jne.). Mutta et voi saada päivityksiä seuraavaan pääversioon (kuten v4.x, v5.x). Esimerkiksi kun lisenssisi vanheni, viimeisin versio oli v4.4.3 ja uusin esikatseluversio v5.0.0-rc.2, voit käyttää v4.X.X, mutta et voi käyttää v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Et voi asentaa uusia moduuleja ja teemoja, jotka on lisätty ABP Commercial -alustalle käyttöoikeuden päättymisen jälkeen.",
"WhatHappensWhenLicenseEndsExplanation5": "Et voi käyttää ABP Suitea.",
"WhatHappensWhenLicenseEndsExplanation6": "Et voi enää saada <a href=\"{0}\"> premium-tukea </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Voit uusia tilauksesi, jos haluat jatkaa näiden etujen saamista. Tilauksen uusimisessa on 20% alennus.",
"WhatHappensWhenLicenseEndsExplanation7": "Voit jatkaa (uusia) lisenssiäsi, jos haluat jatkaa näiden etujen saamista. Jos jatkat lisenssiäsi <strong>1 kuukauden</strong> kuluessa lisenssin vanhenemisesta, seuraavat alennukset sovelletaan: Team License {0}% alennus, Business License {1}% alennus, Enterprise License {2}% alennus .",
"WhenShouldIRenewMyLicense": "Milloin minun pitäisi uusia lisenssini?",
"WhenShouldIRenewMyLicenseExplanation1": "Jos uusit lisenssin <strong> kuukauden kuluessa </strong> lisenssin voimassaolon päättymisestä, lisenssin kokonaishintaan sovelletaan 20% alennusta.",
"WhenShouldIRenewMyLicenseExplanation2": "Jos uusit lisenssin kuukauden kuluttua lisenssin voimassaolon päättymispäivästä, uusimishinta on sama kuin lisenssin ostohinta eikä uusimiselle ole alennusta.",
"WhenShouldIRenewMyLicenseExplanation": "Jos uusit lisenssisi <strong>1 kuukauden</strong> kuluessa lisenssin vanhenemisesta, seuraavat alennukset sovelletaan: Team License {0} % alennus, Business License {1} % alennus, Enterprise License {2} % alennus . Jos uusit lisenssisi <strong>1 kuukauden</strong> lisenssin päättymispäivän jälkeen, uusimishinta on sama kuin lisenssin ostohinta, eikä uusimisesta saa alennusta.",
"TrialPlan": "Onko sinulla kokeilusuunnitelma?",
"TrialPlanExplanation": "Toistaiseksi ABP Commercialilla ei ole kokeilusuunnitelmaa. Joukkueen lisensseille tarjoamme 30 päivän rahanpalautustakuun. Voit vain pyytää hyvitystä 30 ensimmäisen päivän aikana. Yritys- ja yrityslisensseille hyvitämme 60% 30 päivässä. Tämä johtuu siitä, että yritys- ja yrityslisenssit sisältävät kaikkien moduulien ja teemojen täydellisen lähdekoodin.",
"DoYouAcceptBankWireTransfer": "Hyväksytkö pankkisiirron?",
"DoYouAcceptBankWireTransferExplanation": "Kyllä, hyväksymme pankkisiirron.<br/> Kun olet lähettänyt lisenssimäärän pankkisiirrolla, lähetä meille kuitti ja pyydetty lisenssityyppi sähköpostitse.<br/> Kansainväliset pankkitilitiedot:",
"DoYouAcceptBankWireTransferExplanation": "Kyllä, hyväksymme pankkisiirron.<br />Kun olet lähettänyt lisenssimaksun pankkisiirrolla, lähetä meille sähköposti osoitteeseen accounting@abp.io kuittisi ja pyydetty lisenssityyppi. Kansainväliset pankkitilitietomme:",
"HowToUpgrade": "Kuinka päivittää olemassa olevia sovelluksia, kun uusi versio on saatavilla?",
"HowToUpgradeExplanation1": "Kun luot uuden sovelluksen ABP Commercial -sovelluksella, kaikkia moduuleja ja teemaa käytetään NuGet- ja NPM-paketteina. Joten voit päivittää paketit helposti, kun uusi versio on saatavilla.",
"HowToUpgradeExplanation2": "Normaalien NuGet/NPM-päivitysten lisäksi <a href=\"{0}\"> ABP CLI </a> tarjoaa päivityskomennon, joka etsii ja päivittää kaikki ratkaisusi ABP-paketit.",
@ -390,6 +389,9 @@
"TrialLicenseExpireMessage": "Käytät kokeiluversiota, ja kokeilukäyttölupasi vanhenee {0}.",
"TryForFree": "Kokeile ilmaiseksi",
"TrialLicenseExpiredInfo": "Kokeilulisenssijaksosi on umpeutunut!",
"CommercialNewsletterConfirmationMessage": "Hyväksyn <a href=\"https://commercial.abp.io/TermsConditions\">käyttöehdot</a> ja <a href=\"https://commercial.abp.io/Privacy\">tietosuojakäytännön </a>."
"CommercialNewsletterConfirmationMessage": "Hyväksyn <a href=\"https://commercial.abp.io/TermsConditions\">käyttöehdot</a> ja <a href=\"https://commercial.abp.io/Privacy\">tietosuojakäytännön </a>.",
"ContinueWithNewOrganization": "Jatka uudessa organisaatiossa",
"RenewLicenseEarly": "Jos uusin ajokorttini etuajassa, saanko koko vuoden?",
"RenewLicenseEarylExplanation": "Kun uusit lisenssisi ennen lisenssin vanhenemispäivää, lisenssin voimassaolopäivään lisätään 1 vuosi. Jos lisenssisi vanhenee esimerkiksi {0}-06-06 ja uusit sen {0}-01-01, uusi lisenssisi päättymispäivä on {1}-06-06."
}
}

18
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/fr.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Quelle est la différence entre l'extension de licence et la mise à niveau?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Extension: </strong> en prolongeant/renouvelant votre licence, vous continuerez à bénéficier d'une assistance premium et à des mises à jour majeures pour les modules et les thèmes. De plus, vous pourrez continuer à créer de nouveaux projets. Et vous pourrez toujours utiliser ABP Suite, ce qui accélère votre développement.<hr/><strong> Mise à niveau: </strong> En mettant à jour votre licence, vous passerez à un plan de licence supérieur qui vous permettra d’obtenir des avantages supplémentaires . Consultez le <a href=\"/pricing\"> tableau de comparaison des licences </a> pour vérifier les différences entre les plans de licence.<strong> En revanche, lors de la mise à niveau, la date d'expiration de votre licence ne changera pas! </strong> Pour prolonger la date de fin de votre licence, vous devez prolonger votre licence.",
"LicenseRenewalCost": "Quel est le coût du renouvellement de la licence après 1 an?",
"LicenseRenewalCostExplanation": "Le taux de renouvellement (extension) de toutes les licences perpétuelles ABP Commercial correspond à {0} du prix catalogue de la licence. Le prix de renouvellement de la licence d'équipe standard est de {1} $, la licence professionnelle standard de {2} $ et la licence d'entreprise standard de {3} $. Si vous êtes déjà client, <a href='{4}' target='_blank'> connectez-vous à votre compte </a> pour consulter les tarifs de renouvellement disponibles.",
"LicenseRenewalCostExplanation": "Le prix de renouvellement (extension) de la licence d'équipe standard est de {0} $, la licence d'entreprise standard est de {1} $ et la licence d'entreprise standard est de {2} $. Si vous êtes déjà client, <a href='{3}' target='_blank'>connectez-vous à votre compte</a> pour consulter les tarifs de renouvellement disponibles.",
"HowDoIRenewMyLicense": "Comment renouveler ma licence?",
"HowDoIRenewMyLicenseExplanation": "Vous pouvez renouveler votre licence en accédant à la <a href='{0}' target='_blank'> page de gestion de l'organisation </a>. Afin de profiter de nos tarifs réduits de renouvellement anticipé, assurez-vous de renouveler avant l'expiration de votre licence. Cependant, ne vous inquiétez pas de ne pas savoir quand votre opportunité de renouvellement anticipé se termine. Vous recevrez 2 e-mails de rappel avant l'expiration de votre abonnement. Nous les enverrons dans les 30 jours, 7 jours avant l'expiration.",
"IsSourceCodeIncluded": "Ma licence inclut-elle le code source des modules et thèmes commerciaux?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Puis-je changer les développeurs enregistrés de mon organisation à l'avenir?",
"ChangingDevelopersExplanation": "En plus d'ajouter de nouveaux développeurs à votre licence, vous pouvez également modifier les développeurs existants (vous pouvez supprimer un développeur et en ajouter un nouveau sur le même siège) sans aucun coût supplémentaire.",
"WhatHappensWhenLicenseEnds": "Que se passe-t-il à la fin de ma période de licence?",
"WhatHappensWhenLicenseEndsExplanation1": "Le type de licence commerciale ABP est <a href=\"{0}\" target=\"_blank\"> licence perpétuelle </a>. Une fois votre licence expirée, vous pouvez continuer à développer votre projet. Et vous n'êtes pas obligé de renouveler votre licence. Votre licence est livrée avec un plan de mise à jour et de support d'un an prêt à l'emploi. Pour continuer à recevoir de nouvelles fonctionnalités, des améliorations de performances, des corrections de bogues, une assistance et continuer à utiliser ABP Suite, assurez-vous de renouveler votre plan chaque année. Lorsque votre licence expirera, vous ne pourrez plus bénéficier des avantages suivants;",
"WhatHappensWhenLicenseEndsExplanation1": "Le type de licence commerciale ABP est <a href=\"{0}\" target=\"_blank\">licence perpétuelle</a>. Une fois votre licence expirée, vous pouvez continuer à développer votre projet. Et vous n'êtes pas obligé de renouveler votre licence. Votre licence est livrée avec une mise à jour d'un an et un plan d'assistance prêt à l'emploi. Pour continuer à obtenir de nouvelles fonctionnalités, des améliorations de performances, des corrections de bogues, une assistance et continuer à utiliser ABP Suite, vous devez renouveler votre licence. À l'expiration de votre licence, vous ne bénéficierez pas des avantages suivants :",
"WhatHappensWhenLicenseEndsExplanation2": "Vous ne pouvez pas créer de nouvelles solutions en utilisant ABP Commercial, mais vous pouvez continuer à développer vos applications existantes pour toujours.",
"WhatHappensWhenLicenseEndsExplanation3": "Vous pourrez obtenir des mises à jour pour les modules et les thèmes de votre version MAJEURE. Par example; si vous utilisez la v3.2.0 d'un module, vous pouvez toujours obtenir des mises à jour pour la v3.x.x (v3.3.0, v3.5.2... etc.) de ce module. Mais vous ne pouvez pas obtenir de mises à jour pour la prochaine version majeure (comme v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Vous pourrez obtenir des mises à jour pour les modules et les thèmes de votre version MAJEURE (à l'exception des versions RC ou Preview). Par example; si vous utilisez la v3.2.0 d'un module, vous pouvez toujours obtenir des mises à jour pour la v3.x.x (v3.3.0, v3.5.2... etc.) de ce module. Mais vous ne pouvez pas obtenir de mises à jour pour la prochaine version majeure (comme v4.x, v5.x). Par exemple, lorsque votre licence a expiré, la dernière version était la v4.4.3 et la dernière version d'aperçu était la v5.0.0-rc.2, vous pouvez accéder à la v4.X.X mais vous ne pouvez pas accéder à la v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Vous ne pouvez pas installer de nouveaux modules et thèmes ajoutés à la plate-forme ABP Commercial après la fin de votre licence.",
"WhatHappensWhenLicenseEndsExplanation5": "Vous ne pouvez pas utiliser ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Vous ne pouvez plus bénéficier de l '<a href=\"{0}\"> assistance premium </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Vous pouvez renouveler votre abonnement si vous souhaitez continuer à bénéficier de ces avantages. Il y a une réduction de 20% lorsque vous renouvelez votre abonnement.",
"WhatHappensWhenLicenseEndsExplanation7": "Vous pouvez prolonger (renouveler) votre licence si vous souhaitez continuer à bénéficier de ces avantages. Si vous prolongez votre licence dans un délai de <strong>1 mois</strong> après l'expiration de votre licence, les remises suivantes seront appliquées : licence d'équipe {0} % de remise, licence d'entreprise {1} % de remise, licence d'entreprise {2} % de remise .",
"WhenShouldIRenewMyLicense": "Quand dois-je renouveler ma licence?",
"WhenShouldIRenewMyLicenseExplanation1": "Si vous renouvelez votre licence dans un délai de <strong> 1 mois </strong> après l'expiration de votre licence, une réduction de 20% sera appliquée au prix total de la licence.",
"WhenShouldIRenewMyLicenseExplanation2": "Si vous renouvelez votre licence 1 mois après la date d'expiration de votre licence, le prix de renouvellement sera le même que le prix d'achat de la licence et il n'y aura pas de réduction pour votre renouvellement.",
"WhenShouldIRenewMyLicenseExplanation": "Si vous renouvelez votre licence dans un délai de <strong>1 mois</strong> après l'expiration de votre licence, les remises suivantes seront appliquées : licence d'équipe {0} % de remise, licence d'entreprise {1} % de remise, licence d'entreprise {2} % de remise . Si vous renouvelez votre licence <strong>1 mois</strong> après la date d'expiration de votre licence, le prix de renouvellement sera le même que le prix d'achat de la licence et il n'y aura aucune remise sur votre renouvellement.",
"TrialPlan": "Avez-vous un plan d'essai?",
"TrialPlanExplanation": "Pour l'instant, ABP Commercial n'a pas de plan d'essai. Pour les licences Team, nous offrons une garantie de remboursement de 30 jours. Vous pouvez simplement demander un remboursement dans les 30 premiers jours. Pour les licences Business et Enterprise, nous fournissons un remboursement de 60% en 30 jours. En effet, les licences Business et Enterprise incluent le code source complet de tous les modules et thèmes.",
"DoYouAcceptBankWireTransfer": "Acceptez-vous les virements bancaires?",
"DoYouAcceptBankWireTransferExplanation": "Oui, nous acceptons les virements bancaires.<br/> Après avoir envoyé le montant de la licence par virement bancaire, envoyez-nous votre reçu et le type de licence demandé par e-mail.<br/> Nos coordonnées bancaires internationales:",
"DoYouAcceptBankWireTransferExplanation": "Oui, nous acceptons les virements bancaires.<br />Après avoir envoyé les frais de licence par virement bancaire, envoyez-nous par e-mail à accounting@abp.io votre reçu et le type de licence demandé. Nos coordonnées bancaires internationales :",
"HowToUpgrade": "Comment mettre à niveau des applications existantes lorsqu'une nouvelle version est disponible?",
"HowToUpgradeExplanation1": "Lorsque vous créez une nouvelle application à l'aide d'ABP Commercial, tous les modules et le thème sont utilisés en tant que packages NuGet et NPM. Ainsi, vous pouvez facilement mettre à jour les packages lorsqu'une nouvelle version est disponible.",
"HowToUpgradeExplanation2": "Outre les mises à niveau standard de NuGet/NPM, <a href=\"{0}\"> ABP CLI </a> fournit une commande de mise à jour qui recherche et met automatiquement à niveau tous les packages associés à ABP dans votre solution.",
@ -390,6 +389,9 @@
"TrialLicenseExpireMessage": "Vous utilisez la licence d'essai et votre licence d'essai expirera le {0}.",
"TryForFree": "Essayer gratuitement",
"TrialLicenseExpiredInfo": "Votre période de licence d'essai a expiré !",
"CommercialNewsletterConfirmationMessage": "J'accepte les <a href=\"https://commercial.abp.io/TermsConditions\">Conditions générales</a> et la <a href=\"https://commercial.abp.io/Privacy\">Politique de confidentialité </a>."
"CommercialNewsletterConfirmationMessage": "J'accepte les <a href=\"https://commercial.abp.io/TermsConditions\">Conditions générales</a> et la <a href=\"https://commercial.abp.io/Privacy\">Politique de confidentialité </a>.",
"ContinueWithNewOrganization": "Continuer avec une nouvelle organisation",
"RenewLicenseEarly": "Si je renouvelle ma licence plus tôt, obtiendrai-je l'année complète ?",
"RenewLicenseEarylExplanation": "Lorsque vous renouvelez votre licence avant la date d'expiration de votre licence, 1 an sera ajouté à la date d'expiration de votre licence. Par exemple, si votre licence expire le {0}-06-06 et que vous la renouvelez le {0}-01-01, la nouvelle date d'expiration de votre licence sera le {1}-06-06."
}
}

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hi.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "लाइसेंस विस्तार और उन्नयन के बीच क्या अंतर है?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "1 वर्ष के बाद लाइसेंस नवीनीकरण लागत क्या है?",
"LicenseRenewalCostExplanation": "सभी एबीपी वाणिज्यिक स्थायी लाइसेंसों की नवीनीकरण (विस्तार) दर लाइसेंस सूची मूल्य का {0} है। मानक टीम लाइसेंस का नवीनीकरण मूल्य ${1} है, मानक व्यवसाय लाइसेंस ${2} है और मानक एंटरप्राइज़ लाइसेंस ${3} है। यदि आप पहले से ही ग्राहक हैं, तो उपलब्ध नवीनीकरण मूल्य-निर्धारण की समीक्षा के लिए <a href='{4}' target='_blank'>अपने खाते में लॉग इन करें</a>।",
"LicenseRenewalCostExplanation": "मानक टीम लाइसेंस का नवीनीकरण (विस्तार) मूल्य ${0} है, मानक व्यवसाय लाइसेंस ${1} है और मानक एंटरप्राइज़ लाइसेंस ${2} है। यदि आप पहले से ही एक ग्राहक हैं, तो उपलब्ध नवीनीकरण मूल्य निर्धारण की समीक्षा के लिए <a href='{3}' target='_blank'>अपने खाते में लॉग इन करें</a>।",
"HowDoIRenewMyLicense": "मैं अपने लाइसेंस का नवीनीकरण कैसे करूँ?",
"HowDoIRenewMyLicenseExplanation": "आप <a href='{0}' target='_blank'>संगठन प्रबंधन पृष्ठ</a> पर नेविगेट करके अपने लाइसेंस का नवीनीकरण कर सकते हैं। हमारी रियायती प्रारंभिक नवीनीकरण दरों का लाभ उठाने के लिए, अपने लाइसेंस की समय सीमा समाप्त होने से पहले नवीनीकरण करना सुनिश्चित करें। हालाँकि, यह जानने की चिंता न करें कि आपका प्रारंभिक नवीनीकरण अवसर कब बंद होगा। आपकी सदस्यता समाप्त होने से पहले आपको 2 अनुस्मारक ई-मेल प्राप्त होंगे। हम उन्हें समाप्ति से ७ दिन पहले, ३० दिनों में भेजेंगे।",
"IsSourceCodeIncluded": "क्या मेरे लाइसेंस में वाणिज्यिक मॉड्यूल और थीम का स्रोत कोड शामिल है?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "क्या मैं भविष्य में अपने संगठन के पंजीकृत डेवलपर्स को बदल सकता हूं?",
"ChangingDevelopersExplanation": "अपने लाइसेंस में नए डेवलपर्स को जोड़ने के अलावा, आप मौजूदा डेवलपर्स को भी बदल सकते हैं (आप एक डेवलपर को हटा सकते हैं और एक ही सीट पर एक नया जोड़ सकते हैं) बिना किसी अतिरिक्त लागत के।",
"WhatHappensWhenLicenseEnds": "मेरे लाइसेंस की अवधि समाप्त होने पर क्या होता है?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP वाणिज्यिक लाइसेंस प्रकार <a href=\"{0}\" target=\"_blank\">स्थायी लाइसेंस</a> है। आपके लाइसेंस की समय सीमा समाप्त होने के बाद, आप अपने प्रोजेक्ट को विकसित करना जारी रख सकते हैं। और आप अपने लाइसेंस को नवीनीकृत करने के लिए बाध्य नहीं हैं। आपका लाइसेंस बॉक्स से बाहर एक साल के अपडेट और समर्थन योजना के साथ आता है। नई सुविधाओं, प्रदर्शन में सुधार, बग फिक्स, समर्थन प्राप्त करना जारी रखने और एबीपी सूट का उपयोग जारी रखने के लिए, हर साल अपनी योजना को नवीनीकृत करना सुनिश्चित करें। जब आपका लाइसेंस समाप्त हो जाता है, तो आप निम्नलिखित में से अधिक लाभ प्राप्त नहीं कर पाएंगे;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP वाणिज्यिक लाइसेंस प्रकार <a href=\"{0}\" target=\"_blank\">सतत लाइसेंस</a> है। आपके लाइसेंस की समय सीमा समाप्त होने के बाद, आप अपने प्रोजेक्ट को विकसित करना जारी रख सकते हैं। और आप अपने लाइसेंस को नवीनीकृत करने के लिए बाध्य नहीं हैं। आपका लाइसेंस एक साल के अपडेट और आउट ऑफ द बॉक्स के साथ आता है। नई सुविधाओं, प्रदर्शन में सुधार, बग फिक्स, समर्थन प्राप्त करने और एबीपी सूट का उपयोग जारी रखने के लिए, आपको अपने लाइसेंस को नवीनीकृत करने की आवश्यकता है। जब आपका लाइसेंस समाप्त हो जाता है, तो आपको निम्नलिखित लाभ नहीं मिलेंगे;",
"WhatHappensWhenLicenseEndsExplanation2": "आप एबीपी कमर्शियल का उपयोग करके नए समाधान नहीं बना सकते हैं, लेकिन आप अपने मौजूदा अनुप्रयोगों को हमेशा के लिए विकसित कर सकते हैं।",
"WhatHappensWhenLicenseEndsExplanation3": "आप अपने मुख्य संस्करण के भीतर मॉड्यूल और विषयों के लिए अद्यतन प्राप्त करने में सक्षम होंगे। उदाहरण के लिए; यदि आप किसी मॉड्यूल के v3.2.0 का उपयोग कर रहे हैं, तो आप उस मॉड्यूल के v3.x.x (v3.3.0, v3.5.2... आदि) के लिए अपडेट प्राप्त कर सकते हैं। लेकिन आपको अगले प्रमुख संस्करण के लिए अपडेट नहीं मिल सकता है (जैसे v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "आप अपने MAJOR संस्करण (RC या पूर्वावलोकन संस्करणों को छोड़कर) के भीतर मॉड्यूल और थीम के लिए अपडेट प्राप्त करने में सक्षम होंगे। उदाहरण के लिए; यदि आप किसी मॉड्यूल के v3.2.0 का उपयोग कर रहे हैं, तो भी आप उस मॉड्यूल के v3.x.x (v3.3.0, v3.5.2... आदि) के लिए अपडेट प्राप्त कर सकते हैं। लेकिन आप अगले प्रमुख संस्करण (जैसे v4.x, v5.x) के लिए अपडेट प्राप्त नहीं कर सकते। उदाहरण के लिए, जब आपका लाइसेंस समाप्त हो गया था, तो नवीनतम रिलीज़ v4.4.3 था और नवीनतम पूर्वावलोकन संस्करण v5.0.0-rc.2 था, आप v4.X.X तक पहुंच सकते हैं लेकिन आप v5.X.X तक नहीं पहुंच सकते।",
"WhatHappensWhenLicenseEndsExplanation4": "आप अपने लाइसेंस समाप्त होने के बाद एबीपी वाणिज्यिक मंच में जोड़े गए नए मॉड्यूल और थीम स्थापित नहीं कर सकते।",
"WhatHappensWhenLicenseEndsExplanation5": "आप एबीपी सूट का उपयोग नहीं कर सकते।",
"WhatHappensWhenLicenseEndsExplanation6": "अब आपको <a href=\"{0}\">प्रीमियम सहायता</a> नहीं मिल सकती है।",
"WhatHappensWhenLicenseEndsExplanation7": "यदि आप इन लाभों को प्राप्त करना जारी रखना चाहते हैं तो आप अपनी सदस्यता को नवीनीकृत कर सकते हैं। जब आप अपनी सदस्यता को नवीनीकृत करते हैं तो 20% छूट मिलती है।",
"WhatHappensWhenLicenseEndsExplanation7": "यदि आप इन लाभों को प्राप्त करना जारी रखना चाहते हैं तो आप अपने लाइसेंस का विस्तार (नवीनीकरण) कर सकते हैं। यदि आप अपने लाइसेंस की समय सीमा समाप्त होने के बाद <strong>1 महीने</strong> के भीतर अपना लाइसेंस बढ़ाते हैं, तो निम्नलिखित छूट लागू होंगी: टीम लाइसेंस {0}% छूट, व्यवसाय लाइसेंस {1}% छूट, एंटरप्राइज़ लाइसेंस {2}% छूट .",
"WhenShouldIRenewMyLicense": "मुझे अपना लाइसेंस कब नवीनीकृत करना चाहिए?",
"WhenShouldIRenewMyLicenseExplanation1": "यदि आप अपना लाइसेंस समाप्त होने के बाद अपने लाइसेंस का नवीनीकरण <strong> 1 महीने </ strong> के भीतर करते हैं, तो कुल लाइसेंस मूल्य पर% 20 छूट लागू होगी।",
"WhenShouldIRenewMyLicenseExplanation2": "यदि आप अपनी लाइसेंस की समाप्ति तिथि से 1 महीने के बाद अपना लाइसेंस नवीनीकृत करते हैं, तो नवीनीकरण मूल्य लाइसेंस खरीद मूल्य के समान होगा और आपके नवीकरण के लिए कोई छूट नहीं होगी।",
"WhenShouldIRenewMyLicenseExplanation": "यदि आप अपने लाइसेंस की समय सीमा समाप्त होने के बाद <strong>1 महीने</strong> के भीतर अपना लाइसेंस नवीनीकृत करते हैं, तो निम्नलिखित छूटें लागू होंगी: टीम लाइसेंस {0}% छूट, व्यवसाय लाइसेंस {1}% छूट, एंटरप्राइज़ लाइसेंस {2}% छूट . यदि आप अपने लाइसेंस की समाप्ति तिथि के बाद <strong>1 महीने</strong> अपने लाइसेंस का नवीनीकरण करते हैं, तो नवीनीकरण मूल्य लाइसेंस खरीद मूल्य के समान होगा और आपके नवीनीकरण पर कोई छूट नहीं होगी।",
"TrialPlan": "क्या आपके पास एक परीक्षण योजना है?",
"TrialPlanExplanation": "अभी के लिए, एबीपी कमर्शियल में ट्रायल प्लान नहीं है। टीम लाइसेंस के लिए हम 30 दिन की मनी बैक गारंटी प्रदान करते हैं। आप पहले 30 दिनों में धनवापसी का अनुरोध कर सकते हैं। बिजनेस और एंटरप्राइज लाइसेंस के लिए, हम 30 दिनों में 60% रिफंड प्रदान करते हैं। ऐसा इसलिए है क्योंकि व्यवसाय और एंटरप्राइज़ लाइसेंस में सभी मॉड्यूल और थीम का पूर्ण स्रोत कोड शामिल है।",
"DoYouAcceptBankWireTransfer": "क्या आप बैंक वायर ट्रांसफर स्वीकार करते हैं?",
"DoYouAcceptBankWireTransferExplanation": "हां, हम बैंक वायर ट्रांसफर स्वीकार करते हैं। <br/> बैंक वायर ट्रांसफर के माध्यम से लाइसेंस राशि भेजने के बाद, हमें अपनी रसीद और अनुरोधित लाइसेंस प्रकार ई-मेल के माध्यम से भेजें। <br/> हमारे अंतरराष्ट्रीय बैंक खाते की जानकारी:",
"DoYouAcceptBankWireTransferExplanation": "हां, हम बैंक वायर ट्रांसफर स्वीकार करते हैं।<br />बैंक हस्तांतरण के माध्यम से लाइसेंस शुल्क भेजने के बाद, हमें अपनी रसीद और अनुरोधित लाइसेंस के प्रकार accounting@abp.io पर ईमेल करें। हमारे अंतरराष्ट्रीय बैंक खाते की जानकारी:",
"HowToUpgrade": "नया संस्करण उपलब्ध होने पर मौजूदा एप्लिकेशन को कैसे अपग्रेड किया जाए?",
"HowToUpgradeExplanation1": "जब आप ABP कमर्शियल का उपयोग करके एक नया एप्लिकेशन बनाते हैं, तो सभी मॉड्यूल और थीम को NuGet और NPM पैकेज के रूप में उपयोग किया जाता है। इसलिए, नया संस्करण उपलब्ध होने पर आप आसानी से संकुल को अपग्रेड कर सकते हैं।",
"HowToUpgradeExplanation2": "मानक NuGet/NPM अपग्रेड के अलावा, <a href=\"{0}\">ABP CLI</a> एक अपडेट कमांड प्रदान करता है जो आपके समाधान में सभी ABP संबंधित पैकेजों को स्वचालित रूप से ढूंढता और अपग्रेड करता है।",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/hu.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Mi a különbség a licenc kiterjesztése és a frissítés között?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Meghosszabbítás:</strong> A licenc meghosszabbításával/megújításával továbbra is prémium támogatást kap, valamint jelentős frissítéseket kap a modulokhoz és témákhoz. Emellett folytathatja új projektek létrehozását. És továbbra is használhatja az ABP Suite-ot, amely felgyorsítja a fejlesztést.<hr/><strong>Frissítés:</strong> Licencének frissítésével magasabb licenccsomagra lép fel, amely további előnyöket biztosít. . Tekintse meg a <a href=\"/pricing\">licenc-összehasonlító táblázatot</a>, hogy ellenőrizze a licenccsomagok közötti különbségeket.<strong>Másrészt, ha frissít, a licenc lejárati dátuma nem változik!</strong> >A licenc lejárati dátumának meghosszabbításához meg kell hosszabbítania az engedélyt.",
"LicenseRenewalCost": "Mennyibe kerül a licenc megújítása 1 év után?",
"LicenseRenewalCostExplanation": "Az összes ABP Commercial örökös licenc megújítási (meghosszabbítási) aránya a licenc listaárának {0}-a. A normál csapatlicenc megújítási ára {1} USD, a normál üzleti licencé {2} USD, a normál vállalati licencé pedig {3} USD. Ha már ügyfele, <a href='{4}' target='_blank'>jelentkezzen be fiókjába</a>, hogy áttekintse az elérhető megújítási árakat.",
"LicenseRenewalCostExplanation": "A normál csapatlicenc megújítási (meghosszabbítási) ára {0} USD, a normál üzleti licencé {1} USD, a normál vállalati licencé pedig {2} USD. Ha Ön már ügyfél, <a href='{3}' target='_blank'>jelentkezzen be fiókjába</a>, hogy áttekintse az elérhető megújítási árakat.",
"HowDoIRenewMyLicense": "Hogyan újíthatom meg a jogosítványomat?",
"HowDoIRenewMyLicenseExplanation": "Licencét megújíthatja, ha felkeresi a <a href='{0}' target='_blank'>szervezetkezelési oldalt</a>. Ha szeretné kihasználni a kedvezményes korai megújítási díjainkat, ne felejtse el megújítani a licence lejárta előtt. Ne aggódjon amiatt, hogy nem tudja, mikor zárul be a korai megújítási lehetősége. Előfizetése lejárta előtt 3 emlékeztető e-mailt fog kapni. 30 nappal, 7 nappal és 1 nappal a lejárat előtt küldjük el.",
"IsSourceCodeIncluded": "Tartalmazza a licencem a kereskedelmi modulok és témák forráskódját?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Módosíthatom a szervezetem regisztrált fejlesztőit a jövőben?",
"ChangingDevelopersExplanation": "Amellett, hogy új fejlesztőket ad hozzá a licenchez, további költségek nélkül módosíthatja a meglévő fejlesztőket is (eltávolíthat egy fejlesztőt, és hozzáadhat egy újat ugyanarra a helyre).",
"WhatHappensWhenLicenseEnds": "Mi történik, ha lejár a jogosítványom?",
"WhatHappensWhenLicenseEndsExplanation1": "Az ABP Kereskedelmi licenc típusa <a href=\"{0}\" target=\"_blank\">örök licenc</a>. A licenc lejárta után folytathatja a projekt fejlesztését. És nem köteles megújítani az engedélyt. Licencéhez egyéves frissítési és támogatási csomag tartozik. Ha továbbra is új funkciókat, teljesítményfejlesztéseket, hibajavításokat, támogatást szeretne kapni, és továbbra is használni szeretné az ABP Suite szolgáltatást, minden évben újítsa meg tervét. Ha az engedélye lejár, az alábbi előnyök közül többet nem fog tudni igénybe venni;",
"WhatHappensWhenLicenseEndsExplanation1": "Az ABP Kereskedelmi licenc típusa <a href=\"{0}\" target=\"_blank\">örök licenc</a>. A licenc lejárta után folytathatja a projekt fejlesztését. És nem köteles megújítani az engedélyt. Licencéhez egyéves frissítés és támogatási terv tartozik. Ha továbbra is új funkciókat, teljesítményjavításokat, hibajavításokat, támogatást szeretne kapni, és továbbra is használni szeretné az ABP Suite szolgáltatást, meg kell újítania licencét. Ha az engedélye lejár, nem részesül a következő előnyökben;",
"WhatHappensWhenLicenseEndsExplanation2": "Az ABP Commercial használatával nem hozhat létre új megoldásokat, de örökké folytathatja meglévő alkalmazásai fejlesztését.",
"WhatHappensWhenLicenseEndsExplanation3": "Frissítéseket kaphat a MAJOR verziójában található modulokhoz és témákhoz. Például; ha egy modul v3.2.0-s verzióját használja, továbbra is kaphat frissítéseket a modul v3.x.x-hez (v3.3.0, v3.5.2... stb.). De nem kaphat frissítéseket a következő nagyobb verzióhoz (például v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version (except RC or Preview versions). For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x). For example, when your license expired, the latest release was v4.4.3 and the latest preview version was v5.0.0-rc.2, you can access the v4.X.X but you cannot access the v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "A licenc lejárta után nem telepíthet új modulokat és témákat az ABP Commercial platformhoz.",
"WhatHappensWhenLicenseEndsExplanation5": "Az ABP Suite nem használható.",
"WhatHappensWhenLicenseEndsExplanation6": "Többé nem veheti igénybe a <a href=\"{0}\">prémium támogatást</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Megújíthatja előfizetését, ha továbbra is igénybe kívánja venni ezeket az előnyöket. Ha a licence lejártát követő 1 hónapon belül megújítja előfizetését, 20% kedvezmény jár.",
"WhatHappensWhenLicenseEndsExplanation7": "Meghosszabbíthatja (megújíthatja) jogosítványát, ha továbbra is igénybe kívánja venni ezeket az előnyöket. Ha a licenc lejártát követő <strong>1 hónapon belül</strong> meghosszabbítja licencét, a következő kedvezmények érvényesülnek: Csapatengedély: {0}% kedvezmény, Üzleti licenc {1}% kedvezmény, Vállalati licenc {2}% kedvezmény .",
"WhenShouldIRenewMyLicense": "Mikor kell megújítanom a jogosítványomat?",
"WhenShouldIRenewMyLicenseExplanation1": "Ha a licenc lejártát követő <strong>1 hónapon belül</strong> megújítja a licencet, 20 % kedvezményt adunk.",
"WhenShouldIRenewMyLicenseExplanation2": "Ha a licencet a licenc lejárati dátumától számított 1 hónap elteltével újítja meg, a megújítási ár megegyezik a licenc vételárával, és nem jár kedvezmény a megújításra.",
"WhenShouldIRenewMyLicenseExplanation": "Ha a licenc lejártát követő <strong>1 hónapon belül</strong> megújítja a licencet, a következő kedvezmények érvényesek: Csapatlicenc {0}% kedvezmény, Üzleti licenc {1}% kedvezmény, Vállalati licenc {2}% kedvezmény . Ha megújítja a licencet <strong>1 hónappal</strong> a licenc lejárati dátuma után, a megújítási ár megegyezik a licenc vásárlási árával, és nem jár kedvezmény a megújításra.",
"TrialPlan": "Van próbaterv?",
"TrialPlanExplanation": "Az ABP Commercial egyelőre nem rendelkezik próbatervvel. A Team licencekre 30 napos pénzvisszafizetési garanciát vállalunk. Az első 30 napban csak visszatérítést kérhet. A Business és Enterprise licencek esetén 60% visszatérítést biztosítunk 30 napon belül. Ennek az az oka, hogy a Business és Enterprise licencek tartalmazzák az összes modul és téma teljes forráskódját.",
"DoYouAcceptBankWireTransfer": "Elfogadja a banki átutalást?",
"DoYouAcceptBankWireTransferExplanation": "Igen, elfogadunk banki átutalást.<br />Miután banki átutalással elküldte a licencdíjat, küldje el nekünk e-mailben az info@abp.io címre a nyugtát és a kért engedély típusát. Nemzetközi bankszámlánk információi:",
"DoYouAcceptBankWireTransferExplanation": "Igen, elfogadunk banki átutalást.<br />Miután banki átutalással elküldte a licencdíjat, küldje el nekünk e-mailben az accounting@abp.io címre nyugtát és a kért engedély típusát. Nemzetközi bankszámlánk információi:",
"HowToUpgrade": "Hogyan lehet frissíteni a meglévő alkalmazásokat, ha új verzió érhető el?",
"HowToUpgradeExplanation1": "Amikor új alkalmazást hoz létre az ABP Commercial használatával, az összes modul és a téma NuGet és NPM csomagként kerül felhasználásra. Így könnyen frissítheti a csomagokat, ha új verzió érhető el.",
"HowToUpgradeExplanation2": "A szabványos NuGet/NPM frissítéseken kívül az <a href=\"{0}\">ABP CLI</a> frissítési parancsot biztosít, amely automatikusan megkeresi és frissíti az összes ABP-vel kapcsolatos csomagot a megoldásban.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/is.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Hver er munurinn á lengingu leyfis og uppfærslu?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Framlenging: </strong> Með því að framlengja/endurnýja leyfið þitt muntu halda áfram að fá aukagjaldstuðning og fá stórar uppfærslur fyrir einingarnar og þemu. Að auki muntu geta haldið áfram að búa til ný verkefni. Og þú munt samt geta notað ABP Suite sem flýtir fyrir þróun þinni. <Hr/> <strong> Uppfærsla: </strong> Með því að uppfæra leyfið þitt muntu kynna þér hærri leyfisáætlun sem gerir þér kleift að fá frekari ávinning . Skoðaðu <a href=\"/pricing\"> tafla til samanburðar leyfa </a> til að athuga muninn á leyfisáætlunum. <strong> Á hinn bóginn, þegar þú uppfærir mun gildistími leyfis þíns ekki breytast! < /strong> Til að framlengja lokadagsetningu leyfis þíns þarftu að framlengja leyfið.",
"LicenseRenewalCost": "Hver er kostnaður við endurnýjun leyfis eftir 1 ár?",
"LicenseRenewalCostExplanation": "Endurnýjun (framlenging) hlutfall allra ABP Commercial leyfa er {0} af leyfislistaverði. Endurnýjunarverð staðlaða teymisleyfis er $ {1}, venjulegt viðskiptaleyfi er $ {2} og venjulegt fyrirtækjaleyfi er $ {3}. Ef þú ert þegar viðskiptavinur, <a href='{4}' target='_blank'> skráðu þig inn á reikninginn þinn </a> til að fara yfir tiltæk endurnýjunarverð.",
"LicenseRenewalCostExplanation": "Endurnýjunarverð (framlengja) venjulegs liðsleyfis er ${0}, venjulegt viðskiptaleyfi er ${1} og staðlað fyrirtækisleyfi er ${2}. Ef þú ert nú þegar viðskiptavinur skaltu <a href='{3}' target='_blank'>skrá þig inn á reikninginn þinn</a> til að skoða tiltæk endurnýjunarverð.",
"HowDoIRenewMyLicense": "Hvernig endurnýi ég leyfi mitt?",
"HowDoIRenewMyLicenseExplanation": "Þú getur endurnýjað leyfið með því að fara á <a href='{0}' target='_blank'> stjórnunarsíðu fyrirtækisins </a>. Til að nýta afsláttarverð okkar fyrir snemma endurnýjun, vertu viss um að endurnýja áður en leyfið þitt rennur út. Ekki hafa áhyggjur af því að vita ekki hvenær tækifæri þínu til endurnýjunar lokast. Þú færð 2 áminningarpósta áður en áskriftin rennur út. Við sendum þau 30 dögum, 7 dögum fyrir lok.",
"IsSourceCodeIncluded": "Inniheldur leyfi mitt frumkóða viðskiptareininganna og þemanna?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Get ég breytt skráðum forriturum fyrirtækisins míns í framtíðinni?",
"ChangingDevelopersExplanation": "Til viðbótar við að bæta nýjum verktaka við leyfi þitt geturðu einnig breytt núverandi forriturum (þú getur fjarlægt verktaka og bætt nýjum við) án aukakostnaðar.",
"WhatHappensWhenLicenseEnds": "Hvað gerist þegar leyfistímabilinu lýkur?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial er <a href=\"{0}\" target=\"_blank\"> eilíft leyfi </a>. Eftir að leyfi þitt rennur út geturðu haldið áfram að þróa verkefnið þitt. Og þér er ekki skylt að endurnýja leyfið. Leyfi þínu fylgir eins árs uppfærslur og stuðningsáætlun úr kassanum. Til að halda áfram að fá nýja eiginleika, endurbætur á afköstum, villuleiðréttingar, stuðning og halda áfram að nota ABP Suite, vertu viss um að endurnýja áætlun þína á hverju ári. Þegar leyfi þitt rennur út muntu ekki geta fengið fleiri af eftirfarandi ávinningi;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Commercial leyfistegund er <a href=\"{0}\" target=\"_blank\">ælíft leyfi</a>. Eftir að leyfið þitt rennur út geturðu haldið áfram að þróa verkefnið þitt. Og þú ert ekki skyldugur til að endurnýja leyfið þitt. Leyfinu þínu fylgir eins árs uppfærsla og stuðningsáætlun beint úr kassanum. Til að halda áfram að fá nýja eiginleika, auka afköst, villuleiðréttingar, stuðning og halda áfram að nota ABP Suite þarftu að endurnýja leyfið þitt. Þegar leyfið þitt rennur út færðu ekki eftirfarandi fríðindi;",
"WhatHappensWhenLicenseEndsExplanation2": "Þú getur ekki búið til nýjar lausnir með því að nota ABP Commercial, en þú getur haldið áfram að þróa núverandi forrit þín að eilífu.",
"WhatHappensWhenLicenseEndsExplanation3": "Þú munt geta fengið uppfærslur fyrir einingar og þemu í MAJOR útgáfunni þinni. Til dæmis; ef þú ert að nota v3.2.0 af einingu geturðu samt fengið uppfærslur fyrir v3.x.x (v3.3.0, v3.5.2 ... osfrv.) þeirrar einingar. En þú getur ekki fengið uppfærslur fyrir næstu stóru útgáfuna (eins og v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Þú munt geta fengið uppfærslur fyrir einingarnar og þemu í MAJOR útgáfunni þinni (nema RC eða Preview útgáfur). Til dæmis; ef þú ert að nota v3.2.0 af einingu geturðu samt fengið uppfærslur fyrir v3.x.x (v3.3.0, v3.5.2... osfrv.) af þeirri einingu. En þú getur ekki fengið uppfærslur fyrir næstu helstu útgáfu (eins og v4.x, v5.x). Til dæmis, þegar leyfið þitt rann út, nýjasta útgáfan var v4.4.3 og nýjasta forskoðunarútgáfan var v5.0.0-rc.2, þú getur fengið aðgang að v4.X.X en þú getur ekki fengið aðgang að v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Þú getur ekki sett upp nýjar einingar og þemu sem bætt er við ABP Commercial eftir að leyfi þínu lýkur.",
"WhatHappensWhenLicenseEndsExplanation5": "Þú getur ekki notað ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Þú getur ekki fengið <a href=\"{0}\"> úrvalsstuðninginn </a> lengur.",
"WhatHappensWhenLicenseEndsExplanation7": "Þú getur endurnýjað áskriftina þína ef þú vilt halda áfram að fá þessa kosti. Ef þú endurnýjar áskriftina innan 1 mánaðar eftir að leyfi þitt rennur út, er 20% afsláttur veittur.",
"WhatHappensWhenLicenseEndsExplanation7": "Þú getur framlengt (endurnýjað) leyfið þitt ef þú vilt halda áfram að njóta þessara fríðinda. Ef þú framlengir leyfið þitt innan <strong>eins mánaðar</strong> eftir að leyfið þitt rennur út verða eftirfarandi afslættir notaðir: Team Leyfi {0}% afsláttur, Business License {1}% afsláttur, Enterprise License {2}% afsláttur .",
"WhenShouldIRenewMyLicense": "Hvenær ætti ég að endurnýja leyfið mitt?",
"WhenShouldIRenewMyLicenseExplanation1": "Ef þú endurnýjar leyfið þitt innan <strong> 1 mánaðar </strong> eftir að leyfið þitt rennur út, er notaður 20 %afsláttur.",
"WhenShouldIRenewMyLicenseExplanation2": "Ef þú endurnýjar leyfið þitt eftir 1 mánuð frá því að leyfi þitt rennur út, þá verður endurnýjunarverð það sama og kaupverð leyfis og enginn afsláttur verður af endurnýjun þinni.",
"WhenShouldIRenewMyLicenseExplanation": "Ef þú endurnýjar leyfið þitt innan <strong>eins mánaðar</strong> eftir að leyfið þitt rennur út verða eftirfarandi afslættir notaðir: Team Leyfi {0}% afsláttur, Business License {1}% afsláttur, Enterprise License {2}% afsláttur . Ef þú endurnýjar leyfið þitt <strong>1 mánuði</strong> eftir að leyfið rennur út, verður endurnýjunarverðið það sama og kaupverð leyfisins og enginn afsláttur af endurnýjun þinni.",
"TrialPlan": "Ertu með prufuáætlun?",
"TrialPlanExplanation": "Í bili hefur ABP Commercial ekki prufuáætlun. Fyrir teymis leyfi veitum við 30 daga endurgreiðsluábyrgð. Þú getur bara óskað eftir endurgreiðslu fyrstu 30 dagana. Viðskipta- og fyrirtækjalyfið veitir 60% endurgreiðslu á 30 dögum. Þetta er vegna þess að viðskipta- og fyrirtækjaleyfi innihalda fullan kóða allra eininga og þemanna.",
"DoYouAcceptBankWireTransfer": "Samþykki þið bankamillifærslu?",
"DoYouAcceptBankWireTransferExplanation": "Já, við samþykkjum bankamillifærslu. <br /> Eftir að þú hefur sent leyfisgjaldið með millifærslu, sendu okkur kvittunina þína í tölvupósti á info@abp.io með tegund leyfis sem óskað er eftir. Alþjóðlegar bankareikningsupplýsingar okkar:",
"DoYouAcceptBankWireTransferExplanation": "Já, við tökum við bankamillifærslu.<br />Eftir að hafa sent leyfisgjaldið með millifærslu skaltu senda okkur tölvupóst á accounting@abp.io kvittun þína og tegund leyfis sem óskað er eftir. Upplýsingar um alþjóðlega bankareikninginn okkar:",
"HowToUpgrade": "Hvernig á að uppfæra núverandi forrit þegar ný útgáfa er í boði?",
"HowToUpgradeExplanation1": "Þegar þú býrð til nýtt forrit með ABP Commercial eru allar einingarnar og þemað notað sem NuGet og NPM pakkar. Svo þú getur auðveldlega uppfært pakkana þegar ný útgáfa er fáanleg.",
"HowToUpgradeExplanation2": "Til viðbótar við hefðbundna NuGet/NPM uppfærslu veitir <a href=\"{0}\"> ABP CLI </a> uppfærsluskipun sem finnur og uppfærir sjálfkrafa alla ABP tengda pakka í lausninni þinni.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/it.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Qual è la differenza tra estensione della licenza e aggiornamento?",
"LicenseExtendUpgradeDiffExplanation": "<strong> Estensione: </strong> estendendo/rinnovando la tua licenza, continuerai a ricevere supporto premium e a ricevere aggiornamenti importanti per moduli e temi. Inoltre, potrai continuare a creare nuovi progetti. E sarai ancora in grado di utilizzare ABP Suite che accelera il tuo sviluppo.<hr/><strong> Upgrade: </strong> aggiornando la tua licenza, promuoverai un piano di licenza superiore che ti consentirà di ottenere ulteriori vantaggi . Consulta la <a href=\"/pricing\"> tabella di confronto delle licenze </a> per verificare le differenze tra i piani di licenza.<strong> D'altra parte, quando esegui l'upgrade, la data di scadenza della licenza non cambierà! </strong> Per estendere la data di fine della licenza, è necessario estendere la licenza.",
"LicenseRenewalCost": "Qual è il costo del rinnovo della licenza dopo 1 anno?",
"LicenseRenewalCostExplanation": "La tariffa di rinnovo (estensione) di tutte le licenze perpetue ABP Commercial è {0} del prezzo di listino della licenza. Il prezzo di rinnovo della licenza Team standard è $ {1}, la licenza Business standard è $ {2} e la licenza Enterprise standard è $ {3}. Se sei già un cliente, <a href='{4}' target='_blank'> accedi al tuo account </a> per esaminare i prezzi di rinnovo disponibili.",
"LicenseRenewalCostExplanation": "Il prezzo di rinnovo (estensione) della Licenza Team standard è ${0}, la Licenza Business standard è ${1} e la Licenza Enterprise standard è ${2}. Se sei già un cliente, <a href='{3}' target='_blank'>accedi al tuo account</a> per rivedere i prezzi di rinnovo disponibili.",
"HowDoIRenewMyLicense": "Come rinnovo la mia licenza?",
"HowDoIRenewMyLicenseExplanation": "Puoi rinnovare la licenza accedendo alla <a href='{0}' target='_blank'> pagina di gestione dell'organizzazione </a>. Per poter usufruire delle nostre tariffe scontate di rinnovo anticipato, assicurati di rinnovare prima della scadenza della licenza. Tuttavia, non preoccuparti di non sapere quando si chiude la tua opportunità di rinnovo anticipato. Riceverai 2 e-mail di promemoria prima della scadenza dell'abbonamento. Li invieremo a 30 giorni, 7 giorni prima della scadenza.",
"IsSourceCodeIncluded": "La mia licenza include il codice sorgente dei moduli e dei temi commerciali?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Posso cambiare gli sviluppatori registrati della mia organizzazione in futuro?",
"ChangingDevelopersExplanation": "Oltre ad aggiungere nuovi sviluppatori alla tua licenza, puoi anche Modifica gli sviluppatori esistenti (puoi rimuovere uno sviluppatore e aggiungerne uno nuovo alla stessa postazione) senza alcun costo aggiuntivo.",
"WhatHappensWhenLicenseEnds": "Cosa succede al termine del periodo di licenza?",
"WhatHappensWhenLicenseEndsExplanation1": "Il tipo di licenza ABP Commercial è <a href=\"{0}\" target=\"_blank\"> licenza perpetua </a>. Dopo la scadenza della licenza, puoi continuare a sviluppare il tuo progetto. E non sei obbligato a rinnovare la tua licenza. La tua licenza viene fornita con un anno di aggiornamenti e piano di supporto pronto all'uso. Per continuare a ricevere nuove funzionalità, miglioramenti delle prestazioni, correzioni di bug, supporto e continuare a utilizzare ABP Suite, assicurati di rinnovare il tuo piano ogni anno. Quando la tua licenza scade, non sarai in grado di ottenere più dei seguenti vantaggi;",
"WhatHappensWhenLicenseEndsExplanation1": "Il tipo di licenza commerciale ABP è <a href=\"{0}\" target=\"_blank\">licenza perpetua</a>. Dopo la scadenza della licenza, puoi continuare a sviluppare il tuo progetto. E non sei obbligato a rinnovare la patente. La tua licenza viene fornita con un aggiornamento di un anno e un piano di supporto pronti all'uso. Per continuare a ottenere nuove funzionalità, miglioramenti delle prestazioni, correzioni di bug, supporto e continuare a utilizzare ABP Suite, è necessario rinnovare la licenza. Alla scadenza della licenza, non otterrai i seguenti vantaggi;",
"WhatHappensWhenLicenseEndsExplanation2": "Non è possibile creare nuove soluzioni utilizzando ABP Commercial, ma è possibile continuare a sviluppare le applicazioni esistenti per sempre.",
"WhatHappensWhenLicenseEndsExplanation3": "Sarai in grado di ottenere aggiornamenti per i moduli e i temi nella tua versione MAJOR. Per esempio; se stai usando la v3.2.0 di un modulo, puoi comunque ottenere gli aggiornamenti per la v3.x.x (v3.3.0, v3.5.2... ecc.) di quel modulo. Ma non puoi ottenere aggiornamenti per la prossima versione principale (come v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Sarai in grado di ottenere aggiornamenti per i moduli e i temi all'interno della tua versione MAJOR (eccetto le versioni RC o Preview). Per esempio; se stai usando la v3.2.0 di un modulo, puoi comunque ottenere gli aggiornamenti per la v3.x.x (v3.3.0, v3.5.2... ecc.) di quel modulo. Ma non puoi ottenere aggiornamenti per la prossima versione principale (come v4.x, v5.x). Ad esempio, quando la tua licenza è scaduta, l'ultima versione era v4.4.3 e l'ultima versione di anteprima era v5.0.0-rc.2, puoi accedere alla v4.X.X ma non alla v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Non è possibile installare nuovi moduli e temi aggiunti alla piattaforma ABP Commercial al termine della licenza.",
"WhatHappensWhenLicenseEndsExplanation5": "Non è possibile utilizzare ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Non puoi più ottenere l '<a href=\"{0}\"> assistenza premium </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Puoi rinnovare l'abbonamento se desideri continuare a usufruire di questi vantaggi. C'è uno sconto del 20% quando rinnovi l'abbonamento.",
"WhatHappensWhenLicenseEndsExplanation7": "Puoi estendere (rinnovare) la tua licenza se vuoi continuare a ottenere questi vantaggi. Se estendi la tua licenza entro <strong>1 mese</strong> dopo la scadenza della licenza, verranno applicati i seguenti sconti: Licenza Team {0}% di sconto, Licenza Business {1}% di sconto, Licenza Enterprise {2}% di sconto .",
"WhenShouldIRenewMyLicense": "Quando devo rinnovare la mia licenza?",
"WhenShouldIRenewMyLicenseExplanation1": "Se rinnovi la licenza entro <strong> 1 mese </strong> dalla scadenza della licenza, verrà applicato uno sconto del 20% sul prezzo totale della licenza.",
"WhenShouldIRenewMyLicenseExplanation2": "Se rinnovi la licenza dopo 1 mese dalla data di scadenza della licenza, il prezzo di rinnovo sarà lo stesso del prezzo di acquisto della licenza e non ci saranno sconti per il rinnovo.",
"WhenShouldIRenewMyLicenseExplanation": "Se rinnovi la licenza entro <strong>1 mese</strong> dopo la scadenza della licenza, verranno applicati i seguenti sconti: Licenza Team {0}% di sconto, Licenza Business {1}% di sconto, Licenza Enterprise {2}% di sconto . Se rinnovi la licenza <strong>1 mese</strong> dopo la data di scadenza della licenza, il prezzo di rinnovo sarà lo stesso del prezzo di acquisto della licenza e non ci saranno sconti sul rinnovo.",
"TrialPlan": "Hai un piano di prova?",
"TrialPlanExplanation": "Per ora, ABP Commercial non ha un piano di prova. Per le licenze Team forniamo una garanzia di rimborso di 30 giorni. Puoi richiedere un rimborso solo nei primi 30 giorni. Per le licenze Business ed Enterprise, forniamo un rimborso del 60% in 30 giorni. Questo perché le licenze Business ed Enterprise includono il codice sorgente completo di tutti i moduli e i temi.",
"DoYouAcceptBankWireTransfer": "Accettate bonifici bancari?",
"DoYouAcceptBankWireTransferExplanation": "Sì, accettiamo bonifico bancario.<br/> Dopo aver inviato l'importo della licenza tramite bonifico bancario, inviaci la ricevuta e il tipo di licenza richiesto tramite e-mail.<br/> Informazioni sul nostro conto bancario internazionale:",
"DoYouAcceptBankWireTransferExplanation": "Sì, accettiamo bonifico bancario.<br />Dopo aver inviato il canone tramite bonifico bancario, inviaci un'e-mail a accounting@abp.io con la ricevuta e il tipo di licenza richiesta. Le nostre informazioni sul conto bancario internazionale:",
"HowToUpgrade": "Come aggiornare le applicazioni esistenti quando è disponibile una nuova versione?",
"HowToUpgradeExplanation1": "Quando crei una nuova applicazione utilizzando ABP Commercial, tutti i moduli e il tema vengono utilizzati come pacchetti NuGet e NPM. Quindi, puoi facilmente aggiornare i pacchetti quando è disponibile una nuova versione.",
"HowToUpgradeExplanation2": "Oltre agli aggiornamenti NuGet/NPM standard, <a href=\"{0}\"> ABP CLI </a> fornisce un comando di aggiornamento che trova e aggiorna automaticamente tutti i pacchetti relativi a ABP nella soluzione.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/nl.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Wat is het verschil tussen licentieverlenging en upgrade?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Verlengen:</strong> door uw licentie te verlengen/vernieuwen, blijft u premium ondersteuning krijgen en krijgt u belangrijke updates voor de modules en thema's. Bovendien kunt u doorgaan met het maken van nieuwe projecten. En u kunt nog steeds ABP Suite gebruiken, wat uw ontwikkeling versnelt.<hr/><strong>Upgraden:</strong> door uw licentie te upgraden, promoveert u naar een hoger licentieplan waarmee u extra voordelen kunt krijgen . Bekijk de <a href=\"/pricing\">licentievergelijkingstabel</a> om de verschillen tussen de licentieplannen te controleren.<strong>Aan de andere kant, wanneer u een upgrade uitvoert, verandert de vervaldatum van uw licentie niet!</strong >Om de einddatum van uw licentie te verlengen, moet u uw licentie verlengen.",
"LicenseRenewalCost": "Wat zijn de kosten voor het verlengen van de licentie na 1 jaar?",
"LicenseRenewalCostExplanation": "Het tarief voor verlenging (verlenging) van alle eeuwigdurende licenties van ABP Commercial is {0} van de catalogusprijs van de licentie. De verlengingsprijs van de standaard Teamlicentie is ${1}, de standaard Business-licentie is ${2} en de standaard Enterprise-licentie is ${3}. Als u al klant bent, <a href='{4}' target='_blank'>log in op uw account</a> om de beschikbare verlengingsprijzen te bekijken.",
"LicenseRenewalCostExplanation": "Het tarief voor catalogusverlenging van alle eeuwigdurende licenties van ABP Commercial is {0} van de licentieprijs van de licentie. De verlengingsprijs van de standaard Teamlicentie is ${1}, de standaard Business-licentie is ${2} en de standaard Enterprise-licentie is ${3}. Als u al klant bent, <a href='{4}' target='_blank'>log in op uw account</a> om de beschikbare verlengingsprijzen te bekijken.",
"HowDoIRenewMyLicense": "Hoe verleng ik mijn licentie?",
"HowDoIRenewMyLicenseExplanation": "U kunt uw licentie verlengen door naar de <a href='{0}' target='_blank'>organisatiebeheerpagina</a> te gaan. Om te profiteren van onze gereduceerde tarieven voor vroege verlenging, moet u ervoor zorgen dat u verlengt voordat uw licentie verloopt. U hoeft zich echter geen zorgen te maken dat u niet weet wanneer uw mogelijkheid tot vervroegde verlenging afloopt. Je ontvangt 3 herinneringsmails voordat je abonnement afloopt. We sturen ze 30 dagen, 7 dagen en 1 dag voor de vervaldatum.",
"IsSourceCodeIncluded": "Bevat mijn licentie de broncode van de commerciële modules en thema's?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Kan ik de geregistreerde ontwikkelaars van mijn organisatie in de toekomst wijzigen?",
"ChangingDevelopersExplanation": "Naast het toevoegen van nieuwe ontwikkelaars aan uw licentie, kunt u ook de bestaande ontwikkelaars wijzigen (u kunt een ontwikkelaar verwijderen en een nieuwe toevoegen aan dezelfde stoel) zonder extra kosten.",
"WhatHappensWhenLicenseEnds": "Wat gebeurt er als mijn licentieperiode afloopt?",
"WhatHappensWhenLicenseEndsExplanation1": "Het commerciële ABP-licentietype is <a href=\"{0}\" target=\"_blank\">eeuwigdurende licentie</a>. Nadat uw licentie is verlopen, kunt u doorgaan met het ontwikkelen van uw project. En je bent niet verplicht om je rijbewijs te verlengen. Uw licentie wordt standaard geleverd met een jaarabonnement voor updates en ondersteuning. Om nieuwe functies, prestatieverbeteringen, bugfixes en ondersteuning te blijven ontvangen en ABP Suite te blijven gebruiken, moet u uw abonnement elk jaar verlengen. Wanneer uw licentie verloopt, kunt u niet meer van de volgende voordelen krijgen;",
"WhatHappensWhenLicenseEndsExplanation1": "Het commerciële ABP-licentietype is <a href=\"{0}\" target=\"_blank\">permanente licentie</a>. Nadat uw licentie is verlopen, kunt u doorgaan met het ontwikkelen van uw project. En je bent niet verplicht om je rijbewijs te verlengen. Uw licentie wordt standaard geleverd met een jaarupdate en ondersteuningsplan. Om nieuwe functies, prestatieverbeteringen, bugfixes, ondersteuning te blijven krijgen en ABP Suite te blijven gebruiken, moet u uw licentie verlengen. Wanneer uw licentie verloopt, krijgt u niet de volgende voordelen;",
"WhatHappensWhenLicenseEndsExplanation2": "Met de ABP Commercial kunt u geen nieuwe oplossingen creëren, maar u kunt wel eeuwig doorgaan met het doorontwikkelen van uw bestaande applicaties.",
"WhatHappensWhenLicenseEndsExplanation3": "U kunt updates krijgen voor de modules en thema's binnen uw MAJOR-versie. Bijvoorbeeld; als je v3.2.0 van een module gebruikt, kun je nog steeds updates krijgen voor v3.x.x (v3.3.0, v3.5.2... etc.) van die module. Maar u kunt geen updates krijgen voor de volgende hoofdversie (zoals v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "U kunt updates krijgen voor de modules en thema's binnen uw MAJOR-versie (behalve RC- of Preview-versies). Bijvoorbeeld; als je v3.2.0 van een module gebruikt, kun je nog steeds updates krijgen voor v3.x.x (v3.3.0, v3.5.2... etc.) van die module. Maar u kunt geen updates krijgen voor de volgende hoofdversie (zoals v4.x, v5.x). Toen uw licentie bijvoorbeeld verliep, was de nieuwste release v4.4.3 en de nieuwste preview-versie v5.0.0-rc.2, hebt u toegang tot v4.X.X, maar hebt u geen toegang tot v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "U kunt geen nieuwe modules en thema's installeren die zijn toegevoegd aan het ABP Commercieel platform nadat uw licentie is afgelopen.",
"WhatHappensWhenLicenseEndsExplanation5": "U kunt geen gebruik maken van de ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "U kunt geen <a href=\"{0}\">premium ondersteuning</a> meer krijgen.",
"WhatHappensWhenLicenseEndsExplanation7": "U kunt uw abonnement verlengen als u van deze voordelen wilt blijven genieten. Als u uw abonnement verlengt binnen 1 maand nadat uw licentie is verlopen, wordt 20% korting toegepast.",
"WhatHappensWhenLicenseEndsExplanation7": "U kunt uw licentie verlengen (vernieuwen) als u van deze voordelen wilt blijven genieten. Als u uw licentie verlengt binnen <strong>1 maand</strong> nadat uw licentie is verlopen, worden de volgende kortingen toegepast: Teamlicentie {0}% korting, Zakelijke licentie {1}% korting, Enterprise-licentie {2}% korting .",
"WhenShouldIRenewMyLicense": "Wanneer moet ik mijn licentie verlengen?",
"WhenShouldIRenewMyLicenseExplanation1": "Als u uw licentie verlengt binnen <strong>1 maand</strong> nadat uw licentie is verlopen, wordt een korting van %20 toegepast.",
"WhenShouldIRenewMyLicenseExplanation2": "Als u uw licentie verlengt na 1 maand vanaf de vervaldatum van uw licentie, is de verlengingsprijs hetzelfde als de aankoopprijs van de licentie en is er geen korting voor uw verlenging.",
"WhenShouldIRenewMyLicenseExplanation": "Als u uw licentie verlengt binnen <strong>1 maand</strong> nadat uw licentie is verlopen, worden de volgende kortingen toegepast: Teamlicentie {0}% korting, Zakelijke licentie {1}% korting, Enterprise-licentie {2}% korting . Als u uw licentie <strong>1 maand</strong> na de vervaldatum van uw licentie verlengt, is de verlengingsprijs gelijk aan de aankoopprijs van de licentie en wordt er geen korting op uw verlenging gegeven.",
"TrialPlan": "Heb je een proefplan?",
"TrialPlanExplanation": "Voorlopig heeft ABP Commercial geen proefabonnement. Voor de Team-licenties bieden we 30 dagen geld-terug-garantie. U kunt de eerste 30 dagen gewoon een terugbetaling aanvragen. Voor de Business- en Enterprise-licenties bieden we 60% restitutie in 30 dagen. Dit komt doordat Business en Enterprise licenties de volledige broncode van alle modules en thema's bevatten.",
"DoYouAcceptBankWireTransfer": "Accepteert u bankoverschrijvingen?",
"DoYouAcceptBankWireTransferExplanation": "Ja, we accepteren bankoverschrijvingen.<br />Nadat u de licentievergoeding via bankoverschrijving heeft verzonden, stuurt u een e-mail naar info@abp.io met uw betalingsbewijs en het type licentie dat u heeft aangevraagd. Onze internationale bankrekeninggegevens:",
"DoYouAcceptBankWireTransferExplanation": "Ja, we accepteren bankoverschrijvingen.<br />Nadat u de licentievergoeding via bankoverschrijving heeft verzonden, stuurt u een e-mail naar accounting@abp.io met uw kwitantie en het type licentie dat u heeft aangevraagd. Onze internationale bankrekeninggegevens:",
"HowToUpgrade": "Hoe kan ik bestaande applicaties upgraden wanneer er een nieuwe versie beschikbaar is?",
"HowToUpgradeExplanation1": "Wanneer je een nieuwe applicatie maakt met ABP Commercial, worden alle modules en het thema gebruikt als NuGet- en NPM-pakketten. U kunt de pakketten dus eenvoudig upgraden wanneer er een nieuwe versie beschikbaar is.",
"HowToUpgradeExplanation2": "Naast de standaard NuGet/NPM-upgrades, biedt <a href=\"{0}\">ABP CLI</a> een update-opdracht die automatisch alle ABP-gerelateerde pakketten in uw oplossing vindt en opwaardeert.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pl-PL.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Jaka jest różnica między rozszerzeniem licencji a aktualizacją?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Przedłużanie:</strong> przedłużając/odnawiając licencję, będziesz nadal otrzymywać wsparcie premium i ważne aktualizacje modułów i motywów. Poza tym będziesz mógł kontynuować tworzenie nowych projektów. I nadal będziesz mógł korzystać z pakietu ABP Suite, który przyspieszy Twój rozwój.<hr/><strong>Aktualizacja:</strong> Uaktualniając swoją licencję, awansujesz do wyższego planu licencyjnego, który pozwoli Ci uzyskać dodatkowe korzyści . Zobacz <a href=\"/pricing\">tablicę porównawczą licencji</a>, aby sprawdzić różnice między planami licencyjnymi.<strong>Z drugiej strony po uaktualnieniu data wygaśnięcia licencji nie ulegnie zmianie!</strong >Aby przedłużyć datę zakończenia licencji, musisz przedłużyć swoją licencję.",
"LicenseRenewalCost": "Jaki jest koszt odnowienia licencji po 1 roku?",
"LicenseRenewalCostExplanation": "Stawka odnawiania (przedłużania) wszystkich komercyjnych licencji wieczystych ABP wynosi {0} ceny katalogowej licencji. Cena odnowienia standardowej licencji zespołowej wynosi {1} USD, standardowej licencji biznesowej {2} USD, a standardowej Licencji Enterprise {3} USD. Jeśli jesteś już klientem, <a href='{4}' target='_blank'>zaloguj się na swoje konto</a>, aby sprawdzić dostępne ceny odnowienia.",
"LicenseRenewalCostExplanation": "Cena odnowienia (przedłużenia) standardowej licencji zespołowej to {0}$, standardowej licencji biznesowej to {1}$, a standardowej licencji Enterprise to {2}$. Jeśli jesteś już klientem, <a href='{3}' target='_blank'>zaloguj się na swoje konto</a>, aby sprawdzić dostępne ceny odnowienia.",
"HowDoIRenewMyLicense": "Jak odnowić licencję?",
"HowDoIRenewMyLicenseExplanation": "Możesz odnowić licencję, przechodząc na <a href='{0}' target='_blank'>stronę zarządzania organizacją</a>. Aby skorzystać z naszych obniżonych stawek za wcześniejsze odnowienie, pamiętaj o odnowieniu przed wygaśnięciem licencji. Nie martw się jednak, że nie wiesz, kiedy kończy się Twoja szansa na wczesne odnowienie. Otrzymasz 3 e-maile z przypomnieniem przed wygaśnięciem subskrypcji. Wyślemy je na 30 dni, 7 dni i 1 dzień przed wygaśnięciem.",
"IsSourceCodeIncluded": "Czy moja licencja zawiera kod źródłowy modułów i motywów komercyjnych?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Czy mogę w przyszłości zmienić zarejestrowanych programistów mojej organizacji?",
"ChangingDevelopersExplanation": "Oprócz dodawania nowych programistów do swojej licencji możesz również zmieniać istniejących programistów (możesz usunąć programistę i dodać nowego do tego samego stanowiska) bez żadnych dodatkowych kosztów.",
"WhatHappensWhenLicenseEnds": "Co się stanie, gdy skończy się mój okres licencji?",
"WhatHappensWhenLicenseEndsExplanation1": "Typ licencji komercyjnej ABP to <a href=\"{0}\" target=\"_blank\">licencja wieczysta</a>. Po wygaśnięciu licencji możesz kontynuować rozwijanie swojego projektu. I nie musisz odnawiać swojej licencji. Twoja licencja jest dostarczana z rocznym planem aktualizacji i pomocy technicznej zaraz po wyjęciu z pudełka. Aby nadal otrzymywać nowe funkcje, ulepszenia wydajności, poprawki błędów, wsparcie i nadal korzystać z pakietu ABP Suite, pamiętaj o odnawianiu swojego planu co roku. Po wygaśnięciu licencji nie będziesz mógł uzyskać więcej z następujących korzyści;",
"WhatHappensWhenLicenseEndsExplanation1": "Typ licencji komercyjnej ABP to <a href=\"{0}\" target=\"_blank\">licencja wieczysta</a>. Po wygaśnięciu licencji możesz kontynuować rozwijanie swojego projektu. I nie musisz odnawiać swojej licencji. Twoja licencja jest dostarczana z roczną aktualizacją i planem wsparcia po wyjęciu z pudełka. Aby nadal otrzymywać nowe funkcje, ulepszenia wydajności, poprawki błędów, wsparcie i nadal korzystać z pakietu ABP Suite, musisz odnowić licencję. Po wygaśnięciu licencji nie uzyskasz następujących korzyści;",
"WhatHappensWhenLicenseEndsExplanation2": "Nie możesz tworzyć nowych rozwiązań za pomocą ABP Commercial, ale możesz dalej rozwijać swoje istniejące aplikacje w nieskończoność.",
"WhatHappensWhenLicenseEndsExplanation3": "Będziesz mógł otrzymywać aktualizacje modułów i motywów w swojej GŁÓWNEJ wersji. Na przykład; jeśli używasz v3.2.0 modułu, nadal możesz otrzymywać aktualizacje dla v3.x.x (v3.3.0, v3.5.2... itd.) tego modułu. Ale nie możesz pobrać aktualizacji dla następnej głównej wersji (takiej jak v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Będziesz mógł otrzymywać aktualizacje modułów i motywów w swojej GŁÓWNEJ wersji (z wyjątkiem wersji RC i Preview). Na przykład; jeśli używasz v3.2.0 modułu, nadal możesz otrzymywać aktualizacje dla v3.x.x (v3.3.0, v3.5.2... itd.) tego modułu. Ale nie możesz pobrać aktualizacji dla następnej głównej wersji (takiej jak v4.x, v5.x). Na przykład, gdy Twoja licencja wygasła, najnowsza wersja to 4.4.3, a najnowsza wersja zapoznawcza to 5.0.0-rc.2, możesz uzyskać dostęp do wersji 4.X.X, ale nie możesz uzyskać dostępu do wersji 5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Nie możesz instalować nowych modułów i motywów dodanych do platformy ABP Commercial po wygaśnięciu licencji.",
"WhatHappensWhenLicenseEndsExplanation5": "Nie możesz korzystać z pakietu ABP.",
"WhatHappensWhenLicenseEndsExplanation6": "Nie możesz już uzyskać <a href=\"{0}\">pomocy premium</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Możesz odnowić swoją subskrypcję, jeśli chcesz nadal korzystać z tych korzyści. Jeśli odnowisz subskrypcję w ciągu 1 miesiąca po wygaśnięciu licencji, zostanie zastosowana zniżka 20%.",
"WhatHappensWhenLicenseEndsExplanation7": "Możesz przedłużyć (odnowić) swoją licencję, jeśli chcesz nadal korzystać z tych korzyści. Jeśli przedłużysz licencję w ciągu <strong>1 miesiąca</strong> po wygaśnięciu licencji, zostaną zastosowane następujące rabaty: Licencja zespołowa {0}% rabatu, Licencja biznesowa {1}% rabatu, Licencja Enterprise {2}% rabatu .",
"WhenShouldIRenewMyLicense": "Kiedy powinienem odnowić licencję?",
"WhenShouldIRenewMyLicenseExplanation1": "Jeśli odnowisz licencję w ciągu <strong>1 miesiąca</strong> po wygaśnięciu licencji, zostanie zastosowana zniżka w wysokości 20%.",
"WhenShouldIRenewMyLicenseExplanation2": "Jeśli odnowisz licencję po upływie 1 miesiąca od daty wygaśnięcia licencji, cena odnowienia będzie taka sama jak cena zakupu licencji i nie będzie rabatu za odnowienie.",
"WhenShouldIRenewMyLicenseExplanation": "Jeśli odnowisz licencję w ciągu <strong>1 miesiąca</strong> po wygaśnięciu licencji, zostaną zastosowane następujące rabaty: licencja zespołowa {0}% rabatu, licencja biznesowa {1}% rabatu, licencja Enterprise {2}% rabatu . Jeśli odnowisz licencję <strong>1 miesiąc</strong> po dacie wygaśnięcia licencji, cena odnowienia będzie taka sama jak cena zakupu licencji i nie będzie rabatu na odnowienie.",
"TrialPlan": "Czy masz plan próbny?",
"TrialPlanExplanation": "Na razie ABP Commercial nie ma planu próbnego. W przypadku licencji Team zapewniamy 30-dniową gwarancję zwrotu pieniędzy. Możesz po prostu poprosić o zwrot pieniędzy w ciągu pierwszych 30 dni. W przypadku licencji Business i Enterprise zapewniamy zwrot 60% w ciągu 30 dni. Dzieje się tak, ponieważ licencje Business i Enterprise zawierają pełny kod źródłowy wszystkich modułów i motywów.",
"DoYouAcceptBankWireTransfer": "Czy akceptujesz przelew bankowy?",
"DoYouAcceptBankWireTransferExplanation": "Tak, akceptujemy przelew bankowy.<br />Po wysłaniu opłaty licencyjnej przelewem bankowym wyślij nam e-mail na adres info@abp.io z potwierdzeniem odbioru i rodzajem żądanej licencji. Informacje o naszych międzynarodowych kontach bankowych:",
"DoYouAcceptBankWireTransferExplanation": "Tak, akceptujemy przelew bankowy.<br />Po wysłaniu opłaty licencyjnej przelewem bankowym wyślij nam e-mail na adres accounting@abp.io z potwierdzeniem odbioru i rodzajem żądanej licencji. Informacje o naszych międzynarodowych kontach bankowych:",
"HowToUpgrade": "Jak zaktualizować istniejące aplikacje, gdy dostępna jest nowa wersja?",
"HowToUpgradeExplanation1": "Podczas tworzenia nowej aplikacji przy użyciu ABP Commercial wszystkie moduły i motyw są używane jako pakiety NuGet i NPM. Możesz więc łatwo zaktualizować pakiety, gdy dostępna będzie nowa wersja.",
"HowToUpgradeExplanation2": "Oprócz standardowych uaktualnień NuGet/NPM <a href=\"{0}\">ABP CLI</a> udostępnia polecenie aktualizacji, które automatycznie wyszukuje i uaktualnia wszystkie pakiety powiązane z ABP w Twoim rozwiązaniu.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/pt-BR.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Qual é a diferença entre extensão de licença e atualização?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "Qual é o custo de renovação da licença após 1 ano?",
"LicenseRenewalCostExplanation": "A taxa de renovação (extensão) de todas as licenças perpétuas da ABP Commercial é {0} do preço de lista da licença. O preço de renovação da Licença de equipe padrão é $ {1}, a Licença comercial padrão é $ {2} e a Licença corporativa padrão é $ {3}. Se você já é um cliente, <a href='{4}' target='_blank'> faça login em sua conta </a> para verificar os preços de renovação disponíveis.",
"LicenseRenewalCostExplanation": "O preço de renovação (extensão) da Licença de equipe padrão é $ {0}, a Licença comercial padrão é $ {1} e a Licença corporativa padrão é $ {2}. Se você já é um cliente, <a href='{3}' target='_blank'> faça login em sua conta </a> para verificar os preços de renovação disponíveis.",
"HowDoIRenewMyLicense": "Como eu renovo minha licença?",
"HowDoIRenewMyLicenseExplanation": "Você pode renovar sua licença navegando até a <a href='{0}' target='_blank'> página de gerenciamento da organização </a>. Para aproveitar nossas taxas de desconto de renovação antecipada, certifique-se de renovar antes que sua licença expire. Não se preocupe em não saber quando sua oportunidade de Renovação Antecipada terminará. Você receberá 3 e-mails de lembrete antes que sua assinatura expire. Iremos enviá-los 30 dias, 7 dias e 1 dia antes do vencimento.",
"IsSourceCodeIncluded": "Minha licença inclui o código-fonte dos módulos e temas comerciais?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Posso mudar os desenvolvedores registrados da minha organização no futuro?",
"ChangingDevelopersExplanation": "Além de adicionar novos desenvolvedores à sua licença, você também pode alterar os desenvolvedores existentes (você pode remover um desenvolvedor e adicionar um novo ao mesmo assento) sem nenhum custo adicional.",
"WhatHappensWhenLicenseEnds": "O que acontece quando meu período de licença termina?",
"WhatHappensWhenLicenseEndsExplanation1": "O tipo de licença comercial ABP é <a href=\"{0}\" target=\"_blank\"> licença perpétua </a>. Depois que sua licença expirar, você pode continuar desenvolvendo seu projeto. E você não é obrigado a renovar sua licença. Sua licença vem com um plano de suporte e atualizações de um ano pronto para uso. Para continuar a receber novos recursos, melhorias de desempenho, correções de bugs, suporte e continuar a usar o ABP Suite, certifique-se de renovar seu plano a cada ano. Quando sua licença expirar, você não poderá obter mais dos seguintes benefícios;",
"WhatHappensWhenLicenseEndsExplanation1": "O tipo de licença comercial ABP é <a href=\"{0}\" target=\"_blank\"> licença perpétua </a>. Depois que sua licença expirar, você pode continuar desenvolvendo seu projeto. E você não é obrigado a renovar sua licença. Sua licença vem com um plano de atualização e suporte de um ano pronto para uso. Para continuar a obter novos recursos, melhorias de desempenho, correções de bugs, suporte e continuar a usar o ABP Suite, você precisa renovar sua licença. Quando sua licença expirar, você não obterá os seguintes benefícios;",
"WhatHappensWhenLicenseEndsExplanation2": "Você não pode criar novas soluções usando o ABP Commercial, mas pode continuar a desenvolver seus aplicativos existentes para sempre.",
"WhatHappensWhenLicenseEndsExplanation3": "Você poderá obter atualizações para os módulos e temas em sua versão PRINCIPAL. Por exemplo; se estiver usando a v3.2.0 de um módulo, você ainda pode obter atualizações para v3.x.x (v3.3.0, v3.5.2 ... etc.) desse módulo. Mas você não pode obter atualizações para a próxima versão principal (como v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Você poderá obter atualizações para os módulos e temas em sua versão MAJOR (exceto versões RC ou Preview). Por exemplo; se estiver usando a v3.2.0 de um módulo, você ainda pode obter atualizações para v3.x.x (v3.3.0, v3.5.2 ... etc.) desse módulo. Mas você não pode obter atualizações para a próxima versão principal (como v4.x, v5.x). Por exemplo, quando sua licença expirou, a versão mais recente foi a v4.4.3 e a versão de visualização mais recente foi a v5.0.0-rc.2, você pode acessar a v4.X.X, mas não pode acessar a v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Você não pode instalar novos módulos e temas adicionados à plataforma comercial da ABP após o término de sua licença.",
"WhatHappensWhenLicenseEndsExplanation5": "Você não pode usar o ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Você não pode mais obter o <a href=\"{0}\"> suporte premium </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Você pode renovar sua assinatura se quiser continuar a obter esses benefícios. Se você renovar sua assinatura dentro de 1 mês após a expiração da licença, um desconto de 20% será aplicado.",
"WhatHappensWhenLicenseEndsExplanation7": "Você pode estender (renovar) sua licença se quiser continuar a obter esses benefícios. Se você estender sua licença em <strong> 1 mês </strong> após a expiração da licença, os seguintes descontos serão aplicados: Licença de equipe {0}% de desconto, Licença de negócios {1}% de desconto, Licença empresarial {2}% de desconto .",
"WhenShouldIRenewMyLicense": "Quando devo renovar minha licença?",
"WhenShouldIRenewMyLicenseExplanation1": "Se você renovar sua licença em <strong> 1 mês </strong> após a expiração da licença, um desconto de 20% será aplicado.",
"WhenShouldIRenewMyLicenseExplanation2": "Se você renovar sua licença após 1 mês da data de expiração da licença, o preço de renovação será igual ao preço de compra da licença e não haverá desconto para sua renovação.",
"WhenShouldIRenewMyLicenseExplanation": "Se você renovar sua licença em <strong> 1 mês </strong> após a expiração da licença, os seguintes descontos serão aplicados: Licença de equipe {0}% de desconto, Licença de negócios {1}% de desconto, Licença empresarial {2}% de desconto . Se você renovar sua licença <strong> 1 mês </strong> após a data de expiração de sua licença, o preço de renovação será o mesmo que o preço de compra da licença e não haverá desconto em sua renovação.",
"TrialPlan": "Você tem um plano experimental?",
"TrialPlanExplanation": "Por enquanto, a ABP Commercial não tem um plano de teste. Para as licenças Team, oferecemos 30 dias de garantia de devolução do dinheiro. Você pode apenas solicitar um reembolso nos primeiros 30 dias. Para as licenças Business e Enterprise, oferecemos reembolso de 60% em 30 dias. Isso ocorre porque as licenças Business e Enterprise incluem o código-fonte completo de todos os módulos e temas.",
"DoYouAcceptBankWireTransfer": "Você aceita transferência bancária?",
"DoYouAcceptBankWireTransferExplanation": "Sim, aceitamos transferência bancária. <br /> Após o envio da licença por transferência bancária, envie-nos um e-mail para info@abp.io com o seu recibo e o tipo de licença solicitada. Nossas informações de conta bancária internacional:",
"DoYouAcceptBankWireTransferExplanation": "Sim, aceitamos transferência bancária. <br /> Após enviar a taxa de licença por transferência bancária, envie-nos um e-mail para accounting@abp.io com seu recibo e o tipo de licença solicitada. Nossas informações de conta bancária internacional:",
"HowToUpgrade": "Como atualizar os aplicativos existentes quando uma nova versão estiver disponível?",
"HowToUpgradeExplanation1": "Quando você cria um novo aplicativo usando ABP Comercial, todos os módulos e o tema são usados como pacotes NuGet e NPM. Assim, você pode atualizar facilmente os pacotes quando uma nova versão estiver disponível.",
"HowToUpgradeExplanation2": "Além das atualizações NuGet/NPM padrão, <a href=\"{0}\"> ABP CLI </a> fornece um comando de atualização que automaticamente encontra e atualiza todos os pacotes relacionados a ABP em sua solução.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ro-RO.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Care este diferenţa dintre prelungirea licenţei şi îmbunătăţirea acesteia?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Prelungirea:</strong> Prin prelungirea/reînnoirea licenţei dumneavoastră, veţi continua să aveţi acces la asistenţă premium, şi veţi avea parte de actualizările majore ale modulelor şi temelor. Pe lângă asta, veţi putea în continuare să creaţi proiecte noi. Veţi putea folosi în continuare suita ABP, ceea ce va accelera dezvoltarea.<hr/><strong>Îmbunătăţirea:</strong> Prin îmbunătăţirea licenţei dumneavoastră, veţi promova la un plan de licenţă superior, care vă va permite să beneficiaţi de anumite avantaje. Consultaţi <a href=\"/pricing\">tabelul de comparare a licenţelor</a> pentru a verifica diferenţele dintre planurile de licenţă.<strong>Pe de altă parte, când îmbunătăţiţi licenţa, data de expirare a acesteia nu se va schimba!</strong>Pentru a vă extinde data de încheiere a licenţei, va trebui să vă extindeţi licenţa.",
"LicenseRenewalCost": "Care este costul de reînnoire a licenţei dupa 1 an?",
"LicenseRenewalCostExplanation": "Rata de reînnoire (extindere) a tuturor licenţelor ABP Comercial reprezintă {0} din preţul listei licenţelor. Preţul de reînnoire a licenţei standard de echipă este de ${1}, cel pentru licenţa standard de afaceri este de ${2} iar cel pentru licenţa standard enterprise este de ${3}. Dacă deja sunteţi clientul nostru, <a href='{4}' target='_blank'>autentificaţi-vă</a> pentru a examina preţurile disponibile pentru reînnoire.",
"LicenseRenewalCostExplanation": "Prețul de reînnoire (extindere) al licenței standard de echipă este de {0} USD, al licenței standard de afaceri este de {1} USD și al licenței standard Enterprise este de {2} USD. Dacă sunteți deja client, <a href='{3}' target='_blank'>conectați-vă la contul dvs.</a> pentru a examina prețurile de reînnoire disponibile.",
"HowDoIRenewMyLicense": "Cum îmi reînnoiesc licenţa?",
"HowDoIRenewMyLicenseExplanation": "Puteţi să vă reînnoiţi licenţa prin accesarea paginii <a href='{0}' target='_blank'>pagina de gestionare a organizaţiei</a>. Pentru a profita de tarifele noastre reduse de reînnoire anticipată, asiguraţi-vă că reînnoiţi înainte de expirarea licenţei. Totuşi, nu vă faceţi griji dacă nu ştiţi când expiră oportunitatea dumneavoastră de reînnoire anticipată. Veţi primi 2 e-mailuri de reamintire înainte de expirarea abonamentului. Vi le vom trimite cu 30, respectiv 7 zile înainte de expirare.",
"IsSourceCodeIncluded": "Licenţa mea include şi codul sursă al modulelor comerciale şi a temelor?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Pe viitor, pot schimba dezvoltatorii ataşaţi organizaţiei mele?",
"ChangingDevelopersExplanation": "În plus faţă de adăugarea de noi dezvoltatori la licenţa dumneavoastră, puteţi schimba şi dezvoltatorii existenţi(puteţi elimina un dezvoltator şi adăuga unul nou în locul lui) fără costuri suplimentare.",
"WhatHappensWhenLicenseEnds": "Ce se întâmplă când se încheie perioada licenţei mele?",
"WhatHappensWhenLicenseEndsExplanation1": "Tipul de licenţă ABP Comercial este o <a href=\"{0}\" target=\"_blank\">licenţă perpetuă</a>. După ce vă expiră licenţa, puteţi continua dezvoltarea proiectului dumneavoastră. Şi nu sunteţi obligat să vă reînnoiţi licenţa. Licenţa dumneavoastră vine la pachet cu actualizări şi plan de asistenţă valabile timp de un an. Pentru a continua să beneficiaţi de noi caracteristici, îmbunătăţiri de performanţe, corectarea erorilor, asistenţă şi să continuaţi să utilizaţi suita ABP, asiguraţi-vă că vă reînnoiţi licenţa anual. Când vă expiră licenţa, nu veţi mai beneficia de niciunul din beneficiile următoare;",
"WhatHappensWhenLicenseEndsExplanation1": "Tipul de licență comercială ABP este <a href=\"{0}\" target=\"_blank\">licență perpetuă</a>. După expirarea licenței, puteți continua să vă dezvoltați proiectul. Și nu sunteți obligat să vă reînnoiți permisul. Licența dvs. vine cu o actualizare de un an și un plan de asistență. Pentru a beneficia în continuare de noi funcții, îmbunătățiri de performanță, remedieri de erori, asistență și pentru a continua să utilizați ABP Suite, trebuie să vă reînnoiți licența. La expirarea licenței, nu veți beneficia de următoarele beneficii;",
"WhatHappensWhenLicenseEndsExplanation2": "Nu puteţi crea noi soluţii folosind ABP Commercial, dar puteţi continua dezvoltarea aplicaţiilor existente oricând.",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version. For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Veți putea obține actualizări pentru modulele și temele din versiunea dvs. MAJOR (cu excepția versiunilor RC sau Preview). De exemplu; dacă utilizați v3.2.0 a unui modul, puteți obține în continuare actualizări pentru v3.x.x (v3.3.0, v3.5.2... etc.) ale acelui modul. Dar nu puteți obține actualizări pentru următoarea versiune majoră (cum ar fi v4.x, v5.x). De exemplu, când licența dvs. a expirat, cea mai recentă versiune a fost v4.4.3 și cea mai recentă versiune de previzualizare a fost v5.0.0-rc.2, puteți accesa v4.X.X, dar nu puteți accesa v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Nu puteţi instala noi module şi teme adăugate pe platforma ABP Comercial după ce se încheie licenţa dumneavoastră.",
"WhatHappensWhenLicenseEndsExplanation5": "Nu puteţi folosi suita ABP.",
"WhatHappensWhenLicenseEndsExplanation6": "Nu veţi mai avea parte de <a href=\"{0}\">asistenţă premium</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Puteţi să vă reînnoiţi abonamentul dacă vreţi să continuaţi să aveţi parte de aceste beneficii. Dacă vă reînnoiţi abonamentul în termen de o lună după ce vă expiră licenţa, vi se aplică un discount de 20%.",
"WhatHappensWhenLicenseEndsExplanation7": "Vă puteți prelungi (reînnoi) licența dacă doriți să continuați să beneficiați de aceste beneficii. Dacă vă prelungiți licența în termen de <strong>1 lună</strong> după expirarea licenței, se vor aplica următoarele reduceri: Licență de echipă {0}% reducere, Licență de afaceri {1}% reducere, Licență Enterprise {2}% reducere .",
"WhenShouldIRenewMyLicense": "Când ar trebui să-mi reînnoiesc licenţa?",
"WhenShouldIRenewMyLicenseExplanation1": "Dacă vă reînnoiţi licenţa în termen de <strong>1 lună</strong> după ce vă expiră licenţa, se va aplica un discount de 20%.",
"WhenShouldIRenewMyLicenseExplanation2": "Dacă vă reînnoiţi licenţa la o lună după ce aceasta a expirat, preţul de reînnoire va fi acelaşi cu cel iniţial, şi nu va fi aplicat niciun discount pentru reînnoirea dumneavoastră.",
"WhenShouldIRenewMyLicenseExplanation": "Dacă vă reînnoiți licența în termen de <strong>o lună</strong> de la expirarea licenței, se vor aplica următoarele reduceri: Licență de echipă {0}% reducere, Licență de afaceri {1}% reducere, Licență Enterprise {2}% reducere . Dacă vă reînnoiți licența la <strong>1 lună</strong> după data de expirare a licenței, prețul de reînnoire va fi același cu prețul de achiziție a licenței și nu va exista nicio reducere la reînnoirea dvs.",
"TrialPlan": "Aveţi un plan de încercare?",
"TrialPlanExplanation": "Pentru moment, ABP Comercial nu include un plan de încercare. Pentru licenţa de Team oferim înapoirea banilor în termen de 30 de zile. Puteţi să solicitaţi o restituire în primele 30 de zile. Pentru licenţele de tip Business şi Enterprise, noi asigurăm restituirea a 60% din sumă în 30 de zile. Acest lucru se datorează faptului că licenţele de tip Business şi Enterprise includ codul sursă complet al tuturor modulelor şi temelor.",
"DoYouAcceptBankWireTransfer": "Acceptaţi transfer bancar?",
"DoYouAcceptBankWireTransferExplanation": "Da, acceptăm transfer bancar.<br />După trimiterea taxei de licenţă prin transfer bancar, trimiteţi-ne pe e-mail la info@abp.io chitanţa dumneavoastră şi tipul de licenţă solicitat. Informaţiile despre contul bancar internaţional al nostru:",
"DoYouAcceptBankWireTransferExplanation": "Da, acceptăm transfer bancar.<br />După ce ați trimis taxa de licență prin transfer bancar, trimiteți-ne un e-mail la accounting@abp.io chitanța dvs. și tipul de licență solicitat. Informațiile noastre internaționale despre contul nostru bancar:",
"HowToUpgrade": "Cum se actualizează aplicaţiile existente atunci când este disponibilă o nouă versiune?",
"HowToUpgradeExplanation1": "Cand creaţi o nouă aplicaţie folosind ABP Commercial, toate modulele şi tema sunt folosite sub formă de pachete NuGet şi NPM. Astfel, puteţi cu uşurinţă să actualizaţi pachetele atunci când o versiune nouă este disponibilă.",
"HowToUpgradeExplanation2": "Pe lângă actualizările standard NuGet-NPM, <a href=\"{0}\">ABP CLI</a> furnizează o comandă de actualizare automată care identifică şi actualizează toate pachetele legate de ABP din soluţia dumneavoastră.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/ru.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "В чем разница между продлением лицензии и обновлением?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "Какова стоимость продления лицензии через 1 год?",
"LicenseRenewalCostExplanation": "Скорость продления (продления) всех бессрочных коммерческих лицензий ABP составляет {0} от стоимости лицензии. Стоимость продления стандартной групповой лицензии составляет {1} долл. США, стандартной бизнес-лицензии составляет {2} долл. США, а стандартной корпоративной лицензии составляет {3} долл. США. Если вы уже являетесь клиентом, <a href='{4}' target='_blank'> войдите в свою учетную запись </a>, чтобы просмотреть доступные цены на продление.",
"LicenseRenewalCostExplanation": "Стоимость продления (продления) стандартной лицензии для группы составляет {0} долл. США, стандартной бизнес-лицензии составляет {1} долл. США, а стандартной лицензии Enterprise составляет {2} долл. США. Если вы уже являетесь клиентом, <a href='{3}' target='_blank'> войдите в свою учетную запись </a>, чтобы просмотреть доступные цены на продление.",
"HowDoIRenewMyLicense": "Как мне продлить лицензию?",
"HowDoIRenewMyLicenseExplanation": "Вы можете продлить лицензию, перейдя на <a href='{0}' target='_blank'> страницу управления организацией </a>. Чтобы воспользоваться нашими скидками на раннее продление, убедитесь, что вы продлили подписку до истечения срока действия лицензии. Однако не беспокойтесь о том, что не знаете, когда закроется ваша возможность раннего продления. Вы получите 3 напоминания по электронной почте до истечения срока подписки. Мы отправим их за 30 дней, 7 дней и 1 день до истечения срока.",
"IsSourceCodeIncluded": "Включает ли моя лицензия исходный код коммерческих модулей и тем?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Могу ли я сменить зарегистрированных разработчиков моей организации в будущем?",
"ChangingDevelopersExplanation": "Помимо добавления новых разработчиков к вашей лицензии, вы также можете изменить существующих разработчиков (вы можете удалить разработчика и добавить нового на то же место) без каких-либо дополнительных затрат.",
"WhatHappensWhenLicenseEnds": "Что произойдет, когда закончится срок моей лицензии?",
"WhatHappensWhenLicenseEndsExplanation1": "Тип коммерческой лицензии ABP - <a href=\"{0}\" target=\"_blank\"> бессрочная лицензия </a>. По истечении срока действия лицензии вы можете продолжить разработку своего проекта. И вы не обязаны продлевать лицензию. Ваша лицензия поставляется с годовым планом обновлений и поддержки. Чтобы продолжать получать новые функции, улучшения производительности, исправления ошибок, поддержку и продолжать использовать ABP Suite, не забудьте ежегодно продлевать свой план. Когда срок действия вашей лицензии истечет, вы не сможете получить больше следующих преимуществ;",
"WhatHappensWhenLicenseEndsExplanation1": "Тип коммерческой лицензии ABP - <a href=\"{0}\" target=\"_blank\"> бессрочная лицензия </a>. По истечении срока действия лицензии вы можете продолжить разработку своего проекта. И вы не обязаны продлевать лицензию. Ваша лицензия поставляется с годовым обновлением и планом поддержки прямо из коробки. Чтобы продолжать получать новые функции, улучшения производительности, исправления ошибок, поддержку и продолжать использовать ABP Suite, вам необходимо продлить лицензию. По истечении срока действия лицензии вы не получите следующих преимуществ;",
"WhatHappensWhenLicenseEndsExplanation2": "Вы не можете создавать новые решения с помощью ABP Commercial, но вы можете продолжать разрабатывать существующие приложения бесконечно.",
"WhatHappensWhenLicenseEndsExplanation3": "Вы сможете получать обновления для модулей и тем в вашей ОСНОВНОЙ версии. Например; если вы используете модуль v3.2.0, вы все равно можете получать обновления для v3.x.x (v3.3.0, v3.5.2 ... и т. д.) этого модуля. Но вы не можете получать обновления для следующей основной версии (например, v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "You will be able to get updates for the modules and themes within your MAJOR version (except RC or Preview versions). For example; if you are using v3.2.0 of a module, you can still get updates for v3.x.x (v3.3.0, v3.5.2... etc.) of that module. But you cannot get updates for the next major version (like v4.x, v5.x). For example, when your license expired, the latest release was v4.4.3 and the latest preview version was v5.0.0-rc.2, you can access the v4.X.X but you cannot access the v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Вы не можете устанавливать новые модули и темы, добавленные на коммерческую платформу ABP, после истечения срока действия лицензии.",
"WhatHappensWhenLicenseEndsExplanation5": "Вы не можете использовать ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Вы больше не можете получать <a href=\"{0}\"> премиум-поддержку </a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Вы можете продлить подписку, если хотите и дальше пользоваться этими преимуществами. Если вы продлеваете подписку в течение 1 месяца после истечения срока действия лицензии, применяется скидка 20%.",
"WhatHappensWhenLicenseEndsExplanation7": "Вы можете продлить (обновить) вашу лицензию, если хотите и дальше пользоваться этими преимуществами. Если вы продлите лицензию в течение <strong> 1 месяца </strong> после истечения срока действия лицензии, будут применяться следующие скидки: групповая лицензия {0}% скидка, бизнес-лицензия {1}% скидка, корпоративная лицензия {2}% скидка .",
"WhenShouldIRenewMyLicense": "Когда мне следует продлить лицензию?",
"WhenShouldIRenewMyLicenseExplanation1": "Если вы продлеваете лицензию в течение <strong> 1 месяца </strong> после истечения срока действия лицензии, применяется скидка 20%.",
"WhenShouldIRenewMyLicenseExplanation2": "Если вы продлите свою лицензию через 1 месяц с даты истечения срока действия лицензии, цена продления будет такой же, как цена покупки лицензии, и не будет скидки на продление.",
"WhenShouldIRenewMyLicenseExplanation": "Если вы продлите лицензию в течение <strong> 1 месяца </strong> после истечения срока действия лицензии, будут применяться следующие скидки: групповая лицензия {0}% скидка, бизнес-лицензия {1}% скидка, корпоративная лицензия {2}% скидка . Если вы продлеваете лицензию <strong> через 1 месяц </strong> после даты истечения срока действия лицензии, цена продления будет такой же, как цена покупки лицензии, и при продлении скидки не будет.",
"TrialPlan": "У вас есть пробный план?",
"TrialPlanExplanation": "На данный момент у ABP Commercial нет пробного плана. Для командных лицензий мы предоставляем 30-дневную гарантию возврата денег. Вы можете просто запросить возврат в течение первых 30 дней. Для лицензий Business и Enterprise мы возвращаем 60% в течение 30 дней. Это связано с тем, что лицензии Business и Enterprise включают полный исходный код всех модулей и тем.",
"DoYouAcceptBankWireTransfer": "Вы принимаете банковский перевод?",
"DoYouAcceptBankWireTransferExplanation": "Да, мы принимаем банковский перевод. <br /> После отправки платы за лицензию банковским переводом отправьте нам по электронной почте info@abp.io квитанцию и тип запрошенной лицензии. Информация о нашем международном банковском счете:",
"DoYouAcceptBankWireTransferExplanation": "Да, мы принимаем банковский перевод. <br /> После отправки платы за лицензию банковским переводом отправьте нам электронное письмо по адресу accounting@abp.io, квитанцию и тип запрошенной лицензии. Информация о нашем международном банковском счете:",
"HowToUpgrade": "Как обновить существующие приложения, когда доступна новая версия?",
"HowToUpgradeExplanation1": "Когда вы создаете новое приложение с помощью ABP Commercial, все модули и тема используются как пакеты NuGet и NPM. Таким образом, вы можете легко обновить пакеты, когда станет доступна новая версия.",
"HowToUpgradeExplanation2": "Помимо стандартных обновлений NuGet/NPM, <a href=\"{0}\"> ABP CLI </a> предоставляет команду обновления, которая автоматически находит и обновляет все связанные с ABP пакеты в вашем решении.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sk.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Aký je rozdiel medzi rozšírením a aktualizáciou licencie?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Predĺženie:</strong> Predĺžením/obnovením licencie budete naďalej dostávať prémiovú podporu a hlavné aktualizácie modulov a tém. Okrem toho budete môcť pokračovať vo vytváraní nových projektov, naďalej používať balík ABP Suite, ktorý urýchľuje váš vývoj. <hr/><strong>Podpísanie licencie:</strong> Rozšírením licencie postúpite na vyšší licenčný plán, ktorý vám umožní získať ďalšie výhody. Pozrite si <a href=\"/pricing\">tabuľku porovnania licencií</a> a skontrolujte rozdiely medzi licenčnými plánmi.<strong>Na druhej strane, pri upgrade sa dátum skončenia platnosti vašej licencie nezmení!</strong> Ak chcete predĺžiť dátum skončenia platnosti vašej licencie, musíte si licenciu predĺžiť.",
"LicenseRenewalCost": "Aké sú náklady na obnovenie licencie po 1 roku?",
"LicenseRenewalCostExplanation": "Sadzba za obnovenie (predĺženie) všetkých trvalých licencií ABP Commercial je {0} z cenníkovej ceny licencie. Cena za obnovenie štandardnej tímovej licencie je {1} USD, štandardnej obchodnej licencie je {2} USD a štandardnej podnikovej licencie je {3} USD. Ak už ste zákazníkom, <a href='{4}' target='_blank'>prihláste sa do svojho konta</a> a prezrite si dostupné ceny za obnovenie.",
"LicenseRenewalCostExplanation": "Cena obnovenia (predĺženia) štandardnej tímovej licencie je ${0}, štandardnej obchodnej licencie je ${1} a štandardnej podnikovej licencie je ${2}. Ak už ste zákazníkom, <a href='{3}' target='_blank'>prihláste sa do svojho účtu</a> a pozrite si dostupné ceny za obnovenie.",
"HowDoIRenewMyLicense": "Ako si môžem obnoviť licenciu?",
"HowDoIRenewMyLicenseExplanation": "Svoju licenciu môžete obnoviť tak, že prejdete na stránku <a href='{0}' target='_blank'> správa organizície</a>. Ak chcete využiť naše zľavnené ceny za predčasné obnovenie, uistite sa, že ste licenciu obnovili pred uplynutím jej platnosti. Netrápte sa však tým, že neviete, kedy sa vaša možnosť predčasného obnovenia skončí. Pred vypršaním platnosti predplatného dostanete 2 e-maily s pripomienkami. Budeme ich posielať o 30 dní, teda 7 dní pred vypršaním platnosti.",
"IsSourceCodeIncluded": "Zahŕňa moja licencia zdrojový kód komerčných modulov a tém?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Môžem v budúcnosti zmeniť registrovaných vývojárov svojej organizácie?",
"ChangingDevelopersExplanation": "Okrem pridávania nových vývojárov do licencie môžete tiež meniť existujúcich vývojárov (môžete odstrániť vývojára a pridať nového na to isté miesto) bez akýchkoľvek ďalších nákladov.",
"WhatHappensWhenLicenseEnds": "Čo sa stane po skončení platnosti licencie?",
"WhatHappensWhenLicenseEndsExplanation1": "Typ komerčnej licencie ABP je <a href=\"{0}\" target=\"_blank\">trvalá licencia</a>. Po uplynutí platnosti licencie môžete pokračovať vo vývoji svojho projektu. A nie ste povinní obnoviť svoju licenciu. Vaša licencia sa dodáva s ročným plánom aktualizácií a podpory už v balení. Ak chcete aj naďalej dostávať nové funkcie, vylepšenia výkonu, opravy chýb, podporu a pokračovať v používaní balíka ABP Suite, nezabudnite si plán každý rok obnoviť. Po skončení platnosti vašej licencie nebudete môcť získať ďalšie z nasledujúcich výhod;",
"WhatHappensWhenLicenseEndsExplanation1": "Typ licencie ABP Commercial je <a href=\"{0}\" target=\"_blank\">trvalá licencia</a>. Po vypršaní platnosti licencie môžete pokračovať vo vývoji svojho projektu. A nie ste povinní obnoviť si licenciu. Vaša licencia sa dodáva s jednoročnou aktualizáciou a plánom podpory hneď po vybalení. Ak chcete naďalej získavať nové funkcie, vylepšenia výkonu, opravy chýb, podporu a naďalej používať ABP Suite, musíte si obnoviť licenciu. Po vypršaní platnosti licencie nezískate nasledujúce výhody;",
"WhatHappensWhenLicenseEndsExplanation2": "Pomocou ABP Commercial nemôžete vytvárať nové riešenia, ale navždy môžete pokračovať vo vývoji existujúcich aplikácií.",
"WhatHappensWhenLicenseEndsExplanation3": "Budete môcť získať aktualizácie modulov a tém v rámci vašej hlavnej verzie. Ak napríklad používate modul vo verzii 3.2.0, stále môžete získať aktualizácie pre verziu 3.x.x (v3.3.0, v3.5.2... atď.) tohto modulu. Nemôžete však získať aktualizácie pre ďalšiu hlavnú verziu (napr. v4.x, v5.x).",
"WhatHappensWhenLicenseEndsExplanation3": "Budete môcť získať aktualizácie pre moduly a témy v rámci vašej HLAVNEJ verzie (okrem verzií RC alebo Preview). Napríklad; ak používate verziu 3.2.0 modulu, stále môžete získať aktualizácie pre verziu 3.x.x (v3.3.0, v3.5.2... atď.) tohto modulu. Nemôžete však získať aktualizácie pre ďalšiu hlavnú verziu (napríklad v4.x, v5.x). Napríklad, keď platnosť vašej licencie vypršala, najnovšie vydanie bolo v4.4.3 a najnovšia ukážková verzia bola v5.0.0-rc.2, máte prístup k verzii 4.X.X, ale nemáte prístup k verzii 5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Po skončení platnosti vašej licencie nemôžete inštalovať nové moduly a témy pridané do platformy ABP Commercial.",
"WhatHappensWhenLicenseEndsExplanation5": "Balík ABP Suite nemôžete používať.",
"WhatHappensWhenLicenseEndsExplanation6": "Už nemôžete získať <a href=\"{0}\">prémiovú podporu</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Ak chcete tieto výhody využívať aj naďalej, môžete si predplatné obnoviť. Pri obnovení predplatného sa poskytuje 20 % zľava.",
"WhatHappensWhenLicenseEndsExplanation7": "You can extend (renew) your license if you want to continue to get these benefits. If you extend your license within <strong>1 month</strong> after your license expires, the following discounts will be applied: Team License {0}% discount, Business License {1}% discount, Enterprise License {2}% discount.",
"WhenShouldIRenewMyLicense": "Kedy si mám obnoviť licenciu?",
"WhenShouldIRenewMyLicenseExplanation1": "Ak si licenciu obnovíte do <strong>1 mesiaca</strong> po vypršaní platnosti licencie, na celkovú cenu licencie bude uplatnená zľava 20%.",
"WhenShouldIRenewMyLicenseExplanation2": "Ak obnovíte licenciu po uplynutí 1 mesiaca od dátumu vypršania platnosti licencie, cena za obnovenie bude rovnaká ako cena za nákup licencie a na obnovenie nebude poskytnutá žiadna zľava.",
"WhenShouldIRenewMyLicenseExplanation": "Ak si licenciu obnovíte do <strong>1 mesiaca</strong> po vypršaní platnosti licencie, budú sa uplatňovať tieto zľavy: Tímová licencia {0}% zľava, Obchodná licencia {1}% zľava, Enterprise licencia {2}% zľava . Ak si licenciu obnovíte <strong>1 mesiac</strong> po dátume skončenia platnosti licencie, cena za obnovenie bude rovnaká ako cena za nákup licencie a na obnovenie nebude poskytnutá žiadna zľava.",
"TrialPlan": "Máte skúšobný plán?",
"TrialPlanExplanation": "Spoločnosť ABP Commercial zatiaľ nemá skúšobný plán. Pre tímové licencie poskytujeme 30-dňovú záruku vrátenia peňazí. Stačí požiadať o vrátenie peňazí počas prvých 30 dní. V prípade licencií Business a Enterprise poskytujeme 60% vrátenie peňazí do 30 dní. Je to preto, že licencie Business a Enterprise obsahujú úplný zdrojový kód všetkých modulov a tém.",
"DoYouAcceptBankWireTransfer": "Prijímate bankový prevod?",
"DoYouAcceptBankWireTransferExplanation": "Áno, akceptujeme bankový prevod.<br />Po zaslaní sumy za licenciu bankovým prevodom nám pošlite potvrdenie a požadovaný typ licencie e-mailom.<br />Naše informácie o medzinárodnom bankovom účte:",
"DoYouAcceptBankWireTransferExplanation": "Áno, akceptujeme bankový prevod.<br />Po odoslaní licenčného poplatku bankovým prevodom nám pošlite e-mail na adresu accounting@abp.io svoje potvrdenie a požadovaný typ licencie. Informácie o našom medzinárodnom bankovom účte:",
"HowToUpgrade": "Ako aktualizovať existujúce aplikácie, keď je k dispozícii nová verzia?",
"HowToUpgradeExplanation1": "Pri vytváraní novej aplikácie pomocou ABP Commercial sa všetky moduly a téma použijú ako balíky NuGet a NPM. Balíky teda môžete ľahko aktualizovať, keď je k dispozícii nová verzia.",
"HowToUpgradeExplanation2": "Okrem štandardných aktualizácií NuGet/NPM poskytuje <a href=\"{0}\">ABP CLI</a> príkaz update, ktorý automaticky nájde a aktualizuje všetky balíky súvisiace s ABP vo vašom riešení.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/sl.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Kakšna je razlika med podaljšanjem licence in nadgradnjo?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Razširitev:</strong> S podaljšanjem/obnovitvijo licence boste še naprej prejemali vrhunsko podporo in večje posodobitve za module in teme. Poleg tega boste lahko nadaljevali z ustvarjanjem novih projektov. Še vedno boste lahko uporabljali zbirko ABP Suite, ki pospeši vaš razvoj.<hr/><strong>Nadgradnja:</strong> Z nadgradnjo vaše licence boste napredovali v višji licenčni načrt, ki vam bo omogočil dodatne ugodnosti . Če želite preveriti razlike med licenčnimi načrti, glejte <a href=\"/pricing\">tabelo za primerjavo licenc</a>.<strong>Po drugi strani pa se datum poteka licence ne bo spremenil, ko nadgradite!</strong> >Če želite podaljšati končni datum licence, morate podaljšati licenco.",
"LicenseRenewalCost": "Kakšni so stroški podaljšanja licence po 1 letu?",
"LicenseRenewalCostExplanation": "Stopnja podaljšanja (podaljšanja) vseh trajnih licenc ABP Commercial je {0} maloprodajne cene licence. Cena podaljšanja standardne licence za ekipo je {1} $, standardne poslovne licence {2} $ in standardne licence za podjetje je {3} $. Če ste že stranka, se <a href='{4}' target='_blank'>prijavite v svoj račun</a> in si oglejte razpoložljive cene za podaljšanje.",
"LicenseRenewalCostExplanation": "Cena podaljšanja (podaljšanja) standardne licence ekipe je {0} $, standardne poslovne licence {1} $ in standardne licence za podjetje je {2} $. Če ste že stranka, se <a href='{3}' target='_blank'>prijavite v svoj račun</a> in si oglejte razpoložljive cene za podaljšanje.",
"HowDoIRenewMyLicense": "Kako podaljšam licenco?",
"HowDoIRenewMyLicenseExplanation": "Licenco lahko podaljšate tako, da se pomaknete na <a href='{0}' target='_blank'>stran za upravljanje organizacije</a>. Če želite izkoristiti naše znižane cene zgodnjega podaljšanja, se prepričajte, da ste jo podaljšali, preden vam poteče licenca. Ne skrbite, da ne boste vedeli, kdaj se izteče vaša priložnost za zgodnjo obnovo. Pred potekom naročnine boste prejeli 3 e-poštna sporočila z opomnikom. Poslali jih bomo 30 dni, 7 dni in 1 dan pred iztekom.",
"IsSourceCodeIncluded": "Ali moja licenca vključuje izvorno kodo komercialnih modulov in tem?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Ali lahko v prihodnosti spremenim registrirane razvijalce svoje organizacije?",
"ChangingDevelopersExplanation": "Poleg dodajanja novih razvijalcev vaši licenci lahko spremenite tudi obstoječe razvijalce (lahko odstranite razvijalca in dodate novega na isto mesto) brez dodatnih stroškov.",
"WhatHappensWhenLicenseEnds": "Kaj se zgodi, ko se moje licenčno obdobje konča?",
"WhatHappensWhenLicenseEndsExplanation1": "Vrsta licence ABP Commercial je <a href=\"{0}\" target=\"_blank\">trajna licenca</a>. Po poteku licence lahko nadaljujete z razvojem svojega projekta. In licence vam ni treba podaljšati. Vaša licenca je priložena enoletnemu načrtu za posodobitve in podporo. Če želite še naprej prejemati nove funkcije, izboljšave zmogljivosti, popravke napak, podporo in še naprej uporabljati ABP Suite, vsako leto obnovite svoj načrt. Ko vam licenca poteče, ne boste mogli več prejemati naslednjih ugodnosti;",
"WhatHappensWhenLicenseEndsExplanation1": "Vrsta licence ABP Commercial je <a href=\"{0}\" target=\"_blank\">trajna licenca</a>. Po poteku licence lahko nadaljujete z razvojem svojega projekta. In licence vam ni treba podaljšati. Vaša licenca je priložena enoletnemu načrtu za posodobitev in podporo. Če želite še naprej prejemati nove funkcije, izboljšave zmogljivosti, popravke napak, podporo in še naprej uporabljati ABP Suite, morate obnoviti licenco. Ko vaša licenca poteče, ne boste prejeli naslednjih ugodnosti;",
"WhatHappensWhenLicenseEndsExplanation2": "Z uporabo ABP Commercial ne morete ustvarjati novih rešitev, lahko pa za vedno razvijate svoje obstoječe aplikacije.",
"WhatHappensWhenLicenseEndsExplanation3": "V svoji MAJOR različici boste lahko prejemali posodobitve za module in teme. Na primer; če uporabljate v3.2.0 modula, lahko še vedno dobite posodobitve za v3.x.x (v3.3.0, v3.5.2 ... itd.) tega modula. Vendar ne morete dobiti posodobitev za naslednjo večjo različico (na primer v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Prejeli boste lahko posodobitve za module in teme v vaši MAJOR različici (razen različic RC ali Preview). Na primer; če uporabljate v3.2.0 modula, lahko še vedno dobite posodobitve za v3.x.x (v3.3.0, v3.5.2 ... itd.) tega modula. Vendar ne morete dobiti posodobitev za naslednjo večjo različico (na primer v4.x, v5.x). Na primer, ko je vaša licenca potekla, je bila najnovejša izdaja v4.4.3 in najnovejša različica za predogled v5.0.0-rc.2, lahko dostopate do v4.X.X, vendar ne morete dostopati do v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Po prenehanju licence ne morete namestiti novih modulov in tem, ki so bili dodani platformi ABP Commercial.",
"WhatHappensWhenLicenseEndsExplanation5": "Ne morete uporabljati ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Ne morete več dobiti <a href=\"{0}\">premium podpore</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "Če želite še naprej prejemati te ugodnosti, lahko podaljšate naročnino. Če naročnino podaljšate v roku 1 meseca po poteku licence, velja 20 % popust.",
"WhatHappensWhenLicenseEndsExplanation7": "Licenco lahko podaljšate (obnovite), če želite še naprej uživati te ugodnosti. Če podaljšate licenco v <strong>1 mesecu</strong> po poteku licence, bodo uveljavljeni naslednji popusti: licenca ekipe {0} % popusta, poslovna licenca {1} % popusta, licenca podjetja {2} % popusta .",
"WhenShouldIRenewMyLicense": "Kdaj naj podaljšam licenco?",
"WhenShouldIRenewMyLicenseExplanation1": "Če licenco podaljšate v <strong>1 mesecu</strong> po poteku licence, velja 20 % popust.",
"WhenShouldIRenewMyLicenseExplanation2": "Če licenco podaljšate po 1 mesecu od datuma poteka veljavnosti licence, bo cena podaljšanja enaka nakupni ceni licence in za podaljšanje ne bo popusta.",
"WhenShouldIRenewMyLicenseExplanation": "Če licenco podaljšate v <strong>1 mesecu</strong> po poteku licence, bodo uporabljeni naslednji popusti: licenca za ekipo {0} % popusta, poslovna licenca {1} % popusta, licenca za podjetje {2} % popusta . Če podaljšate licenco <strong>1 mesec</strong> po datumu poteka veljavnosti licence, bo cena podaljšanja enaka nakupni ceni licence in pri podaljšanju ne bo popusta.",
"TrialPlan": "Ali imate poskusni načrt?",
"TrialPlanExplanation": "Za zdaj ABP Commercial nima načrta za preskus. Za licence ekipe nudimo 30-dnevno garancijo vračila denarja. Zahtevate lahko samo vračilo kupnine v prvih 30 dneh. Za licence Business in Enterprise nudimo 60 % vračilo v 30 dneh. To je zato, ker licence Business in Enterprise vključujejo celotno izvorno kodo vseh modulov in tem.",
"DoYouAcceptBankWireTransfer": "Ali sprejemate bančno nakazilo?",
"DoYouAcceptBankWireTransferExplanation": "Da, sprejemamo bančno nakazilo.<br />Ko pošljete licenčnino prek bančnega nakazila, nam pošljite e-pošto na info@abp.io vaše potrdilo o prejemu in vrsto zahtevane licence. Naši podatki o mednarodnem bančnem računu:",
"DoYouAcceptBankWireTransferExplanation": "Da, sprejemamo bančno nakazilo.<br />Ko pošljete licenčnino prek bančnega nakazila, nam pošljite e-pošto na accounting@abp.io vaše potrdilo o prejemu in vrsto zahtevane licence. Naši podatki o mednarodnem bančnem računu:",
"HowToUpgrade": "Kako nadgraditi obstoječe aplikacije, ko je na voljo nova različica?",
"HowToUpgradeExplanation1": "Ko ustvarite novo aplikacijo z uporabo ABP Commercial, se vsi moduli in tema uporabljajo kot paketa NuGet in NPM. Tako lahko preprosto nadgradite pakete, ko je na voljo nova različica.",
"HowToUpgradeExplanation2": "Poleg standardnih nadgradenj NuGet/NPM ponuja <a href=\"{0}\">ABP CLI</a> ukaz za posodobitev, ki samodejno poišče in nadgradi vse pakete, povezane z ABP, v vaši rešitvi.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/tr.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Lisans uzatma ve yükseltme arasındaki fark nedir?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Uzatma:</strong> Lisansınızı uzatarak/yenileyerek, premium destek almaya ve modüller ve temalar için önemli güncellemeler almaya devam edeceksiniz. Ayrıca, yeni projeler oluşturmaya devam edebileceksiniz. Ve geliştirmenizi hızlandıran ABP Suite'i kullanmaya devam edebileceksiniz.<hr/><strong>Yükseltme:</strong> Lisansınızı yükselterek, ek avantajlar elde etmenizi sağlayacak daha yüksek bir lisans planına terfi edeceksiniz. . Lisans planları arasındaki farkları kontrol etmek için <a href=\"/pricing\">lisans karşılaştırma tablosuna</a> bakın.<strong>Öte yandan, yükseltme yaptığınızda lisans geçerlilik bitiş tarihiniz değişmez!</strong >Lisans bitiş tarihinizi uzatmak için lisansınızı uzatmanız gerekir.",
"LicenseRenewalCost": "1 yıl sonra ehliyet yenileme ücreti ne kadardır?",
"LicenseRenewalCostExplanation": "Tüm ABP Ticari kalıcı lisanslarının yenileme (uzatma) oranı, lisans liste fiyatının {0} kadarıdır. Standart Takım Lisansının yenileme fiyatı {1}$, standart İşletme Lisansı {2}$ ve standart Enterprise Lisansı {3}$'dır. Zaten bir müşteriyseniz, mevcut yenileme fiyatlarını incelemek için <a href='{4}' target='_blank'>hesabınıza giriş yapın</a>.",
"LicenseRenewalCostExplanation": "Standart Takım Lisansının yenileme (uzatma) fiyatı ${0}, standart İşletme Lisansı ${1} ve standart Enterprise Lisansı {2} $'dır. Zaten bir müşteriyseniz, mevcut yenileme fiyatlarını incelemek için <a href='{3}' target='_blank'>hesabınıza giriş yapın</a>.",
"HowDoIRenewMyLicense": "Lisansımı nasıl yenilerim?",
"HowDoIRenewMyLicenseExplanation": "<a href='{0}' target='_blank'>Kuruluş yönetimi sayfasına</a> giderek lisansınızı yenileyebilirsiniz. İndirimli Erken Yenileme fiyatlarımızdan yararlanmak için lisansınızın süresi dolmadan yenilemeyi unutmayınız. Bununla birlikte, Erken Yenileme fırsatınızın ne zaman kapanacağını bilmemek konusunda endişelenmeyin. Aboneliğiniz sona ermeden önce 3 hatırlatma e-postası alacaksınız. Son kullanma tarihinden 30 gün, 7 gün ve 1 gün önce göndereceğiz.",
"IsSourceCodeIncluded": "Lisansım ticari modüllerin ve temaların kaynak kodunu içeriyor mu?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Gelecekte kuruluşumun kayıtlı geliştiricilerini değiştirebilir miyim?",
"ChangingDevelopersExplanation": "Lisansınıza yeni geliştiriciler eklemenin yanı sıra mevcut geliştiricileri de herhangi bir ek ücret ödemeden değiştirebilirsiniz (bir geliştiriciyi kaldırıp aynı koltuğa yeni bir tane ekleyebilirsiniz).",
"WhatHappensWhenLicenseEnds": "Lisans sürem sona erdiğinde ne olur?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Ticari lisans türü <a href=\"{0}\" target=\"_blank\">kalıcı lisanstır</a>. Lisansınızın süresi dolduktan sonra projenizi geliştirmeye devam edebilirsiniz. Ve ehliyetinizi yenilemek zorunda değilsiniz. Lisansınız, kutudan çıktığı gibi bir yıllık Güncellemeler ve Destek planıyla birlikte gelir. Yeni özellikler, performans geliştirmeleri, hata düzeltmeleri, destek almaya devam etmek ve ABP Suite'i kullanmaya devam etmek için planınızı her yıl yenilemeyi unutmayın. Lisansınızın süresi dolduğunda, aşağıdaki avantajlardan daha fazlasını elde edemezsiniz;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Ticari lisans türü <a href=\"{0}\" target=\"_blank\">kalıcı lisanstır</a>. Lisansınızın süresi dolduktan sonra projenizi geliştirmeye devam edebilirsiniz. Ve lisansınızı yenilemek zorunda değilsiniz. Lisansınız, kutudan çıktığı gibi bir yıllık güncelleme ve destek planıyla birlikte gelir. Yeni özellikler, performans geliştirmeleri, hata düzeltmeleri, destek almaya devam etmek ve ABP Suite'i kullanmaya devam etmek için lisansınızı yenilemeniz gerekir. Lisansınızın süresi dolduğunda aşağıdaki avantajlardan yararlanamazsınız;",
"WhatHappensWhenLicenseEndsExplanation2": "ABP Ticari kullanarak yeni çözümler üretemezsiniz, ancak mevcut uygulamalarınızı sonsuza kadar geliştirmeye devam edebilirsiniz.",
"WhatHappensWhenLicenseEndsExplanation3": "MAJOR sürümünüzdeki modüller ve temalar için güncellemeler alabileceksiniz. Örneğin; Bir modülün v3.2.0'ını kullanıyorsanız, yine de o modülün v3.x.x (v3.3.0, v3.5.2... vb.) güncellemelerini alabilirsiniz. Ancak bir sonraki ana sürüm için güncellemeler alamazsınız (v4.x, v5.x gibi)",
"WhatHappensWhenLicenseEndsExplanation3": "MAJOR sürümünüzdeki modüller ve temalar için güncellemeler alabileceksiniz (RC veya Önizleme sürümleri hariç). Örneğin; Bir modülün v3.2.0'ını kullanıyorsanız, yine de o modülün v3.x.x (v3.3.0, v3.5.2... vb.) güncellemelerini alabilirsiniz. Ancak bir sonraki ana sürüm için güncellemeler alamazsınız (v4.x, v5.x gibi). Örneğin, lisansınızın süresi dolduğunda, en son sürüm v4.4.3 ve en son önizleme sürümü v5.0.0-rc.2 olduğunda, v4.X.X'e erişebilirsiniz ancak v5.X.X'e erişemezsiniz.",
"WhatHappensWhenLicenseEndsExplanation4": "ABP Ticari platformuna eklenen yeni modülleri ve temaları lisansınız sona erdikten sonra kuramazsınız.",
"WhatHappensWhenLicenseEndsExplanation5": "ABP Suite'i kullanamazsınız.",
"WhatHappensWhenLicenseEndsExplanation6": "Artık <a href=\"{0}\">premium desteği</a> alamazsınız.",
"WhatHappensWhenLicenseEndsExplanation7": "Bu avantajlardan yararlanmaya devam etmek istiyorsanız aboneliğinizi yenileyebilirsiniz. Lisansınızın süresi dolduktan sonra 1 ay içerisinde aboneliğinizi yenilerseniz %20 indirim uygulanır.",
"WhatHappensWhenLicenseEndsExplanation7": "Bu avantajlardan yararlanmaya devam etmek istiyorsanız lisansınızı uzatabilirsiniz (yenileyebilirsiniz). Lisansınızın süresi dolduktan sonra <strong>1 ay</strong> içinde lisansınızı uzatırsanız, aşağıdaki indirimler uygulanacaktır: Takım Lisansı %{0} indirim, İşletme Lisansı %{1} indirim, Kurumsal Lisans %{2} indirim .",
"WhenShouldIRenewMyLicense": "Ehliyetimi ne zaman yenilemeliyim?",
"WhenShouldIRenewMyLicenseExplanation1": "Lisansınızın süresi dolduktan sonra <strong>1 ay</strong> içinde lisansınızı yenilerseniz %20 indirim uygulanır.",
"WhenShouldIRenewMyLicenseExplanation2": "Lisansınızın bitiş tarihinden 1 ay sonra lisansınızı yenilerseniz, yenileme fiyatı lisans satın alma fiyatı ile aynı olacak ve yenilemenizde indirim yapılmayacaktır.",
"WhenShouldIRenewMyLicenseExplanation": "Lisansınızın süresi dolduktan sonra <strong>1 ay</strong> içinde lisansınızı yenilerseniz, aşağıdaki indirimler uygulanacaktır: Takım Lisansı %{0} indirim, İşletme Lisansı %{1} indirim, Kurumsal Lisans %{2} indirim . Lisansınızın sona erme tarihinden <strong>1 ay</strong> sonra lisansınızı yenilerseniz, yenileme fiyatı lisans satın alma fiyatı ile aynı olacak ve yenilemenizde indirim yapılmayacaktır.",
"TrialPlan": "Deneme planınız var mı?",
"TrialPlanExplanation": "ABP Commercial'ın şimdilik bir deneme planı yok. Ekip lisansları için 30 gün para iade garantisi veriyoruz. Sadece ilk 30 gün içinde geri ödeme talebinde bulunabilirsiniz. Business ve Enterprise lisansları için 30 gün içinde %60 geri ödeme sağlıyoruz. Bunun nedeni, Business ve Enterprise lisanslarının tüm modüllerin ve temaların tam kaynak kodunu içermesidir.",
"DoYouAcceptBankWireTransfer": "Banka havalesini kabul ediyor musunuz?",
"DoYouAcceptBankWireTransferExplanation": "Evet, banka havalesini kabul ediyoruz.<br />Lisans ücretini banka havalesi yoluyla gönderdikten sonra, makbuzunuzu ve istenen lisans türünü info@abp.io adresine e-posta ile gönderin. Uluslararası banka hesap bilgilerimiz:",
"DoYouAcceptBankWireTransferExplanation": "Evet, banka havalesini kabul ediyoruz.<br />Lisans ücretini banka havalesi yoluyla gönderdikten sonra, dekontunuzu ve talep edilen lisans türünü accounting@abp.io adresinden bize e-posta ile gönderin. Uluslararası banka hesap bilgilerimiz:",
"HowToUpgrade": "Yeni bir sürüm mevcut olduğunda mevcut uygulamalar nasıl yükseltilir?",
"HowToUpgradeExplanation1": "ABP Commercial kullanarak yeni bir uygulama oluşturduğunuzda, tüm modüller ve tema NuGet ve NPM paketleri olarak kullanılır. Böylece yeni bir sürüm çıktığında paketleri kolayca yükseltebilirsiniz.",
"HowToUpgradeExplanation2": "Standart NuGet/NPM yükseltmelerine ek olarak, <a href=\"{0}\">ABP CLI</a>, çözümünüzdeki ABP ile ilgili tüm paketleri otomatik olarak bulan ve yükselten bir güncelleme komutu sağlar.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/vi.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "Sự khác biệt giữa gia hạn giấy phép và nâng cấp là gì?",
"LicenseExtendUpgradeDiffExplanation": "<strong>Extending:</strong> By extending/renewing your license, you will continue to get premium support and get major updates for the modules and themes. Besides, you will be able to continue creating new projects. And you will still be able to use ABP Suite which speeds up your development.<hr/><strong>Upgrading:</strong> By upgrading your license, you will promote to a higher license plan which will allow you to get additional benefits. See the <a href=\"/pricing\">license comparison table</a> to check the differences between the license plans.<strong>On the other hand, when you upgrade, your license expiry date will not change!</strong>To extend your license end date, you need to extend your license.",
"LicenseRenewalCost": "Chi phí gia hạn giấy phép sau 1 năm là bao nhiêu?",
"LicenseRenewalCostExplanation": "Tỷ lệ gia hạn (gia hạn) của tất cả các giấy phép vĩnh viễn của ABP Thương mại bằng {0} giá niêm yết của giấy phép. Giá gia hạn của Giấy phép nhóm tiêu chuẩn là $ {1}, Giấy phép Kinh doanh tiêu chuẩn là $ {2} và Giấy phép Doanh nghiệp tiêu chuẩn là $ {3}. Nếu bạn đã là khách hàng, hãy <a href='{4}' target='_blank'> đăng nhập vào tài khoản của bạn </a> để xem lại giá gia hạn hiện có.",
"LicenseRenewalCostExplanation": "Giá gia hạn (gia hạn) của Giấy phép nhóm tiêu chuẩn là $ {0}, Giấy phép kinh doanh tiêu chuẩn là $ {1} và Giấy phép doanh nghiệp tiêu chuẩn là $ {2}. Nếu bạn đã là khách hàng, hãy <a href='{3}' target='_blank'> đăng nhập vào tài khoản của bạn </a> để xem lại giá gia hạn hiện có.",
"HowDoIRenewMyLicense": "Làm cách nào để gia hạn giấy phép của tôi?",
"HowDoIRenewMyLicenseExplanation": "Bạn có thể gia hạn giấy phép của mình bằng cách điều hướng đến <a href='{0}' target='_blank'> trang quản lý tổ chức </a>. Để tận dụng mức giá Gia hạn sớm được chiết khấu của chúng tôi, hãy đảm bảo bạn gia hạn trước khi giấy phép hết hạn. Tuy nhiên, đừng lo lắng về việc không biết khi nào cơ hội Gia hạn sớm của bạn đóng lại. Bạn sẽ nhận được 3 e-mail nhắc nhở trước khi đăng ký của bạn hết hạn. Chúng tôi sẽ gửi chúng vào 30 ngày, 7 ngày và 1 ngày trước khi hết hạn.",
"IsSourceCodeIncluded": "Giấy phép của tôi có bao gồm mã nguồn của các mô-đun và chủ đề thương mại không?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "Tôi có thể thay đổi các nhà phát triển đã đăng ký của tổ chức của mình trong tương lai không?",
"ChangingDevelopersExplanation": "Ngoài việc thêm các nhà phát triển mới vào giấy phép của mình, bạn cũng có thể thay đổi các nhà phát triển hiện có (bạn có thể xóa một nhà phát triển và thêm một nhà phát triển mới vào cùng một chỗ ngồi) mà không phải trả thêm bất kỳ chi phí nào.",
"WhatHappensWhenLicenseEnds": "Điều gì xảy ra khi thời hạn cấp phép của tôi kết thúc?",
"WhatHappensWhenLicenseEndsExplanation1": "Loại giấy phép thương mại của ABP là <a href=\"{0}\" target=\"_blank\"> giấy phép vĩnh viễn </a>. Sau khi giấy phép của bạn hết hạn, bạn có thể tiếp tục phát triển dự án của mình. Và bạn không có nghĩa vụ phải gia hạn giấy phép của mình. Giấy phép của bạn đi kèm với gói Cập nhật và Hỗ trợ kéo dài một năm. Để tiếp tục nhận được các tính năng mới, cải tiến hiệu suất, sửa lỗi, hỗ trợ và tiếp tục sử dụng ABP Suite, hãy đảm bảo gia hạn gói của bạn mỗi năm. Khi giấy phép của bạn hết hạn, bạn sẽ không thể nhận được nhiều lợi ích hơn sau đây;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP Loại giấy phép thương mại là <a href=\"{0}\" target=\"_blank\"> giấy phép vĩnh viễn </a>. Sau khi giấy phép của bạn hết hạn, bạn có thể tiếp tục phát triển dự án của mình. Và bạn không có nghĩa vụ phải gia hạn giấy phép của mình. Giấy phép của bạn đi kèm với một bản cập nhật và kế hoạch hỗ trợ trong một năm. Để tiếp tục nhận các tính năng mới, cải tiến hiệu suất, sửa lỗi, hỗ trợ và tiếp tục sử dụng ABP Suite, bạn cần gia hạn giấy phép của mình. Khi giấy phép của bạn hết hạn, bạn sẽ không nhận được những lợi ích sau đây;",
"WhatHappensWhenLicenseEndsExplanation2": "Bạn không thể tạo các giải pháp mới bằng ABP Commercial, nhưng bạn có thể tiếp tục phát triển các ứng dụng hiện có của mình mãi mãi.",
"WhatHappensWhenLicenseEndsExplanation3": "Bạn sẽ có thể nhận được các bản cập nhật cho các mô-đun và chủ đề trong phiên bản CHÍNH của bạn. Ví dụ; nếu bạn đang sử dụng v3.2.0 của một mô-đun, bạn vẫn có thể nhận được các bản cập nhật cho v3.x.x (v3.3.0, v3.5.2 ... v.v.) của mô-đun đó. Nhưng bạn không thể nhận các bản cập nhật cho phiên bản chính tiếp theo (như v4.x, v5.x)",
"WhatHappensWhenLicenseEndsExplanation3": "Bạn sẽ có thể nhận được bản cập nhật cho các mô-đun và chủ đề trong phiên bản CHÍNH của mình (ngoại trừ phiên bản RC hoặc Preview). Ví dụ; nếu bạn đang sử dụng v3.2.0 của một mô-đun, bạn vẫn có thể nhận được các bản cập nhật cho v3.x.x (v3.3.0, v3.5.2 ... v.v.) của mô-đun đó. Nhưng bạn không thể nhận các bản cập nhật cho phiên bản chính tiếp theo (như v4.x, v5.x). Ví dụ: khi giấy phép của bạn hết hạn, bản phát hành mới nhất là v4.4.3 và phiên bản xem trước mới nhất là v5.0.0-rc.2, bạn có thể truy cập v4.X.X nhưng không thể truy cập v5.X.X.",
"WhatHappensWhenLicenseEndsExplanation4": "Bạn không thể cài đặt các mô-đun và chủ đề mới được thêm vào nền tảng ABP Commercial sau khi giấy phép của bạn hết hạn.",
"WhatHappensWhenLicenseEndsExplanation5": "Bạn không thể sử dụng ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "Bạn không thể nhận được <a href=\"{0}\"> hỗ trợ cao cấp </a> nữa.",
"WhatHappensWhenLicenseEndsExplanation7": "Bạn có thể gia hạn đăng ký của mình nếu bạn muốn tiếp tục nhận được những lợi ích này. Nếu bạn gia hạn đăng ký của mình trong vòng 1 tháng sau khi giấy phép hết hạn, bạn sẽ được giảm giá 20%.",
"WhatHappensWhenLicenseEndsExplanation7": "Bạn có thể gia hạn (gia hạn) giấy phép của mình nếu bạn muốn tiếp tục nhận được những lợi ích này. Nếu bạn gia hạn giấy phép của mình trong vòng <strong> 1 tháng </strong> sau khi giấy phép của bạn hết hạn, các chiết khấu sau sẽ được áp dụng: Giảm giá {0}% cho Giấy phép Nhóm, Giảm giá {1}% Giấy phép Kinh doanh, Giảm giá {2}% Giấy phép Doanh nghiệp .",
"WhenShouldIRenewMyLicense": "Khi nào tôi nên gia hạn giấy phép của mình?",
"WhenShouldIRenewMyLicenseExplanation1": "Nếu bạn gia hạn giấy phép trong vòng <strong> 1 tháng </strong> sau khi giấy phép của bạn hết hạn, chiết khấu% 20 sẽ được áp dụng.",
"WhenShouldIRenewMyLicenseExplanation2": "Nếu bạn gia hạn giấy phép sau 1 tháng kể từ ngày giấy phép hết hạn, giá gia hạn sẽ giống như giá mua giấy phép và sẽ không có chiết khấu cho việc gia hạn của bạn.",
"WhenShouldIRenewMyLicenseExplanation": "Nếu bạn gia hạn giấy phép của mình trong vòng <strong> 1 tháng </strong> sau khi giấy phép của bạn hết hạn, các chiết khấu sau sẽ được áp dụng: Giảm giá {0}% cho Giấy phép Nhóm, Giảm giá {1}% Giấy phép Kinh doanh, Giảm giá {2}% Giấy phép Doanh nghiệp . Nếu bạn gia hạn giấy phép <strong> 1 tháng </strong> sau ngày giấy phép hết hạn, giá gia hạn sẽ giống như giá mua giấy phép và sẽ không có chiết khấu khi gia hạn của bạn.",
"TrialPlan": "Bạn có kế hoạch dùng thử không?",
"TrialPlanExplanation": "Hiện tại, ABP Commercial không có kế hoạch dùng thử. Đối với giấy phép Nhóm, chúng tôi cung cấp bảo đảm hoàn tiền trong 30 ngày. Bạn chỉ có thể yêu cầu hoàn lại tiền trong 30 ngày đầu tiên. Đối với giấy phép Doanh nghiệp và Doanh nghiệp, chúng tôi hoàn lại 60% trong 30 ngày. Điều này là do giấy phép Doanh nghiệp và Doanh nghiệp bao gồm mã nguồn đầy đủ của tất cả các mô-đun và chủ đề.",
"DoYouAcceptBankWireTransfer": "Bạn có chấp nhận chuyển khoản ngân hàng không?",
"DoYouAcceptBankWireTransferExplanation": "Có, chúng tôi chấp nhận chuyển khoản ngân hàng. <br /> Sau khi gửi phí cấp phép qua chuyển khoản ngân hàng, hãy gửi email cho chúng tôi theo địa chỉ info@abp.io biên lai của bạn và loại giấy phép được yêu cầu. Thông tin tài khoản ngân hàng quốc tế của chúng tôi:",
"DoYouAcceptBankWireTransferExplanation": "Có, chúng tôi chấp nhận chuyển khoản ngân hàng. <br /> Sau khi gửi phí cấp phép qua chuyển khoản ngân hàng, hãy gửi email cho chúng tôi theo địa chỉ accounting@abp.io biên lai của bạn và loại giấy phép được yêu cầu. Thông tin tài khoản ngân hàng quốc tế của chúng tôi:",
"HowToUpgrade": "Làm thế nào để nâng cấp các ứng dụng hiện có khi có phiên bản mới?",
"HowToUpgradeExplanation1": "Khi bạn tạo một ứng dụng mới bằng ABP Commercial, tất cả các mô-đun và chủ đề được sử dụng dưới dạng gói NuGet và NPM. Vì vậy, bạn có thể dễ dàng nâng cấp các gói khi có phiên bản mới.",
"HowToUpgradeExplanation2": "Ngoài các nâng cấp NuGet/NPM tiêu chuẩn, <a href=\"{0}\"> ABP CLI </a> cung cấp lệnh cập nhật tự động tìm và nâng cấp tất cả các gói liên quan đến ABP trong giải pháp của bạn.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hans.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "许可扩展和升级有什么区别?",
"LicenseExtendUpgradeDiffExplanation": "<strong>扩展:</strong> 通过扩展/更新许可,你将继续获得高级支持,并获得有关模块和主题的重大更新. 此外你将能够继续创建新项目. 而且你仍然可以使用ABP Suite来加快开发速度.<hr/><strong>升级:</strong> 通过升级许可,你将升级到更高的许可计划,这将使你获得更多好处. 查看 <a href=\"/pricing\">许可比较表</a>来检查许可计划之间的差异. <strong>另一方面,当你升级时你的许可到期日期不会改变!</strong>要延长你的许可终止日期,你需要延长你的许可.",
"LicenseRenewalCost": "一年后的许可续期费用是多少?",
"LicenseRenewalCostExplanation": "ABP商业版的续费价格均为原价的{0}. Team版本的续费价格是${1}, Business版本的续订价格是${2}, Enterprise版本的续订价格是${3}. 如果你已经购买了, 请<a href='{4}' target='_blank'>登录帐户</a>以查看续订价格.",
"LicenseRenewalCostExplanation": "标准 Team 许可证的续订(扩展)价格为 ${0},标准 Business License 为 ${1},标准 Enterprise License 为 ${2}。 如果您已经是客户,请<a href='{3}' target='_blank'>登录您的帐户</a>查看可用的续订价格。",
"HowDoIRenewMyLicense": "如何续费我的许可证?",
"HowDoIRenewMyLicenseExplanation": "你可以<a href='{0} target='_blank'>登录</a>以进行续费. 为了享受我们的续费折扣, 请确保在许可证到期之前进行续费, 我们会在到期前7天和30天发送2封续费提醒邮件.",
"IsSourceCodeIncluded": "我的许可是否包括商业模块和主题的源代码?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "我将来可以更改我组织的注册开发人员吗?",
"ChangingDevelopersExplanation": "除了将新的开发人员添加到你的许可中之外,你还可以更改现有的开发人员(可以删除一个开发人员并将新的开发人员添加到同一位置),而无需任何额外费用.",
"WhatHappensWhenLicenseEnds": "我的许可期限结束后会怎样?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP商业版具有<a href=\"{0}\" target=\"_blank\">永久许可类型</a>.许可到期后, 你可以继续开发你的项目.并且你没有义务续订许可.许可到期后;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP 商业许可类型为<a href=\"{0}\" target=\"_blank\">永久许可</a>。 许可证到期后,您可以继续开发您的项目。 而且您没有义务更新您的许可证。 您的许可证随附开箱即用的一年更新和支持计划。 要继续获得新功能、性能增强、错误修复、支持和继续使用 ABP Suite,您需要更新您的许可证。 当您的许可证到期时,您将无法获得以下好处;",
"WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商业版创建新的解决方案,但可以永远继续开发现有的应用程序.",
"WhatHappensWhenLicenseEndsExplanation3": "你能够在你的主版本中获得模块和主题的更新.例如;如果你使用的是模块的v3.2.0版本,你仍然可以获得v3.x.x版本的更新.(v3.3.0 v3.5.2…等等)的.但是你无法获得下一个主要版本(如v4.x,v5.x)的更新",
"WhatHappensWhenLicenseEndsExplanation3": "您将能够获得主要版本(RC 或预览版除外)中的模块和主题的更新。 例如; 如果您使用的是模块的 v3.2.0,您仍然可以获得该模块的 v3.x.x(v3.3.0、v3.5.2...等)的更新。 但是您无法获得下一个主要版本(如 v4.x、v5.x)的更新。 比如你的license过期了,最新版本是v4.4.3,最新预览版本是v5.0.0-rc.2,你可以访问v4.X.X,但是不能访问v5.X.X。",
"WhatHappensWhenLicenseEndsExplanation4": "许可到期后,你无法安装添加到ABP商业平台的新模块和主题.",
"WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "你不再获得<a href=\"{0}\">高级支持</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "如果你想继续获得这些好处,可以继续续订. 续订时有20%的折扣.",
"WhatHappensWhenLicenseEndsExplanation7": "如果您想继续获得这些好处,您可以延长(续订)您的许可证。 如果您在许可证到期后 <strong>1 个月</strong>内延长许可证,将享受以下折扣:团队许可证 {0}% 折扣、商业许可证 {1}% 折扣、企业许可证 {2}% 折扣 .",
"WhenShouldIRenewMyLicense": "我什么时候应该续订我的许可?",
"WhenShouldIRenewMyLicenseExplanation1": "如果你在许可到期后的<strong> 1个月</strong>内续订许可,则许可总价将享受%20的折扣.",
"WhenShouldIRenewMyLicenseExplanation2": "如果你在你的许可过期日期1个月后更新你的许可,更新价格将与许可购买价格相同,你的更新将没有折扣.",
"WhenShouldIRenewMyLicenseExplanation": "如果您在许可证到期后 <strong>1 个月</strong>内续订许可证,将享受以下折扣:团队许可证 {0}% 折扣、商业许可证 {1}% 折扣、企业许可证 {2}% 折扣 . 如果您在许可证到期后 <strong>1 个月</strong>续订许可证,续订价格将与许可证购买价格相同,并且续订不会有折扣。",
"TrialPlan": "你们有试用计划吗?",
"TrialPlanExplanation": "目前,ABP商业版还没有试用计划.对于团队许可,我们提供30天的退款保证.你可以在30天内要求退款.对于企业营业执照,我们提供30天内60%的退款.这是因为商业和企业许可包含所有模块和主题的完整源代码.",
"DoYouAcceptBankWireTransfer": "你们接受银行电汇吗?",
"DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇.<br />通过银行电汇转账,通过电子邮件将收据和所要求的许可类型发送给我们.<br />我们的国际银行帐户信息:",
"DoYouAcceptBankWireTransferExplanation": "是的,我们接受银行电汇。<br />在通过银行转账发送许可费后,将您的收据和所需的许可类型通过电子邮件发送至accounting@abp.io。 我们的国际银行账户信息:",
"HowToUpgrade": "可用新版本时如何升级现有应用程序?",
"HowToUpgradeExplanation1": "使用ABP商业版创建新应用程序时,所有模块和主题均用作NuGet和NPM软件包. 因此,当有新版本可用时,你可以轻松升级软件包.",
"HowToUpgradeExplanation2": "除了标准的NuGet/NPM升级之外,<a href=\"{0}\"> ABP CLI </a>还提供了一条更新命令,该命令可自动查找和升级解决方案中的所有与ABP相关的软件包.",

13
abp_io/AbpIoLocalization/AbpIoLocalization/Commercial/Localization/Resources/zh-Hant.json

@ -180,7 +180,7 @@
"LicenseExtendUpgradeDiff": "許可擴展和升級有什麽區別?",
"LicenseExtendUpgradeDiffExplanation": "<strong>擴展:</strong> 通過擴展/更新許可,你將繼續獲得高級支持,並獲得有關模塊和主題的重大更新. 此外你將能夠繼續創建新項目. 而且你仍然可以使用ABP Suite來加快開發速度.<hr/><strong>升級:</strong> 通過升級許可,你將升級到更高的許可計劃,這將使你獲得更多好處. 查看 <a href=\"/pricing\">許可比較表</a>來檢查許可計劃之間的差異. <strong>另一方面,當你升級時你的許可到期日期不會改變!</strong>要延長你的許可終止日期,你需要延長你的許可.",
"LicenseRenewalCost": "一年後的許可續期費用是多少?",
"LicenseRenewalCostExplanation": "ABP商業版的續費價格均為原價的{0}. Team版本的續費價格是${1}, Business版本的續訂價格是${2}, Enterprise版本的續訂價格是${3}. 如果你已經購買了, 請<a href='{4}' target='_blank'>登錄帳戶</a>以查看續訂價格.",
"LicenseRenewalCostExplanation": "標準 Team 許可證的續訂(擴展)價格為 ${0},標準 Business License 為 ${1},標準 Enterprise License 為 ${2}。 如果您已經是客戶,請<a href='{3}' target='_blank'>登錄您的帳戶</a>查看可用的續訂價格。",
"HowDoIRenewMyLicense": "如何續費我的許可證?",
"HowDoIRenewMyLicenseExplanation": "你可以<a href='{0} target='_blank'>登錄</a>以進行續費. 為了享受我們的續費折扣, 請確保在許可證到期之前進行續費, 我們會在到期前7天和30天發送2封續費提醒郵件.",
"IsSourceCodeIncluded": "我的許可是否包括商業模塊和主題的源代碼?",
@ -191,20 +191,19 @@
"ChangingDevelopers": "我將來可以更改我組織的註冊開發人員嗎?",
"ChangingDevelopersExplanation": "除了將新的開發人員添加到你的許可中之外,你還可以更改現有的開發人員(可以刪除一個開發人員並將新的開發人員添加到同一位置),而無需任何額外費用.",
"WhatHappensWhenLicenseEnds": "我的許可期限結束後會怎樣?",
"WhatHappensWhenLicenseEndsExplanation1": "ABP商業版具有<a href=\"{0}\" target=\"_blank\">永久許可類型</a>.許可到期後, 你可以繼續開發你的項目.並且你沒有義務續訂許可.許可到期後;",
"WhatHappensWhenLicenseEndsExplanation1": "ABP 商業許可類型為<a href=\"{0}\" target=\"_blank\">永久許可</a>。 許可證到期後,您可以繼續開發您的項目。 而且您沒有義務更新您的許可證。 您的許可證隨附開箱即用的一年更新和支持計劃。 要繼續獲得新功能、性能增強、錯誤修復、支持和繼續使用 ABP Suite,您需要更新您的許可證。 當您的許可證到期時,您將無法獲得以下好處;",
"WhatHappensWhenLicenseEndsExplanation2": "你不能使用ABP商業版創建新的解決方案,但可以永遠繼續開發現有的應用程序.",
"WhatHappensWhenLicenseEndsExplanation3": "你能夠在你的主版本中獲得模塊和主題的更新.例如;如果你使用的是模塊的v3.2.0版本,你仍然可以獲得v3.x.x版本的更新.(v3.3.0 v3.5.2…等等)的.但是你無法獲得下一個主要版本(如v4.x,v5.x)的更新",
"WhatHappensWhenLicenseEndsExplanation3": "您將能夠獲得主要版本(RC 或預覽版除外)中的模塊和主題的更新。 例如; 如果您使用的是模塊的 v3.2.0,您仍然可以獲得該模塊的 v3.x.x(v3.3.0、v3.5.2...等)的更新。 但是您無法獲得下一個主要版本(如 v4.x、v5.x)的更新。 比如你的license過期了,最新版本是v4.4.3,最新預覽版本是v5.0.0-rc.2,你可以訪問v4.X.X,但是不能訪問v5.X.X。",
"WhatHappensWhenLicenseEndsExplanation4": "許可到期後,你無法安裝添加到ABP商業平臺的新模塊和主題.",
"WhatHappensWhenLicenseEndsExplanation5": "你不能使用ABP Suite.",
"WhatHappensWhenLicenseEndsExplanation6": "你不再獲得<a href=\"{0}\">高級支持</a>.",
"WhatHappensWhenLicenseEndsExplanation7": "如果你想繼續獲得這些好處,可以繼續續訂. 續訂時有20%的折扣.",
"WhatHappensWhenLicenseEndsExplanation7": "如果您想繼續獲得這些好處,您可以延長(續訂)您的許可證。 如果您在許可證到期後 <strong>1 個月</strong>內延長許可證,將適用以下折扣:團隊許可證 {0}% 折扣、商業許可證 {1}% 折扣、企業許可證 {2}% 折扣 .",
"WhenShouldIRenewMyLicense": "我什麽時候應該續訂我的許可?",
"WhenShouldIRenewMyLicenseExplanation1": "如果你在许可到期后的<strong> 1个月</strong>内续订许可,则许可总价将享受%20的折扣.",
"WhenShouldIRenewMyLicenseExplanation2": "如果你在你的許可過期日期1個月後更新你的許可,更新價格將與許可購買價格相同,你的更新將沒有折扣.",
"WhenShouldIRenewMyLicenseExplanation": "如果您在許可證到期後 <strong>1 個月</strong>內續訂許可證,將享受以下折扣:團隊許可證 {0}% 折扣、商業許可證 {1}% 折扣、企業許可證 {2}% 折扣 . 如果您在許可證到期後 <strong>1 個月</strong>續訂許可證,續訂價格將與許可證購買價格相同,並且續訂不會有折扣。",
"TrialPlan": "你們有試用計劃嗎?",
"TrialPlanExplanation": "目前,ABP商業版還沒有試用計劃.對於團隊許可,我們提供30天的退款保證.你可以在30天內要求退款.對於企業營業執照,我們提供30天內60%的退款.這是因為商業和企業許可包含所有模塊和主題的完整源代碼.",
"DoYouAcceptBankWireTransfer": "你們接受銀行電匯嗎?",
"DoYouAcceptBankWireTransferExplanation": "是的,我們接受銀行電匯.<br />通過銀行電匯轉賬,通過電子郵件將收據和所要求的許可類型發送給我們.<br />我們的國際銀行帳戶信息:",
"DoYouAcceptBankWireTransferExplanation": "是的,我們接受銀行電匯。<br />在通過銀行轉賬發送許可費後,將您的收據和所需的許可類型通過電子郵件發送至accounting@abp.io。 我們的國際銀行賬戶信息:",
"HowToUpgrade": "可用新版本時如何升級現有應用程序?",
"HowToUpgradeExplanation1": "使用ABP商業版創建新應用程序時,所有模塊和主題均用作NuGet和NPM軟件包. 因此,當有新版本可用時,你可以輕松升級軟件包.",
"HowToUpgradeExplanation2": "除了標準的NuGet/NPM升級之外,<a href=\"{0}\"> ABP CLI </a>還提供了一條更新命令,該命令可自動查找和升級解決方案中的所有與ABP相關的軟件包.",

4
codecov.yml

@ -2,3 +2,7 @@ codecov:
branch: dev
require_ci_to_pass: yes
allow_coverage_offsets: true
status:
project:
default:
threshold: 1%

2
common.props

@ -1,7 +1,7 @@
<Project>
<PropertyGroup>
<LangVersion>latest</LangVersion>
<Version>5.0.0</Version>
<Version>5.1.0</Version>
<NoWarn>$(NoWarn);CS1591;CS0436</NoWarn>
<PackageIconUrl>https://abp.io/assets/abp_nupkg.png</PackageIconUrl>
<PackageProjectUrl>https://abp.io/</PackageProjectUrl>

11
docs/en/Authorization.md

@ -428,7 +428,7 @@ This is already done for the startup template integration tests.
Claims are important elements of authentication and authorization. ABP uses the `IAbpClaimsPrincipalFactory` service to create claims on authentication. This service was designed as extensible. If you need to add your custom claims to the authentication ticket, you can implement the `IAbpClaimsPrincipalContributor` in your application.
**Example: Add a `SocialSecurityNumber` claim:**
**Example: Add a `SocialSecurityNumber` claim and get it:**
```csharp
public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipalContributor, ITransientDependency
@ -448,6 +448,15 @@ public class SocialSecurityNumberClaimsPrincipalContributor : IAbpClaimsPrincipa
}
}
}
public static class CurrentUserExtensions
{
public static string GetSocialSecurityNumber(this ICurrentUser currentUser)
{
return currentUser.FindClaimValue("SocialSecurityNumber");
}
}
```
## See Also

30
docs/en/Background-Workers-Hangfire.md

@ -66,6 +66,33 @@ public class MyLogWorker : HangfireBackgroundWorkerBase
> You can directly implement the `IHangfireBackgroundWorker`, but `HangfireBackgroundWorkerBase` provides some useful properties like Logger.
### UnitOfWork
For use with `UnitOfWorkAttribute`, you need to define an interface for worker:
```csharp
public interface IMyLogWorker : IHangfireBackgroundWorker
{
}
[ExposeServices(typeof(IMyLogWorker))]
public class MyLogWorker : HangfireBackgroundWorkerBase, IMyLogWorker
{
public MyLogWorker()
{
RecurringJobId = nameof(MyLogWorker);
CronExpression = Cron.Daily();
}
[UnitOfWork]
public override Task DoWorkAsync()
{
Logger.LogInformation("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}
```
## Register BackgroundWorkerManager
After creating a background worker class, you should add it to the `IBackgroundWorkerManager`. The most common place is the `OnApplicationInitialization` method of your module class:
@ -78,6 +105,9 @@ public class MyModule : AbpModule
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<MyLogWorker>();
//If the interface is defined
//context.AddBackgroundWorker<IMyLogWorker>();
}
}
````

76
docs/en/Connection-Strings.md

@ -1,15 +1,17 @@
# Connection Strings
ABP Framework is designed to be [modular](Module-Development-Basics.md), [microservice compatible](Microservice-Architecture.md) and [multi-tenancy](Multi-Tenancy.md) aware. Connection string management is also designed to support these scenarios;
> Connection string system is especially needed when you want to create or use a modular system. If you have a monolithic application with a single database, you can go with the [ABP startup solution template](Startup-Templates/Application.md), which is properly configured for you.
* Allows to set separate connection strings for every module, so every module can have its own physical database. Modules even might be configured to use different DBMSs.
ABP Framework is designed to be [modular](Module-Development-Basics.md) and [multi-tenancy](Multi-Tenancy.md) aware. Connection string management is also designed to support these scenarios;
* Allows to set separate connection strings for every module, so every module can have its own physical database. Modules even might be configured to use different database providers.
* Allows to set separate connection string and use a separate database per tenant (in a SaaS application).
It also supports hybrid scenarios;
* Allows to group modules into databases (all modules into a single shared database, 2 modules to database A, 3 modules to database B, 1 module to database C and rest of the modules to database D... etc.)
* Allows to group modules into databases (e.g., all modules into a single shared database or two modules to database A, three modules to database B, one module to database C and rest of the modules to database D)
* Allows to group tenants into databases, just like the modules.
* Allows to separate databases per tenant per module (which might be harder to maintain for you because of too many databases, but the ABP framework supports it).
* Allows to separate databases per tenant per module (which might be hard to maintain for you because of too many databases, but the ABP framework supports it).
All the [pre-built application modules](Modules/Index.md) are designed to be compatible these scenarios.
@ -29,15 +31,19 @@ See the following configuration:
This configuration defines three different connection strings:
* `MyMainDb` (the `Default` connection string) is the main connection string of the application. If you don't specify a connection string for a module, it fallbacks to the `Default` connection string. The [application startup template](Startup-Templates/Application.md) is configured to use a single connection string, so all the modules uses a single shared database.
* `MyIdsDb` is used by the [IdentityServer](Modules/IdentityServer.md) module.
* `MyPermissionDb` is used by the [Permission Management](Modules/Permission-Management.md) module.
* `MyMainDb` (the `Default` connection string) is the main connection string of the application. If you don't specify a connection string for a module, it fallbacks to the `Default` connection string. The [application startup template](Startup-Templates/Application.md) is configured to use a single connection string, so all the modules uses a single, shared database.
* `MyIdsDb` (the `AbpIdentityServer` connection string) is used by the [IdentityServer](Modules/IdentityServer.md) module.
* `MyPermissionDb` (the `AbpPermissionManagement` connection string) is used by the [Permission Management](Modules/Permission-Management.md) module.
[Pre-built application modules](Modules/Index.md) define constants for the connection string names. For example, the IdentityServer module defines a ` ConnectionStringName ` constant in the ` AbpIdentityServerDbProperties ` class (located in the ` Volo.Abp.IdentityServer ` namespace). Other modules similarly define constants, so you can investigate the connection string name.
[Pre-built application modules](Modules/Index.md) define constants for the connection string names. For example, the [IdentityServer module](Modules/IdentityServer.md) defines a ` ConnectionStringName ` constant in the ` AbpIdentityServerDbProperties ` class (located in the ` Volo.Abp.IdentityServer ` namespace). Other modules similarly define constants, so you can investigate the connection string name.
### AbpDbConnectionOptions
ABP actually uses the `AbpDbConnectionOptions` to get the connection strings. If you set the connection strings as explained above, `AbpDbConnectionOptions` is automatically filled. However, you can set or override the connection strings using [the options pattern](Options.md). You can configure the `AbpDbConnectionOptions` in the `ConfigureServices` method of your [module](Module-Development-Basics.md) as shown below:
`AbpDbConnectionOptions` is the options class that is used to set the connection strings and configure database structures.
#### Setting the connection strings
ABP uses the `AbpDbConnectionOptions` to get the connection strings. If you configure the connection strings as explained above, `AbpDbConnectionOptions` is automatically filled. However, you can set or override the connection strings using [the options pattern](Options.md). You can configure the `AbpDbConnectionOptions` in the `ConfigureServices` method of your [module](Module-Development-Basics.md) as shown below:
````csharp
public override void ConfigureServices(ServiceConfigurationContext context)
@ -50,6 +56,52 @@ public override void ConfigureServices(ServiceConfigurationContext context)
}
````
#### Configuring the database structures
`Databases` property of the `AbpDbConnectionOptions` class is used to group multiple connection strings (of multiple modules) to a single connection string.
See the following connection strings:
````json
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyMainDb;Trusted_Connection=True;",
"AbpIdentity": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;",
"AbpIdentityServer": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;",
"AbpPermissionManagement": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;"
}
````
In this example, we've defined four connection strings, but the last three of them are the same; `AbpIdentity`, `AbpIdentityServer` and `AbpPermissionManagement` uses the same database, named `MySecondaryDb`. The main application and the other modules use the `Default` connection string, hence the `MyMainDb` database.
What we want to do here is to group three modules (`AbpIdentity`, `AbpIdentityServer` and `AbpPermissionManagement`) in a single database, but we needed to specify each one manually. Because the fallback connection string is the `Default` one, if we don't specify it for a module.
To eliminate the repetitive connection string definition, we can configure the `AbpDbConnectionOptions.Databases` property to group these connection strings, as shown in the following code (we place that in the `ConfigureServices` method of our [module class](Module-Development-Basics.md)):
````csharp
Configure<AbpDbConnectionOptions>(options =>
{
options.Databases.Configure("MySecondaryDb", db =>
{
db.MappedConnections.Add("AbpIdentity");
db.MappedConnections.Add("AbpIdentityServer");
db.MappedConnections.Add("AbpPermissionManagement");
});
});
````
Then we can change the `appsettings.json` file as shown in the following code block:
````json
"ConnectionStrings": {
"Default": "Server=localhost;Database=MyMainDb;Trusted_Connection=True;",
"MySecondaryDb": "Server=localhost;Database=MySecondaryDb;Trusted_Connection=True;"
}
````
`MySecondaryDb` becomes the new connection string for the mapped connections.
> ABP first looks for the module-specific connection string, then looks if a database mapping is available, finally fallbacks to the `Default` connection string.
## Set the Connection String Name
A module typically has a unique connection string name associated to its `DbContext` class using the `ConnectionStringName` attribute. Example:
@ -62,15 +114,13 @@ public class IdentityServerDbContext
}
````
For [Entity Framework Core](Entity-Framework-Core.md) and [MongoDB](MongoDB.md), write this to your `DbContext` class (and the interface if it has).
> If you are developing a reusable, database provider independent module see also [the best practices guide](Best-Practices/Index.md).
For [Entity Framework Core](Entity-Framework-Core.md) and [MongoDB](MongoDB.md), write this to your `DbContext` class (and the interface if it has). In this way, ABP uses the specified connection string for the related `DbContext` instances.
## Database Migrations for the Entity Framework Core
Relational databases require to create the database and the database schema (tables, views... etc.) before using it.
The startup template (with EF Core ORM) comes with a single database and a `.EntityFrameworkCore` project that contains related classes and the migration files for that database. This project mainly defines a *YourProjectName*DbContext that calls the `Configure...()` methods of the used modules, like `builder.ConfigurePermissionManagement()`.
The startup template (with EF Core ORM) comes with a single database and a `.EntityFrameworkCore` project that contains related classes and the migration files for that database. This project mainly defines a `YourProjectNameDbContext` class that calls the `Configure...()` methods of the used modules, like `builder.ConfigurePermissionManagement()`.
Once you want to separate a module's database, you typically will need to create a second migration path. See the [EF Core Migrations](Entity-Framework-Core-Migrations.md) document to learn how to create and use a different database for a desired module.

11
docs/en/Modules/Cms-Kit/Index.md

@ -18,9 +18,14 @@ Click to a feature to understand and learn how to use it.
All features are individually usable. If you disable a feature, it completely disappears from your application, even from the database tables, by the help of the [Global Features](../../Global-Features.md) system.
## How to Install
## Pre Requirements
- This module depends on [BlobStoring](../../Blob-Storing.md) module for keeping media content.
> Make sure `BlobStoring` module is installed and at leats one provider is configured properly. For more information, check the [documentation](../../Blob-Storing.md).
- CMS Kit uses [distributed cache](../../Caching.md) for responding faster.
> Using a distributed cache, such as [Redis](../../Redis-Cache.md), is highly recommended for data consistency in distributed/clustered deployments.
> This module is depends on [BlobStoring](../../Blob-Storing.md) module, please install `BlobStoring` module first and add a provider. For more information, check the [documentation](../../Blob-Storing.md).
## How to Install
[ABP CLI](../../CLI.md) allows installing a module to a solution using the `add-module` command. You can install the CMS Kit module in a command-line terminal with the following command:
@ -71,4 +76,4 @@ All tables/collections use the `Cms` prefix by default. Set static properties on
This module uses `CmsKit` for the connection string name. If you don't define a connection string with this name, it fallbacks to the `Default` connection string.
See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details.
See the [connection strings](https://docs.abp.io/en/abp/latest/Connection-Strings) documentation for details.

45
docs/en/Tutorials/Part-1.md

@ -13,7 +13,7 @@ In this tutorial series, you will build an ABP based web application named `Acme
* **{{DB_Value}}** as the database provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts;
This tutorial is organized as the following parts:
- **Part 1: Creating the server side (this part)**
- [Part 2: The book list page](Part-2.md)
@ -34,7 +34,7 @@ This tutorial has multiple versions based on your **UI** and **Database** prefer
* [Blazor UI with EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore)
* [Angular UI with MongoDB](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb)
> If you encounter the "filename too long" or "unzip error" on Windows, it's probably related to the Windows maximum file path limitation. Windows has a maximum file path limitation of 250 characters. To solve this, [enable the long path option in Windows 10](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> If you encounter the "filename too long" or "unzip" error on Windows, it's probably related to the Windows maximum file path limitation. Windows has a maximum file path limitation of 250 characters. To solve this, [enable the long path option in Windows 10](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> If you face long path errors related to Git, try the following command to enable long paths in Windows. See https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
> `git config --system core.longpaths true`
@ -49,14 +49,14 @@ This part is also recorded as a video tutorial and **<a href="https://www.youtub
## Creating the Solution
Before starting to the development, create a new solution named `Acme.BookStore` and run it by following the [getting started tutorial](../Getting-Started.md).
Before starting the development, create a new solution named `Acme.BookStore` and run it by following the [getting started tutorial](../Getting-Started.md).
## Create the Book Entity
**Domain layer** in the startup template is separated into two projects:
- `Acme.BookStore.Domain` contains your [entities](../Entities.md), [domain services](../Domain-Services.md) and other core domain objects.
- `Acme.BookStore.Domain.Shared` contains `constants`, `enums` or other domain related objects those can be shared with clients.
- `Acme.BookStore.Domain.Shared` contains `constants`, `enums` or other domain related objects that can be shared with clients.
So, define your entities in the domain layer (`Acme.BookStore.Domain` project) of the solution.
@ -82,10 +82,10 @@ namespace Acme.BookStore.Books
````
* ABP Framework has two fundamental base classes for entities: `AggregateRoot` and `Entity`. **Aggregate Root** is a [Domain Driven Design](../Domain-Driven-Design.md) concept which can be thought as a root entity that is directly queried and worked on (see the [entities document](../Entities.md) for more).
* `Book` entity inherits from the `AuditedAggregateRoot` which adds some base [auditing](../Audit-Logging.md) properties (like `CreationTime`, `CreatorId`, `LastModificationTime`...) on top of the `AggregateRoot` class. ABP automatically manages these properties for you.
* The `Book` entity inherits from the `AuditedAggregateRoot` which adds some base [auditing](../Audit-Logging.md) properties (like `CreationTime`, `CreatorId`, `LastModificationTime`...) on top of the `AggregateRoot` class. ABP automatically manages these properties for you.
* `Guid` is the **primary key type** of the `Book` entity.
> This tutorials leaves the entity properties with **public get/set** for the sake of simplicity. See the [entities document](../Entities.md) if you learn more about DDD best practices.
> This tutorial leaves the entity properties with **public get/set** for the sake of simplicity. See the [entities document](../Entities.md) if you want to learn more about DDD best practices.
### BookType Enum
@ -113,11 +113,11 @@ The final folder/file structure should be as shown below:
![bookstore-book-and-booktype](images/bookstore-book-and-booktype.png)
### Add Book Entity to the DbContext
### Add the Book Entity to the DbContext
{{if DB == "EF"}}
EF Core requires to relate entities with your `DbContext`. The easiest way to do this is to add a `DbSet` property to the `BookStoreDbContext` class in the `Acme.BookStore.EntityFrameworkCore` project, as shown below:
EF Core requires that you relate the entities with your `DbContext`. The easiest way to do so is adding a `DbSet` property to the `BookStoreDbContext` class in the `Acme.BookStore.EntityFrameworkCore` project, as shown below:
````csharp
public class BookStoreDbContext : AbpDbContext<BookStoreDbContext>
@ -147,7 +147,7 @@ public class BookStoreMongoDbContext : AbpMongoDbContext
### Map the Book Entity to a Database Table
Locate to `OnModelCreating` method in the `BookStoreDbContext` class and add the mapping code for the `Book` entity:
Navigate to the `OnModelCreating` method in the `BookStoreDbContext` class and add the mapping code for the `Book` entity:
````csharp
using Acme.BookStore.Books;
@ -185,8 +185,8 @@ namespace Acme.BookStore.EntityFrameworkCore
}
````
* `BookStoreConsts` has constant values for schema and table prefixes for your tables. You don't have to use it, but suggested to control the table prefixes in a single point.
* `ConfigureByConvention()` method gracefully configures/maps the inherited properties. Always use it for all your entities.
* `BookStoreConsts` has constant values for the schema and table prefixes for your tables. You don't have to use it, but it's suggested to control the table prefixes in a single point.
* The `ConfigureByConvention()` method gracefully configures/maps the inherited properties. Always use it for all your entities.
### Add Database Migration
@ -202,13 +202,13 @@ This will add a new migration class to the project:
![bookstore-efcore-migration](./images/bookstore-efcore-migration.png)
> If you are using Visual Studio, you may want to use `Add-Migration Created_Book_Entity -c BookStoreMigrationsDbContext` and `Update-Database -c BookStoreMigrationsDbContext` commands in the *Package Manager Console (PMC)*. In this case, ensure that {{if UI=="MVC"}}`Acme.BookStore.Web`{{else if UI=="BlazorServer"}}`Acme.BookStore.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`Acme.BookStore.HttpApi.Host`{{end}} is the startup project and `Acme.BookStore.EntityFrameworkCore` is the *Default Project* in PMC.
> If you are using Visual Studio, you may want to use the `Add-Migration Created_Book_Entity -c BookStoreMigrationsDbContext` and `Update-Database -c BookStoreMigrationsDbContext` commands in the *Package Manager Console (PMC)*. In this case, ensure that {{if UI=="MVC"}}`Acme.BookStore.Web`{{else if UI=="BlazorServer"}}`Acme.BookStore.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`Acme.BookStore.HttpApi.Host`{{end}} is the startup project and `Acme.BookStore.EntityFrameworkCore` is the *Default Project* in PMC.
{{end}}
### Add Sample Seed Data
> It's good to have some initial data in the database before running the application. This section introduces the [Data Seeding](../Data-Seeding.md) system of the ABP framework. You can skip this section if you don't want to create seed data, but it is suggested to follow it to learn this useful ABP Framework feature.
> It's good to have some initial data in the database before running the application. This section introduces the [Data Seeding](../Data-Seeding.md) system of the ABP framework. You can skip this section if you don't want to create the data seeding, but it is suggested to follow along and learn this useful ABP Framework feature.
Create a class deriving from the `IDataSeedContributor` in the `*.Domain` project by copying the following code:
@ -263,7 +263,7 @@ namespace Acme.BookStore
}
```
* This code simply uses the `IRepository<Book, Guid>` (the default [repository](../Repositories.md)) to insert two books to the database, if there is no book currently in the database.
* This code simply uses the `IRepository<Book, Guid>` (the default [repository](../Repositories.md)) to insert two books to the database in case there weren't any books in it.
### Update the Database
@ -271,7 +271,6 @@ Run the `Acme.BookStore.DbMigrator` application to update the database:
![bookstore-dbmigrator-on-solution](images/bookstore-dbmigrator-on-solution.png)
`.DbMigrator` is a console application that can be run to **migrate the database schema** and **seed the data** on **development** and **production** environments.
## Create the Application Service
@ -307,10 +306,10 @@ namespace Acme.BookStore.Books
````
* **DTO** classes are used to **transfer data** between the *presentation layer* and the *application layer*. See the [Data Transfer Objects document](https://docs.abp.io/en/abp/latest/Data-Transfer-Objects) for more details.
* `BookDto` is used to transfer book data to the presentation layer in order to show the book information on the UI.
* `BookDto` is derived from the `AuditedEntityDto<Guid>` which has audit properties just like the `Book` entity defined above.
* The `BookDto` is used to transfer the book data to the presentation layer in order to show the book information on the UI.
* The `BookDto` is derived from the `AuditedEntityDto<Guid>` which has audit properties just like the `Book` entity defined above.
It will be needed to map `Book` entities to `BookDto` objects while returning books to the presentation layer. [AutoMapper](https://automapper.org) library can automate this conversion when you define the proper mapping. The startup template comes with AutoMapper pre-configured. So, you can just define the mapping in the `BookStoreApplicationAutoMapperProfile` class in the `Acme.BookStore.Application` project:
It will be needed to map the `Book` entities to the `BookDto` objects while returning books to the presentation layer. [AutoMapper](https://automapper.org) library can automate this conversion when you define the proper mapping. The startup template comes with AutoMapper pre-configured. So, you can just define the mapping in the `BookStoreApplicationAutoMapperProfile` class in the `Acme.BookStore.Application` project:
````csharp
using Acme.BookStore.Books;
@ -359,10 +358,10 @@ namespace Acme.BookStore.Books
}
````
* This `DTO` class is used to get book information from the user interface while creating or updating a book.
* This `DTO` class is used to get a book information from the user interface while creating or updating the book.
* It defines data annotation attributes (like `[Required]`) to define validations for the properties. `DTO`s are [automatically validated](https://docs.abp.io/en/abp/latest/Validation) by the ABP framework.
Just like done for the `BookDto` above, we should define the mapping from the `CreateUpdateBookDto` object to the `Book` entity. The final class will be like shown below:
As done to the `BookDto` above, we should define the mapping from the `CreateUpdateBookDto` object to the `Book` entity. The final class will be as shown below:
````csharp
using Acme.BookStore.Books;
@ -440,13 +439,13 @@ namespace Acme.BookStore.Books
* `BookAppService` is derived from `CrudAppService<...>` which implements all the CRUD (create, read, update, delete) methods defined by the `ICrudAppService`.
* `BookAppService` injects `IRepository<Book, Guid>` which is the default repository for the `Book` entity. ABP automatically creates default repositories for each aggregate root (or entity). See the [repository document](https://docs.abp.io/en/abp/latest/Repositories).
* `BookAppService` uses `IObjectMapper` service ([see](../Object-To-Object-Mapping.md)) to map `Book` objects to `BookDto` objects and `CreateUpdateBookDto` objects to `Book` objects. The Startup template uses the [AutoMapper](http://automapper.org/) library as the object mapping provider. We have defined the mappings before, so it will work as expected.
* `BookAppService` uses `IObjectMapper` service ([see](../Object-To-Object-Mapping.md)) to map the `Book` objects to the `BookDto` objects and `CreateUpdateBookDto` objects to the `Book` objects. The Startup template uses the [AutoMapper](http://automapper.org/) library as the object mapping provider. We have defined the mappings before, so it will work as expected.
## Auto API Controllers
In a typical ASP.NET Core application, you create **API Controllers** to expose application services as **HTTP API** endpoints. This allows browsers or 3rd-party clients to call them over HTTP.
In a typical ASP.NET Core application, you create **API Controllers** to expose the application services as **HTTP API** endpoints. This allows browsers or 3rd-party clients to call them over HTTP.
ABP can [**automagically**](../API/Auto-API-Controllers.md) configures your application services as MVC API Controllers by convention.
ABP can [**automagically**](../API/Auto-API-Controllers.md) configure your application services as MVC API Controllers by convention.
### Swagger UI

86
docs/en/Tutorials/Part-2.md

@ -13,7 +13,7 @@ In this tutorial series, you will build an ABP based web application named `Acme
* **{{DB_Value}}** as the ORM provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts;
This tutorial is organized as the following parts:
- [Part 1: Creating the server side](Part-1.md)
- **Part 2: The book list page (this part)**
@ -53,7 +53,7 @@ This part is also recorded as a video tutorial and **<a href="https://www.youtub
It's common to call the HTTP API endpoints via AJAX from the **JavaScript** side. You can use `$.ajax` or another tool to call the endpoints. However, ABP offers a better way.
ABP **dynamically** creates **[JavaScript Proxies](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md)** for all API endpoints. So, you can use any **endpoint** just like calling a **JavaScript function**.
ABP **dynamically** creates **[JavaScript Proxies](../UI/AspNetCore/Dynamic-JavaScript-Proxies.md)** for all the API endpoints. So, you can use any **endpoint** just like calling a **JavaScript function**.
### Testing in the Developer Console
@ -66,8 +66,8 @@ acme.bookStore.books.book.getList({}).done(function (result) { console.log(resul
* `acme.bookStore.books` is the namespace of the `BookAppService` converted to [camelCase](https://en.wikipedia.org/wiki/Camel_case).
* `book` is the conventional name for the `BookAppService` (removed `AppService` postfix and converted to camelCase).
* `getList` is the conventional name for the `GetListAsync` method defined in the `CrudAppService` base class (removed `Async` postfix and converted to camelCase).
* `{}` argument is used to send an empty object to the `GetListAsync` method which normally expects an object of type `PagedAndSortedResultRequestDto` that is used to send paging and sorting options to the server (all properties are optional with default values, so you can send an empty object).
* `getList` function returns a `promise`. You can pass a callback to the `then` (or `done`) function to get the result returned from the server.
* The `{}` argument is used to send an empty object to the `GetListAsync` method which normally expects an object of type `PagedAndSortedResultRequestDto` that is used to send paging and sorting options to the server (all properties are optional with default values, so you can send an empty object).
* The `getList` function returns a `promise`. You can pass a callback to the `then` (or `done`) function to get the result returned from the server.
Running this code produces the following output:
@ -90,9 +90,9 @@ acme.bookStore.books.book.create({
});
````
> If you downloaded the source code of the tutorial and following the steps from the sample, you should also pass the `authorId` parameter to the create method for **creating a new book**.
> If you downloaded the source code of the tutorial and are following the steps from the sample, you should also pass the `authorId` parameter to the create method for **creating a new book**.
You should see a message in the console something like that:
You should see a message in the console that looks something like this:
````text
successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
@ -100,19 +100,19 @@ successfully created the book with id: 439b0ea8-923e-8e1e-5d97-39f2c7ac4246
Check the `Books` table in the database to see the new book row. You can try `get`, `update` and `delete` functions yourself.
We will use these dynamic proxy functions in the next sections to communicate to the server.
We will use these dynamic proxy functions in the next sections to communicate with the server.
{{end}}
## Localization
Before starting to the UI development, we first want to prepare the localization texts (you normally do this when needed while developing your application).
Before starting the UI development, we first want to prepare the localization texts (you normally do this when needed while developing your application).
Localization texts are located under the `Localization/BookStore` folder of the `Acme.BookStore.Domain.Shared` project:
![bookstore-localization-files](images/bookstore-localization-files-v2.png)
Open the `en.json` (*the English translations*) file and change the content as below:
Open the `en.json` (*the English translations*) file and change the content as shown below:
````json
{
@ -152,17 +152,17 @@ Open the `en.json` (*the English translations*) file and change the content as b
* Add `Menu:` prefix for menu items.
* Use `Enum:<enum-type>:<enum-value>` naming convention to localize the enum members. When you do it like that, ABP can automatically localize the enums in some proper cases.
If a text is not defined in the localization file, it **fallbacks** to the localization key (as ASP.NET Core's standard behavior).
If a text is not defined in the localization file, it **falls back** to the localization key (as ASP.NET Core's standard behavior).
> ABP's localization system is built on [ASP.NET Core's standard localization](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) system and extends it in many ways. See the [localization document](../Localization.md) for details.
> ABP's localization system is built on the [ASP.NET Core's standard localization](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/localization) system and extends it in many ways. Check the [localization document](../Localization.md) for details.
{{if UI == "MVC"}}
## Create a Books Page
It's time to create something visible and usable! Instead of classic MVC, we will use the [Razor Pages UI](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) approach which is recommended by Microsoft.
It's time to create something visible and usable! Instead of the classic MVC, we will use the [Razor Pages UI](https://docs.microsoft.com/en-us/aspnet/core/tutorials/razor-pages/razor-pages-start) approach which is recommended by Microsoft.
Create `Books` folder under the `Pages` folder of the `Acme.BookStore.Web` project. Add a new Razor Page by right clicking the Books folder then selecting **Add > Razor Page** menu item. Name it as `Index`:
Create a `Books` folder under the `Pages` folder of the `Acme.BookStore.Web` project. Add a new Razor Page by right clicking the Books folder then selecting **Add > Razor Page** menu item. Name it as `Index`:
![bookstore-add-index-page](images/bookstore-add-index-page-v2.png)
@ -213,21 +213,21 @@ context.Menu.AddItem(
);
````
Run the project, login to the application with the username `admin` and the password `1q2w3E*` and see the new menu item has been added to the main menu:
Run the project, login to the application with the username `admin` and the password `1q2w3E*` and you can see that the new menu item has been added to the main menu:
![bookstore-menu-items](images/bookstore-new-menu-item.png)
When you click to the Books menu item under the Book Store parent, you are being redirected to the new empty Books Page.
When you click on the Books menu item under the Book Store parent, you will be redirected to the new empty Books Page.
### Book List
We will use the [Datatables.net](https://datatables.net/) jQuery library to show the book list. Datatables library completely work via AJAX, it is fast, popular and provides a good user experience.
We will use the [Datatables.net](https://datatables.net/) jQuery library to show the book list. Datatables library completely works via AJAX, it is fast, popular and provides a good user experience.
> Datatables library is configured in the startup template, so you can directly use it in any page without including any style or script file to your page.
> Datatables library is configured in the startup template, so you can directly use it in any page without including any style or script file for your page.
#### Index.cshtml
Change the `Pages/Books/Index.cshtml` as following:
Change the `Pages/Books/Index.cshtml` as the following:
````html
@page
@ -250,8 +250,8 @@ Change the `Pages/Books/Index.cshtml` as following:
</abp-card>
````
* `abp-script` [tag helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro) is used to add external **scripts** to the page. It has many additional features compared to standard `script` tag. It handles **minification** and **versioning**. See the [bundling & minification document](../UI/AspNetCore/Bundling-Minification.md) for details.
* `abp-card` is a tag helper for Twitter Bootstrap's [card component](https://getbootstrap.com/docs/4.5/components/card/). There are other useful tag helpers provided by the ABP Framework to easily use most of the [bootstrap](https://getbootstrap.com/) components. You could use the regular HTML tags instead of these tag helpers, but using tag helpers reduces HTML code and prevents errors by help the of IntelliSense and compile time type checking. Further information, see the [tag helpers](../UI/AspNetCore/Tag-Helpers/Index.md) document.
* `abp-script` [tag helper](https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/intro) is used to add external **scripts** to the page. It has many additional features compared to the standard `script` tag. It handles **minification** and **versioning**. Check the [bundling & minification document](../UI/AspNetCore/Bundling-Minification.md) for details.
* `abp-card` is a tag helper for Twitter Bootstrap's [card component](https://getbootstrap.com/docs/4.5/components/card/). There are other useful tag helpers provided by the ABP Framework to easily use most of [bootstrap](https://getbootstrap.com/)'s components. You could use the regular HTML tags instead of these tag helpers, but using tag helpers reduces HTML code and prevents errors by the help of the IntelliSense and compiles time type checking. For further information, check the [tag helpers](../UI/AspNetCore/Tag-Helpers/Index.md) document.
#### Index.js
@ -316,9 +316,9 @@ $(function () {
});
````
* `abp.localization.getResource` gets a function that is used to localize text using the same JSON file defined in the server side. In this way, you can share the localization values with the client side.
* `abp.localization.getResource` gets a function that is used to localize text using the same JSON file defined on the server side. In this way, you can share the localization values with the client side.
* `abp.libs.datatables.normalizeConfiguration` is a helper function defined by the ABP Framework. There's no requirement to use it, but it simplifies the [Datatables](https://datatables.net/) configuration by providing conventional default values for missing options.
* `abp.libs.datatables.createAjax` is another helper function to adapt ABP's dynamic JavaScript API proxies to [Datatable](https://datatables.net/)'s expected parameter format
* `abp.libs.datatables.createAjax` is another helper function to adapt the ABP's dynamic JavaScript API proxies to the [Datatable](https://datatables.net/)'s expected parameter format
* `acme.bookStore.books.book.getList` is the dynamic JavaScript proxy function introduced before.
* [luxon](https://moment.github.io/luxon/) library is also a standard library that is pre-configured in the solution, so you can use to perform date/time operations easily.
@ -336,9 +336,9 @@ This is a fully working, server side paged, sorted and localized table of books.
## Install NPM packages
> Notice: This tutorial is based on the ABP Framework v3.1.0+ If your project version is older, then please upgrade your solution. See the [migration guide](../UI/Angular/Migration-Guide-v3.md) if you are upgrading an existing project with v2.x.
> Notice: This tutorial is based on the ABP Framework v3.1.0+ If your project version is older, then please upgrade your solution. Check the [migration guide](../UI/Angular/Migration-Guide-v3.md) if you are upgrading an existing project with v2.x.
If you haven't done it before, open a new command line interface (terminal window) and go to your `angular` folder and then run `yarn` command to install the NPM packages:
If you haven't done it before, open a new command line interface (terminal window) and go to your `angular` folder and then run the `yarn` command to install the NPM packages:
```bash
yarn
@ -400,7 +400,7 @@ export class BookModule { }
### Routing
Generated code places the new route definition to the `src/app/app-routing.module.ts` file as shown below:
The generated code places the new route definition to the `src/app/app-routing.module.ts` file as shown below:
````js
const routes: Routes = [
@ -409,7 +409,7 @@ const routes: Routes = [
];
````
Now, open the `src/app/route.provider.ts` file replace the `configureRoutes` function declaration as shown below:
Now, open the `src/app/route.provider.ts` file and replace the `configureRoutes` function declaration as shown below:
```js
function configureRoutes(routes: RoutesService) {
@ -443,18 +443,18 @@ function configureRoutes(routes: RoutesService) {
`RoutesService` is a service provided by the ABP Framework to configure the main menu and the routes.
* `path` is the URL of the route.
* `name` is the localized menu item name (see the [localization document](../UI/Angular/Localization.md) for details).
* `name` is the localized menu item name (check the [localization document](../UI/Angular/Localization.md) for details).
* `iconClass` is the icon of the menu item (you can use [Font Awesome](https://fontawesome.com/) icons by default).
* `order` is the order of the menu item.
* `layout` is the layout of the BooksModule's routes (there are three types of pre-defined layouts: `eLayoutType.application`, `eLayoutType.account` or `eLayoutType.empty`).
For more information, see the [RoutesService document](../UI/Angular/Modifying-the-Menu.md#via-routesservice).
For more information, check the [RoutesService document](../UI/Angular/Modifying-the-Menu.md#via-routesservice).
### Service Proxy Generation
[ABP CLI](../CLI.md) provides `generate-proxy` command that generates client proxies for your HTTP APIs to make easy to consume your HTTP APIs from the client side. Before running `generate-proxy` command, your host must be up and running.
[ABP CLI](../CLI.md) provides a `generate-proxy` command that generates client proxies for your HTTP APIs to make your HTTP APIs easy to consume by the client side. Before running the `generate-proxy` command, your host must be up and running.
> **Warning**: There is a problem with IIS Express; it doesn't allow to connect to the application from another process. If you are using Visual Studio, select the `Acme.BookStore.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below:
> **Warning**: There is a problem with IIS Express; it doesn't allow connecting to the application from another process. If you are using Visual Studio, select the `Acme.BookStore.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below:
![vs-run-without-iisexpress](images/vs-run-without-iisexpress.png)
@ -499,9 +499,9 @@ export class BookComponent implements OnInit {
```
* We imported and injected the generated `BookService`.
* We are using the [ListService](../UI/Angular/List-Service.md), a utility service of the ABP Framework which provides easy pagination, sorting and searching.
* We are using the [ListService](../UI/Angular/List-Service.md), a utility service from the ABP Framework which provides easy pagination, sorting and searching.
Open the `/src/app/book/book.component.html` and replace the content as below:
Open the `/src/app/book/book.component.html` and replace the content as shown below:
```html
<div class="card">
@ -546,7 +546,7 @@ Now you can see the final result on your browser:
## Create a Books Page
It's time to create something visible and usable! Right click to the `Pages` folder under the `Acme.BookStore.Blazor` project and add a new **razor component**, named `Books.razor`:
It's time to create something visible and usable! Right click on the `Pages` folder under the `Acme.BookStore.Blazor` project and add a new **razor component**, named `Books.razor`:
![blazor-add-books-component](images/blazor-add-books-component.png)
@ -562,7 +562,7 @@ Replace the contents of this component as shown below:
}
````
### Add Books Page to the Main Menu
### Add the Books Page to the Main Menu
Open the `BookStoreMenuContributor` class in the `Blazor` project add the following code to the end of the `ConfigureMainMenuAsync` method:
@ -582,17 +582,17 @@ context.Menu.AddItem(
);
````
Run the project, login to the application with the username `admin` and the password `1q2w3E*` and see the new menu item has been added to the main menu:
Run the project, login to the application with the username `admin` and the password `1q2w3E*` and see that the new menu item has been added to the main menu:
![blazor-menu-bookstore](images/blazor-menu-bookstore.png)
When you click to the Books menu item under the Book Store parent, you are being redirected to the new empty Books Page.
When you click on the Books menu item under the Book Store parent, you will be redirected to the new empty Books Page.
### Book List
We will use the [Blazorise library](https://blazorise.com/) as the UI component kit. It is a very powerful library that supports major HTML/CSS frameworks, including the Bootstrap.
We will use the [Blazorise library](https://blazorise.com/) as the UI component kit. It is a very powerful library that supports major HTML/CSS frameworks, including Bootstrap.
ABP Framework provides a generic base class, `AbpCrudPageBase<...>`, to create CRUD style pages. This base class is compatible to the `ICrudAppService` that was used to build the `IBookAppService`. So, we can inherit from the `AbpCrudPageBase` to automate the code behind for the standard CRUD stuff.
ABP Framework provides a generic base class - `AbpCrudPageBase<...>`, to create CRUD style pages. This base class is compatible with the `ICrudAppService` that was used to build the `IBookAppService`. So, we can inherit from the `AbpCrudPageBase` to automate the code behind for the standard CRUD stuff.
Open the `Books.razor` and replace the content as the following:
@ -651,17 +651,17 @@ Open the `Books.razor` and replace the content as the following:
</Card>
````
> If you see some syntax errors, you can ignore them if your application properly built and run. Visual Studio still has some bugs with Blazor.
> If you see some syntax errors, you can ignore them if your application is properly built and running. Visual Studio still has some bugs with Blazor.
* Inherited from the `AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>` which implements all the CRUD details for us.
* Inherited from `AbpCrudPageBase<IBookAppService, BookDto, Guid, PagedAndSortedResultRequestDto, CreateUpdateBookDto>` which implements all the CRUD details for us.
* `Entities`, `TotalCount`, `PageSize`, `OnDataGridReadAsync` are defined in the base class.
* Injected `IStringLocalizer<BookStoreResource>` (as `L` object) and used for localization.
While the code above pretty easy to understand, you can check the Blazorise [Card](https://blazorise.com/docs/components/card/) and [DataGrid](https://blazorise.com/docs/extensions/datagrid/) documents to understand them better.
While the code above is pretty easy to understand, you can check the Blazorise [Card](https://blazorise.com/docs/components/card/) and [DataGrid](https://blazorise.com/docs/extensions/datagrid/) documents to understand them better.
#### About the AbpCrudPageBase
We will continue to benefit from the `AbpCrudPageBase` for the books page. You could just inject the `IBookAppService` and perform all the server side calls yourself (thanks to the [Dynamic C# HTTP API Client Proxy](../API/Dynamic-CSharp-API-Clients.md) system of the ABP Framework). We will do it manually for the authors page to demonstrate how to call server side HTTP APIs in your Blazor applications.
We will continue benefitting from `AbpCrudPageBase` for the books page. You could just inject the `IBookAppService` and perform all the server side calls yourself (thanks to the [Dynamic C# HTTP API Client Proxy](../API/Dynamic-CSharp-API-Clients.md) system of the ABP Framework). We will do it manually for the authors page to demonstrate how to call the server side HTTP APIs in your Blazor applications.
## Run the Final Application
@ -675,4 +675,4 @@ This is a fully working, server side paged, sorted and localized table of books.
## The Next Part
See the [next part](Part-3.md) of this tutorial.
Check the [next part](Part-3.md) of this tutorial.

86
docs/en/Tutorials/Part-3.md

@ -13,7 +13,7 @@ In this tutorial series, you will build an ABP based web application named `Acme
* **{{DB_Value}}** as the ORM provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts;
This tutorial is organized as the following parts:
- [Part 1: Creating the server side](Part-1.md)
- [Part 2: The book list page](Part-2.md)
@ -51,19 +51,19 @@ This part is also recorded as a video tutorial and **<a href="https://www.youtub
## Creating a New Book
In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like in the image below:
In this section, you will learn how to create a new modal dialog form to create a new book. The modal dialog will look like the image below:
![bookstore-create-dialog](images/bookstore-create-dialog-2.png)
### Create the Modal Form
Create a new razor page, named `CreateModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project.
Create a new razor page named `CreateModal.cshtml` under the `Pages/Books` folder of the `Acme.BookStore.Web` project.
![bookstore-add-create-dialog](images/bookstore-add-create-dialog-v2.png)
#### CreateModal.cshtml.cs
Open the `CreateModal.cshtml.cs` file (`CreateModalModel` class) and replace with the following code:
Open the `CreateModal.cshtml.cs` file (`CreateModalModel` class) and replace it with the following code:
````C#
using System.Threading.Tasks;
@ -98,7 +98,7 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* This class is derived from the `BookStorePageModel` instead of standard `PageModel`. `BookStorePageModel` indirectly inherits the `PageModel` and adds some common properties & methods that can be shared in your page model classes.
* This class is derived from the `BookStorePageModel` instead of the standard `PageModel`. `BookStorePageModel` indirectly inherits the `PageModel` and adds some common properties & methods that can be shared in your page model classes.
* `[BindProperty]` attribute on the `Book` property binds post request data to this property.
* This class simply injects the `IBookAppService` in the constructor and calls the `CreateAsync` method in the `OnPostAsync` handler.
* It creates a new `CreateUpdateBookDto` object in the `OnGet` method. ASP.NET Core can work without creating a new instance like that. However, it doesn't create an instance for you and if your class has some default value assignments or code execution in the class constructor, they won't work. For this case, we set default values for some of the `CreateUpdateBookDto` properties.
@ -129,7 +129,7 @@ Open the `CreateModal.cshtml` file and paste the code below:
</abp-dynamic-form>
````
* This modal uses `abp-dynamic-form` [tag helper](../UI/AspNetCore/Tag-Helpers/Dynamic-Forms.md) to automatically create the form from the `CreateBookViewModel` model class.
* This modal uses `abp-dynamic-form` [tag helper](../UI/AspNetCore/Tag-Helpers/Dynamic-Forms.md) to automatically create the form from the `CreateBookViewModel` model class.
* `abp-model` attribute indicates the model object where it's the `Book` property in this case.
* `abp-form-content` tag helper is a placeholder to render the form controls (it is optional and needed only if you have added some other content in the `abp-dynamic-form` tag, just like in this page).
@ -155,7 +155,7 @@ Open the `Pages/Books/Index.cshtml` and set the content of `abp-card-header` tag
</abp-card-header>
````
The final content of the `Index.cshtml` is shown below:
The final content of `Index.cshtml` is shown below:
````html
@page
@ -193,7 +193,7 @@ This adds a new button called **New book** to the **top-right** of the table:
![bookstore-new-book-button](images/bookstore-new-book-button-2.png)
Open the `Pages/Books/Index.js` and add the following code just after the `Datatable` configuration:
Open the `Pages/Books/Index.js` file and add the following code right after the `Datatable` configuration:
````js
var createModal = new abp.ModalManager(abp.appPath + 'Books/CreateModal');
@ -208,11 +208,11 @@ $('#NewBookButton').click(function (e) {
});
````
* `abp.ModalManager` is a helper class to manage modals in the client side. It internally uses Twitter Bootstrap's standard modal, but abstracts many details by providing a simple API.
* `abp.ModalManager` is a helper class to manage modals on the client side. It internally uses Twitter Bootstrap's standard modal, but abstracts many details by providing a simple API.
* `createModal.onResult(...)` used to refresh the data table after creating a new book.
* `createModal.open();` is used to open the model to create a new book.
The final content of the `Index.js` should be like that:
The final content of the `Index.js` file should be like this:
````js
$(function () {
@ -290,7 +290,7 @@ Create a new razor page, named `EditModal.cshtml` under the `Pages/Books` folder
### EditModal.cshtml.cs
Open the `EditModal.cshtml.cs` file (`EditModalModel` class) and replace with the following code:
Open the `EditModal.cshtml.cs` file (`EditModalModel` class) and replace it with the following code:
````csharp
using System;
@ -331,13 +331,13 @@ namespace Acme.BookStore.Web.Pages.Books
}
````
* `[HiddenInput]` and `[BindProperty]` are standard ASP.NET Core MVC attributes. `SupportsGet` is used to be able to get `Id` value from query string parameter of the request.
* In the `OnGetAsync` method, we get `BookDto ` from the `BookAppService` and this is being mapped to the DTO object `CreateUpdateBookDto`.
* `[HiddenInput]` and `[BindProperty]` are standard ASP.NET Core MVC attributes. `SupportsGet` is used to be able to get the `Id` value from the query string parameter of the request.
* In the `OnGetAsync` method, we get the `BookDto` from the `BookAppService` and this is being mapped to the DTO object `CreateUpdateBookDto`.
* The `OnPostAsync` uses `BookAppService.UpdateAsync(...)` to update the entity.
### Mapping from BookDto to CreateUpdateBookDto
To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebAutoMapperProfile.cs` in the `Acme.BookStore.Web` project and change it as shown below:
To be able to map the `BookDto` to `CreateUpdateBookDto`, configure a new mapping. To do this, open the `BookStoreWebAutoMapperProfile.cs` file in the `Acme.BookStore.Web` project and change it as shown below:
````csharp
using AutoMapper;
@ -385,16 +385,16 @@ Replace `EditModal.cshtml` content with the following content:
</abp-dynamic-form>
````
This page is very similar to the `CreateModal.cshtml`, except:
This page is very similar to `CreateModal.cshtml`, except:
* It includes an `abp-input` for the `Id` property to store `Id` of the editing book (which is a hidden input).
* It includes an `abp-input` for the `Id` property to store the `Id` of the editing book (which is a hidden input).
* It uses `Books/EditModal` as the post URL.
### Add "Actions" Dropdown to the Table
We will add a dropdown button to the table named *Actions*.
Open the `Pages/Books/Index.js` and replace the content as below:
Open the `Pages/Books/Index.js` file and replace the content as below:
````js
$(function () {
@ -482,8 +482,8 @@ $(function () {
* Added a new `ModalManager` named `editModal` to open the edit modal dialog.
* Added a new column at the beginning of the `columnDefs` section. This column is used for the "*Actions*" dropdown button.
* "*Edit*" action simply calls `editModal.open()` to open the edit dialog.
* `editModal.onResult(...)` callback refreshes the data table when you close the edit modal.
* The "*Edit*" action simply calls `editModal.open()` to open the edit dialog.
* The `editModal.onResult(...)` callback refreshes the data table when you close the edit modal.
You can run the application and edit any book by selecting the edit action on a book.
@ -493,7 +493,7 @@ The final UI looks as below:
## Deleting a Book
Open the `Pages/Books/Index.js` and add a new item to the `rowAction` `items`:
Open the `Pages/Books/Index.js` file and add a new item to the `rowAction` `items`:
````js
{
@ -512,8 +512,8 @@ Open the `Pages/Books/Index.js` and add a new item to the `rowAction` `items`:
}
````
* `confirmMessage` option is used to ask a confirmation question before executing the `action`.
* `acme.bookStore.books.book.delete(...)` method makes an AJAX request to the server to delete a book.
* The `confirmMessage` option is used to ask a confirmation question before executing the `action`.
* The `acme.bookStore.books.book.delete(...)` method makes an AJAX request to the server to delete a book.
* `abp.notify.info()` shows a notification after the delete operation.
Since we've used two new localization texts (`BookDeletionConfirmationMessage` and `SuccessfullyDeleted`) you need to add these to the localization file (`en.json` under the `Localization/BookStore` folder of the `Acme.BookStore.Domain.Shared` project):
@ -721,10 +721,10 @@ Open `/src/app/book/book.component.html` and make the following changes:
</abp-modal>
```
* Added `New book` button to the card header..
* Added a `New book` button to the card header..
* Added the `abp-modal` which renders a modal to allow user to create a new book. `abp-modal` is a pre-built component to show modals. While you could use another approach to show a modal, `abp-modal` provides additional benefits.
You can open your browser and click **New book** button to see the new modal.
You can open your browser and click the **New book** button to see the new modal.
![Empty modal for new book](images/bookstore-empty-new-book-modal.png)
@ -801,11 +801,11 @@ export class BookComponent implements OnInit {
```
* Imported `FormGroup`, `FormBuilder` and `Validators` from `@angular/forms`.
* Added `form: FormGroup` property.
* Added `bookTypes` property as a list of `BookType` enum members. That will be used in form options.
* Added a `form: FormGroup` property.
* Added a `bookTypes` property as a list of `BookType` enum members. That will be used in form options.
* Injected `FormBuilder` into the constructor. [FormBuilder](https://angular.io/api/forms/FormBuilder) provides convenient methods for generating form controls. It reduces the amount of boilerplate needed to build complex forms.
* Added `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method.
* Added `save` method.
* Added a `buildForm` method to the end of the file and executed the `buildForm()` in the `createBook` method.
* Added a `save` method.
Open `/src/app/book/book.component.html` and replace `<ng-template #abpBody> </ng-template>` with the following code part:
@ -863,7 +863,7 @@ Also replace `<ng-template #abpFooter> </ng-template>` with the following code p
### Datepicker
We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. So, need to arrange dependencies related to this component.
We've used [NgBootstrap datepicker](https://ng-bootstrap.github.io/#/components/datepicker/overview) in this component. So, we need to arrange the dependencies related to this component.
Open `/src/app/book/book.module.ts` and replace the content as below:
@ -959,7 +959,7 @@ export class BookComponent implements OnInit {
```
* Imported ` NgbDateNativeAdapter` and `NgbDateAdapter`.
* We added a new provider `NgbDateAdapter` that converts Datepicker value to `Date` type. See the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details.
* We added a new provider `NgbDateAdapter` that converts the Datepicker value to `Date` type. Check out the [datepicker adapters](https://ng-bootstrap.github.io/#/components/datepicker/overview) for more details.
Now, you can open your browser to see the changes:
@ -1054,14 +1054,14 @@ export class BookComponent implements OnInit {
```
* We declared a variable named `selectedBook` as `BookDto`.
* We added `editBook` method. This method fetches the book with the given `id` and sets it to `selectedBook` object.
* We added an `editBook` method. This method fetches the book with the given `id` and sets it to `selectedBook` object.
* We replaced the `buildForm` method so that it creates the form with the `selectedBook` data.
* We replaced the `createBook` method so it sets `selectedBook` to an empty object.
* We changed the `save` method to handle both of create and update operations.
### Add "Actions" Dropdown to the Table
Open the `/src/app/book/book.component.html`  and add the following `ngx-datatable-column` definition as the first column in the `ngx-datatable`:
Open `/src/app/book/book.component.html`  and add the following `ngx-datatable-column` definition as the first column in the `ngx-datatable`:
```html
<ngx-datatable-column
@ -1101,11 +1101,11 @@ Also, change the `ng-template #abpHeader` section as shown below:
</ng-template>
```
This template will show **Edit** text for edit record operation, **New Book** for new record operation in the title.
This template will show the **Edit** text for edit record operation, **New Book** for new record operation in the title.
## Deleting a Book
Open the `/src/app/book/book.component.ts` and inject the `ConfirmationService`.
Open the `/src/app/book/book.component.ts` file and inject the `ConfirmationService`.
Replace the constructor as below:
@ -1137,7 +1137,7 @@ delete(id: string) {
* We injected `ConfirmationService` to the constructor.
* Added a `delete` method.
> See the [Confirmation Popup documentation](../UI/Angular/Confirmation-Service) for more about this service.
> Check out the [Confirmation Popup documentation](../UI/Angular/Confirmation-Service) for more about this service.
### Add a Delete Button
@ -1169,7 +1169,7 @@ Clicking the "Delete" action calls the `delete` method which then shows a confir
In this section, you will learn how to create a new modal dialog form to create a new book. Since we've inherited from the `AbpCrudPageBase`, we only need to develop the view part.
### Add "New Button" Button
### Add a "New Button" Button
Open the `Books.razor` and replace the `<CardHeader>` section with the following code:
@ -1191,7 +1191,7 @@ This will change the card header by adding a "New book" button to the right side
![blazor-add-book-button](images/blazor-add-book-button.png)
Now, we can add a modal that will be opened when we click to the button.
Now, we can add a modal that will be opened when we click the button.
### Book Creation Modal
@ -1259,7 +1259,7 @@ This code requires a service; Inject the `AbpBlazorMessageLocalizerHelper<T>` at
````
* The form implements validation and the `AbpBlazorMessageLocalizerHelper` is used to simply localize the validation messages.
* `CreateModal` object, `CloseCreateModalAsync` and `CreateEntityAsync` method are defined by the base class. See the [Blazorise documentation](https://blazorise.com/docs/) if you want to understand the `Modal` and the other components.
* The `CreateModal` object, `CloseCreateModalAsync` and `CreateEntityAsync` methods are defined by the base class. Check out the [Blazorise documentation](https://blazorise.com/docs/) if you want to understand the `Modal` and the other components.
That's all. Run the application and try to add a new book:
@ -1267,7 +1267,7 @@ That's all. Run the application and try to add a new book:
## Updating a Book
Editing a books is similar to the creating a new book.
Editing a book is similar to creating a new book.
### Actions Dropdown
@ -1287,7 +1287,7 @@ Open the `Books.razor` and add the following `DataGridEntityActionsColumn` secti
* `OpenEditModalAsync` is defined in the base class which takes the entity (book) to edit.
`DataGridEntityActionsColumn` component is used to show an "Actions" dropdown for each row in the `DataGrid`. `DataGridEntityActionsColumn` shows a **single button** instead of a dropdown if there is only one available action inside it:
The `DataGridEntityActionsColumn` component is used to show an "Actions" dropdown for each row in the `DataGrid`. The `DataGridEntityActionsColumn` shows a **single button** instead of a dropdown if there is only one available action inside it:
![blazor-edit-book-action](images/blazor-edit-book-action-2.png)
@ -1384,7 +1384,7 @@ You can now run the application and try to edit a book.
## Deleting a Book
Open the `Books.razor` page and add the following `EntityAction` under the "Edit" action inside the `EntityActions`:
Open the `Books.razor` page and add the following `EntityAction` code under the "Edit" action inside `EntityActions`:
````xml
<EntityAction TItem="BookDto"
@ -1405,7 +1405,7 @@ Run the application and try to delete a book.
## Full CRUD UI Code
Here the complete code to create the book management CRUD page, that has been developed in the last two parts:
Here's the complete code to create the book management CRUD page, that has been developed in the last two parts:
````xml
@page "/books"
@ -1596,4 +1596,4 @@ Here the complete code to create the book management CRUD page, that has been de
## The Next Part
See the [next part](Part-4.md) of this tutorial.
Check out the [next part](Part-4.md) of this tutorial.

4
docs/en/Tutorials/Part-5.md

@ -10,7 +10,7 @@
In this tutorial series, you will build an ABP based web application named `Acme.BookStore`. This application is used to manage a list of books and their authors. It is developed using the following technologies:
* **{{DB_Value}}** as the ORM provider.
* **{{DB_Value}}** as the ORM provider.
* **{{UI_Value}}** as the UI Framework.
This tutorial is organized as the following parts;
@ -142,7 +142,7 @@ Now, you can use the permissions to authorize the book management.
### Application Layer & HTTP API
Open the `BookAppService` class and add set the policy names as the permission names defined above:
Open the `BookAppService` class and set the policy names as the permission names defined above:
````csharp
using System;

74
docs/en/Tutorials/Todo/Index.md

@ -8,11 +8,11 @@
}
````
This is a single-part, quick-start tutorial to build a simple todo application with the ABP Framework. Here, a screenshot from the final application:
This is a single-part quick-start tutorial to build a simple todo application with the ABP Framework. Here's a screenshot from the final application:
![todo-list](todo-list.png)
You can find source code of the completed application [here](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
You can find the source code of the completed application [here](https://github.com/abpframework/abp-samples/tree/master/TodoApp).
## Pre-Requirements
@ -56,7 +56,7 @@ This will create a new solution, named *TodoApp*. Once the solution is ready, op
### Create the Database
If you are using Visual Studio, right click to the `TodoApp.DbMigrator` project, select *Set as StartUp Project*, then hit *Ctrl+F5* to run it without debugging. It will create the initial database and seed the initial data.
If you are using Visual Studio, right click on the `TodoApp.DbMigrator` project, select *Set as StartUp Project*, then hit *Ctrl+F5* to run it without debugging. It will create the initial database and seed the initial data.
{{if DB=="EF"}}
@ -74,7 +74,7 @@ It is good to run the application before starting the development. Ensure the {{
It is good to run the application before starting the development. The solution has two main applications;
* `TodoApp.HttpApi.Host` host the server-side HTTP API.
* `TodoApp.HttpApi.Host` hosts the server-side HTTP API.
* `TodoApp.Blazor` is the client-side Blazor WebAssembly application.
Ensure the `TodoApp.HttpApi.Host` project is the startup project, then run the application (Ctrl+F5 in Visual Studio) to see the server-side HTTP API on the [Swagger UI](https://swagger.io/tools/swagger-ui/):
@ -85,16 +85,16 @@ You can explore and test your HTTP API with this UI. Now, we can set the `TodoAp
{{else if UI=="NG"}}
It is good to run the application before starting the development. The solution has two main applications;
It is good to run the application before starting the development. The solution has two main applications:
* `TodoApp.HttpApi.Host` (in the .NET solution) host the server-side HTTP API.
* `angular` folder contains the Angular application.
Ensure the `TodoApp.HttpApi.Host` project is the startup project, then run the application (Ctrl+F5 in Visual Studio) to see the server-side HTTP API on the [Swagger UI](https://swagger.io/tools/swagger-ui/):
Ensure that the `TodoApp.HttpApi.Host` project is the startup project, then run the application (Ctrl+F5 in Visual Studio) to see the server-side HTTP API on the [Swagger UI](https://swagger.io/tools/swagger-ui/):
![todo-swagger-ui-initial](todo-swagger-ui-initial.png)
You can explore and test your HTTP API with this UI. If that works, we can run the Angular client application.
You can explore and test your HTTP API with this UI. If it works, we can run the Angular client application.
First, run the following command to restore the NPM packages;
@ -114,13 +114,13 @@ This command takes time, but eventually runs and opens the application in your d
![todo-ui-initial](todo-ui-initial.png)
You can click to the *Login* button, use `admin` as the username and `1q2w3E*` as the password to login to the application.
You can click on the *Login* button, use `admin` as the username and `1q2w3E*` as the password to login to the application.
All ready. We can start the coding!
All ready. We can start coding!
## Domain Layer
This application has a single [entity](../../Entities.md) and we are starting by creating it. Create a new `TodoItem` class inside the *TodoApp.Domain* project:
This application has a single [entity](../../Entities.md) and we'll start by creating it. Create a new `TodoItem` class inside the *TodoApp.Domain* project:
````csharp
using System;
@ -151,7 +151,7 @@ Open the `TodoAppDbContext` class in the `EntityFrameworkCore` folder of the *To
public DbSet<TodoItem> TodoItems { get; set; }
````
Then locate to `OnModelCreating` method in the `TodoAppDbContext` class and add the mapping code for the `TodoItem ` entity:
Then navigate to the `OnModelCreating` method in the `TodoAppDbContext` class and add the mapping code for the `TodoItem ` entity:
````csharp
protected override void OnModelCreating(ModelBuilder builder)
@ -171,7 +171,7 @@ protected override void OnModelCreating(ModelBuilder builder)
}
````
We've mapped `TodoItem` entity to a `TodoItems` table in the database.
We've mapped the `TodoItem` entity to the `TodoItems` table in the database.
### Code First Migrations
@ -193,11 +193,11 @@ You can apply changes to the database using the following command, in the same c
dotnet ef database update
````
> If you are using Visual Studio, you may want to use `Add-Migration Added_TodoItem` and `Update-Database` commands in the *Package Manager Console (PMC)*. In this case, ensure that {{if UI=="MVC"}}`TodoApp.Web`{{else if UI=="BlazorServer"}}`TodoApp.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`TodoApp.HttpApi.Host`{{end}} is the startup project and `TodoApp.EntityFrameworkCore` is the *Default Project* in PMC.
> If you are using Visual Studio, you may want to use the `Add-Migration Added_TodoItem` and `Update-Database` commands in the *Package Manager Console (PMC)*. In this case, ensure that {{if UI=="MVC"}}`TodoApp.Web`{{else if UI=="BlazorServer"}}`TodoApp.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`TodoApp.HttpApi.Host`{{end}} is the startup project and `TodoApp.EntityFrameworkCore` is the *Default Project* in PMC.
{{else if DB=="Mongo"}}
Next step is to setup the [MongoDB](../../MongoDB.md) configuration. Open the `TodoAppMongoDbContext` class in the `MongoDb` folder of the *TodoApp.MongoDB* project and make the following changes;
Next step is to setup the [MongoDB](../../MongoDB.md) configuration. Open the `TodoAppMongoDbContext` class in the `MongoDb` folder of the *TodoApp.MongoDB* project and make the following changes:
1. Add a new property to the class:
@ -216,13 +216,13 @@ modelBuilder.Entity<TodoItem>(b =>
{{end}}
Now, we can use ABP repositories to save and retrieve todo items, as we'll do in the next section.
Now, we can use the ABP repositories to save and retrieve the todo items, as we'll do in the next section.
## Application Layer
An [Application Service](../../Application-Services.md) is used to perform use cases of the application. We need to perform the following use cases:
An [Application Service](../../Application-Services.md) is used to perform the use cases of the application. We need to perform the following use cases:
* Get the list of todo items
* Get the list of the todo items
* Create a new todo item
* Delete an existing todo item
@ -264,7 +264,7 @@ namespace TodoApp
}
````
This is a very simple DTO class that matches to our `TodoItem` entity. We are ready to implement the `ITodoAppService`.
This is a very simple DTO class that matches our `TodoItem` entity. We are ready to implement the `ITodoAppService`.
### Application Service Implementation
@ -313,7 +313,7 @@ public async Task<List<TodoItemDto>> GetListAsync()
}
````
We are simply getting the complete `TodoItem` list from database, mapping them to `TodoItemDto` objects and returning as the result.
We are simply getting the complete `TodoItem` list from the database, mapping them to `TodoItemDto` objects and returning as the result.
#### Creating a New Todo Item
@ -334,7 +334,7 @@ public async Task<TodoItemDto> CreateAsync(string text)
}
````
Repository's `InsertAsync` method inserts the given `TodoItem` to database and returns the same `TodoItem` object. It also sets the `Id`, so we can use it on the returning object. We are simply returning a `TodoItemDto` by creating from the new `TodoItem` entity.
The repository's `InsertAsync` method inserts the given `TodoItem` to the database and returns the same `TodoItem` object. It also sets the `Id`, so we can use it on the returning object. We are simply returning a `TodoItemDto` by creating from the new `TodoItem` entity.
#### Deleting a Todo Item
@ -351,7 +351,7 @@ The application service is ready to be used from the UI layer.
## User Interface Layer
It is time to show the todo items on the UI! Before starting to write the code, it would be good to remember what we are trying to build. Here, a sample screenshot from the final UI:
It is time to show the todo items on the UI! Before starting to write the code, it would be good to remember what we are trying to build. Here's a sample screenshot from the final UI:
![todo-list](todo-list.png)
@ -388,11 +388,11 @@ namespace TodoApp.Web.Pages
}
````
This class uses the `ITodoAppService` to get the list of todo items and assign the the `TodoItems` property. We will use it to render the todo items on the razor page.
This class uses the `ITodoAppService` to get the list of todo items and assign the `TodoItems` property. We will use it to render the todo items on the razor page.
### Index.cshtml
Open the `Index.cshtml` file in the `Pages` folder of the *TodoApp.Web* project and replace with the following content:
Open the `Index.cshtml` file in the `Pages` folder of the *TodoApp.Web* project and replace it with the following content:
````xml
@page
@ -442,7 +442,7 @@ This page imports a CSS and a JavaScript file, so we should also create them.
### Index.js
Open the `Index.js` file in the `Pages` folder of the *TodoApp.Web* project and replace with the following content:
Open the `Index.js` file in the `Pages` folder of the *TodoApp.Web* project and replace it with the following content:
````js
$(function () {
@ -473,15 +473,15 @@ $(function () {
});
````
In the first part, we are subscribing to click events of the trash icons near to the todo items, deleting the related item on the server and showing a notification on the UI. Also, we are removing the deleted item from DOM, so we don't need to refresh the page.
In the first part, we are subscribing to the click events of the trash icons near the todo items, deleting the related item on the server and showing a notification on the UI. Also, we are removing the deleted item from the DOM, so we don't need to refresh the page.
In the second part, we are creating a new todo item on the server. If it succeeds, we are then manipulating DOM to insert a new `<li>` element to the todo list. This way we don't need to refresh the whole page after creating a new todo item.
In the second part, we are creating a new todo item on the server. If it succeeds, we are then manipulating the DOM to insert a new `<li>` element to the todo list. This way we don't need to refresh the whole page after creating a new todo item.
The interesting part here is how we communicate with the server. See the *Dynamic JavaScript Proxies & Auto API Controllers* section to understand how it works. But now, let's continue and complete the application.
### Index.css
As the final touch, open the `Index.css` file in the `Pages` folder of the *TodoApp.Web* project and replace with the following content:
As the final touch, open the `Index.css` file in the `Pages` folder of the *TodoApp.Web* project and replace it with the following content:
````css
#TodoList{
@ -516,9 +516,9 @@ Now, you can run the application again and see the result.
### Dynamic JavaScript Proxies & Auto API Controllers
In the `Index.js` file, we've used `todoApp.todo.delete(...)` and `todoApp.todo.create(...)` functions to communicate with the server. These functions are dynamically created by the ABP Framework, thanks to the [Dynamic JavaScript Client Proxy](../../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) system. They perform HTTP API calls to the server and return a promise, so you can register a callback to the `then` function as we've done above.
In the `Index.js` file, we've used the `todoApp.todo.delete(...)` and `todoApp.todo.create(...)` functions to communicate with the server. These functions are dynamically created by the ABP Framework, thanks to the [Dynamic JavaScript Client Proxy](../../UI/AspNetCore/Dynamic-JavaScript-Proxies.md) system. They perform HTTP API calls to the server and return a promise, so you can register a callback to the `then` function as we've done above.
However, you may notice that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
However, you may notice that we haven't created any API Controllers, so how does the server handle these requests? This question brings us to the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
If you open the [Swagger UI](https://swagger.io/tools/swagger-ui/) by entering the `/swagger` URL in your application, you can see the Todo API:
@ -567,7 +567,7 @@ namespace TodoApp.Blazor.Pages
}
````
This class uses the `ITodoAppService` to perform operations for the todo items. It manipulates the `TodoItems` list after create and delete operations. This way, we don't need to refresh the whole todo list from the server.
This class uses `ITodoAppService` to perform operations for the todo items. It manipulates the `TodoItems` list after create and delete operations. This way, we don't need to refresh the whole todo list from the server.
{{if UI=="Blazor"}}
@ -619,7 +619,7 @@ Open the `Index.razor` file in the `Pages` folder of the *TodoApp.Blazor* projec
### Index.razor.css
As the final touch, open the `Index.razor.css` file in the `Pages` folder of the *TodoApp.Blazor* project and replace with the following content:
As the final touch, open the `Index.razor.css` file in the `Pages` folder of the *TodoApp.Blazor* project and replace it with the following content:
````css
#TodoList{
@ -660,7 +660,7 @@ In the `Index.razor.cs` file, we've injected (with the `[Inject]` attribute) and
The magic is done by the ABP Framework's [Dynamic C# Client Proxy](../../API/Dynamic-CSharp-API-Clients.md) system. It uses the standard `HttpClient` and performs HTTP API requests to the remote server. It also handles all the standard tasks for us, including authorization, JSON serialization and exception handling.
However, you may ask that we haven't created any API Controller, so how server handles these requests? This question brings us the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
However, you may ask that we haven't created any API Controller, so how does the server handle these requests? This question brings us to the [Auto API Controller](../../API/Auto-API-Controllers.md) feature of the ABP Framework. It automatically converts the application services to API Controllers by convention.
If you run the `TodoApp.HttpApi.Host` application, you can see the Todo API:
@ -676,7 +676,7 @@ ABP provides a handy feature to automatically create client-side services to eas
You first need to run the `TodoApp.HttpApi.Host` project since the proxy generator reads API definitions from the server application.
> **Warning**: There is an issue with IIS Express: it doesn't allow to connect to the application from another process. If you are using Visual Studio, select the `TodoApp.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below:
> **Warning**: There is an issue with IIS Express: it doesn't allow connecting to the application from another process. If you are using Visual Studio, select the `TodoApp.HttpApi.Host` instead of IIS Express in the run button drop-down list, as shown in the figure below:
![run-without-iisexpress](run-without-iisexpress.png)
@ -686,7 +686,7 @@ Once you run the `TodoApp.HttpApi.Host` project, open a command-line terminal in
abp generate-proxy -t ng
````
If everything goes well, it should generate an output like shown below:
If everything goes well, it should generate an output as shown below:
````bash
CREATE src/app/proxy/generate-proxy.json (170978 bytes)
@ -696,7 +696,7 @@ CREATE src/app/proxy/models.ts (66 bytes)
CREATE src/app/proxy/index.ts (58 bytes)
````
We can then use the `todoService` to use the server-side HTTP APIs, as we'll do in the next section.
We can then use `todoService` to use the server-side HTTP APIs, as we'll do in the next section.
### home.component.ts
@ -745,7 +745,7 @@ export class HomeComponent implements OnInit {
````
We've used the `todoService` to get the list of todo items and assigned the returning value to the `todoItems` array. We've also added `create` and `delete` methods. These methods will be used in the view side.
We've used `todoService` to get the list of todo items and assigned the returning value to the `todoItems` array. We've also added `create` and `delete` methods. These methods will be used on the view side.
### home.component.html
@ -819,7 +819,7 @@ Now, you can run the application again to see the result.
## Conclusion
In this tutorial, we've built a very simple application to warm up to the ABP Framework. If you are looking to build a serious application, please check the [web application development tutorial](../Part-1.md) which covers all the aspects of a real-life web application development.
In this tutorial, we've built a very simple application to warm up for the ABP Framework. If you are looking to build a serious application, please check the [web application development tutorial](../Part-1.md) which covers all the aspects of real-life web application development.
## Source Code

67
docs/en/UI/Angular/Theming.md

@ -204,25 +204,78 @@ constructor(private sessionState: SessionStateService) {
}
````
##### User Menu
User menu is a component that can be replaceable. See an example to learn how can you replace it:
`UserMenuService` is used to get the user menu's items and render on the dropdown. You can add/update/remove an item by using the service.
You can either pass a `component`, a piece of `html` or a `textTemplate` to render an item.
All of the options are shown below. You can choose either of them.
**Example: Adding/updating/removing an user menu item**
````ts
import { eThemeBasicComponents } from '@abp/ng.theme.basic';
import { NavItemsService } from '@abp/ng.theme.shared';
import { eUserMenuItems } from '@abp/ng.theme.basic';
import { UserMenuService } from '@abp/ng.theme.shared';
import { Component } from '@angular/core';
import { Router } from '@angular/router';
// make sure that you import this component in a NgModule
@Component({
selector: 'abp-current-user-test',
template: `
<a class="dropdown-item pointer" (click)="data.action()">
<i *ngIf="data.textTemplate.icon" [class]="data.textTemplate.icon"></i>
{{ data.textTemplate.text | abpLocalization }}
</a>
`,
})
export class UserMenuItemComponent {
// you can inject the data through `INJECTOR_PIPE_DATA_TOKEN` token
constructor(@Inject(INJECTOR_PIPE_DATA_TOKEN) public data: UserMenu) {}
}
@Component({/* component metadata */})
export class AppComponent {
constructor(private navItems: NavItemsService) {
this.navItems.patchItem(eThemeBasicComponents.CurrentUser, { component: MyUserMenuComponent });
constructor(private userMenu: UserMenuService, private router: Router) {
this.userMenu.addItems([
{
id: 'UserMenu.MyAccount',
order: 1,
// HTML example
html: `<a class="dropdown-item pointer">My account</a>`,
// text template example
textTemplate: {
text: 'AbpAccount::MyAccount',
icon: 'fa fa-cog',
},
// component example
component: UserMenuItemComponent,
action: () => {
this.router.navigateByUrl('/account/manage');
},
},
]);
this.userMenu.patchItem(eUserMenuItems.MyAccount, {
html: `<a class="dropdown-item pointer">My profile</a>`,
});
this.userMenu.removeItem(eUserMenuItems.Logout);
}
}
````
[`ConfigStateService`](Config-State-Service.md) service can be used to obtain the `application-configuration` API response (e.g. getting current user or tenant).
In the example above, added a new user menu item labeled "Reports", updated the "My account" item HTML content, and removed the "Logout" item.
See the result:
![image](https://user-images.githubusercontent.com/34455572/148387770-5b5e25fb-f855-447c-8ead-c04c69b6d6f7.png)
#### Page Alerts
`PageAlertService` service is used to get the current page alerts to render on the layout. See the [Page Alerts](Page-Alerts.md) document to learn more.
`PageAlertService` service is used to get the current page alerts to render on the layout. See the [Page Alerts](Page-Alerts.md) document to learn more.

25
docs/zh-Hans/Autofac-Integration.md

@ -32,26 +32,23 @@ namespace MyCompany.MyProject
### ASP.NET Core 应用程序
如下所示, 在 **Startup.cs** 文件中调用 `UseAutofac()`:
如下所示, 在 **Program.cs** 文件中调用 `UseAutofac()`:
````csharp
public class Startup
public class Program
{
public IServiceProvider ConfigureServices(IServiceCollection services)
public static int Main(string[] args)
{
services.AddApplication<MyWebModule>(options =>
{
//Integrate Autofac!
options.UseAutofac();
});
return services.BuildServiceProviderFromFactory();
CreateHostBuilder(args).Build().Run();
}
public void Configure(IApplicationBuilder app)
{
app.InitializeApplication();
}
internal static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
.UseAutofac(); //Integrate Autofac!
}
````

30
docs/zh-Hans/Background-Workers-Hangfire.md

@ -67,6 +67,33 @@ public class MyLogWorker : HangfireBackgroundWorkerBase
> 你可以直接实现 `IHangfireBackgroundWorker`, 但是 `HangfireBackgroundWorkerBase` 提供了一些有用的属性,例如 `Logger`.
### UnitOfWork
使用 `UnitOfWorkAttribute` 你需要为工作者定义一个接口:
```csharp
public interface IMyLogWorker : IHangfireBackgroundWorker
{
}
[ExposeServices(typeof(IMyLogWorker))]
public class MyLogWorker : HangfireBackgroundWorkerBase, IMyLogWorker
{
public MyLogWorker()
{
RecurringJobId = nameof(MyLogWorker);
CronExpression = Cron.Daily();
}
[UnitOfWork]
public override Task DoWorkAsync()
{
Logger.LogInformation("Executed MyLogWorker..!");
return Task.CompletedTask;
}
}
```
## 注册到后台工作者管理器
创建一个后台工作者后, 你应该添加到 `IBackgroundWorkerManager`, 最常用的地方是在你模块类的 `OnApplicationInitialization` 方法中:
@ -79,6 +106,9 @@ public class MyModule : AbpModule
ApplicationInitializationContext context)
{
context.AddBackgroundWorker<MyLogWorker>();
//如果定义了接口
//context.AddBackgroundWorker<IMyLogWorker>();
}
}
````

3
docs/zh-Hans/Modules/Cms-Kit.md

@ -1,3 +0,0 @@
# CMS Kit Module
TODO

3
docs/zh-Hans/Modules/Cms-Kit/Blogging.md

@ -0,0 +1,3 @@
# CMS Kit: Blogging
TODO...

3
docs/zh-Hans/Modules/Cms-Kit/Comments.md

@ -0,0 +1,3 @@
# CMS Kit: Comments
TODO...

79
docs/zh-Hans/Modules/Cms-Kit/Index.md

@ -0,0 +1,79 @@
# 内容管理系统套件模块
此模块为您的应用程序提供内容管理系统 (Content Management System, CMS) 功能. 它提供 **核心构建块** 和完整工作的 **子系统**, 以创建启用 CMS 功能的您自己的网站, 或出于任何目的使用网站中的构建块.
> **此模块目前仅适用于 MVC / Razor 页面 UI**. 虽然没有官方的 Blazor 软件包, 但它也可以在 Blazor 服务器 UI 中工作, 因为实际上 Blazor 服务器 UI 实际上是一个运行在 ASP.NET Core MVC / Razor 页面应用程序的混合型应用程序.
目前提供以下功能:
* 提供 [**页面**](Pages.md) 管理系统来管理具有动态 URL 的动态页面.
* 提供 [**博客**](Blogging.md) 系统来创建发表具有多种博客支持的博客文章.
* 提供 [**标签**](Tags.md) 系统来标记任何资源, 如博客文章.
* 提供 [**评论**](Comments.md) 系统来添加对任何资源的评论功能, 如博客文章或产品评价页面.
* 提供 [**反应**](Reactions.md) 系统来添加对任何资源的反应 (表情符号) 功能, 如博客文章或评论.
* 提供 [**评级**](Ratings.md) 系统来添加对任何资源的评级功能.
* 提供 [**菜单**](Menus.md) 系统来动态管理公共菜单.
点击功能以了解和学习如何去使用它.
所有功能均可单独使用. 如果你禁用了一个功能, 则在 [全局功能](../../Global-Features.md) 系统的帮助下, 该功能会从你的应用程序甚至数据库表中完全消失.
## 预备要求
- 此模块依赖于 [Blob 存储](../../Blob-Storing.md) 模块来保存媒体内容.
> 确保 `BlobStoring` 模块已安装并至少正确地配置了一个提供程序. 请查阅 [文档](../../Blob-Storing.md) 了解更多信息.
- CMS Kit 使用 [分布式缓存](../../Caching.md) 来提高响应速度.
> 强烈建议在分布式/集群部署中为实现数据一致性使用分布式缓存, 如 [Redis](../../Redis-Cache.md).
## 如何安装
可以使用 [ABP CLI](../../CLI.md) 的 `add-module` 命令为解决方案安装模块. 您可以使用以下命令在命令行中安装 CMS Kit 模块:
```bash
abp add-module Volo.CmsKit
```
> 默认情况下, Cms-Kit `GlobalFeature` 被禁用. 因此初始迁移将为空. 所以, 当你使用 EF Core 安装时,你可以添加 `--skip-db-migrations` 命令来跳过迁移. 启用 Cms-Kit 全局功能后, 请添加新的迁移.
安装过程完成后, 在您的解决方案 `Domain.Shared` 项目中打开 `GlobalFeatureConfigurator` 类, 并将以下代码写入 `Configure` 方法中, 以启用 CMS Kit 模块的全部功能.
```csharp
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{
cmsKit.EnableAll();
});
```
你可能更愿意逐个启用这些功能, 而不是启用全部功能. 以下示例仅启用了 [标签](Tags.md) 和 [评论](Comments.md) 功能:
````csharp
GlobalFeatureManager.Instance.Modules.CmsKit(cmsKit =>
{
cmsKit.Tags.Enable();
cmsKit.Comments.Enable();
});
````
> 如果你使用 EF Core, 不要忘记添加一个新的迁移并更新你的数据库.
## 软件包
此模块遵循 [模块开发最佳实践指南](https://docs.abp.io/zh-Hans/abp/latest/Best-Practices/Index), 由多个 NuGet 和 NPM 软件包组成. 如果你想了解软件包及其之间的关系, 请参阅指南.
CMS Kit 软件包专为各种使用场景而设计. 如果您查阅了 [CMS Kit 软件包](https://www.nuget.org/packages?q=Volo.CmsKit) 您将看到一些有 `Admin` 和 `Public` 后缀的软件包. 该模块有两个应用程序层, 原因是他们可能被用于不同类型的应用程序. 这些应用程序层仅使用一个领域层.
- `Volo.CmsKit.Admin.*` 软件包包括管理员 (后台) 应用程序所必须的功能.
- `Volo.CmsKit.Public.*` 软件包包括被用于用户阅读博客文章和发表评论的公共网站上的功能.
- `Volo.CmsKit.*` (不带 Admin/Public 后缀) 软件包称为统一包. 统一包分别是添加 Admin 和 Public (相关层的) 软件包的快照. 如果您有一个用于管理和公共网站的单应用程序, 您可以使用这些软件包.
## 内部结构
### 表/集合 前缀&架构
所有表/集合使用 `Cms` 作为默认前缀. 如果需要更改表的前缀或者设置一个架构名称 (如果你的数据库提供程序支持), 请在 `CmsKitDbProperties` 类中设置静态属性.
### 连接字符串
此模块使用 `CmsKit` 作为连接字符串的名称. 如果您未使用此名称定义连接字符串, 它将回退为 `Default` 连接字符串.
有关详细信息, 请参阅 [连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings) 文档.

3
docs/zh-Hans/Modules/Cms-Kit/Menus.md

@ -0,0 +1,3 @@
# CMS Kit: Pages
TODO...

3
docs/zh-Hans/Modules/Cms-Kit/Pages.md

@ -0,0 +1,3 @@
# CMS Kit: Pages
TODO...

3
docs/zh-Hans/Modules/Cms-Kit/Ratings.md

@ -0,0 +1,3 @@
# Rating System
TODO...

3
docs/zh-Hans/Modules/Cms-Kit/Reactions.md

@ -0,0 +1,3 @@
# Reaction System
TODO...

3
docs/zh-Hans/Modules/Cms-Kit/Tags.md

@ -0,0 +1,3 @@
# Tag Management
TODO...

310
docs/zh-Hans/Modules/Identity.md

@ -1,28 +1,320 @@
# 身份管理模块
身份模块基于Microsoft Identity库用于管理[组织单元](Organization-Units.md), 角色, 用户和他们的权限.
身份模块基于 [Microsoft Identity 库](https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/identity) 用于管理角色,用户及其权限.
> 参阅 [源码](https://github.com/abpframework/abp/tree/dev/modules/identity). 文档很快会被完善.
## 如何安装
## Identity安全日志
当你使用 ABP 框架 [创建一个新的解决方案](https://abp.io/get-started) 时, 此模块将被预安装 (作为 NuGet/NPM 包). 你可以继续用其作为包并轻松地获取更新, 也可以将其源代码包含在解决方案中(请参阅 `get-source` [CLI](../CLI.md))以开发自定义模块.
安全日志可以记录账户的一些重要的操作或者改动, 你可以在在一些功能中保存安全日志.
### 源代码
你可以注入和使用 `IdentitySecurityLogManager` 或 `ISecurityLogManager` 来保存安全日志. 默认它会创建一个安全日志对象并填充常用的值. 如 `CreationTime`, `ClientIpAddress`, `BrowserInfo`, `current user/tenant`等等. 当然你可以自定义这些值.
可以 [在此处](https://github.com/abpframework/abp/tree/dev/modules/identity) 访问源代码。源代码使用 [MIT](https://choosealicense.com/licenses/mit/) 许可, 所以你可以免费使用和自定义它.
## 用户界面
此模块提供了 [Blazor](../UI/Blazor/Overall.md), [Angular](../UI/Angular/Quick-Start.md) 和 [MVC / Razor Pages](../UI/AspNetCore/Overall.md) 的 UI 可选.
### 菜单项
此模块在 *管理* 菜单下添加了一个 *身份管理* 菜单项:
![身份模块菜单](../images/identity-module-menu.png)
这个菜单项和相关页面已获得授权. 这意味着当前用户必须拥有相关权限才能使其可见. `admin` 角色 (和拥有此角色的用户, 如 `admin` 用户) 已经拥有这些权限. 如果你想要使其他角色/用户也启用权限, 请打开 *角色* 或 *用户* 页面的 *权限* 对话框, 并检查如下所示的权限:
![身分模块权限](../images/identity-module-permissions.png)
请参阅 [授权文档](../Authorization.md) 以了解权限系统.
### 页面
本节介绍此模块提供的主要页面.
#### 用户
此页用于查看用户列表. 您可以创建/编辑和删除用户, 将角色分配给用户.
![身分模块用户](../images/identity-module-users.png)
一个用户可以有零个或多个角色. 用户从其角色继承权限. 此外, 你可以给用户直接分配权限 (通过点击 *操作* 按钮, 然后选择 *权限*) .
#### 角色
角色用于按分组给用户分配权限.
![身份模块角色](../images/identity-module-roles.png)
角色除了角色名称之外还有2个属性:
* `Default`: 如果某个角色被标记为 "default", 那么当新用户 (使用 [账户模块](Account.md)) 注册到应用程序时, 其将被作为默认角色分配给新用户.
* `Public`: 用户的公共角色可以被应用程序中的其他用户看到. 这个功能在身份模块中没有用到, 但被提供作为你可能希望在你自己的应用程序中使用的功能.
## 其他功能
本节包括此模块提供的没有 UI 页面的其他功能.
### 组织单元
组织单元 (OU) 可被用于 **按层级对用户和实体进行分组**.
#### 组织单元实体
组织单元由 **OrganizationUnit** 实体表示. 它的基本属性是:
- **TenantId**: 组织单元的租户Id. 对于宿主可以是 null.
- **ParentId**: 父级组织单元的Id. 如果这是一个根级组织单元,它可以是 null.
- **Code**: 对于租户唯一的层级字符串编码.
- **DisplayName**: 组织单元的显示名称.
#### 组织树
由于组织单元可以有父级, 因此租户的所有组织单元是一个 **树** 结构. 这个树有一些规则;
- 可以有多个根级 (`ParentId` 是 `null` 的) .
- 一个组织单元的第一级子项数量有限制 (因为下面解释的固定的组织单元编码单位长度) .
#### 组织单元编码
组织单元编码是通过 `OrganizationUnitManager` 服务自动生成和维护的. 它是一个字符串, 像这样:
"**00001.00042.00005**"
通常用这种编码可以轻易地 (递归) 查询出数据库中组织单元的所有子项. 这个编码有一些规则 (当你使用 `OrganizationUnitManager` 时自动被应用的) :
- 对 [租户](../Multi-Tenancy.md) 是 **唯一的**.
- 同一组织单元的全部子项都具有 **以父级组织单元编码开头的** 编码.
- 如示例中所示, 它是固定长度的且是基于树中组织单元的级别的.
- 尽管组织单元编码是唯一的, 但如果你移动了相关的组织单元, 它也可以被更改.
请注意, 你必须根据Id引用一个组织单元, 而不是编码, 因为编码后续是可以被更改的.
#### 组织单元管理
`OrganizationUnitManager` 类可以被 [注入](../Dependency-Injection.md) 并用来管理组织单元. 常见用例如下:
- 创建, 更新和删除组织单元.
- 在组织单元树中移动一个组织单元.
- 获取关于组织单元树及其项的信息.
### 身份安全日志
安全日志系统可以记录账户的一些重要的操作或者改动 (例如 *登录* 和 *更改密码*) . 如果需要, 你也可以保存安全日志.
你可以注入和使用 `IdentitySecurityLogManager` 或 `ISecurityLogManager` 来写入安全日志. 默认它会创建一个日志对象并填充常用的值, 如 `CreationTime`, `ClientIpAddress`, `BrowserInfo`, `current user/tenant` 等等. 当然你可以覆盖这些值.
```cs
await IdentitySecurityLogManager.SaveAsync(new IdentitySecurityLogContext()
{
Identity = "IdentityServer";
Action = "ChangePassword";
Identity = "IdentityServer";
Action = "ChangePassword";
});
```
通过配置 `AbpSecurityLogOptions` 来提供应用程序的名称或者禁用安全日志功能. 默认是**启用**状态.
通过配置 `AbpSecurityLogOptions` 来为日志提供应用程序的名称 (如果你有多个应用程序并且想要在日志中区分应用程序) 或者禁用安全日志功能.
```cs
Configure<AbpSecurityLogOptions>(options =>
{
options.ApplicationName = "AbpSecurityTest";
options.ApplicationName = "AbpSecurityTest";
});
```
## 选项
`IdentityOptions` 是由 Microsoft [Identity 库](https://docs.microsoft.com/zh-cn/aspnet/core/security/authentication/identity) 提供的标准 [选项类](../Options.md) . 所以, 你可以在 [模块](../Module-Development-Basics.md) 类的 `ConfigureServices` 方法中设置这些选项.
**例如: 设置所需的密码最小长度**
````csharp
Configure<IdentityOptions>(options =>
{
options.Password.RequiredLength = 5;
});
````
ABP 允许你在运行时通过使用 [设置系统](../Settings.md) 更进一步地更改这些选项. 你可以 [注入](../Dependency-Injection.md) `ISettingManager` 并使用 `Set...` 方法中的一种来更改用户, 租户或全局所有用户的选项值.
**例如: 更改当前租户所需的密码最小长度**
````csharp
public class MyService : ITransientDependency
{
private readonly ISettingManager _settingManager;
public MyService(ISettingManager settingManager)
{
_settingManager = settingManager;
}
public async Task ChangeMinPasswordLength(int minLength)
{
await _settingManager.SetForCurrentTenantAsync(
IdentitySettingNames.Password.RequiredLength,
minLength.ToString()
);
}
}
````
`IdentitySettingNames` 类 (在 `Volo.Abp.Identity.Settings` 命名空间中) 为设置名称定义了一些常量.
## 分布式事件
此模块定义了如下 ETOs (事件传输对象) 以允许你去订阅模块中实体的改动.
* `UserEto` 在 `IdentityUser` 实体更改完成时发布.
* `IdentityRoleEto` 在 `IdentityRole` 实体更改完成时发布.
* `IdentityClaimTypeEto` 在 `IdentityClaimType` 实体更改完成时发布.
* `OrganizationUnitEto` 在 `OrganizationUnit` 实体更改完成时发布.
**例如: 当一个新用户被创建时接收通知**
````csharp
public class MyHandler :
IDistributedEventHandler<EntityCreatedEto<UserEto>>,
ITransientDependency
{
public async Task HandleEventAsync(EntityCreatedEto<UserEto> eventData)
{
UserEto user = eventData.Entity;
// TODO: ...
}
}
````
`UserEto` 和 `IdentityRoleEto` 默认自动发布事件. 你应该自己配置其他的 Eto. 请参阅 [分布式事件总线文档](../Distributed-Event-Bus.md) 了解预定义事件的详细信息.
> 订阅分布式事件对于分布式场景 (如微服务架构) 特别有用. 如果你正在构建单体式应用程序, 或者在运行了身份模块的同一进程内监听事件, 那么订阅 [本地事件](../Local-Event-Bus.md) 更高效, 更简单.
## 内部构件
本节包括模块的一些内部详细信息, 您不是那么需要, 但在一些情况下可能需要使用.
### 领域层
#### 聚合
##### 用户
用户通常是一个登录并使用应用程序的人.
* `IdentityUser` (聚合根): 表示系统中的一个用户.
* `IdentityUserRole` (集合): 分配给用户的角色.
* `IdentityUserClaim` (集合): 用户的自定义声明.
* `IdentityUserLogin` (集合): 用户的外部登录.
* `IdentityUserToken` (集合): 用户的令牌 (用于 Microsoft Identity 服务).
##### 角色
角色通常是分配给用户的一组权限.
* `IdentityRole` (聚合根): 表示系统中的角色.
* `IdentityRoleClaim` (集合): 角色的自定义声明.
##### 声明类型
声明类型是可以被分配给系统中其他实体 (如角色和用户) 的自定义声明的定义.
* `IdentityClaimType` (聚合根): 表示声明类型的定义. 它包括一些用于定义声明类型和验证规则的属性 (例如, 必须的, 正则表达式, 描述, 值类型) .
##### 身份安全日志
`IdentitySecurityLog` 对象表示系统中与授权相关的操作 (如 *登录*) .
* `IdentitySecurityLog` (聚合根): 表示系统中的安全日志.
##### 组织单元
组织单元是一个有层级结构的实体.
* ```OrganizationUnit``` (聚合根): 表示系统中的组织单元.
* ```Roles``` (集合): 组织单元的角色.
#### 仓储
此模块定义了以下自定义仓储:
* `IIdentityUserRepository`
* `IIdentityRoleRepository`
* `IIdentityClaimTypeRepository`
* ```IIdentitySecurityLogRepository```
* ```IOrganizationUnitRepository```
#### 领域服务
##### 用户管理
`IdentityUserManager` 常用于管理用户, 他们的权限, 声明, 密码, 电子邮件等等. 它派生自 Microsoft Identity 的 `UserManager<T>` 类, 其中 `T` 是 `IdentityUser`.
##### 角色管理
`IdentityRoleManager` 常用于管理角色和他们的声明. 它派生自 Microsoft Identity 的 `RoleManager<T>` 类, 其中 `T` 是 `IdentityRole`.
##### 声明类型管理
`IdenityClaimTypeManager` 常用于对聚合根 `IdentityClaimType` 执行某些操作.
##### 组织单元管理
```OrganizationUnitManager``` 常用于对聚合根 `OrganizationUnit` 执行某些操作.
##### 安全日志管理
```IdentitySecurityLogManager``` 常用于保存安全日志.
### 服务层
#### 应用服务
* `IdentityUserAppService` (实现 `IIdentityUserAppService`): 实现了用户管理 UI 的用例.
* `IdentityRoleAppService` (实现 `IIdentityRoleAppService`): 实现了角色管理 UI 的用例.
* `IdentityClaimTypeAppService` (实现 `IIdentityClaimTypeAppService`): 实现了声明类型管理 UI 的用例.
* `IdentitySettingsAppService` (实现 `IIdentitySettingsAppService`): 用于获取和更新身份模块的设置.
* `IdentityUserLookupAppService` (实现 `IIdentityUserLookupAppService`): 用于根据 `id` 或 `userName` 获取用户信息. 它旨在由ABP内部使用.
* `ProfileAppService` (实现 `IProfileAppService`): 用于更改用户的简介和密码.
* ```IdentitySecurityLogAppService``` (实现 ```IIdentitySecurityLogAppService```): 实现了安全日志 UI 的用例.
* ```OrganizationUnitAppService``` (实现 ```OrganizationUnitAppService```): 实现了组织单元管理 UI 的用例.
### 数据库提供程序
此模块为数据库提供 [Entity Framework Core](../Entity-Framework-Core.md) 和 [MongoDB](../MongoDB.md) 两种选择.
#### EF Core
NuGet 包 [Volo.Abp.Identity.EntityFrameworkCore](https://www.nuget.org/packages/Volo.Abp.Identity.EntityFrameworkCore) 实现了 EF Core 的集成.
##### 数据库表
* **AbpRoles**
* AbpRoleClaims
* **AbpUsers**
* AbpUserClaims
* AbpUserLogins
* AbpUserRoles
* AbpUserTokens
* **AbpClaimTypes**
* **AbpOrganizationUnits**
* AbpOrganizationUnitRoles
* AbpUserOrganizationUnits
* **AbpSecurityLogs**
#### MongoDB
NuGet 包 [Volo.Abp.Identity.MongoDB](https://www.nuget.org/packages/Volo.Abp.Identity.MongoDB) 实现了 MongoDB 的集成.
##### 数据库集合
* **AbpRoles**
* **AbpUsers**
* **AbpClaimTypes**
* **AbpOrganizationUnits**
* **AbpSecurityLogs**
#### 常用数据库属性
你可以设置 `AbpIdentityDbProperties` 中的以下属性来更改数据库选项:
* `DbTablePrefix` (`Abp` 作为默认值) 是表/集合名称的前缀.
* `DbSchema` (`null` 作为默认值) 是数据库架构.
* `ConnectionStringName` (`AbpIdentity` 作为默认值) 是此模块的 [连接字符串](../Connection-Strings.md) 名称.
它们是静态属性. 你需要在开始运行应用程序前设置它们 (通常在 `Program.cs` 中).

36
docs/zh-Hans/Modules/IdentityServer.md

@ -1,18 +1,18 @@
# 身份服务器模块
身份服务器模块提供了一个 [IdentityServer](https://github.com/IdentityServer/IdentityServer4) (IDS) 的完全集成,该框架提供高级身份验证功能,如单点登录和API访问控制.此模块将客户端,资源以及其他 IDS 相关的对象保存到数据库中.
身份服务器模块提供了一个 [IdentityServer](https://github.com/IdentityServer/IdentityServer4) (IDS) 的完全集成, 该框架提供高级身份验证功能, 如单点登录和API访问控制.此模块将客户端,资源以及其他 IDS 相关的对象保存到数据库中.
## 如何安装
当你使用 ABP 框架 [创建一个新的解决方案](https://abp.io/get-started) 时,此模块将被预安装(作为 NuGet/NPM 包).你可以继续用其作为包并轻松地获取更新,也可以将其源代码包含在解决方案中(请参阅 `get-source` [CLI](../CLI.md))以开发自定义模块.
当你使用 ABP 框架 [创建一个新的解决方案](https://abp.io/get-started) 时, 此模块将被预安装(作为 NuGet/NPM 包).你可以继续用其作为包并轻松地获取更新, 也可以将其源代码包含在解决方案中(请参阅 `get-source` [CLI](../CLI.md))以开发自定义模块.
### 源代码
可以 [在此处](https://github.com/abpframework/abp/tree/dev/modules/identityserver) 访问源代码.源代码使用 [MIT](https://choosealicense.com/licenses/mit/) 许可,所以你可以免费使用和自定义它.
可以 [在此处](https://github.com/abpframework/abp/tree/dev/modules/identityserver) 访问源代码.源代码使用 [MIT](https://choosealicense.com/licenses/mit/) 许可, 所以你可以免费使用和自定义它.
## 用户界面
此模块使用了领域逻辑和数据库集成,但没有提供任何 UI.如果你需要动态添加客户端和资源, 管理 UI 是非常有用的.在这种情况下,你可以自己构建管理 UI,或者考虑购买为此模块提供了管理 UI 的 [ABP 商业版](https://commercial.abp.io/).
此模块使用了领域逻辑和数据库集成, 但没有提供任何 UI.如果你需要动态添加客户端和资源, 管理 UI 是非常有用的.在这种情况下, 你可以自己构建管理 UI, 或者考虑购买为此模块提供了管理 UI 的 [ABP 商业版](https://commercial.abp.io/).
## 与其他模块的关系
@ -22,15 +22,15 @@
### AbpIdentityServerBuilderOptions
`AbpIdentityServerBuilderOptions` 在你的身份服务器 [模块](https://docs.abp.io/en/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如:
`AbpIdentityServerBuilderOptions` 在你的身份服务器 [模块](https://docs.abp.io/zh-Hans/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如:
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<AbpIdentityServerBuilderOptions>(builder =>
{
//Set options here...
});
PreConfigure<AbpIdentityServerBuilderOptions>(builder =>
{
//Set options here...
});
}
````
@ -41,15 +41,15 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
* `IntegrateToAspNetIdentity` (默认值:true):集成到 ASP.NET Identity.
* `AddDeveloperSigningCredential` (默认值:true):设置为 false 禁止调用 IIdentityServerBuilder 中的 `AddDeveloperSigningCredential()`.
`IIdentityServerBuilder` 可以在你的身份服务器 [模块](https://docs.abp.io/en/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如:
`IIdentityServerBuilder` 可以在你的身份服务器 [模块](https://docs.abp.io/zh-Hans/abp/latest/Module-Development-Basics) 中的 `PreConfigureServices` 方法中配置.例如:
````csharp
public override void PreConfigureServices(ServiceConfigurationContext context)
{
PreConfigure<IIdentityServerBuilder>(builder =>
{
builder.AddSigningCredential(...);
});
PreConfigure<IIdentityServerBuilder>(builder =>
{
builder.AddSigningCredential(...);
});
}
````
@ -107,7 +107,7 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
#### 领域服务
此模块不包含任何领域服务,但重写了下面的服务;
此模块不包含任何领域服务, 但重写了下面的服务;
* `AbpProfileService` (当 `AbpIdentityServerBuilderOptions.IntegrateToAspNetIdentity` 为 true 时使用)
* `AbpClaimsService`
@ -132,13 +132,13 @@ public override void PreConfigureServices(ServiceConfigurationContext context)
##### 表/集合 前缀 & 架构
所有表/集合都使用 `IdentityServer` 作为默认前缀.如果你需要改变表的前缀或设置一个架构名称(如果你的数据库提供程序支持),请设置 `AbpIdentityServerDbProperties` 类的静态属性.
所有表/集合都使用 `IdentityServer` 作为默认前缀.如果你需要改变表的前缀或设置一个架构名称(如果你的数据库提供程序支持), 请设置 `AbpIdentityServerDbProperties` 类的静态属性.
##### 连接字符串
此模块使用 `AbpIdentityServer` 作为连接字符串的名称.如果你没有用这个名称定义连接字符串,它将回退到 `Default` 连接字符串.
此模块使用 `AbpIdentityServer` 作为连接字符串的名称.如果你没有用这个名称定义连接字符串, 它将回退到 `Default` 连接字符串.
有关详细信息,请参阅 [连接字符串](https://docs.abp.io/en/abp/latest/Connection-Strings) 文档.
有关详细信息, 请参阅 [连接字符串](https://docs.abp.io/zh-Hans/abp/latest/Connection-Strings) 文档.
#### EF Core

107
docs/zh-Hans/Modules/Tenant-Management.md

@ -0,0 +1,107 @@
# 租户管理模块
[多租户](../Multi-Tenancy.md) 是 ABP 框架的核心功能之一. 它提供了构建 SaaS (软件及服务) 解决方案的基础架构. ABP 的多租户系统通过提供 `ITenantStore` 接口来抽象租户存储的位置. 您需要做的就是实现该接口.
**租户管理模块是 `ITenantStore` 接口的实现. 它将租户存储在数据库中. 它还提供了 UI 来管理租户及其 [功能](../Features.md).**
> 请参阅 [多租户](../Multi-Tenancy.md) 文档,以了解 ABP 框架的多租户系统. 本文重点介绍租户管理模块.
### 关于商业版 SaaS 模块
[SaaS 模块](https://commercial.abp.io/modules/Volo.Saas) 是此模块的替代实现, 具有更多的功能和可能性. 它作为 [ABP 商业版](https://commercial.abp.io/) 订阅的一部分分发.
## 如何安装
当你使用 ABP 框架 [创建一个新的解决方案](https://abp.io/get-started) 时, 此模块将被预安装(作为 NuGet/NPM 包). 你可以继续用其作为包并轻松地获取更新, 也可以将其源代码包含在解决方案中(请参阅 `get-source` [CLI](../CLI.md))以开发自定义模块.
### 源代码
可以 [在此处](https://github.com/abpframework/abp/tree/dev/modules/identity) 访问源代码。源代码使用 [MIT](https://choosealicense.com/licenses/mit/) 许可, 所以你可以免费使用和自定义它.
## 用户界面
此模块将 "管理 -> 租户管理 -> 租户" 菜单项添加到应用程序的主菜单, 这将打开如下页面:
![租户管理页面](../images/module-tenant-management-page.png)
在这个页面中, 你可以查看所有租户. 你可以按照如下所示创建一个新的租户:
![租户管理新增租户](../images/module-tenant-management-new-tenant.png)
在这个模态框中;
* **租户名称**: 租户唯一的名称. 如果为租户使用二级域名, 这将是二级域名名称.
* **管理员电子邮件地址**: 租户管理员的电子邮件地址.
* **管理员密码**: 租户管理员的密码.
当您点击租户附近的 *操作* 按钮时, 您将看见可以执行的操作:
![租户管理操作](../images/module-tenant-management-actions.png)
### 管理租户功能
功能操作会打开一个模态框, 来对相关租户进行启用/禁用/设置 [功能](../Features.md). 这有一个模态框的例子:
![功能模态框](../images/features-modal.png)
### 管理主机功能
如果您使用应用程序的功能也在主机端, *管理主机功能* 按钮则用于设置主机端的功能.
## 内部结构
如果要 [自定义](../Customizing-Application-Modules-Guide.md) 此模块而不更改 [其源代码](https://github.com/abpframework/abp/tree/dev/modules/tenant-management), 则可以将此节作为参考.
### 领域层
#### 聚合
* `Tenant`
#### 仓储
* `ITenantRepository`
#### 领域服务
* `TenantManager`
### 应用层
#### 应用服务
* `TenantAppService`
#### 权限
- `AbpTenantManagement.Tenants`: 租户管理.
- `AbpTenantManagement.Tenants.Create`: 创建一个新的租户.
- `AbpTenantManagement.Tenants.Update`: 编辑一个已存在的租户.
- `AbpTenantManagement.Tenants.Delete`: 删除一个已存在的租户.
- `AbpTenantManagement.Tenants.ManageFeatures`: 管理租户的功能.
### EF Core 集成
* `TenantManagementDbContext` (实现了 `ITenantManagementDbContext`)
**数据库表:**
* `AbpTenants`
* `AbpTenantConnectionStrings`
### MongoDB 集成
* `TenantManagementMongoDbContext` (实现了 `ITenantManagementMongoDbContext`)
**数据库集合:**
* `AbpTenants` (也包括连接字符串)
## 注意事项
ABP 框架允许租户有专用的数据库, 以允许 *每个租户用一个数据库*. 此模块具有使该实现成为可能 (查阅其源代码) 的基础架构, 但是它没有实现应用程序层和 UI 功能以使其开箱即用. 您可以自己实现这些功能, 也可以考虑使用已完全实现这些功能并提供了更多业务功能的 [ABP 商业版 Saas 模块](https://docs.abp.io/en/commercial/latest/modules/saas).
## 另请参见
* [多租户](../Multi-Tenancy.md)
* [ABP 商业版 SaaS 模块](https://docs.abp.io/en/commercial/latest/modules/saas)

3
docs/zh-Hans/Modules/Tentant-Management.md

@ -1,3 +0,0 @@
# 租户管理模块
TODO

636
docs/zh-Hans/Tutorials/Part-5.md

@ -1 +1,635 @@
TODO..
# Web应用程序开发教程 - 第五章: 授权
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
* **{{DB_Text}}** 做为ORM提供程序.
* **{{UI_Value}}** 做为UI框架.
本教程分为以下部分:
- [Part 1: 创建服务端](Part-1.md)
- [Part 2: 图书列表页面](Part-2.md)
- [Part 3: 创建,更新和删除图书](Part-2.md)
- [Part 4: 集成测试](Part-4.md)
- **Part 5: 授权**(本章)
- [Part 6: 作者: 领域层](Part-6.md)
- [Part 7: 作者: 数据库集成](Part-7.md)
- [Part 8: 作者: 应用服务层](Part-8.md)
- [Part 9: 作者: 用户页面](Part-9.md)
- [Part 10: 图书到作者的关系](Part-10.md)
## 下载源码
本教程根据你的**UI** 和 **数据库**偏好有多个版本,我们准备了几种可供下载的源码组合:
* [MVC (Razor Pages) UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore)
* [Blazor UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore)
* [Angular UI 与 MongoDB](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb)
> 如果你在Windows中遇到 "文件名太长" or "解压错误", 很可能与Windows最大文件路径限制有关. Windows文件路径的最大长度为250字符. 为了解决这个问题,参阅 [在Windows 10中启用长路径](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> 如果你遇到与Git相关的长路径错误, 尝试使用下面的命令在Windows中启用长路径. 参阅 https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
> `git config --system core.longpaths true`
{{if UI == "MVC" && DB == "EF"}}
### 视频教程
本章也被录制为视频教程 **<a href="https://www.youtube.com/watch?v=1WsfMITN_Jk&list=PLsNclT2aHJcPNaCf7Io3DbMN6yAk_DgWJ&index=5" target="_blank">发布在YouTube</a>**.
{{end}}
## 权限
ABP框架提供了一个基于ASP.NET Core[授权基础架构](https://docs.microsoft.com/en-us/aspnet/core/security/authorization/introduction)的[授权系统](../Authorization.md). 基于标准授权基础架构的一个主要功能是添加了 **权限系统**, 这个系统允许定义权限并且根据角色, 用户或客户端启用/禁用权限.
### 权限名称
权限必须有唯一的名称 (一个 `字符串`). 最好的方法是把它定义为一个 `常量`, 这样我们就可以重用这个权限名称了.
打开 `Acme.BookStore.Application.Contracts` 项目中的 `BookStorePermissions` 类 (位于 `Permissions` 文件夹) 并替换为以下代码:
````csharp
namespace Acme.BookStore.Permissions
{
public static class BookStorePermissions
{
public const string GroupName = "BookStore";
public static class Books
{
public const string Default = GroupName + ".Books";
public const string Create = Default + ".Create";
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
}
}
````
权限名称具有层次结构. 例如, "创建图书" 权限被定义为 `BookStore.Books.Create`. ABP不强制必须如此, 但这是一种有益的做法.
### 权限定义
在使用权限前必须定义它们.
打开 `Acme.BookStore.Application.Contracts` 项目中的 `BookStorePermissionDefinitionProvider` 类 (位于 `Permissions` 文件夹) 并替换为以下代码:
````csharp
using Acme.BookStore.Localization;
using Volo.Abp.Authorization.Permissions;
using Volo.Abp.Localization;
namespace Acme.BookStore.Permissions
{
public class BookStorePermissionDefinitionProvider : PermissionDefinitionProvider
{
public override void Define(IPermissionDefinitionContext context)
{
var bookStoreGroup = context.AddGroup(BookStorePermissions.GroupName, L("Permission:BookStore"));
var booksPermission = bookStoreGroup.AddPermission(BookStorePermissions.Books.Default, L("Permission:Books"));
booksPermission.AddChild(BookStorePermissions.Books.Create, L("Permission:Books.Create"));
booksPermission.AddChild(BookStorePermissions.Books.Edit, L("Permission:Books.Edit"));
booksPermission.AddChild(BookStorePermissions.Books.Delete, L("Permission:Books.Delete"));
}
private static LocalizableString L(string name)
{
return LocalizableString.Create<BookStoreResource>(name);
}
}
}
````
这个类定义了一个 **权限组** (在UI上分组权限, 下文会看到) 和 权限组中的**4个权限**. 而且, **创建**, **编辑** 和 **删除** 是 `BookStorePermissions.Books.Default` 权限的子权限. **仅当父权限被选择**时, 子权限才能被选择.
最后, 编辑本地化文件 (`Acme.BookStore.Domain.Shared` 项目的 `Localization/BookStore` 文件夹中的 `en.json`) 定义上面使用的本地化键:
````json
"Permission:BookStore": "Book Store",
"Permission:Books": "Book Management",
"Permission:Books.Create": "Creating new books",
"Permission:Books.Edit": "Editing the books",
"Permission:Books.Delete": "Deleting the books"
````
> 本地化键名可以是任意的, 并没有强制的规则. 但我们推荐上面使用的约定.
### 权限管理界面
完成权限定义后, 可以在**权限管理模态窗口**看到它们.
在*管理 -> Identity -> 角色* 页面, 选择admin角色的 *权限* 操作, 打开权限管理模态窗口:
![bookstore-permissions-ui](images/bookstore-permissions-ui.png)
授予你希望的权限并保存.
> **提示**: 如果运行 `Acme.BookStore.DbMigrator` 应用程序, 新权限会被自动授予admin.
## 授权
现在, 你可以使用权限授权图书管理.
### 应用层 和 HTTP API
打开 the `BookAppService` 类, 设置策略名称为上面定义的权限名称.
````csharp
using System;
using Acme.BookStore.Permissions;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Books
{
public class BookAppService :
CrudAppService<
Book, //The Book entity
BookDto, //Used to show books
Guid, //Primary key of the book entity
PagedAndSortedResultRequestDto, //Used for paging/sorting
CreateUpdateBookDto>, //Used to create/update a book
IBookAppService //implement the IBookAppService
{
public BookAppService(IRepository<Book, Guid> repository)
: base(repository)
{
GetPolicyName = BookStorePermissions.Books.Default;
GetListPolicyName = BookStorePermissions.Books.Default;
CreatePolicyName = BookStorePermissions.Books.Create;
UpdatePolicyName = BookStorePermissions.Books.Edit;
DeletePolicyName = BookStorePermissions.Books.Delete;
}
}
}
````
加入代码到构造器. 基类中的 `CrudAppService` 自动在CRUD操作中使用这些权限. 这不仅实现了 **应用服务** 的安全性, 也实现了 **HTTP API** 安全性, 因为如前解释的, HTTP API 自动使用这些服务. (参阅 [自动 API controllers](../API/Auto-API-Controllers.md)).
> 在稍后开发作者管理功能时, 你将会看到声明式授权, 使用 `[Authorize(...)]` 特性.
{{if UI == "MVC"}}
### Razor 页面
虽然安全的 HTTP API和应用服务阻止未授权用户使用服务, 但他们依然可以导航到图书管理页面. 虽然当页面发起第一个访问服务器的AJAX请求时会收到授权异常, 但为了更好的用户体验和安全性, 我们应该对页面进行授权.
打开 `BookStoreWebModule` 在 `ConfigureServices` 方法中加入以下代码:
````csharp
Configure<RazorPagesOptions>(options =>
{
options.Conventions.AuthorizePage("/Books/Index", BookStorePermissions.Books.Default);
options.Conventions.AuthorizePage("/Books/CreateModal", BookStorePermissions.Books.Create);
options.Conventions.AuthorizePage("/Books/EditModal", BookStorePermissions.Books.Edit);
});
````
现在未授权用户会被重定向至**登录页面**.
#### 隐藏新建图书按钮
图书管理页面有一个 *新建图书* 按钮, 当用户没有 *图书新建* 权限时就不可见的.
![bookstore-new-book-button-small](images/bookstore-new-book-button-small.png)
打开 the `Pages/Books/Index.cshtml` 文件, 替换内容为以下代码:
````html
@page
@using Acme.BookStore.Localization
@using Acme.BookStore.Permissions
@using Acme.BookStore.Web.Pages.Books
@using Microsoft.AspNetCore.Authorization
@using Microsoft.Extensions.Localization
@model IndexModel
@inject IStringLocalizer<BookStoreResource> L
@inject IAuthorizationService AuthorizationService
@section scripts
{
<abp-script src="/Pages/Books/Index.js"/>
}
<abp-card>
<abp-card-header>
<abp-row>
<abp-column size-md="_6">
<abp-card-title>@L["Books"]</abp-card-title>
</abp-column>
<abp-column size-md="_6" class="text-right">
@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.Books.Create))
{
<abp-button id="NewBookButton"
text="@L["NewBook"].Value"
icon="plus"
button-type="Primary"/>
}
</abp-column>
</abp-row>
</abp-card-header>
<abp-card-body>
<abp-table striped-rows="true" id="BooksTable"></abp-table>
</abp-card-body>
</abp-card>
````
* 加入 `@inject IAuthorizationService AuthorizationService` 以访问授权服务.
* 使用 `@if (await AuthorizationService.IsGrantedAsync(BookStorePermissions.Books.Create))` 检查图书创建权限, 条件显示 *新建图书* 按钮.
### JavaScript端
图书管理页面中的图书表格每行都有操作按钮. 操作按钮包括 *编辑* 和 *删除* 操作:
![bookstore-edit-delete-actions](images/bookstore-edit-delete-actions.png)
如果用户没有权限, 应该隐藏相关的操作. 表格行中的操作有一个 `visible` 属性, 可以设置为 `false` 隐藏操作项.
打开 `Acme.BookStore.Web` 项目中的 `Pages/Books/Index.js`, 为 `编辑` 操作加入 `visible` 属性:
````js
{
text: l('Edit'),
visible: abp.auth.isGranted('BookStore.Books.Edit'), //CHECK for the PERMISSION
action: function (data) {
editModal.open({ id: data.record.id });
}
}
````
对 `Delete` 操作进行同样的操作:
````js
visible: abp.auth.isGranted('BookStore.Books.Delete')
````
* `abp.auth.isGranted(...)` 检查前面定义的权限.
* `visible` 也可以是一个返回 `bool` 值的函数. 这个函数可以稍后根据某些条件计算.
### 菜单项
即使我们在图书管理页面的所有层都控制了权限, 应用程序的主菜单依然会显示. 我们应该隐藏用户没有权限的菜单项.
打开 `BookStoreMenuContributor` 类, 找到下面的代码:
````csharp
context.Menu.AddItem(
new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
).AddItem(
new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
)
)
);
````
替换为以下代码:
````csharp
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
));
}
````
你需要为 `ConfigureMenuAsync` 方法加入 `async` 关键字, 并重新组织返回值. 最终的 `BookStoreMenuContributor` 类应该如下:
````csharp
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Acme.BookStore.Localization;
using Acme.BookStore.MultiTenancy;
using Acme.BookStore.Permissions;
using Volo.Abp.TenantManagement.Web.Navigation;
using Volo.Abp.UI.Navigation;
namespace Acme.BookStore.Web.Menus
{
public class BookStoreMenuContributor : IMenuContributor
{
public async Task ConfigureMenuAsync(MenuConfigurationContext context)
{
if (context.Menu.Name == StandardMenus.Main)
{
await ConfigureMainMenuAsync(context);
}
}
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
if (!MultiTenancyConsts.IsEnabled)
{
var administration = context.Menu.GetAdministration();
administration.TryRemoveMenuItem(TenantManagementMenuNames.GroupName);
}
var l = context.GetLocalizer<BookStoreResource>();
context.Menu.Items.Insert(0, new ApplicationMenuItem("BookStore.Home", l["Menu:Home"], "~/"));
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/Books"
));
}
}
}
}
````
{{else if UI == "NG"}}
### Angular Guard 配置
UI的第一步是防止未认证用户看见"图书"菜单项并进入图书管理页面.
打开 `/src/app/book/book-routing.module.ts` 替换为以下代码:
````js
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';
import { AuthGuard, PermissionGuard } from '@abp/ng.core';
import { BookComponent } from './book.component';
const routes: Routes = [
{ path: '', component: BookComponent, canActivate: [AuthGuard, PermissionGuard] },
];
@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule],
})
export class BookRoutingModule {}
````
* 从 `@abp/ng.core` 引入 `AuthGuard` 和 `PermissionGuard`.
* 在路由定义中添加 `canActivate: [AuthGuard, PermissionGuard]`.
打开 `/src/app/route.provider.ts`, 在 `/books` 路由中添加 `requiredPolicy: 'BookStore.Books'`. `/books` 路由应该如以下配置:
````js
{
path: '/books',
name: '::Menu:Books',
parentName: '::Menu:BookStore',
layout: eLayoutType.application,
requiredPolicy: 'BookStore.Books',
}
````
### 隐藏新建图书按钮
当用户没有 *图书新建* 权限时, 图书管理页面上的 *新建图书* 按钮应该不可见.
![bookstore-new-book-button-small](images/bookstore-new-book-button-small.png)
打开 `/src/app/book/book.component.html` 文件, 替换创建按钮的HTML内容如下:
````html
<!-- Add the abpPermission directive -->
<button *abpPermission="'BookStore.Books.Create'" id="create" class="btn btn-primary" type="button" (click)="createBook()">
<i class="fa fa-plus mr-1"></i>
<span>{%{{{ '::NewBook' | abpLocalization }}}%}</span>
</button>
````
* 加入 `*abpPermission="'BookStore.Books.Create'"`, 当用户没有权限时隐藏按钮.
### 隐藏编辑和删除操作
图书管理页面中的图书表格每行都有操作按钮. 操作按钮包括 *编辑* 和 *删除* 操作:
![bookstore-edit-delete-actions](images/bookstore-edit-delete-actions.png)
如果用户没有权限, 应该隐藏相关的操作.
打开 `/src/app/book/book.component.html` 文件, 替换编辑和删除按钮的内容如下:
````html
<!-- Add the abpPermission directive -->
<button *abpPermission="'BookStore.Books.Edit'" ngbDropdownItem (click)="editBook(row.id)">
{%{{{ '::Edit' | abpLocalization }}}%}
</button>
<!-- Add the abpPermission directive -->
<button *abpPermission="'BookStore.Books.Delete'" ngbDropdownItem (click)="delete(row.id)">
{%{{{ '::Delete' | abpLocalization }}}%}
</button>
````
* 加入 `*abpPermission="'BookStore.Books.Create'"`, 当用户没有编辑权限时隐藏按钮.
* 加入 `*abpPermission="'BookStore.Books.Delete'"`, 当用户没有删除权限时隐藏按钮.
{{else if UI == "Blazor"}}
### Razor验证组件
打开 `Acme.BookStore.Blazor` 项目中的 `/Pages/Books.razor` 文件, 在` @page` 指令和命名空间引入(`@using` 行)后添加 `Authorize` 特性, 如下所示:
````html
@page "/books"
@attribute [Authorize(BookStorePermissions.Books.Default)]
@using Acme.BookStore.Permissions
@using Microsoft.AspNetCore.Authorization
...
````
添加这个特性阻止未登录用户或未授权用户访问这个页面. 用户重试后, 会被重定向到登录页面.
### 显示/隐藏操作
图书管理页面上的每一种图书都有 *新建* 按钮和 *编辑*, *删除* 操作. 如果用户没有相关权限, 这些按钮/操作应该被隐藏.
基类 `AbpCrudPageBase` 已经具有这些操作需要的功能.
#### 设置策略 (权限) 名称
加入以下代码到 `Books.razor` 文件结尾:
````csharp
@code
{
public Books() // Constructor
{
CreatePolicyName = BookStorePermissions.Books.Create;
UpdatePolicyName = BookStorePermissions.Books.Edit;
DeletePolicyName = BookStorePermissions.Books.Delete;
}
}
````
基类 `AbpCrudPageBase` 自动检查相关操作的权限. 如果需要手动检查, 它也定义了相应的属性.
* `HasCreatePermission`: True, 如果用户具有新建实体的权限.
* `HasUpdatePermission`: True, 如果用户具有编辑/更新实体的权限.
* `HasDeletePermission`: True, 如果用户具有删除实体的权限.
> **Blazor 提示**: 当添加少量代码到 `@code` 是没有问题的. 当添加的代码变长时, 建议使用代码后置方法以便于维护. 我们将在作者部分使用这个方法.
#### 隐藏新建图书按钮
检查 *新建图书* 按钮权限:
````xml
@if (HasCreatePermission)
{
<Button Color="Color.Primary"
Clicked="OpenCreateModalAsync">@L["NewBook"]</Button>
}
````
#### 隐藏编辑/删除操作
`EntityAction` 组件定义了 `Visible` 属性 (参数) 以条件显示操作.
更新 `EntityActions` 部分:
````xml
<EntityActions TItem="BookDto" EntityActionsColumn="@EntityActionsColumn">
<EntityAction TItem="BookDto"
Text="@L["Edit"]"
Visible=HasUpdatePermission
Clicked="() => OpenEditModalAsync(context)" />
<EntityAction TItem="BookDto"
Text="@L["Delete"]"
Visible=HasDeletePermission
Clicked="() => DeleteEntityAsync(context)"
ConfirmationMessage="()=>GetDeleteConfirmationMessage(context)" />
</EntityActions>
````
#### 关于权限缓存
你可以运行和测试权限. 从admin角色中移除一个图书相关权限, 观察到相关按钮/操作从UI上消失.
在客户端, **ABP框架缓存当前用户的权限** . 所以, 当你修改了你的权限, 你需要手工 **刷新页面**. 如果不刷新并试图使用被禁的操作, 你会从服务器收到一个HTTP 403 (forbidden) 响应.
> 修改角色或用户的权限在服务端立即生效. 所以, 缓存系统不会导致安全问题.
### 菜单项
即使我们在图书管理页面的所有层都控制了权限, 应用程序的主菜单依然会显示. 我们应该隐藏用户没有权限的菜单项.
打开 `Acme.BookStore.Blazor` 项目中的 `BookStoreMenuContributor` 类, 找到以下代码:
````csharp
context.Menu.AddItem(
new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
).AddItem(
new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/books"
)
)
);
````
替换为以下代码:
````csharp
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/books"
));
}
````
你需要为 `ConfigureMenuAsync` 方法加入 `async` 关键字并重新整理返回值. 最终的 `ConfigureMainMenuAsync` 方法如下:
````csharp
private async Task ConfigureMainMenuAsync(MenuConfigurationContext context)
{
var l = context.GetLocalizer<BookStoreResource>();
context.Menu.Items.Insert(
0,
new ApplicationMenuItem(
"BookStore.Home",
l["Menu:Home"],
"/",
icon: "fas fa-home"
)
);
var bookStoreMenu = new ApplicationMenuItem(
"BooksStore",
l["Menu:BookStore"],
icon: "fa fa-book"
);
context.Menu.AddItem(bookStoreMenu);
//CHECK the PERMISSION
if (await context.IsGrantedAsync(BookStorePermissions.Books.Default))
{
bookStoreMenu.AddItem(new ApplicationMenuItem(
"BooksStore.Books",
l["Menu:Books"],
url: "/books"
));
}
}
````
{{end}}
## 下一章
查看本教程的[下一章](Part-6.md).

279
docs/zh-Hans/Tutorials/Part-6.md

@ -1 +1,278 @@
TODO..
# Web应用程序开发教程 - 第六章: 作者: 领域层
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
* **{{DB_Text}}** 做为ORM提供程序.
* **{{UI_Value}}** 做为UI框架.
本教程分为以下部分:
- [Part 1: 创建服务端](Part-1.md)
- [Part 2: 图书列表页面](Part-2.md)
- [Part 3: 创建,更新和删除图书](Part-2.md)
- [Part 4: 集成测试](Part-4.md)
- [Part 5: 授权](Part-5.md)
- **Part 6: 作者: 领域层**(本章)
- [Part 7: 作者: 数据库集成](Part-7.md)
- [Part 8: 作者: 应用服务层](Part-8.md)
- [Part 9: 作者: 用户页面](Part-9.md)
- [Part 10: 图书到作者的关系](Part-10.md)
## 下载源码
本教程根据你的**UI** 和 **数据库**偏好有多个版本,我们准备了几种可供下载的源码组合:
* [MVC (Razor Pages) UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore)
* [Blazor UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore)
* [Angular UI 与 MongoDB](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb)
> 如果你在Windows中遇到 "文件名太长" or "解压错误", 很可能与Windows最大文件路径限制有关. Windows文件路径的最大长度为250字符. 为了解决这个问题,参阅 [在Windows 10中启用长路径](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> 如果你遇到与Git相关的长路径错误, 尝试使用下面的命令在Windows中启用长路径. 参阅 https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
> `git config --system core.longpaths true`
## 简介
在前面的章节中, 我们使用 ABP 框架轻松地构建了一些服务;
* 使用 [CrudAppService](../Application-Services.md) 基类, 而不是为标准的增删改查操作手工开发应用服务.
* 使用 [generic repositories](../Repositories.md) 自动完成数据层功能.
对于 "作者" 部分;
* 我们将要展示在需要的情况下, 如何 **手工做一些事情**.
* 我们将要实现一些 **领域驱动设计 (DDD) 最佳实践**.
> **开发将会逐层完成, 一次聚焦一层. 在真实项目中, 你会逐个功能(垂直)开发, 如同前面的教程. 通过这种方式, 你可以体验这两种方式**
## 作者实体
在 `Acme.BookStore.Domain` 项目中创建 `Authors` 文件夹 (命名空间), 在其中加入 `Author` 类:
````csharp
using System;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Entities.Auditing;
namespace Acme.BookStore.Authors
{
public class Author : FullAuditedAggregateRoot<Guid>
{
public string Name { get; private set; }
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
private Author()
{
/* This constructor is for deserialization / ORM purpose */
}
internal Author(
Guid id,
[NotNull] string name,
DateTime birthDate,
[CanBeNull] string shortBio = null)
: base(id)
{
SetName(name);
BirthDate = birthDate;
ShortBio = shortBio;
}
internal Author ChangeName([NotNull] string name)
{
SetName(name);
return this;
}
private void SetName([NotNull] string name)
{
Name = Check.NotNullOrWhiteSpace(
name,
nameof(name),
maxLength: AuthorConsts.MaxNameLength
);
}
}
}
````
* 由 `FullAuditedAggregateRoot<Guid>` 继承使得实体支持[软删除](../Data-Filtering.md) (指实体被删除时, 它并没有从数据库中被删除, 而只是被标记删除), 实体也具有了 [审计](../Entities.md) 属性.
* `Name` 属性的 `private set` 限制从类的外部设置这个属性. 有两种方法设置名字 (两种都进行了验证):
* 当新建一个作者时, 通过构造器.
* 使用 `ChangeName` 方法更新名字.
* `构造器` 和 `ChangeName` 方法的访问级别是 `internal`, 强制这些方法只能在领域层由 `AuthorManager` 使用. 稍后将对此进行解释.
* `Check` 类是一个ABP框架工具类, 用于检查方法参数 (如果参数非法会抛出 `ArgumentException`).
`AuthorConsts` 是一个简单的类, 它位于 `Acme.BookStore.Domain.Shared` 项目的 `Authors` 命名空间 (文件夹)中:
````csharp
namespace Acme.BookStore.Authors
{
public static class AuthorConsts
{
public const int MaxNameLength = 64;
}
}
````
在 `Acme.BookStore.Domain.Shared` 项目中创建这个类, 因为[数据传输类](../Data-Transfer-Objects.md) (DTOs) 稍后会再一次用到它.
## AuthorManager: 领域服务
`Author` 构造器和 `ChangeName` 方法的访问级别是 `internal`, 所以它们只能在领域层使用. 在 `Acme.BookStore.Domain` 项目中的 `Authors` 文件夹 (命名空间)创建 `AuthorManager` 类:
````csharp
using System;
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp;
using Volo.Abp.Domain.Services;
namespace Acme.BookStore.Authors
{
public class AuthorManager : DomainService
{
private readonly IAuthorRepository _authorRepository;
public AuthorManager(IAuthorRepository authorRepository)
{
_authorRepository = authorRepository;
}
public async Task<Author> CreateAsync(
[NotNull] string name,
DateTime birthDate,
[CanBeNull] string shortBio = null)
{
Check.NotNullOrWhiteSpace(name, nameof(name));
var existingAuthor = await _authorRepository.FindByNameAsync(name);
if (existingAuthor != null)
{
throw new AuthorAlreadyExistsException(name);
}
return new Author(
GuidGenerator.Create(),
name,
birthDate,
shortBio
);
}
public async Task ChangeNameAsync(
[NotNull] Author author,
[NotNull] string newName)
{
Check.NotNull(author, nameof(author));
Check.NotNullOrWhiteSpace(newName, nameof(newName));
var existingAuthor = await _authorRepository.FindByNameAsync(newName);
if (existingAuthor != null && existingAuthor.Id != author.Id)
{
throw new AuthorAlreadyExistsException(newName);
}
author.ChangeName(newName);
}
}
}
````
* `AuthorManager` 强制使用一种可控的方式创建作者和修改作者的名字. 应用层 (后面会介绍) 将会使用这些方法.
> **DDD 提示**: 如非必须并且用于执行核心业务规则, 不要引入领域服务方法. 对于这个场景, 我们使用这个服务保证名字的唯一性.
两个方法都检查是否存在同名用户, 如果存在, 抛出业务异常 `AuthorAlreadyExistsException`, 这个异常定义在 `Acme.BookStore.Domain` 项目 (`Authors` 文件夹中):
````csharp
using Volo.Abp;
namespace Acme.BookStore.Authors
{
public class AuthorAlreadyExistsException : BusinessException
{
public AuthorAlreadyExistsException(string name)
: base(BookStoreDomainErrorCodes.AuthorAlreadyExists)
{
WithData("name", name);
}
}
}
````
`BusinessException` 是一个特殊的异常类型. 在需要时抛出领域相关异常是一个好的实践. ABP框架会自动处理它, 并且它也容易本地化. `WithData(...)` 方法提供额外的数据给异常对象, 这些数据将会在本地化中或出于其它一些目的被使用.
打开 `Acme.BookStore.Domain.Shared` 项目中的 `BookStoreDomainErrorCodes` 并修改为:
````csharp
namespace Acme.BookStore
{
public static class BookStoreDomainErrorCodes
{
public const string AuthorAlreadyExists = "BookStore:00001";
}
}
````
这里定义了一个字符串, 表示应用程序抛出的错误码, 这个错误码可以被客户端应用程序处理. 为了用户, 你可能希望本地化它. 打开 `Acme.BookStore.Domain.Shared` 项目中的 `Localization/BookStore/en.json` , 加入以下项:
````json
"BookStore:00001": "There is already an author with the same name: {name}"
````
当 `AuthorAlreadyExistsException` 被抛出, 终端用户将会在UI上看到组织好的错误消息.
## IAuthorRepository
`AuthorManager` 注入了 `IAuthorRepository`, 所以我们需要定义它. 在 `Acme.BookStore.Domain` 项目的 `Authors` 文件夹 (命名空间) 中创建这个新接口:
````csharp
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Authors
{
public interface IAuthorRepository : IRepository<Author, Guid>
{
Task<Author> FindByNameAsync(string name);
Task<List<Author>> GetListAsync(
int skipCount,
int maxResultCount,
string sorting,
string filter = null
);
}
}
````
* `IAuthorRepository` 扩展了标准 `IRepository<Author, Guid>` 接口, 所以所有的标准 [repository](../Repositories.md) 方法对于 `IAuthorRepository` 都是可用的.
* `FindByNameAsync` 在 `AuthorManager` 中用来根据姓名查询用户.
* `GetListAsync` 用于应用层以获得一个排序的, 经过过滤的作者列表, 显示在UI上.
我们会在下一章实现这个repository.
> 这两个方法似乎 **看上去没有必要**, 因为标准repositories已经是 `IQueryable`, 你可以直接使用它们, 而不是自定义方法. 在实际应用程序中, 这么做是没问题的. 但在这个 **学习指南**中, 解释如何在需要时创建自定义repository方法是有价值的.
## 结论
这一章覆盖了图书管理程序作者相关功能的领域层. 在这一章中创建/更新的文件在下图中被高亮:
![bookstore-author-domain-layer](images/bookstore-author-domain-layer.png)
## 下一章
查看本教程的[下一章](Part-7.md).

239
docs/zh-Hans/Tutorials/Part-7.md

@ -1 +1,238 @@
TODO..
# Web应用程序开发教程 - 第七章: 数据库集成
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
* **{{DB_Text}}** 做为ORM提供程序.
* **{{UI_Value}}** 做为UI框架.
本教程分为以下部分:
- [Part 1: 创建服务端](Part-1.md)
- [Part 2: 图书列表页面](Part-2.md)
- [Part 3: 创建,更新和删除图书](Part-2.md)
- [Part 4: 集成测试](Part-4.md)
- [Part 5: 授权](Part-5.md)
- [Part 6: 作者: 领域层](Part-6.md)
- **Part 7: 数据库集成**(本章)
- [Part 8: 作者: 应用服务层](Part-8.md)
- [Part 9: 作者: 用户页面](Part-9.md)
- [Part 10: 图书到作者的关系](Part-10.md)
## 下载源码
本教程根据你的**UI** 和 **数据库**偏好有多个版本,我们准备了几种可供下载的源码组合:
* [MVC (Razor Pages) UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore)
* [Blazor UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore)
* [Angular UI 与 MongoDB](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb)
> 如果你在Windows中遇到 "文件名太长" or "解压错误", 很可能与Windows最大文件路径限制有关. Windows文件路径的最大长度为250字符. 为了解决这个问题,参阅 [在Windows 10中启用长路径](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> 如果你遇到与Git相关的长路径错误, 尝试使用下面的命令在Windows中启用长路径. 参阅 https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
> `git config --system core.longpaths true`
## 简介
这章阐述如何为前一章介绍的 `作者` 实体配置数据库集成.
{{if DB=="EF"}}
## DB Context
打开 `Acme.BookStore.EntityFrameworkCore` 项目中的 `BookStoreDbContext` 加入 `DbSet` 属性:
````csharp
public DbSet<Author> Authors { get; set; }
````
定位到相同项目中的 `BookStoreDbContext` 类中的 `OnModelCreating` 方法, 加入以下代码到方法的结尾:
````csharp
builder.Entity<Author>(b =>
{
b.ToTable(BookStoreConsts.DbTablePrefix + "Authors",
BookStoreConsts.DbSchema);
b.ConfigureByConvention();
b.Property(x => x.Name)
.IsRequired()
.HasMaxLength(AuthorConsts.MaxNameLength);
b.HasIndex(x => x.Name);
});
````
这和前面的 `Book` 实体做的一样, 所以不再赘述.
## 创建数据库迁移
配置启动解决方案为使用 [Entity Framework Core Code First Migrations](https://docs.microsoft.com/en-us/ef/core/managing-schemas/migrations/). 因为我们还没有修改数据库映射配置,所以需要创建一个新的迁移并对数据库应用变更.
打开命令行终端, 切换当前目录为 `Acme.BookStore.EntityFrameworkCore` 项目目录, 输入以下命令:
````bash
dotnet ef migrations add Added_Authors
````
这会在项目中添加一个迁移类:
![bookstore-efcore-migration-authors](./images/bookstore-efcore-migration-authors.png)
你可以在同一个命令行终端中使用以下命令对数据库应用更改:
````bash
dotnet ef database update
````
> 如果你使用 Visual Studio, 可能希望在 *Package Manager Console (PMC)* 使用 `Add-Migration Added_Authors -c BookStoreMigrationsDbContext` 和 `Update-Database -c BookStoreMigrationsDbContext` 命令. 如果这样, 保证 {{if UI=="MVC"}}`Acme.BookStore.Web`{{else if UI=="BlazorServer"}}`Acme.BookStore.Blazor`{{else if UI=="Blazor" || UI=="NG"}}`Acme.BookStore.HttpApi.Host`{{end}} 是启动项目并且在PMC中 `Acme.BookStore.EntityFrameworkCore` 是 *默认项目* .
{{else if DB=="Mongo"}}
## DB Context
打开 `Acme.BookStore.MongoDB` 项目 `MongoDb 文件夹`中的 `BookStoreMongoDbContext`, 在类中加入以下属性:
````csharp
public IMongoCollection<Author> Authors => Collection<Author>();
````
{{end}}
## 实现 IAuthorRepository
{{if DB=="EF"}}
在 `Acme.BookStore.EntityFrameworkCore` 项目 (`Authors` 文件夹)中创建一个新类 `EfCoreAuthorRepository`, 粘贴以下代码:
````csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Threading.Tasks;
using Acme.BookStore.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
using Volo.Abp.Domain.Repositories.EntityFrameworkCore;
using Volo.Abp.EntityFrameworkCore;
namespace Acme.BookStore.Authors
{
public class EfCoreAuthorRepository
: EfCoreRepository<BookStoreDbContext, Author, Guid>,
IAuthorRepository
{
public EfCoreAuthorRepository(
IDbContextProvider<BookStoreDbContext> dbContextProvider)
: base(dbContextProvider)
{
}
public async Task<Author> FindByNameAsync(string name)
{
var dbSet = await GetDbSetAsync();
return await dbSet.FirstOrDefaultAsync(author => author.Name == name);
}
public async Task<List<Author>> GetListAsync(
int skipCount,
int maxResultCount,
string sorting,
string filter = null)
{
var dbSet = await GetDbSetAsync();
return await dbSet
.WhereIf(
!filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter)
)
.OrderBy(sorting)
.Skip(skipCount)
.Take(maxResultCount)
.ToListAsync();
}
}
}
````
* 继承自 `EfCoreRepository`, 所以继承了标准repository的方法实现.
* `WhereIf` 是ABP 框架的快捷扩展方法. 它仅当第一个条件满足时, 执行 `Where` 查询. (根据名字查询, 仅当 filter 不为空). 你可以不使用这个方法, 但这些快捷方法可以提高效率.
* `sorting` 可以是一个字符串, 如 `Name`, `Name ASC` 或 `Name DESC`. 通过使用 [System.Linq.Dynamic.Core](https://www.nuget.org/packages/System.Linq.Dynamic.Core) NuGet 包是可能的.
> 参阅 [EF Core 集成文档](../Entity-Framework-Core.md) 获得基于EF Core的repositories的更多信息.
{{else if DB=="Mongo"}}
在 `Acme.BookStore.MongoDB` 项目 (`Authors` 文件夹)中创建一个新类 `MongoDbAuthorRepository`, 粘贴以下代码:
```csharp
using System;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Collections.Generic;
using System.Threading.Tasks;
using Acme.BookStore.MongoDB;
using MongoDB.Driver;
using MongoDB.Driver.Linq;
using Volo.Abp.Domain.Repositories.MongoDB;
using Volo.Abp.MongoDB;
namespace Acme.BookStore.Authors
{
public class MongoDbAuthorRepository
: MongoDbRepository<BookStoreMongoDbContext, Author, Guid>,
IAuthorRepository
{
public MongoDbAuthorRepository(
IMongoDbContextProvider<BookStoreMongoDbContext> dbContextProvider
) : base(dbContextProvider)
{
}
public async Task<Author> FindByNameAsync(string name)
{
var queryable = await GetMongoQueryableAsync();
return await queryable.FirstOrDefaultAsync(author => author.Name == name);
}
public async Task<List<Author>> GetListAsync(
int skipCount,
int maxResultCount,
string sorting,
string filter = null)
{
var queryable = await GetMongoQueryableAsync();
return await queryable
.WhereIf<Author, IMongoQueryable<Author>>(
!filter.IsNullOrWhiteSpace(),
author => author.Name.Contains(filter)
)
.OrderBy(sorting)
.As<IMongoQueryable<Author>>()
.Skip(skipCount)
.Take(maxResultCount)
.ToListAsync();
}
}
}
```
* 继承自 `MongoDbRepository`, 所以继承了标准repository的方法实现.
* `WhereIf` 是ABP 框架的快捷扩展方法. 它仅当第一个条件满足时, 执行 `Where` 查询. (根据名字查询, 仅当 filter 不为空). 你可以不使用这个方法, 但这些快捷方法可以提高效率.
* `sorting` 可以是一个字符串, 如 `Name`, `Name ASC` 或 `Name DESC`. 通过使用 [System.Linq.Dynamic.Core](https://www.nuget.org/packages/System.Linq.Dynamic.Core) NuGet 包是可能的.
> 参阅 [MongoDB 集成文档](../MongoDB.md) 获得基于MongoDB的repositories的更多信息.
{{end}}
## 下一章
查看本教程的[下一章](Part-8.md).

575
docs/zh-Hans/Tutorials/Part-8.md

@ -1 +1,574 @@
TODO..
# Web应用程序开发教程 - 第八章: 作者: 应用服务层
````json
//[doc-params]
{
"UI": ["MVC","Blazor","BlazorServer","NG"],
"DB": ["EF","Mongo"]
}
````
## 关于本教程
在本系列教程中, 你将构建一个名为 `Acme.BookStore` 的用于管理书籍及其作者列表的基于ABP的应用程序. 它是使用以下技术开发的:
* **{{DB_Text}}** 做为ORM提供程序.
* **{{UI_Value}}** 做为UI框架.
本教程分为以下部分:
- [Part 1: 创建服务端](Part-1.md)
- [Part 2: 图书列表页面](Part-2.md)
- [Part 3: 创建,更新和删除图书](Part-2.md)
- [Part 4: 集成测试](Part-4.md)
- [Part 5: 授权](Part-5.md)
- [Part 6: 作者: 领域层](Part-6.md)
- [Part 7: 作者: 数据库集成](Part-7.md)
- [Part 8: 作者: 应用服务层](本章)
- [Part 9: 作者: 用户页面](Part-9.md)
- [Part 10: 图书到作者的关系](Part-10.md)
## 下载源码
本教程根据你的**UI** 和 **数据库**偏好有多个版本,我们准备了几种可供下载的源码组合:
* [MVC (Razor Pages) UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Mvc-EfCore)
* [Blazor UI 与 EF Core](https://github.com/abpframework/abp-samples/tree/master/BookStore-Blazor-EfCore)
* [Angular UI 与 MongoDB](https://github.com/abpframework/abp-samples/tree/master/BookStore-Angular-MongoDb)
> 如果你在Windows中遇到 "文件名太长" or "解压错误", 很可能与Windows最大文件路径限制有关. Windows文件路径的最大长度为250字符. 为了解决这个问题,参阅 [在Windows 10中启用长路径](https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd#enable-long-paths-in-windows-10-version-1607-and-later).
> 如果你遇到与Git相关的长路径错误, 尝试使用下面的命令在Windows中启用长路径. 参阅 https://github.com/msysgit/msysgit/wiki/Git-cannot-create-a-file-or-directory-with-a-long-path
> `git config --system core.longpaths true`
## 简介
这章阐述如何为前一章介绍的 `作者` 实体创建应用服务层.
## IAuthorAppService
我们首先创建 [应用服务](../Application-Services.md) 接口和相关的 [DTO](../Data-Transfer-Objects.md)s. 在 `Acme.BookStore.Application.Contracts` 项目的 `Authors` 命名空间 (文件夹) 创建一个新接口 `IAuthorAppService`:
````csharp
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace Acme.BookStore.Authors
{
public interface IAuthorAppService : IApplicationService
{
Task<AuthorDto> GetAsync(Guid id);
Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input);
Task<AuthorDto> CreateAsync(CreateAuthorDto input);
Task UpdateAsync(Guid id, UpdateAuthorDto input);
Task DeleteAsync(Guid id);
}
}
````
* `IApplicationService` 是一个常规接口, 所有应用服务都继承自它, 所以 ABP 框架可以识别它们.
* 在 `Author` 实体中定义标准方法用于CRUD操作.
* `PagedResultDto` 是一个ABP框架中预定义的 DTO 类. 它拥有一个 `Items` 集合 和一个 `TotalCount` 属性, 用于返回分页结果.
* 优先从 `CreateAsync` 方法返回 `AuthorDto` (新创建的作者), 虽然在这个程序中没有这么做 - 这里只是展示一种不同用法.
这个类使用下面定义的DTOs (为你的项目创建它们).
### AuthorDto
````csharp
using System;
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Authors
{
public class AuthorDto : EntityDto<Guid>
{
public string Name { get; set; }
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
````
* `EntityDto<T>` 只有一个类型为指定泛型参数的 `Id` 属性. 你可以自己创建 `Id` 属性, 而不是继承自 `EntityDto<T>`.
### GetAuthorListDto
````csharp
using Volo.Abp.Application.Dtos;
namespace Acme.BookStore.Authors
{
public class GetAuthorListDto : PagedAndSortedResultRequestDto
{
public string Filter { get; set; }
}
}
````
* `Filter` 用于搜索作者. 它可以是 `null` (或空字符串) 以获得所有用户.
* `PagedAndSortedResultRequestDto` 具有标准分页和排序属性: `int MaxResultCount`, `int SkipCount` 和 `string Sorting`.
> ABP 框架拥有这些基本的DTO类以简化并标准化你的DTOs. 参阅 [DTO 文档](../Data-Transfer-Objects.md) 获得所有DTO类的详细信息.
### CreateAuthorDto
````csharp
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Authors
{
public class CreateAuthorDto
{
[Required]
[StringLength(AuthorConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
````
数据标记特性可以用来验证DTO. 参阅 [验证文档](../Validation.md) 获得详细信息.
### UpdateAuthorDto
````csharp
using System;
using System.ComponentModel.DataAnnotations;
namespace Acme.BookStore.Authors
{
public class UpdateAuthorDto
{
[Required]
[StringLength(AuthorConsts.MaxNameLength)]
public string Name { get; set; }
[Required]
public DateTime BirthDate { get; set; }
public string ShortBio { get; set; }
}
}
````
> 我们可以在创建和更新操作间分享 (重用) 相同的DTO. 虽然可以这么做, 但我们推荐为这些操作创建不同的DTOs, 因为我们发现随着时间的推移, 它们通常会变得有差异. 所以, 与紧耦合相比, 代码重复也是合理的.
## AuthorAppService
是时候实现 `IAuthorAppService` 接口了. 在 `Acme.BookStore.Application` 项目的 `Authors` 命名空间 (文件夹) 中创建一个新类 `AuthorAppService` :
````csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Acme.BookStore.Permissions;
using Microsoft.AspNetCore.Authorization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore.Authors
{
[Authorize(BookStorePermissions.Authors.Default)]
public class AuthorAppService : BookStoreAppService, IAuthorAppService
{
private readonly IAuthorRepository _authorRepository;
private readonly AuthorManager _authorManager;
public AuthorAppService(
IAuthorRepository authorRepository,
AuthorManager authorManager)
{
_authorRepository = authorRepository;
_authorManager = authorManager;
}
//...SERVICE METHODS WILL COME HERE...
}
}
````
* `[Authorize(BookStorePermissions.Authors.Default)]` 是一个检查权限(策略)的声明式方法, 用来给当前用户授权. 参阅 [授权文档](../Authorization.md) 获得详细信息. `BookStorePermissions` 类在后文会被更新, 现在不需要担心编译错误.
* 由 `BookStoreAppService` 派生, 这个类是一个简单基类, 可以做为模板. 它继承自标准的 `ApplicationService` 类.
* 实现上面定义的 `IAuthorAppService` .
* 注入 `IAuthorRepository` 和 `AuthorManager` 以使用服务方法.
现在, 我们逐个介绍服务方法. 复制这些方法到 `AuthorAppService` 类.
### GetAsync
````csharp
public async Task<AuthorDto> GetAsync(Guid id)
{
var author = await _authorRepository.GetAsync(id);
return ObjectMapper.Map<Author, AuthorDto>(author);
}
````
这个方法根据 `Id` 获得 `Author` 实体, 使用 [对象到对象映射](../Object-To-Object-Mapping.md) 转换为 `AuthorDto`. 这需要配置AutoMapper, 后面会介绍.
### GetListAsync
````csharp
public async Task<PagedResultDto<AuthorDto>> GetListAsync(GetAuthorListDto input)
{
if (input.Sorting.IsNullOrWhiteSpace())
{
input.Sorting = nameof(Author.Name);
}
var authors = await _authorRepository.GetListAsync(
input.SkipCount,
input.MaxResultCount,
input.Sorting,
input.Filter
);
var totalCount = input.Filter == null
? await _authorRepository.CountAsync()
: await _authorRepository.CountAsync(
author => author.Name.Contains(input.Filter));
return new PagedResultDto<AuthorDto>(
totalCount,
ObjectMapper.Map<List<Author>, List<AuthorDto>>(authors)
);
}
````
* 为处理客户端没有设置的情况, 在方法的开头设置默认排序是 "根据作者名".
* 使用 `IAuthorRepository.GetListAsync` 从数据库中获得分页的, 排序的和过滤的作者列表. 我们已经在教程的前一章中实现了它. 再一次强调, 实际上不需要创建这个方法, 因为我们可以从数据库中直接查询, 这里只是演示如何创建自定义repository方法.
* 直接查询 `AuthorRepository` , 得到作者的数量. 如果客户端发送了过滤条件, 会得到过滤后的作者数量.
* 最后, 通过映射 `Author` 列表到 `AuthorDto` 列表, 返回分页后的结果.
### CreateAsync
````csharp
[Authorize(BookStorePermissions.Authors.Create)]
public async Task<AuthorDto> CreateAsync(CreateAuthorDto input)
{
var author = await _authorManager.CreateAsync(
input.Name,
input.BirthDate,
input.ShortBio
);
await _authorRepository.InsertAsync(author);
return ObjectMapper.Map<Author, AuthorDto>(author);
}
````
* `CreateAsync` 需要 `BookStorePermissions.Authors.Create` 权限 (另外包括 `AuthorAppService` 类声明的 `BookStorePermissions.Authors.Default` 权限).
* 使用 `AuthorManager` (领域服务) 创建新作者.
* 使用 `IAuthorRepository.InsertAsync` 插入新作者到数据库.
* 使用 `ObjectMapper` 返回 `AuthorDto` , 代表新创建的作者.
> **DDD提示**: 一些开发者可能会发现可以在 `_authorManager.CreateAsync` 插入新实体. 我们认为把它留给应用层是更好的设计, 因为应用层更了解应该何时插入实体到数据库(在插入实体前可能需要额外的工作. 如果在领域层插入, 可能需要额外的更新操作). 但是, 你拥有最终的决定权.
### UpdateAsync
````csharp
[Authorize(BookStorePermissions.Authors.Edit)]
public async Task UpdateAsync(Guid id, UpdateAuthorDto input)
{
var author = await _authorRepository.GetAsync(id);
if (author.Name != input.Name)
{
await _authorManager.ChangeNameAsync(author, input.Name);
}
author.BirthDate = input.BirthDate;
author.ShortBio = input.ShortBio;
await _authorRepository.UpdateAsync(author);
}
````
* `UpdateAsync` 需要额外的 `BookStorePermissions.Authors.Edit` 权限.
* 使用 `IAuthorRepository.GetAsync` 从数据库中获得作者实体. 如果给定的id没有找到作者, `GetAsync` 抛出 `EntityNotFoundException`, 这在web应用程序中导致一个 `404` HTTP 状态码. 在更新操作中先获取实体再更新它, 是一个好的实践.
* 如果客户端请求, 使用 `AuthorManager.ChangeNameAsync` (领域服务方法) 修改作者姓名.
* 因为没有任何业务逻辑, 直接更新 `BirthDate` 和 `ShortBio`, 它们可以接受任何值.
* 最后, 调用 `IAuthorRepository.UpdateAsync` 更新实体到数据库.
{{if DB == "EF"}}
> **EF Core 提示**: Entity Framework Core 拥有 **change tracking** 系统并在unit of work 结束时 **自动保存** 任何修改到实体 (你可以简单地认为APB框架在方法结束时自动调用 `SaveChanges`). 所以, 即使你在方法结束时没有调用 `_authorRepository.UpdateAsync(...)` , 它依然可以工作. 如果你不考虑以后修改EF Core, 你可以移除这一行.
{{end}}
### DeleteAsync
````csharp
[Authorize(BookStorePermissions.Authors.Delete)]
public async Task DeleteAsync(Guid id)
{
await _authorRepository.DeleteAsync(id);
}
````
* `DeleteAsync` 需要额外的 `BookStorePermissions.Authors.Delete` 权限.
* 直接使用repository的 `DeleteAsync` 方法.
## 权限定义
你还不能编译代码, 因为它需要 `BookStorePermissions` 类定义中一些常数.
打开 `Acme.BookStore.Application.Contracts` 项目中的 `BookStorePermissions` 类 (在 `Permissions` 文件夹中), 修改为如下代码:
````csharp
namespace Acme.BookStore.Permissions
{
public static class BookStorePermissions
{
public const string GroupName = "BookStore";
public static class Books
{
public const string Default = GroupName + ".Books";
public const string Create = Default + ".Create";
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
// *** ADDED a NEW NESTED CLASS ***
public static class Authors
{
public const string Default = GroupName + ".Authors";
public const string Create = Default + ".Create";
public const string Edit = Default + ".Edit";
public const string Delete = Default + ".Delete";
}
}
}
````
然后打开同一项目中的 `BookStorePermissionDefinitionProvider`, 在 `Define` 方法的结尾加入以下行:
````csharp
var authorsPermission = bookStoreGroup.AddPermission(
BookStorePermissions.Authors.Default, L("Permission:Authors"));
authorsPermission.AddChild(
BookStorePermissions.Authors.Create, L("Permission:Authors.Create"));
authorsPermission.AddChild(
BookStorePermissions.Authors.Edit, L("Permission:Authors.Edit"));
authorsPermission.AddChild(
BookStorePermissions.Authors.Delete, L("Permission:Authors.Delete"));
````
最后, 在 `Acme.BookStore.Domain.Shared` 项目中的 `Localization/BookStore/en.json` 加入以下项, 用以本地化权限名称:
````csharp
"Permission:Authors": "Author Management",
"Permission:Authors.Create": "Creating new authors",
"Permission:Authors.Edit": "Editing the authors",
"Permission:Authors.Delete": "Deleting the authors"
````
## 对象到对象映射
`AuthorAppService` 使用 `ObjectMapper` 将 `Author` 对象 转换为 `AuthorDto` 对象. 所以, 我们需要在 AutoMapper 配置中定义映射.
打开 `Acme.BookStore.Application` 项目中的 `BookStoreApplicationAutoMapperProfile` 类, 加入以下行到构造函数:
````csharp
CreateMap<Author, AuthorDto>();
````
## 种子数据
如同图书管理部分所做的, 在数据库中生成一些初始作者实体. 不仅当第一次运行应用程序时是有用的, 对自动化测试也是很有用的.
打开 `Acme.BookStore.Domain` 项目中的 `BookStoreDataSeederContributor`, 修改文件内容如下:
````csharp
using System;
using System.Threading.Tasks;
using Acme.BookStore.Authors;
using Acme.BookStore.Books;
using Volo.Abp.Data;
using Volo.Abp.DependencyInjection;
using Volo.Abp.Domain.Repositories;
namespace Acme.BookStore
{
public class BookStoreDataSeederContributor
: IDataSeedContributor, ITransientDependency
{
private readonly IRepository<Book, Guid> _bookRepository;
private readonly IAuthorRepository _authorRepository;
private readonly AuthorManager _authorManager;
public BookStoreDataSeederContributor(
IRepository<Book, Guid> bookRepository,
IAuthorRepository authorRepository,
AuthorManager authorManager)
{
_bookRepository = bookRepository;
_authorRepository = authorRepository;
_authorManager = authorManager;
}
public async Task SeedAsync(DataSeedContext context)
{
if (await _bookRepository.GetCountAsync() <= 0)
{
await _bookRepository.InsertAsync(
new Book
{
Name = "1984",
Type = BookType.Dystopia,
PublishDate = new DateTime(1949, 6, 8),
Price = 19.84f
},
autoSave: true
);
await _bookRepository.InsertAsync(
new Book
{
Name = "The Hitchhiker's Guide to the Galaxy",
Type = BookType.ScienceFiction,
PublishDate = new DateTime(1995, 9, 27),
Price = 42.0f
},
autoSave: true
);
}
// ADDED SEED DATA FOR AUTHORS
if (await _authorRepository.GetCountAsync() <= 0)
{
await _authorRepository.InsertAsync(
await _authorManager.CreateAsync(
"George Orwell",
new DateTime(1903, 06, 25),
"Orwell produced literary criticism and poetry, fiction and polemical journalism; and is best known for the allegorical novella Animal Farm (1945) and the dystopian novel Nineteen Eighty-Four (1949)."
)
);
await _authorRepository.InsertAsync(
await _authorManager.CreateAsync(
"Douglas Adams",
new DateTime(1952, 03, 11),
"Douglas Adams was an English author, screenwriter, essayist, humorist, satirist and dramatist. Adams was an advocate for environmentalism and conservation, a lover of fast cars, technological innovation and the Apple Macintosh, and a self-proclaimed 'radical atheist'."
)
);
}
}
}
}
````
{{if DB=="EF"}}
你现在可以运行 `.DbMigrator` 控制台应用程序, **迁移** **数据库 schema** 并生成 **种子** 初始数据.
{{else if DB=="Mongo"}}
你现在可以运行 `.DbMigrator` 控制台应用程序, **迁移** **数据库 schema** 并生成 **种子** 初始数据.
{{end}}
## 测试作者应用服务
最后, 你可以为 `IAuthorAppService` 写一些测试. 在 `Acme.BookStore.Application.Tests` 项目的 `Authors` 命名空间(文件夹)中加入一个名为 `AuthorAppService_Tests` 新类:
````csharp
using System;
using System.Threading.Tasks;
using Shouldly;
using Xunit;
namespace Acme.BookStore.Authors
{ {{if DB=="Mongo"}}
[Collection(BookStoreTestConsts.CollectionDefinitionName)]{{end}}
public class AuthorAppService_Tests : BookStoreApplicationTestBase
{
private readonly IAuthorAppService _authorAppService;
public AuthorAppService_Tests()
{
_authorAppService = GetRequiredService<IAuthorAppService>();
}
[Fact]
public async Task Should_Get_All_Authors_Without_Any_Filter()
{
var result = await _authorAppService.GetListAsync(new GetAuthorListDto());
result.TotalCount.ShouldBeGreaterThanOrEqualTo(2);
result.Items.ShouldContain(author => author.Name == "George Orwell");
result.Items.ShouldContain(author => author.Name == "Douglas Adams");
}
[Fact]
public async Task Should_Get_Filtered_Authors()
{
var result = await _authorAppService.GetListAsync(
new GetAuthorListDto {Filter = "George"});
result.TotalCount.ShouldBeGreaterThanOrEqualTo(1);
result.Items.ShouldContain(author => author.Name == "George Orwell");
result.Items.ShouldNotContain(author => author.Name == "Douglas Adams");
}
[Fact]
public async Task Should_Create_A_New_Author()
{
var authorDto = await _authorAppService.CreateAsync(
new CreateAuthorDto
{
Name = "Edward Bellamy",
BirthDate = new DateTime(1850, 05, 22),
ShortBio = "Edward Bellamy was an American author..."
}
);
authorDto.Id.ShouldNotBe(Guid.Empty);
authorDto.Name.ShouldBe("Edward Bellamy");
}
[Fact]
public async Task Should_Not_Allow_To_Create_Duplicate_Author()
{
await Assert.ThrowsAsync<AuthorAlreadyExistsException>(async () =>
{
await _authorAppService.CreateAsync(
new CreateAuthorDto
{
Name = "Douglas Adams",
BirthDate = DateTime.Now,
ShortBio = "..."
}
);
});
}
//TODO: Test other methods...
}
}
````
完成应用服务方法的测试, 它们应该很容易理解.
## 下一章
查看本教程的[下一章](Part-9.md).

1250
docs/zh-Hans/Tutorials/Part-9.md

File diff suppressed because it is too large

BIN
docs/zh-Hans/Tutorials/images/bookstore-efcore-migration-authors.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

2
docs/zh-Hans/docs-nav.json

@ -692,7 +692,7 @@
},
{
"text": "CMS Kit",
"path": "Modules/Cms-Kit.md"
"path": "Modules/Cms-Kit/Index.md"
},
{
"text": "文档",

BIN
docs/zh-Hans/images/features-modal.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 35 KiB

After

Width:  |  Height:  |  Size: 19 KiB

BIN
docs/zh-Hans/images/identity-module-menu.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/zh-Hans/images/identity-module-permissions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 KiB

BIN
docs/zh-Hans/images/identity-module-roles.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

BIN
docs/zh-Hans/images/identity-module-users.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
docs/zh-Hans/images/module-tenant-management-actions.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

BIN
docs/zh-Hans/images/module-tenant-management-new-tenant.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

BIN
docs/zh-Hans/images/module-tenant-management-page.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

4
framework/src/Volo.Abp.AspNetCore.Components.Web.Theming/Layout/PageHeader.razor.cs

@ -37,7 +37,7 @@ public partial class PageHeader : ComponentBase
ToolbarItemRenders = new List<RenderFragment>();
}
protected override async Task OnParametersSetAsync()
protected async override Task OnParametersSetAsync()
{
await base.OnParametersSetAsync();
if (Toolbar != null)
@ -65,7 +65,7 @@ public partial class PageHeader : ComponentBase
}
}
protected override async Task OnInitializedAsync()
protected async override Task OnInitializedAsync()
{
await base.OnInitializedAsync();
}

2
framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Microsoft/AspNetCore/Components/WebAssembly/Hosting/AbpWebAssemblyHostBuilderExtensions.cs

@ -65,7 +65,7 @@ public static class AbpWebAssemblyHostBuilderExtensions
return application;
}
public async static Task InitializeAsync(
public async static Task InitializeApplicationAsync(
[NotNull] this IAbpApplicationWithExternalServiceProvider application,
[NotNull] IServiceProvider serviceProvider)
{

2
framework/src/Volo.Abp.AspNetCore.Components/Volo.Abp.AspNetCore.Components.csproj

@ -15,7 +15,7 @@
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\Volo.Abp.Localization\Volo.Abp.Localization.csproj" />
<ProjectReference Include="..\Volo.Abp.Timing\Volo.Abp.Timing.csproj" />
<ProjectReference Include="..\Volo.Abp.ObjectMapping\Volo.Abp.ObjectMapping.csproj" />
<ProjectReference Include="..\Volo.Abp.Security\Volo.Abp.Security.csproj" />
</ItemGroup>

3
framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpAspNetCoreComponentsModule.cs

@ -6,13 +6,14 @@ using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Security;
using Volo.Abp.Timing;
namespace Volo.Abp.AspNetCore.Components;
[DependsOn(
typeof(AbpObjectMappingModule),
typeof(AbpSecurityModule),
typeof(AbpLocalizationModule)
typeof(AbpTimingModule)
)]
public class AbpAspNetCoreComponentsModule : AbpModule
{

8
framework/src/Volo.Abp.AspNetCore.Components/Volo/Abp/AspNetCore/Components/AbpComponentBase.cs

@ -11,7 +11,9 @@ using Volo.Abp.AspNetCore.Components.ExceptionHandling;
using Volo.Abp.AspNetCore.Components.Messages;
using Volo.Abp.AspNetCore.Components.Notifications;
using Volo.Abp.Localization;
using Volo.Abp.MultiTenancy;
using Volo.Abp.ObjectMapping;
using Volo.Abp.Timing;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Components;
@ -54,6 +56,9 @@ public abstract class AbpComponentBase : OwningComponentBase
protected ICurrentUser CurrentUser => LazyGetRequiredService(ref _currentUser);
private ICurrentUser _currentUser;
protected ICurrentTenant CurrentTenant => LazyGetRequiredService(ref _currentTenant);
private ICurrentTenant _currentTenant;
protected IUiMessageService Message => LazyGetNonScopedRequiredService(ref _message);
private IUiMessageService _message;
@ -66,6 +71,9 @@ public abstract class AbpComponentBase : OwningComponentBase
protected IAlertManager AlertManager => LazyGetNonScopedRequiredService(ref _alertManager);
private IAlertManager _alertManager;
protected IClock Clock => LazyGetNonScopedRequiredService(ref _clock);
private IClock _clock;
protected AlertList Alerts => AlertManager.Alerts;
protected IObjectMapper ObjectMapper {

5
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/Bootstrap/BootstrapScriptContributor.cs

@ -12,5 +12,10 @@ public class BootstrapScriptContributor : BundleContributor
{
context.Files.AddIfNotContains("/libs/bootstrap/js/bootstrap.bundle.js");
context.Files.AddIfNotContains("/libs/bootstrap/js/bootstrap.enable.tooltips.everywhere.js");
if (context.FileProvider.GetFileInfo("/libs/bootstrap/js/bootstrap.enable.popovers.everywhere.js").Exists)
{
context.Files.AddIfNotContains("/libs/bootstrap/js/bootstrap.enable.popovers.everywhere.js");
}
}
}

6
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/sweetalert2/abp-sweetalert2.js

@ -100,10 +100,10 @@ var abp = abp || {};
abp.event.on('abp.configurationInitialized', function () {
var l = abp.localization.getResource('AbpUi');
abp.libs.sweetAlert.config.default.confirmButtonText = l('Yes');
abp.libs.sweetAlert.config.default.denyButtonText = l('No');
abp.libs.sweetAlert.config.default.cancelButtonText = l('Cancel');
abp.libs.sweetAlert.config.confirm.title = l('AreYouSure');
abp.libs.sweetAlert.config.confirm.confirmButtonText = l('Yes');
abp.libs.sweetAlert.config.confirm.denyButtonText = l('No');
abp.libs.sweetAlert.config.confirm.cancelButtonText = l('Cancel');
abp.libs.sweetAlert.config.confirm.showCancelButton = true;
abp.libs.sweetAlert.config.confirm.reverseButtons = true;
});

10
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/AspNetCoreApiDescriptionModelProvider.cs

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@ -80,7 +80,7 @@ public class AspNetCoreApiDescriptionModelProvider : IApiDescriptionModelProvide
var setting = FindSetting(controllerType);
var moduleModel = applicationModel.GetOrAddModule(
GetRootPath(controllerType, setting),
GetRootPath(controllerType, apiDescription.ActionDescriptor, setting),
GetRemoteServiceName(controllerType, setting)
);
@ -327,7 +327,9 @@ public class AspNetCoreApiDescriptionModelProvider : IApiDescriptionModelProvide
return modelNameProvider.Name ?? parameterInfo.Name;
}
private static string GetRootPath([NotNull] Type controllerType,
private static string GetRootPath(
[NotNull] Type controllerType,
[NotNull] ActionDescriptor actionDescriptor,
[CanBeNull] ConventionalControllerSetting setting)
{
if (setting != null)
@ -335,7 +337,7 @@ public class AspNetCoreApiDescriptionModelProvider : IApiDescriptionModelProvide
return setting.RootPath;
}
var areaAttr = controllerType.GetCustomAttributes().OfType<AreaAttribute>().FirstOrDefault();
var areaAttr = controllerType.GetCustomAttributes().OfType<AreaAttribute>().FirstOrDefault() ?? actionDescriptor.EndpointMetadata.OfType<AreaAttribute>().FirstOrDefault();
if (areaAttr != null)
{
return areaAttr.RouteValue;

4
framework/src/Volo.Abp.AutoMapper/Volo/Abp/AutoMapper/AbpAutoMapperConventionalRegistrar.cs

@ -1,7 +1,6 @@
using System;
using System.Linq;
using AutoMapper;
using AutoMapper.Internal;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.DependencyInjection;
@ -19,7 +18,8 @@ public class AbpAutoMapperConventionalRegistrar : DefaultConventionalRegistrar
protected override bool IsConventionalRegistrationDisabled(Type type)
{
return !OpenTypes.Any(type.ImplementsGenericInterface) || base.IsConventionalRegistrationDisabled(type);
return !type.GetInterfaces().Any(x => x.IsGenericType && OpenTypes.Contains(x.GetGenericTypeDefinition())) ||
base.IsConventionalRegistrationDisabled(type);
}
protected override ServiceLifetime? GetDefaultLifeTimeOrNull(Type type)

4
framework/src/Volo.Abp.BackgroundJobs.RabbitMQ/Volo/Abp/BackgroundJobs/RabbitMQ/AbpBackgroundJobsRabbitMqModule.cs

@ -30,12 +30,12 @@ public class AbpBackgroundJobsRabbitMqModule : AbpModule
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
AsyncHelper.RunSync(() => StartJobQueueManagerAsync(context));
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
AsyncHelper.RunSync(() => StopJobQueueManagerAsync(context));
AsyncHelper.RunSync(() => OnApplicationShutdownAsync(context));
}
private async static Task StartJobQueueManagerAsync(ApplicationInitializationContext context)

6
framework/src/Volo.Abp.BackgroundJobs/Volo/Abp/BackgroundJobs/AbpBackgroundJobsModule.cs

@ -30,10 +30,6 @@ public class AbpBackgroundJobsModule : AbpModule
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundJobOptions>>().Value;
if (options.IsJobExecutionEnabled)
{
AsyncHelper.RunSync(() => context.AddBackgroundWorkerAsync<IBackgroundJobWorker>());
}
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
}

2
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/AbpBackgroundWorkersHangfireModule.cs

@ -10,7 +10,7 @@ namespace Volo.Abp.BackgroundWorkers.Hangfire;
[DependsOn(
typeof(AbpBackgroundWorkersModule),
typeof(AbpHangfireModule))]
public class AbpBackgroundWorkerHangfireModule : AbpModule
public class AbpBackgroundWorkersHangfireModule : AbpModule
{
public override void OnPreApplicationInitialization(ApplicationInitializationContext context)
{

31
framework/src/Volo.Abp.BackgroundWorkers.Hangfire/Volo/Abp/BackgroundWorkers/Hangfire/HangfireBackgroundWorkerManager.cs

@ -4,6 +4,7 @@ using System.Threading;
using System.Threading.Tasks;
using Hangfire;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundWorkers.Hangfire;
@ -21,18 +22,18 @@ public class HangfireBackgroundWorkerManager : IBackgroundWorkerManager, ISingle
return Task.CompletedTask;
}
public async Task AddAsync(IBackgroundWorker worker)
public Task AddAsync(IBackgroundWorker worker)
{
if (worker is IHangfireBackgroundWorker hangfireBackgroundWorker)
{
var unProxyWorker = ProxyHelper.UnProxy(hangfireBackgroundWorker);
if (hangfireBackgroundWorker.RecurringJobId.IsNullOrWhiteSpace())
{
RecurringJob.AddOrUpdate(() => hangfireBackgroundWorker.DoWorkAsync(),
hangfireBackgroundWorker.CronExpression);
RecurringJob.AddOrUpdate(() => ((IHangfireBackgroundWorker)unProxyWorker).DoWorkAsync(),hangfireBackgroundWorker.CronExpression);
}
else
{
RecurringJob.AddOrUpdate(hangfireBackgroundWorker.RecurringJobId,() => hangfireBackgroundWorker.DoWorkAsync(),
RecurringJob.AddOrUpdate(hangfireBackgroundWorker.RecurringJobId,() => ((IHangfireBackgroundWorker)unProxyWorker).DoWorkAsync(),
hangfireBackgroundWorker.CronExpression);
}
}
@ -42,25 +43,35 @@ public class HangfireBackgroundWorkerManager : IBackgroundWorkerManager, ISingle
if (worker is AsyncPeriodicBackgroundWorkerBase or PeriodicBackgroundWorkerBase)
{
var timer = (AbpAsyncTimer) worker.GetType()
var timer = worker.GetType()
.GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
period = timer?.Period;
if (worker is AsyncPeriodicBackgroundWorkerBase)
{
period = ((AbpAsyncTimer)timer)?.Period;
}
else
{
period = ((AbpTimer)timer)?.Period;
}
}
else
{
return;
return Task.CompletedTask;
}
if (period == null)
{
return;
return Task.CompletedTask;
}
var adapterType = typeof(HangfirePeriodicBackgroundWorkerAdapter<>).MakeGenericType(worker.GetType());
var adapterType = typeof(HangfirePeriodicBackgroundWorkerAdapter<>).MakeGenericType(ProxyHelper.GetUnProxiedType(worker));
var workerAdapter = Activator.CreateInstance(adapterType) as IHangfireBackgroundWorker;
RecurringJob.AddOrUpdate(() => workerAdapter.DoWorkAsync(), GetCron(period.Value));
}
return Task.CompletedTask;
}
protected virtual string GetCron(int period)
@ -82,7 +93,7 @@ public class HangfireBackgroundWorkerManager : IBackgroundWorkerManager, ISingle
}
else
{
cron = $"0 0 */{time.TotalDays} * *";
throw new AbpException($"Cannot convert period: {period} to cron expression, use HangfireBackgroundWorkerBase to define worker");
}
return cron;

12
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/AbpBackgroundWorkersQuartzModule.cs

@ -52,16 +52,6 @@ public class AbpBackgroundWorkersQuartzModule : AbpModule
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var quartzBackgroundWorkerOptions = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundWorkerQuartzOptions>>().Value;
if (quartzBackgroundWorkerOptions.IsAutoRegisterEnabled)
{
var backgroundWorkerManager = context.ServiceProvider.GetRequiredService<IBackgroundWorkerManager>();
var works = context.ServiceProvider.GetServices<IQuartzBackgroundWorker>().Where(x => x.AutoRegister);
foreach (var work in works)
{
AsyncHelper.RunSync(() => backgroundWorkerManager.AddAsync(work));
}
}
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
}

5
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzBackgroundWorkerManager.cs

@ -1,8 +1,9 @@
using System;
using System;
using System.Threading;
using System.Threading.Tasks;
using Quartz;
using Volo.Abp.DependencyInjection;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundWorkers.Quartz;
@ -56,7 +57,7 @@ public class QuartzBackgroundWorkerManager : IBackgroundWorkerManager, ISingleto
}
else
{
var adapterType = typeof(QuartzPeriodicBackgroundWorkerAdapter<>).MakeGenericType(worker.GetType());
var adapterType = typeof(QuartzPeriodicBackgroundWorkerAdapter<>).MakeGenericType(ProxyHelper.GetUnProxiedType(worker));
var workerAdapter = Activator.CreateInstance(adapterType) as IQuartzBackgroundWorkerAdapter;

43
framework/src/Volo.Abp.BackgroundWorkers.Quartz/Volo/Abp/BackgroundWorkers/Quartz/QuartzPeriodicBackgroundWorkerAdapter.cs

@ -1,7 +1,8 @@
using System;
using System;
using System.Reflection;
using System.Threading.Tasks;
using Quartz;
using Volo.Abp.DynamicProxy;
using Volo.Abp.Threading;
namespace Volo.Abp.BackgroundWorkers.Quartz;
@ -26,17 +27,25 @@ public class QuartzPeriodicBackgroundWorkerAdapter<TWorker> : QuartzBackgroundWo
public void BuildWorker(IBackgroundWorker worker)
{
int? period;
var workerType = worker.GetType();
var workerType = ProxyHelper.GetUnProxiedType(worker);
if (worker is AsyncPeriodicBackgroundWorkerBase || worker is PeriodicBackgroundWorkerBase)
if (worker is AsyncPeriodicBackgroundWorkerBase or PeriodicBackgroundWorkerBase)
{
if (typeof(TWorker) != worker.GetType())
if (typeof(TWorker) != workerType)
{
throw new ArgumentException($"{nameof(worker)} type is different from the generic type");
}
var timer = (AbpAsyncTimer)worker.GetType().GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
period = timer?.Period;
var timer = workerType.GetProperty("Timer", BindingFlags.Instance | BindingFlags.NonPublic)?.GetValue(worker);
if (worker is AsyncPeriodicBackgroundWorkerBase)
{
period = ((AbpAsyncTimer)timer)?.Period;
}
else
{
period = ((AbpTimer)timer)?.Period;
}
}
else
{
@ -60,26 +69,26 @@ public class QuartzPeriodicBackgroundWorkerAdapter<TWorker> : QuartzBackgroundWo
public override async Task Execute(IJobExecutionContext context)
{
var worker = (IBackgroundWorker)ServiceProvider.GetService(typeof(TWorker));
var worker = (IBackgroundWorker) ServiceProvider.GetService(typeof(TWorker));
var workerContext = new PeriodicBackgroundWorkerContext(ServiceProvider);
switch (worker)
{
case AsyncPeriodicBackgroundWorkerBase asyncWorker:
{
if (_doWorkAsyncMethod != null)
{
if (_doWorkAsyncMethod != null)
{
await (Task)_doWorkAsyncMethod.Invoke(asyncWorker, new object[] { workerContext });
}
break;
await (Task) _doWorkAsyncMethod.Invoke(asyncWorker, new object[] {workerContext});
}
break;
}
case PeriodicBackgroundWorkerBase syncWorker:
{
_doWorkMethod?.Invoke(syncWorker, new object[] { workerContext });
{
_doWorkMethod?.Invoke(syncWorker, new object[] {workerContext});
break;
}
break;
}
}
}
}

20
framework/src/Volo.Abp.BackgroundWorkers/Volo/Abp/BackgroundWorkers/AbpBackgroundWorkersModule.cs

@ -35,27 +35,11 @@ public class AbpBackgroundWorkersModule : AbpModule
public override void OnApplicationInitialization(ApplicationInitializationContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundWorkerOptions>>().Value;
if (options.IsEnabled)
{
AsyncHelper.RunSync(
() => context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.StartAsync()
);
}
AsyncHelper.RunSync(() => OnApplicationInitializationAsync(context));
}
public override void OnApplicationShutdown(ApplicationShutdownContext context)
{
var options = context.ServiceProvider.GetRequiredService<IOptions<AbpBackgroundWorkerOptions>>().Value;
if (options.IsEnabled)
{
AsyncHelper.RunSync(
() => context.ServiceProvider
.GetRequiredService<IBackgroundWorkerManager>()
.StopAsync()
);
}
AsyncHelper.RunSync(() => OnApplicationShutdownAsync(context));
}
}

6
framework/src/Volo.Abp.BlazoriseUI/AbpCrudPageBase.cs

@ -212,7 +212,7 @@ public abstract class AbpCrudPageBase<
EntityActions = new EntityActionDictionary();
}
protected override async Task OnInitializedAsync()
protected async override Task OnInitializedAsync()
{
await SetPermissionsAsync();
await SetEntityActionsAsync();
@ -220,7 +220,7 @@ public abstract class AbpCrudPageBase<
await InvokeAsync(StateHasChanged);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
protected async override Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
@ -350,6 +350,7 @@ public abstract class AbpCrudPageBase<
protected virtual Task CloseCreateModalAsync()
{
NewEntity = new TCreateViewModel();
return InvokeAsync(CreateModal.Hide);
}
@ -464,6 +465,7 @@ public abstract class AbpCrudPageBase<
protected virtual async Task OnCreatedEntityAsync()
{
NewEntity = new TCreateViewModel();
await GetEntitiesAsync();
await InvokeAsync(CreateModal.Hide);

18
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor

@ -2,10 +2,20 @@
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
@if (PropertyInfo != null && Entity != null)
{
<Field>
<Check TValue="bool" @bind-Checked="@Value">@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</Check>
</Field>
}
<Validation Validator="@Validate" MessageLocalizer="@LH.Localize">
<Field>
<Check TValue="bool" @bind-Checked="@Value">
<ChildContent>
@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)
</ChildContent>
<Feedback>
<ValidationError/>
</Feedback>
</Check>
</Field>
</Validation>
}

16
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/CheckExtensionProperty.razor.cs

@ -1,22 +1,10 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Data;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class CheckExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class CheckExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
protected bool Value {
get {
return PropertyInfo.GetInputValueOrDefault<bool>(Entity.GetProperty(PropertyInfo.Name));

22
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor

@ -3,15 +3,21 @@
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@using Volo.Abp.ObjectExtending
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
@if (PropertyInfo != null && Entity != null)
{
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<DateEdit TValue="DateTime?"
InputMode="@(PropertyInfo.IsDate() ? DateInputMode.Date : DateInputMode.DateTime)"
Pattern="@PropertyInfo.GetDateEditInputFormatOrNull()"
@bind-Date="@Value">
</DateEdit>
</Field>
<Validation Validator="@Validate" MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<DateEdit TValue="DateTime?"
InputMode="@(PropertyInfo.IsDate() ? DateInputMode.Date : DateInputMode.DateTime)"
Pattern="@PropertyInfo.GetDateEditInputFormatOrNull()"
@bind-Date="@Value">
<Feedback>
<ValidationError/>
</Feedback>
</DateEdit>
</Field>
</Validation>
}

13
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/DateTimeExtensionProperty.razor.cs

@ -5,23 +5,16 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Blazorise;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class DateTimeExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class DateTimeExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
protected DateTime? Value {
get {
return PropertyInfo.GetInputValueOrDefault<DateTime?>(Entity.GetProperty(PropertyInfo.Name));

6
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionProperties.razor

@ -1,7 +1,6 @@
@typeparam TEntityType
@typeparam TResourceType
@using Volo.Abp.ObjectExtending
@using Volo.Abp.Localization
@using Volo.Abp.Data
@{
@ -13,11 +12,11 @@
{
if (propertyInfo.Type.IsEnum)
{
<SelectExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" />
<SelectExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" LH="@LH" />
}
else if (!propertyInfo.Lookup.Url.IsNullOrEmpty())
{
<LookupExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" />
<LookupExtensionProperty PropertyInfo="@propertyInfo" Entity="@Entity" TEntity="TEntityType" TResourceType="TResourceType" LH="@LH" />
}
else
{
@ -25,6 +24,7 @@
__builder.OpenComponent(0, inputType.MakeGenericType(new[] { typeof(TEntityType), typeof(TResourceType) }));
__builder.AddAttribute(1, "PropertyInfo", propertyInfo);
__builder.AddAttribute(2, "Entity", Entity);
__builder.AddAttribute(3, "LH", LH);
__builder.CloseComponent();
}
}

83
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/ExtensionPropertyComponentBase.cs

@ -0,0 +1,83 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using Blazorise;
using Blazorise.Utilities;
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public abstract class ExtensionPropertyComponentBase<TEntity, TResourceType> : OwningComponentBase
where TEntity : IHasExtraProperties
{
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Inject]
public IValidationMessageLocalizerAttributeFinder ValidationMessageLocalizerAttributeFinder { get; set; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
[Parameter]
public AbpBlazorMessageLocalizerHelper<TResourceType> LH { get; set; }
protected virtual void Validate(ValidatorEventArgs e)
{
e.Status = ValidationStatus.Success;
var validationAttributes = PropertyInfo.GetValidationAttributes();
var validationContext = new ValidationContext(Entity)
{
DisplayName = PropertyInfo.Name,
MemberName = PropertyInfo.Name
};
foreach (var validationAttribute in validationAttributes)
{
var result = validationAttribute.GetValidationResult(e.Value, validationContext);
if (result == ValidationResult.Success || result == null)
{
continue;
}
var errorMessage = result.ErrorMessage;
if (LH != null)
{
var formattedErrorMessage = GetDefaultErrorMessage(validationAttribute);
var errorMessageString = ValidationAttributeHelper.RevertErrorMessagePlaceholders(formattedErrorMessage);
var errorMessageArguments = ValidationMessageLocalizerAttributeFinder.FindAll(errorMessage, errorMessageString)
?.OrderBy(x => x.Index)
?.Select(x => x.Argument);
errorMessage = LH.Localize(errorMessageString, errorMessageArguments);
}
e.MemberNames = result.MemberNames;
e.Status = ValidationStatus.Error;
e.ErrorText = errorMessage;
break;
}
}
private static string GetDefaultErrorMessage(ValidationAttribute validationAttribute)
{
if (validationAttribute is StringLengthAttribute stringLengthAttribute && stringLengthAttribute.MinimumLength != 0)
{
var nullable = ValidationAttributeHelper.ValidationAttributeCustomErrorMessageSetProperty.GetValue((object) validationAttribute) as bool?;
var flag = true;
if (!(nullable.GetValueOrDefault() == flag & nullable.HasValue))
{
return ValidationAttributeHelper.SetErrorMessagePlaceholders("The field {0} must be a string with a minimum length of {2} and a maximum length of {1}.");
}
}
return ValidationAttributeHelper.SetErrorMessagePlaceholders(ValidationAttributeHelper.ValidationAttributeErrorMessageStringProperty.GetValue((object) validationAttribute) as string);
}
}

8
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor

@ -2,18 +2,20 @@
@typeparam TResourceType
@using Abp.Localization
@using Blazorise.Components
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<Autocomplete Data="@lookupItems"
TItem="SelectItem<object>"
TValue="object"
TextField="item=>item.Text"
ValueField="item=>item.Value"
TextField="item => item?.Text"
ValueField="item => item?.Value"
SelectedText="@SelectedText"
SelectedValue="@SelectedValue"
SelectedValueChanged="@SelectedValueChanged"
SearchChanged="@SearchFilterChangedAsync"
Validator="@Validate"
MinLength="0">
</Autocomplete>
</Field>

45
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/LookupExtensionProperty.razor.cs

@ -9,6 +9,8 @@ using System.Net.Http;
using System.Net.Http.Headers;
using System.Text.Json;
using System.Threading.Tasks;
using Blazorise;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.AspNetCore.Components.Web.Extensibility;
using Volo.Abp.Data;
using Volo.Abp.Http;
@ -18,18 +20,11 @@ using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class LookupExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class LookupExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
protected List<SelectItem<object>> lookupItems;
[Inject] public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter] public TEntity Entity { get; set; }
[Parameter] public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
[Inject] public ILookupApiRequestService LookupApiService { get; set; }
public string TextPropertyName => PropertyInfo.Name + "_Text";
@ -42,28 +37,22 @@ public partial class LookupExtensionProperty<TEntity, TResourceType> : Component
}
}
public string SelectedText => Entity.GetProperty<string>(TextPropertyName);
public LookupExtensionProperty()
{
lookupItems = new List<SelectItem<object>>();
}
protected override void OnParametersSet()
protected async override Task OnInitializedAsync()
{
var value = Entity.GetProperty(PropertyInfo.Name);
var text = Entity.GetProperty(TextPropertyName);
if (value != null && text != null)
{
lookupItems.Add(new SelectItem<object>
{
Text = Entity.GetProperty(TextPropertyName).ToString(),
Value = value
});
}
await base.OnInitializedAsync();
await SearchFilterChangedAsync(string.Empty);
}
protected virtual void UpdateLookupTextProperty(object value)
{
var selectedItemText = lookupItems.SingleOrDefault(t => t.Value.Equals(value)).Text;
var selectedItemText = lookupItems.SingleOrDefault(t => t.Value.Equals(value))?.Text;
Entity.SetProperty(TextPropertyName, selectedItemText);
}
@ -86,8 +75,7 @@ public partial class LookupExtensionProperty<TEntity, TResourceType> : Component
selectItems.Add(new SelectItem<object>
{
Text = item.GetProperty(PropertyInfo.Lookup.DisplayPropertyName).GetString(),
Value = JsonSerializer.Deserialize(
item.GetProperty(PropertyInfo.Lookup.ValuePropertyName).GetRawText(), PropertyInfo.Type)
Value = JsonSerializer.Deserialize(item.GetProperty(PropertyInfo.Lookup.ValuePropertyName).GetRawText(), PropertyInfo.Type)
});
}
@ -97,22 +85,11 @@ public partial class LookupExtensionProperty<TEntity, TResourceType> : Component
protected virtual Task SelectedValueChanged(object selectedItem)
{
SelectedValue = selectedItem;
return Task.CompletedTask;
}
protected async Task SearchFilterChangedAsync(string filter)
protected virtual async Task SearchFilterChangedAsync(string filter)
{
lookupItems = await GetLookupItemsAsync(filter);
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await base.OnAfterRenderAsync(firstRender);
if (firstRender)
{
await SearchFilterChangedAsync(string.Empty);
}
}
}

26
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor

@ -1,13 +1,21 @@
@typeparam TEntity
@typeparam TResourceType
@using Abp.Localization
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<Select @bind-SelectedValue="@SelectedValue" >
@foreach (var item in SelectItems)
{
<SelectItem Value="@item.Value">@item.Text</SelectItem>
}
</Select>
</Field>
<Validation Validator="@Validate" MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<Select @bind-SelectedValue="@SelectedValue">
<ChildContent>
@foreach (var item in SelectItems)
{
<SelectItem Value="@item.Value">@item.Text</SelectItem>
}
</ChildContent>
<Feedback>
<ValidationError/>
</Feedback>
</Select>
</Field>
</Validation>

11
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/SelectExtensionProperty.razor.cs

@ -2,23 +2,20 @@
using Microsoft.Extensions.Localization;
using System;
using System.Collections.Generic;
using System.Linq;
using Blazorise;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.Data;
using Volo.Abp.Localization;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class SelectExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class SelectExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
protected List<SelectItem<int>> SelectItems = new();
[Inject] public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter] public TEntity Entity { get; set; }
[Parameter] public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
public int SelectedValue {
get { return Entity.GetProperty<int>(PropertyInfo.Name); }
set { Entity.SetProperty(PropertyInfo.Name, value, false); }

19
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor

@ -2,13 +2,18 @@
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
@if (PropertyInfo != null && Entity != null)
{
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<TextEdit @bind-Text="@Value" Role="@PropertyInfo.GetTextRole()" InputMode="@PropertyInfo.GetTextInputMode()">
</TextEdit>
</Field>
}
<Validation Validator="@Validate" MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>
<TextEdit @bind-Text="@Value" Role="@PropertyInfo.GetTextRole()" InputMode="@PropertyInfo.GetTextInputMode()">
<Feedback>
<ValidationError/>
</Feedback>
</TextEdit>
</Field>
</Validation>
}

17
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TextExtensionProperty.razor.cs

@ -1,23 +1,10 @@
using Microsoft.AspNetCore.Components;
using Microsoft.Extensions.Localization;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
using Volo.Abp.Data;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class TextExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class TextExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
protected string Value {
get {
return PropertyInfo.GetTextInputValueOrNull(Entity.GetProperty(PropertyInfo.Name));

18
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor

@ -2,12 +2,18 @@
@typeparam TResourceType
@using Volo.Abp.BlazoriseUI
@using Volo.Abp.Localization
@inherits ExtensionPropertyComponentBase<TEntity, TResourceType>
@if (PropertyInfo != null && Entity != null)
{
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>-->
<TimeEdit TValue="TimeSpan?" @bind-Time="@Value">
</TimeEdit>
</Field>
}
<Validation Validator="@Validate" MessageLocalizer="@LH.Localize">
<Field>
<FieldLabel>@PropertyInfo.GetLocalizedDisplayName(StringLocalizerFactory)</FieldLabel>-->
<TimeEdit TValue="TimeSpan?" @bind-Time="@Value">
<Feedback>
<ValidationError/>
</Feedback>
</TimeEdit>
</Field>
</Validation>
}

13
framework/src/Volo.Abp.BlazoriseUI/Components/ObjectExtending/TimeExtensionProperty.razor.cs

@ -5,23 +5,16 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Blazorise;
using Volo.Abp.AspNetCore.Components.Web;
using Volo.Abp.Data;
using Volo.Abp.ObjectExtending;
namespace Volo.Abp.BlazoriseUI.Components.ObjectExtending;
public partial class TimeExtensionProperty<TEntity, TResourceType> : ComponentBase
public partial class TimeExtensionProperty<TEntity, TResourceType>
where TEntity : IHasExtraProperties
{
[Inject]
public IStringLocalizerFactory StringLocalizerFactory { get; set; }
[Parameter]
public TEntity Entity { get; set; }
[Parameter]
public ObjectExtensionPropertyInfo PropertyInfo { get; set; }
protected TimeSpan? Value {
get {
return PropertyInfo.GetInputValueOrDefault<TimeSpan?>(Entity.GetProperty(PropertyInfo.Name));

8
framework/src/Volo.Abp.BlazoriseUI/Volo.Abp.BlazoriseUI.csproj

@ -14,10 +14,10 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Blazorise" Version="0.9.5" />
<PackageReference Include="Blazorise.DataGrid" Version="0.9.5" />
<PackageReference Include="Blazorise.Snackbar" Version="0.9.5" />
<PackageReference Include="Blazorise.Components" Version="0.9.5" />
<PackageReference Include="Blazorise" Version="0.9.5.4" />
<PackageReference Include="Blazorise.DataGrid" Version="0.9.5.4" />
<PackageReference Include="Blazorise.Snackbar" Version="0.9.5.4" />
<PackageReference Include="Blazorise.Components" Version="0.9.5.4" />
</ItemGroup>
</Project>

7
framework/src/Volo.Abp.BlobStoring/Volo/Abp/BlobStoring/DefaultBlobProviderSelector.cs

@ -30,7 +30,12 @@ public class DefaultBlobProviderSelector : IBlobProviderSelector, ITransientDepe
if (!BlobProviders.Any())
{
throw new AbpException("No BLOB Storage provider was registered! At least one provider must be registered to be able to use the Blog Storing System.");
throw new AbpException("No BLOB Storage provider was registered! At least one provider must be registered to be able to use the BLOB Storing System.");
}
if (configuration.ProviderType == null)
{
throw new AbpException("No BLOB Storage provider was used! At least one provider must be configured to be able to use the BLOB Storing System.");
}
foreach (var provider in BlobProviders)

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save